diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 6d2ec6bc..abb71330 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -175,6 +175,9 @@ void TParseContext::parserError(const char* s) void TParseContext::handlePragma(TSourceLoc loc, const TVector& tokens) { + if (pragmaCallback) + pragmaCallback(loc.line, tokens); + if (tokens.size() == 0) return; @@ -5223,4 +5226,20 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression, return switchNode; } +void TParseContext::setCurrentLine(int line) +{ + currentScanner->setLine(line); + if (lineCallback) { + lineCallback(line); + } +} + +void TParseContext::notifyVersion(int line, int version, const char* type_string) +{ + if (versionCallback) { + versionCallback(line, version, type_string); + } +} + + } // end namespace glslang diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 7cfc62cb..5aaaf289 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -42,6 +42,8 @@ #include "localintermediate.h" #include "Scan.h" +#include + namespace glslang { struct TPragma { @@ -198,9 +200,11 @@ public: void addError() { ++numErrors; } int getNumErrors() const { return numErrors; } const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); } - void setCurrentLine(int line) { currentScanner->setLine(line); } + void setCurrentLine(int line); void setCurrentString(int string) { currentScanner->setString(string); } + void notifyVersion(int line, int version, const char* type_string); + // The following are implemented in Versions.cpp to localize version/profile/stage/extensions control void initializeExtensionBehavior(); void requireProfile(TSourceLoc, int queryProfiles, const char* featureDesc); @@ -213,10 +217,15 @@ public: void requireExtensions(TSourceLoc, int numExtensions, const char* const extensions[], const char* featureDesc); TExtensionBehavior getExtensionBehavior(const char*); bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); - void updateExtensionBehavior(const char* const extension, const char* behavior); + void updateExtensionBehavior(int line, const char* const extension, const char* behavior); void fullIntegerCheck(TSourceLoc, const char* op); void doubleCheck(TSourceLoc, const char* op); + void setVersionCallback(const std::function& func) { versionCallback = func; } + void setPragmaCallback(const std::function&)>& func) { pragmaCallback = func; } + void setLineCallback(const std::function& func) { lineCallback = func; } + void setExtensionCallback(const std::function& func) { extensionCallback = func; } + protected: void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type); void inheritGlobalDefaults(TQualifier& dst) const; @@ -321,6 +330,13 @@ protected: // array-sizing declarations // TVector ioArraySymbolResizeList; + + // These, if set, will be called when a line, pragma ... is preprocessed. + // They will be called with any parameters to the original directive. + std::function lineCallback; + std::function&)> pragmaCallback; + std::function versionCallback; + std::function extensionCallback; }; } // end namespace glslang diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index e7531cb8..e64732c0 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -462,8 +462,11 @@ bool TParseContext::extensionsTurnedOn(int numExtensions, const char* const exte // // Change the current state of an extension's behavior. // -void TParseContext::updateExtensionBehavior(const char* extension, const char* behaviorString) +void TParseContext::updateExtensionBehavior(int line, const char* extension, const char* behaviorString) { + if (extensionCallback) + extensionCallback(line, extension, behaviorString); + // Translate from text string of extension's behavior to an enum. TExtensionBehavior behavior = EBhDisable; if (! strcmp("require", behaviorString)) @@ -485,29 +488,29 @@ void TParseContext::updateExtensionBehavior(const char* extension, const char* b // see if need to propagate to implicitly modified things if (strcmp(extension, "GL_ANDROID_extension_pack_es31a") == 0) { // to everything in AEP - updateExtensionBehavior("GL_KHR_blend_equation_advanced", behaviorString); - updateExtensionBehavior("GL_OES_sample_variables", behaviorString); - updateExtensionBehavior("GL_OES_shader_image_atomic", behaviorString); - updateExtensionBehavior("GL_OES_shader_multisample_interpolation", behaviorString); - updateExtensionBehavior("GL_OES_texture_storage_multisample_2d_array", behaviorString); - updateExtensionBehavior("GL_EXT_geometry_shader", behaviorString); - updateExtensionBehavior("GL_EXT_gpu_shader5", behaviorString); - updateExtensionBehavior("GL_EXT_primitive_bounding_box", behaviorString); - updateExtensionBehavior("GL_EXT_shader_io_blocks", behaviorString); - updateExtensionBehavior("GL_EXT_tessellation_shader", behaviorString); - updateExtensionBehavior("GL_EXT_texture_buffer", behaviorString); - updateExtensionBehavior("GL_EXT_texture_cube_map_array", behaviorString); + updateExtensionBehavior(line, "GL_KHR_blend_equation_advanced", behaviorString); + updateExtensionBehavior(line, "GL_OES_sample_variables", behaviorString); + updateExtensionBehavior(line, "GL_OES_shader_image_atomic", behaviorString); + updateExtensionBehavior(line, "GL_OES_shader_multisample_interpolation", behaviorString); + updateExtensionBehavior(line, "GL_OES_texture_storage_multisample_2d_array", behaviorString); + updateExtensionBehavior(line, "GL_EXT_geometry_shader", behaviorString); + updateExtensionBehavior(line, "GL_EXT_gpu_shader5", behaviorString); + updateExtensionBehavior(line, "GL_EXT_primitive_bounding_box", behaviorString); + updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString); + updateExtensionBehavior(line, "GL_EXT_tessellation_shader", behaviorString); + updateExtensionBehavior(line, "GL_EXT_texture_buffer", behaviorString); + updateExtensionBehavior(line, "GL_EXT_texture_cube_map_array", behaviorString); } // geometry to io_blocks else if (strcmp(extension, "GL_EXT_geometry_shader") == 0) - updateExtensionBehavior("GL_EXT_shader_io_blocks", behaviorString); + updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString); else if (strcmp(extension, "GL_OES_geometry_shader") == 0) - updateExtensionBehavior("GL_OES_shader_io_blocks", behaviorString); + updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString); // tessellation to io_blocks else if (strcmp(extension, "GL_EXT_tessellation_shader") == 0) - updateExtensionBehavior("GL_EXT_shader_io_blocks", behaviorString); + updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString); else if (strcmp(extension, "GL_OES_tessellation_shader") == 0) - updateExtensionBehavior("GL_OES_shader_io_blocks", behaviorString); + updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString); } void TParseContext::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior) diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index 4b04fed3..c309d554 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -743,17 +743,19 @@ int TPpContext::CPPversion(TPpToken* ppToken) parseContext.error(ppToken->loc, "must be followed by version number", "#version", ""); ppToken->ival = atoi(ppToken->name); - + int versionNumber = ppToken->ival; + int line = ppToken->loc.line; token = scanToken(ppToken); - if (token == '\n') + if (token == '\n') { + parseContext.notifyVersion(line, versionNumber, nullptr); return token; - else { + } else { if (ppToken->atom != coreAtom && ppToken->atom != compatibilityAtom && ppToken->atom != esAtom) parseContext.error(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", ""); - + parseContext.notifyVersion(line, versionNumber, GetAtomString(ppToken->atom)); token = scanToken(ppToken); if (token == '\n') @@ -768,6 +770,7 @@ int TPpContext::CPPversion(TPpToken* ppToken) // Handle #extension int TPpContext::CPPextension(TPpToken* ppToken) { + int line = ppToken->loc.line; int token = scanToken(ppToken); char extensionName[80]; @@ -793,7 +796,7 @@ int TPpContext::CPPextension(TPpToken* ppToken) return token; } - parseContext.updateExtensionBehavior(extensionName, GetAtomString(ppToken->atom)); + parseContext.updateExtensionBehavior(line, extensionName, GetAtomString(ppToken->atom)); token = scanToken(ppToken); if (token == '\n')