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) 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(nullptr) { } ~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 bool forwardCompatible; // true if errors are to be given for use of deprecated features 121 EProfile profile; // the declared profile in the shader (core by default) isEsProfile()122 bool isEsProfile() const { return profile == EEsProfile; } 123 void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc); 124 void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, 125 const char* const extensions[], const char* featureDesc); 126 void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, 127 const char* featureDesc); 128 virtual void initializeExtensionBehavior(); 129 virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc); 130 virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc); 131 virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], 132 const char* featureDesc); 133 virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], 134 const char* featureDesc); 135 virtual TExtensionBehavior getExtensionBehavior(const char*); 136 virtual bool extensionTurnedOn(const char* const extension); 137 virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); 138 virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior); 139 virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior); 140 virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], 141 const char* featureDesc); 142 virtual void checkExtensionStage(const TSourceLoc&, const char* const extension); 143 virtual void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior); 144 virtual void fullIntegerCheck(const TSourceLoc&, const char* op); 145 146 virtual void unimplemented(const TSourceLoc&, const char* featureDesc); 147 virtual void doubleCheck(const TSourceLoc&, const char* op); 148 virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false); 149 virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); 150 virtual bool float16Arithmetic(); 151 virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); 152 virtual void int16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); 153 virtual bool int16Arithmetic(); 154 virtual void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); 155 virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); 156 virtual bool int8Arithmetic(); 157 virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); 158 virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false); 159 virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false); 160 virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false); 161 virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false); 162 virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false); 163 virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false); 164 virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false); 165 virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); 166 virtual void intcoopmatCheck(const TSourceLoc&, const char *op, bool builtIn = false); relaxedErrors()167 bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } suppressWarnings()168 bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } isForwardCompatible()169 bool isForwardCompatible() const { return forwardCompatible; } 170 #endif // GLSLANG_WEB 171 virtual void spvRemoved(const TSourceLoc&, const char* op); 172 virtual void vulkanRemoved(const TSourceLoc&, const char* op); 173 virtual void requireVulkan(const TSourceLoc&, const char* op); 174 virtual void requireSpv(const TSourceLoc&, const char* op); 175 virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version); 176 177 178 #if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL) error(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)179 void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, 180 const char* szExtraInfoFormat, ...) { addError(); } warn(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)181 void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, 182 const char* szExtraInfoFormat, ...) { } ppError(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)183 void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, 184 const char* szExtraInfoFormat, ...) { addError(); } ppWarn(const TSourceLoc &,const char * szReason,const char * szToken,const char * szExtraInfoFormat,...)185 void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, 186 const char* szExtraInfoFormat, ...) { } 187 #else 188 virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, 189 const char* szExtraInfoFormat, ...) = 0; 190 virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, 191 const char* szExtraInfoFormat, ...) = 0; 192 virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, 193 const char* szExtraInfoFormat, ...) = 0; 194 virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, 195 const char* szExtraInfoFormat, ...) = 0; 196 #endif 197 addError()198 void addError() { ++numErrors; } getNumErrors()199 int getNumErrors() const { return numErrors; } 200 setScanner(TInputScanner * scanner)201 void setScanner(TInputScanner* scanner) { currentScanner = scanner; } getScanner()202 TInputScanner* getScanner() const { return currentScanner; } getCurrentLoc()203 const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); } setCurrentLine(int line)204 void setCurrentLine(int line) { currentScanner->setLine(line); } setCurrentColumn(int col)205 void setCurrentColumn(int col) { currentScanner->setColumn(col); } setCurrentSourceName(const char * name)206 void setCurrentSourceName(const char* name) { currentScanner->setFile(name); } setCurrentString(int string)207 void setCurrentString(int string) { currentScanner->setString(string); } 208 209 void getPreamble(std::string&); 210 #ifdef ENABLE_HLSL isReadingHLSL()211 bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } hlslEnable16BitTypes()212 bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } hlslDX9Compatible()213 bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; } 214 #else isReadingHLSL()215 bool isReadingHLSL() const { return false; } 216 #endif 217 218 TInfoSink& infoSink; 219 220 // compilation mode 221 int version; // version, updated by #version in the shader 222 EShLanguage language; // really the stage 223 SpvVersion spvVersion; 224 TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree 225 226 protected: 227 TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is 228 TMap<TString, unsigned int> extensionMinSpv; // for each extension string, store minimum spirv required 229 EShMessages messages; // errors/warnings/rule-sets 230 int numErrors; // number of compile-time errors encountered 231 TInputScanner* currentScanner; 232 233 private: 234 explicit TParseVersions(const TParseVersions&); 235 TParseVersions& operator=(const TParseVersions&); 236 }; 237 238 } // end namespace glslang 239 240 #endif // _PARSE_VERSIONS_INCLUDED_ 241