From 2f1eb37d82d290371f63465716a593ba8492ef87 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Tue, 3 Sep 2013 22:57:27 +0000 Subject: [PATCH] Some rationalization of TIntermediate (to own it's own tree root) and TParseHelper for better encapsulation. Needed by some upcoming intra-stage link validation. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22914 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- glslang/MachineIndependent/Intermediate.cpp | 10 +- glslang/MachineIndependent/ParseHelper.cpp | 11 +- glslang/MachineIndependent/ParseHelper.h | 101 ++++++++++-------- glslang/MachineIndependent/Scan.cpp | 2 +- glslang/MachineIndependent/ShaderLang.cpp | 32 +++--- glslang/MachineIndependent/glslang.y | 4 +- glslang/MachineIndependent/intermOut.cpp | 7 +- .../MachineIndependent/localintermediate.h | 22 ++-- 8 files changed, 107 insertions(+), 82 deletions(-) diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 20eddec7..4d839c3a 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -41,6 +41,8 @@ #include "localintermediate.h" #include "QualifierAlive.h" #include "RemoveTree.h" +#include "SymbolTable.h" + #include namespace glslang { @@ -910,10 +912,10 @@ void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TVari // // This deletes the tree. // -void TIntermediate::remove(TIntermNode* root) +void TIntermediate::removeTree() { - if (root) - RemoveAllTreeNodes(root); + if (treeRoot) + RemoveAllTreeNodes(treeRoot); } //////////////////////////////////////////////////////////////// @@ -1406,7 +1408,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC case EbtDouble: leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); break; - default: + default: return node; } break; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index f2429ae3..e6599e0b 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -35,6 +35,7 @@ // #include "ParseHelper.h" + #include "osinclude.h" #include #include @@ -47,11 +48,11 @@ namespace glslang { TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is, bool fc, EShMessages m) : - intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0), linkage(0), - numErrors(0), loopNestingLevel(0), - structNestingLevel(0), inTypeParen(false), parsingBuiltins(pb), - version(v), profile(p), forwardCompatible(fc), messages(m), - contextPragma(true, false), afterEOF(false), tokensBeforeEOF(false) + intermediate(interm), symbolTable(symt), infoSink(is), language(L), + version(v), profile(p), forwardCompatible(fc), messages(m), + contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), + linkage(0), tokensBeforeEOF(false), + parsingBuiltins(pb), numErrors(0), afterEOF(false) { currentLoc.line = 1; currentLoc.string = 0; diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 78357d8d..1d404e9a 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -69,57 +69,19 @@ public: TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&, bool forwardCompatible = false, EShMessages messages = EShMsgDefault); - TScanContext* scanContext; - TPpContext* ppContext; - TIntermediate& intermediate; // to hold and build a parse tree - TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile - TInfoSink& infoSink; - EShLanguage language; // vertex or fragment language - TIntermNode* treeRoot; // root of parse tree being created - TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not reference by the rest of the AST - int numErrors; // number of compile-time errors encountered - int loopNestingLevel; // 0 if outside all loops - int structNestingLevel; // 0 if outside blocks and structures - TList switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting - bool inTypeParen; // true if in parentheses, looking only for an identifier - const TType* currentFunctionType; // the return type of the function that's currently being parsed - bool functionReturnsValue; // true if a non-void function has a return - bool parsingBuiltins; // true if parsing built-in symbols/functions - - int version; // version, updated by #version in the shader - EProfile profile; // the declared profile in the shader (core by default) - bool forwardCompatible; // true if errors are to be given for use of deprecated features - EShMessages messages; // errors/warnings - TMap extensionBehavior; // for each extension string, what it's current enablement is - - struct TPragma contextPragma; - TPrecisionQualifier defaultPrecision[EbtNumTypes]; - static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex() - TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex]; - bool afterEOF; - bool tokensBeforeEOF; - TSourceLoc currentLoc; - const TString* blockName; - TQualifier globalUniformDefaults; - TQualifier globalInputDefaults; - TQualifier globalOutputDefaults; - TQualifier currentBlockDefaults; - - void initializeExtensionBehavior(); - const char* getPreamble(); +public: bool parseShaderStrings(TPpContext&, char* strings[], int strLen[], int numStrings); - void parserError(const char *s); + void initializeExtensionBehavior(); + void parserError(const char *s); // for bison's yyerror - void handlePragma(const char **tokens, int numTokens); - TBehavior getExtensionBehavior(const char* behavior); - void updateExtensionBehavior(const char* extName, const char* behavior); - void C_DECL error(TSourceLoc, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...); void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...); bool reservedErrorCheck(TSourceLoc, const TString& identifier); + void updateExtensionBehavior(const char* extName, const char* behavior); + void handlePragma(const char **tokens, int numTokens); TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string); TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index); TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field); @@ -197,6 +159,59 @@ public: void requireNotRemoved(TSourceLoc, EProfile callingProfile, int removedVersion, const char *featureDesc); void fullIntegerCheck(TSourceLoc, const char* op); void doubleCheck(TSourceLoc, const char* op); + + void setScanContext(TScanContext* c) { scanContext = c; } + TScanContext* getScanContext() const { return scanContext; } + void setPpContext(TPpContext* c) { ppContext = c; } + TPpContext* getPpContext() const { return ppContext; } + int getNumErrors() const { return numErrors; } + +protected: + const char* getPreamble(); + TBehavior getExtensionBehavior(const char* behavior); + +public: + // + // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access + // + + TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree + TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile + TInfoSink& infoSink; + + // compilation mode + EShLanguage language; // vertex or fragment language + int version; // version, updated by #version in the shader + EProfile profile; // the declared profile in the shader (core by default) + bool forwardCompatible; // true if errors are to be given for use of deprecated features + EShMessages messages; // errors/warnings + + // Current state of parsing + struct TPragma contextPragma; + int loopNestingLevel; // 0 if outside all loops + int structNestingLevel; // 0 if outside blocks and structures + TList switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting + const TType* currentFunctionType; // the return type of the function that's currently being parsed + bool functionReturnsValue; // true if a non-void function has a return + const TString* blockName; + TQualifier currentBlockDefaults; + TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not referenced by the rest of the AST + TPrecisionQualifier defaultPrecision[EbtNumTypes]; + TSourceLoc currentLoc; + bool tokensBeforeEOF; + +protected: + TScanContext* scanContext; + TPpContext* ppContext; + int numErrors; // number of compile-time errors encountered + bool parsingBuiltins; // true if parsing built-in symbols/functions + TMap extensionBehavior; // for each extension string, what it's current enablement is + static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex() + TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex]; + bool afterEOF; + TQualifier globalUniformDefaults; + TQualifier globalInputDefaults; + TQualifier globalOutputDefaults; }; } // end namespace glslang diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index d13e5661..b37c50cb 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -245,7 +245,7 @@ int yylex(YYSTYPE* glslangTokenDesc, glslang::TParseContext& parseContext) { glslang::TParserToken token(*glslangTokenDesc); - return parseContext.scanContext->tokenize(parseContext.ppContext, token); + return parseContext.getScanContext()->tokenize(parseContext.getPpContext(), token); } namespace { diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 4b41509b..ece846bd 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -108,8 +108,8 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink); TPpContext ppContext(parseContext); TScanContext scanContext(parseContext); - parseContext.scanContext = &scanContext; - parseContext.ppContext = &ppContext; + parseContext.setScanContext(&scanContext); + parseContext.setPpContext(&ppContext); // // Parse the built-ins. This should only happen once per @@ -403,8 +403,8 @@ int __fastcall ShFinalize() // Do an actual compile on the given strings. The result is left // in the given compile object. // -// Return: The return value of ShCompile is really boolean, indicating -// success or failure. +// Return: The return value is really boolean, indicating +// success (1) or failure (0). // int ShCompile( const ShHandle handle, @@ -478,8 +478,8 @@ int ShCompile( TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages); glslang::TScanContext scanContext(parseContext); TPpContext ppContext(parseContext); - parseContext.scanContext = &scanContext; - parseContext.ppContext = &ppContext; + parseContext.setScanContext(&scanContext); + parseContext.setPpContext(&ppContext); TSourceLoc beginning; beginning.line = 1; @@ -511,38 +511,36 @@ int ShCompile( bool ret = parseContext.parseShaderStrings(ppContext, const_cast(shaderStrings), lengths, numStrings); if (! ret) success = false; - intermediate.addSymbolLinkageNodes(parseContext.treeRoot, parseContext.linkage, parseContext.language, symbolTable); + intermediate.addSymbolLinkageNodes(intermediate.getTreeRoot(), parseContext.linkage, parseContext.language, symbolTable); // Clean up the symbol table before deallocating the pool memory it used. // The AST is self-sufficient now, so it can be done before the rest of compilation/linking. delete symbolTableMemory; - if (success && parseContext.treeRoot) { + if (success && intermediate.getTreeRoot()) { if (optLevel == EShOptNoGeneration) parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested."); else { - success = intermediate.postProcess(parseContext.treeRoot, parseContext.language); + success = intermediate.postProcess(intermediate.getTreeRoot(), parseContext.language); if (success) { - if (messages & EShMsgAST) - intermediate.outputTree(parseContext.treeRoot, parseContext.infoSink); - // // Call the machine dependent compiler // - if (! compiler->compile(parseContext.treeRoot, parseContext.version, parseContext.profile)) + if (! compiler->compile(intermediate.getTreeRoot(), parseContext.version, parseContext.profile)) success = false; } } } else if (! success) { parseContext.infoSink.info.prefix(EPrefixError); - parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; + parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n"; success = false; - if (messages & EShMsgAST) - intermediate.outputTree(parseContext.treeRoot, parseContext.infoSink); } - intermediate.remove(parseContext.treeRoot); + if (messages & EShMsgAST) + intermediate.outputTree(parseContext.infoSink); + + intermediate.removeTree(); // // Throw away all the temporary memory used by the compilation process. // diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index 1a550236..609b864f 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -2438,11 +2438,11 @@ jump_statement translation_unit : external_declaration { $$ = $1; - parseContext.treeRoot = $$; + parseContext.intermediate.setTreeRoot($$); } | translation_unit external_declaration { $$ = parseContext.intermediate.growAggregate($1, $2); - parseContext.treeRoot = $$; + parseContext.intermediate.setTreeRoot($$); } ; diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index f173780b..d6b618e1 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -35,6 +35,7 @@ // #include "localintermediate.h" +#include "../Include/InfoSink.h" namespace glslang { @@ -567,9 +568,9 @@ bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it // Individual functions can be initialized to 0 to skip processing of that // type of node. It's children will still be processed. // -void TIntermediate::outputTree(TIntermNode* root, TInfoSink& infoSink) +void TIntermediate::outputTree(TInfoSink& infoSink) { - if (root == 0) + if (treeRoot == 0) return; TOutputTraverser it(infoSink); @@ -584,7 +585,7 @@ void TIntermediate::outputTree(TIntermNode* root, TInfoSink& infoSink) it.visitBranch = OutputBranch; it.visitSwitch = OutputSwitch; - root->traverse(&it); + treeRoot->traverse(&it); } } // end namespace glslang diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index f57d2df5..63fb6d6b 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -37,9 +37,10 @@ #include "../Include/intermediate.h" #include "../Public/ShaderLang.h" -#include "SymbolTable.h" #include "Versions.h" +class TInfoSink; + namespace glslang { struct TVectorFields { @@ -47,14 +48,19 @@ struct TVectorFields { int num; }; +class TSymbolTable; +class TVariable; + // // Set of helper functions to help parse and build the tree. // class TIntermediate { -public: - POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) +public: + TIntermediate(int v, EProfile p) : treeRoot(0), profile(p), version(v) { } - TIntermediate(int v, EProfile p) : version(v), profile(p) { } + void setTreeRoot(TIntermNode* r) { treeRoot = r; } + TIntermNode* getTreeRoot() const { return treeRoot; } + TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc); TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); @@ -86,10 +92,12 @@ public: void addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&); - void remove(TIntermNode*); - void outputTree(TIntermNode*, TInfoSink&); - + + void outputTree(TInfoSink& infoSink); + void removeTree(); + protected: + TIntermNode* treeRoot; EProfile profile; int version;