1 // 2 // Copyright (C) 2015-2018 Google, Inc. 3 // Copyright (C) 2017 ARM Limited. 4 // 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions 9 // are met: 10 // 11 // Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // 14 // Redistributions in binary form must reproduce the above 15 // copyright notice, this list of conditions and the following 16 // disclaimer in the documentation and/or other materials provided 17 // with the distribution. 18 // 19 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 20 // contributors may be used to endorse or promote products derived 21 // from this software without specific prior written permission. 22 // 23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 // POSSIBILITY OF SUCH DAMAGE. 35 // 36 37 // This is implemented in Versions.cpp 38 39 #ifndef _PARSE_VERSIONS_INCLUDED_ 40 #define _PARSE_VERSIONS_INCLUDED_ 41 42 #include "../Public/ShaderLang.h" 43 #include "../Include/InfoSink.h" 44 #include "Scan.h" 45 46 #include <map> 47 48 namespace glslang { 49 50 // 51 // Base class for parse helpers. 52 // This just has version-related information and checking. 53 // This class should be sufficient for preprocessing. 54 // 55 class TParseVersions { 56 public: TParseVersions(TIntermediate & interm,int version,EProfile profile,const SpvVersion & spvVersion,EShLanguage language,TInfoSink & infoSink,bool forwardCompatible,EShMessages messages)57 TParseVersions(TIntermediate& interm, int version, EProfile profile, 58 const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, 59 bool forwardCompatible, EShMessages messages) 60 : 61 #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) 62 forwardCompatible(forwardCompatible), 63 profile(profile), 64 #endif 65 infoSink(infoSink), version(version), 66 language(language), 67 spvVersion(spvVersion), 68 intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } ~TParseVersions()69 virtual ~TParseVersions() { } 70 void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); 71 void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); 72 #ifdef GLSLANG_WEB 73 const EProfile profile = EEsProfile; isEsProfile()74 bool isEsProfile() const { return true; } requireProfile(const TSourceLoc & loc,int profileMask,const char * featureDesc)75 void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) 76 { 77 if (! (EEsProfile & profileMask)) 78 error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); 79 } profileRequires(const TSourceLoc & loc,int profileMask,int minVersion,int numExtensions,const char * const extensions[],const char * featureDesc)80 void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, 81 const char* const extensions[], const char* featureDesc) 82 { 83 if ((EEsProfile & profileMask) && (minVersion == 0 || version < minVersion)) 84 error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); 85 } profileRequires(const TSourceLoc & loc,int profileMask,int minVersion,const char * extension,const char * featureDesc)86 void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, 87 const char* featureDesc) 88 { 89 profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); 90 } initializeExtensionBehavior()91 void initializeExtensionBehavior() { } checkDeprecated(const TSourceLoc &,int queryProfiles,int depVersion,const char * featureDesc)92 void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { } requireNotRemoved(const TSourceLoc &,int queryProfiles,int removedVersion,const char * featureDesc)93 void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { } requireExtensions(const TSourceLoc &,int numExtensions,const char * const extensions[],const char * featureDesc)94 void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], 95 const char* featureDesc) { } ppRequireExtensions(const TSourceLoc &,int numExtensions,const char * const extensions[],const char * featureDesc)96 void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], 97 const char* featureDesc) { } getExtensionBehavior(const char *)98 TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; } extensionTurnedOn(const char * const extension)99 bool extensionTurnedOn(const char* const extension) { return false; } extensionsTurnedOn(int numExtensions,const char * const extensions[])100 bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; } updateExtensionBehavior(int line,const char * const extension,const char * behavior)101 void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { } updateExtensionBehavior(const char * const extension,TExtensionBehavior)102 void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { } checkExtensionStage(const TSourceLoc &,const char * const extension)103 void checkExtensionStage(const TSourceLoc&, const char* const extension) { } extensionRequires(const TSourceLoc &,const char * const extension,const char * behavior)104 void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior) { } fullIntegerCheck(const TSourceLoc &,const char * op)105 void fullIntegerCheck(const TSourceLoc&, const char* op) { } doubleCheck(const TSourceLoc &,const char * op)106 void doubleCheck(const TSourceLoc&, const char* op) { } float16Arithmetic()107 bool float16Arithmetic() { return false; } requireFloat16Arithmetic(const TSourceLoc & loc,const char * op,const char * featureDesc)108 void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } int16Arithmetic()109 bool int16Arithmetic() { return false; } requireInt16Arithmetic(const TSourceLoc & loc,const char * op,const char * featureDesc)110 void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } int8Arithmetic()111 bool int8Arithmetic() { return false; } requireInt8Arithmetic(const TSourceLoc & loc,const char * op,const char * featureDesc)112 void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } 113 void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } 114 void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { } 115 void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } relaxedErrors()116 bool relaxedErrors() const { return false; } suppressWarnings()117 bool suppressWarnings() const { return true; } isForwardCompatible()118 bool isForwardCompatible() const { return false; } 119 #else 120 #ifdef GLSLANG_ANGLE 121 const bool forwardCompatible = true; 122 const EProfile profile = ECoreProfile; 123 #else 124 bool forwardCompatible; // true if errors are to be given for use of deprecated features 125 EProfile profile; // the declared profile in the shader (core by default) 126 #endif isEsProfile()127 bool isEsProfile() const { return profile == EEsProfile; } 128 void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc); 129 void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, 130 const char* const extensions[], const char* featureDesc); 131 void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, 132 const char* featureDesc); 133 virtual void initializeExtensionBehavior(); 134 virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc); 135 virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc); 136 virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], 137 const char* featureDesc); 138 virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], 139 const char* featureDesc); 140 virtual TExtensionBehavior getExtensionBehavior(const char*); 141 virtual bool extensionTurnedOn(const char* const extension); 142 virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); 143 virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior); 144 virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior); 145 virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], 146 const char* featureDesc); 147 virtual void checkExtensionStage(const TSourceLoc&, const char* const extension); 148 virtual void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior); 149 virtual void fullIntegerCheck(const TSourceLoc&, const char* op); 150 151 virtual void unimplemented(const TSourceLoc&, const char* featureDesc); 152 virtual void doubleCheck(const TSourceLoc&, const char* op); 153 virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false); 154 virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); 155 virtual bool float16Arithmetic(); 156 virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); 157 virtual void int16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); 158 virtual bool int16Arithmetic(); 159 virtual void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); 160 virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); 161 virtual bool int8Arithmetic(); 162 virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); 163 virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false); 164 virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false); 165 virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false); 166 virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false); 167 virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false); 168 virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false); 169 virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false); 170 virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); 171 virtual void intcoopmatCheck(const TSourceLoc&, const char *op, bool builtIn = false); relaxedErrors()172 bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } suppressWarnings()173 bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } isForwardCompatible()174 bool isForwardCompatible() const { return forwardCompatible; } 175 #endif // GLSLANG_WEB 176 virtual void spvRemoved(const TSourceLoc&, const char* op); 177 virtual void vulkanRemoved(const TSourceLoc&, const char* op); 178 virtual void requireVulkan(const TSourceLoc&, const char* op); 179 virtual void requireSpv(const TSourceLoc&, const char* op); 180 virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version); 181 182 183 #if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL) error(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)184 void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, 185 const char* szExtraInfoFormat, ...) { addError(); } warn(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)186 void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, 187 const char* szExtraInfoFormat, ...) { } ppError(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)188 void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, 189 const char* szExtraInfoFormat, ...) { addError(); } ppWarn(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)190 void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, 191 const char* szExtraInfoFormat, ...) { } 192 #else 193 virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, 194 const char* szExtraInfoFormat, ...) = 0; 195 virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, 196 const char* szExtraInfoFormat, ...) = 0; 197 virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, 198 const char* szExtraInfoFormat, ...) = 0; 199 virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, 200 const char* szExtraInfoFormat, ...) = 0; 201 #endif 202 addError()203 void addError() { ++numErrors; } getNumErrors()204 int getNumErrors() const { return numErrors; } 205 setScanner(TInputScanner * scanner)206 void setScanner(TInputScanner* scanner) { currentScanner = scanner; } getScanner()207 TInputScanner* getScanner() const { return currentScanner; } getCurrentLoc()208 const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); } setCurrentLine(int line)209 void setCurrentLine(int line) { currentScanner->setLine(line); } setCurrentColumn(int col)210 void setCurrentColumn(int col) { currentScanner->setColumn(col); } setCurrentSourceName(const char * name)211 void setCurrentSourceName(const char* name) { currentScanner->setFile(name); } setCurrentString(int string)212 void setCurrentString(int string) { currentScanner->setString(string); } 213 214 void getPreamble(std::string&); 215 #ifdef ENABLE_HLSL isReadingHLSL()216 bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } hlslEnable16BitTypes()217 bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } hlslDX9Compatible()218 bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; } 219 #else isReadingHLSL()220 bool isReadingHLSL() const { return false; } 221 #endif 222 223 TInfoSink& infoSink; 224 225 // compilation mode 226 int version; // version, updated by #version in the shader 227 EShLanguage language; // really the stage 228 SpvVersion spvVersion; 229 TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree 230 231 protected: 232 TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is 233 TMap<TString, unsigned int> extensionMinSpv; // for each extension string, store minimum spirv required 234 EShMessages messages; // errors/warnings/rule-sets 235 int numErrors; // number of compile-time errors encountered 236 TInputScanner* currentScanner; 237 238 private: 239 explicit TParseVersions(const TParseVersions&); 240 TParseVersions& operator=(const TParseVersions&); 241 }; 242 243 } // end namespace glslang 244 245 #endif // _PARSE_VERSIONS_INCLUDED_ 246