glslang front-end: Added a callback mechanism for #line/#pragma/#version/#extension. From Andrew Woloszyn <awoloszyn@google.com>.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@31507 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2015-06-16 23:08:00 +00:00
parent 47632b7aaf
commit 9288f46b95
4 changed files with 65 additions and 24 deletions

View File

@ -175,6 +175,9 @@ void TParseContext::parserError(const char* s)
void TParseContext::handlePragma(TSourceLoc loc, const TVector<TString>& 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

View File

@ -42,6 +42,8 @@
#include "localintermediate.h"
#include "Scan.h"
#include <functional>
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<void(int, int, const char*)>& func) { versionCallback = func; }
void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; }
void setLineCallback(const std::function<void(int)>& func) { lineCallback = func; }
void setExtensionCallback(const std::function<void(int, const char*, const char*)>& 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<TSymbol*> 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<void(int)> lineCallback;
std::function<void(int, const TVector<TString>&)> pragmaCallback;
std::function<void(int, int, const char*)> versionCallback;
std::function<void(int, const char*, const char*)> extensionCallback;
};
} // end namespace glslang

View File

@ -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)

View File

@ -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')