Commit 2f1eb37d by John Kessenich

Some rationalization of TIntermediate (to own it's own tree root) and…

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
parent 807b8e3b
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include "localintermediate.h" #include "localintermediate.h"
#include "QualifierAlive.h" #include "QualifierAlive.h"
#include "RemoveTree.h" #include "RemoveTree.h"
#include "SymbolTable.h"
#include <float.h> #include <float.h>
namespace glslang { namespace glslang {
...@@ -910,10 +912,10 @@ void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TVari ...@@ -910,10 +912,10 @@ void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TVari
// //
// This deletes the tree. // This deletes the tree.
// //
void TIntermediate::remove(TIntermNode* root) void TIntermediate::removeTree()
{ {
if (root) if (treeRoot)
RemoveAllTreeNodes(root); RemoveAllTreeNodes(treeRoot);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
...@@ -1406,7 +1408,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1406,7 +1408,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtDouble: case EbtDouble:
leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst())); leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
break; break;
default: default:
return node; return node;
} }
break; break;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
// //
#include "ParseHelper.h" #include "ParseHelper.h"
#include "osinclude.h" #include "osinclude.h"
#include <stdarg.h> #include <stdarg.h>
#include <algorithm> #include <algorithm>
...@@ -47,11 +48,11 @@ namespace glslang { ...@@ -47,11 +48,11 @@ namespace glslang {
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is, TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is,
bool fc, EShMessages m) : bool fc, EShMessages m) :
intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0), linkage(0), intermediate(interm), symbolTable(symt), infoSink(is), language(L),
numErrors(0), loopNestingLevel(0), version(v), profile(p), forwardCompatible(fc), messages(m),
structNestingLevel(0), inTypeParen(false), parsingBuiltins(pb), contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
version(v), profile(p), forwardCompatible(fc), messages(m), linkage(0), tokensBeforeEOF(false),
contextPragma(true, false), afterEOF(false), tokensBeforeEOF(false) parsingBuiltins(pb), numErrors(0), afterEOF(false)
{ {
currentLoc.line = 1; currentLoc.line = 1;
currentLoc.string = 0; currentLoc.string = 0;
......
...@@ -69,57 +69,19 @@ public: ...@@ -69,57 +69,19 @@ public:
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&, TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&,
bool forwardCompatible = false, EShMessages messages = EShMsgDefault); bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
TScanContext* scanContext; public:
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<TIntermSequence*> 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<TString, TBehavior> 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();
bool parseShaderStrings(TPpContext&, char* strings[], int strLen[], int numStrings); 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, void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
const char *szExtraInfoFormat, ...); const char *szExtraInfoFormat, ...);
void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken, void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken,
const char *szExtraInfoFormat, ...); const char *szExtraInfoFormat, ...);
bool reservedErrorCheck(TSourceLoc, const TString& identifier); 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* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index); TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field); TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
...@@ -197,6 +159,59 @@ public: ...@@ -197,6 +159,59 @@ public:
void requireNotRemoved(TSourceLoc, EProfile callingProfile, int removedVersion, const char *featureDesc); void requireNotRemoved(TSourceLoc, EProfile callingProfile, int removedVersion, const char *featureDesc);
void fullIntegerCheck(TSourceLoc, const char* op); void fullIntegerCheck(TSourceLoc, const char* op);
void doubleCheck(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<TIntermSequence*> 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<TString, TBehavior> 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 } // end namespace glslang
......
...@@ -245,7 +245,7 @@ int yylex(YYSTYPE* glslangTokenDesc, glslang::TParseContext& parseContext) ...@@ -245,7 +245,7 @@ int yylex(YYSTYPE* glslangTokenDesc, glslang::TParseContext& parseContext)
{ {
glslang::TParserToken token(*glslangTokenDesc); glslang::TParserToken token(*glslangTokenDesc);
return parseContext.scanContext->tokenize(parseContext.ppContext, token); return parseContext.getScanContext()->tokenize(parseContext.getPpContext(), token);
} }
namespace { namespace {
......
...@@ -108,8 +108,8 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil ...@@ -108,8 +108,8 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink); TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink);
TPpContext ppContext(parseContext); TPpContext ppContext(parseContext);
TScanContext scanContext(parseContext); TScanContext scanContext(parseContext);
parseContext.scanContext = &scanContext; parseContext.setScanContext(&scanContext);
parseContext.ppContext = &ppContext; parseContext.setPpContext(&ppContext);
// //
// Parse the built-ins. This should only happen once per // Parse the built-ins. This should only happen once per
...@@ -403,8 +403,8 @@ int __fastcall ShFinalize() ...@@ -403,8 +403,8 @@ int __fastcall ShFinalize()
// Do an actual compile on the given strings. The result is left // Do an actual compile on the given strings. The result is left
// in the given compile object. // in the given compile object.
// //
// Return: The return value of ShCompile is really boolean, indicating // Return: The return value is really boolean, indicating
// success or failure. // success (1) or failure (0).
// //
int ShCompile( int ShCompile(
const ShHandle handle, const ShHandle handle,
...@@ -478,8 +478,8 @@ int ShCompile( ...@@ -478,8 +478,8 @@ int ShCompile(
TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages); TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
glslang::TScanContext scanContext(parseContext); glslang::TScanContext scanContext(parseContext);
TPpContext ppContext(parseContext); TPpContext ppContext(parseContext);
parseContext.scanContext = &scanContext; parseContext.setScanContext(&scanContext);
parseContext.ppContext = &ppContext; parseContext.setPpContext(&ppContext);
TSourceLoc beginning; TSourceLoc beginning;
beginning.line = 1; beginning.line = 1;
...@@ -511,38 +511,36 @@ int ShCompile( ...@@ -511,38 +511,36 @@ int ShCompile(
bool ret = parseContext.parseShaderStrings(ppContext, const_cast<char**>(shaderStrings), lengths, numStrings); bool ret = parseContext.parseShaderStrings(ppContext, const_cast<char**>(shaderStrings), lengths, numStrings);
if (! ret) if (! ret)
success = false; 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. // 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. // The AST is self-sufficient now, so it can be done before the rest of compilation/linking.
delete symbolTableMemory; delete symbolTableMemory;
if (success && parseContext.treeRoot) { if (success && intermediate.getTreeRoot()) {
if (optLevel == EShOptNoGeneration) if (optLevel == EShOptNoGeneration)
parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested."); parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested.");
else { else {
success = intermediate.postProcess(parseContext.treeRoot, parseContext.language); success = intermediate.postProcess(intermediate.getTreeRoot(), parseContext.language);
if (success) { if (success) {
if (messages & EShMsgAST)
intermediate.outputTree(parseContext.treeRoot, parseContext.infoSink);
// //
// Call the machine dependent compiler // 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; success = false;
} }
} }
} else if (! success) { } else if (! success) {
parseContext.infoSink.info.prefix(EPrefixError); 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; 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. // Throw away all the temporary memory used by the compilation process.
// //
......
...@@ -2438,11 +2438,11 @@ jump_statement ...@@ -2438,11 +2438,11 @@ jump_statement
translation_unit translation_unit
: external_declaration { : external_declaration {
$$ = $1; $$ = $1;
parseContext.treeRoot = $$; parseContext.intermediate.setTreeRoot($$);
} }
| translation_unit external_declaration { | translation_unit external_declaration {
$$ = parseContext.intermediate.growAggregate($1, $2); $$ = parseContext.intermediate.growAggregate($1, $2);
parseContext.treeRoot = $$; parseContext.intermediate.setTreeRoot($$);
} }
; ;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
// //
#include "localintermediate.h" #include "localintermediate.h"
#include "../Include/InfoSink.h"
namespace glslang { namespace glslang {
...@@ -567,9 +568,9 @@ bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it ...@@ -567,9 +568,9 @@ bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it
// Individual functions can be initialized to 0 to skip processing of that // Individual functions can be initialized to 0 to skip processing of that
// type of node. It's children will still be processed. // 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; return;
TOutputTraverser it(infoSink); TOutputTraverser it(infoSink);
...@@ -584,7 +585,7 @@ void TIntermediate::outputTree(TIntermNode* root, TInfoSink& infoSink) ...@@ -584,7 +585,7 @@ void TIntermediate::outputTree(TIntermNode* root, TInfoSink& infoSink)
it.visitBranch = OutputBranch; it.visitBranch = OutputBranch;
it.visitSwitch = OutputSwitch; it.visitSwitch = OutputSwitch;
root->traverse(&it); treeRoot->traverse(&it);
} }
} // end namespace glslang } // end namespace glslang
...@@ -37,9 +37,10 @@ ...@@ -37,9 +37,10 @@
#include "../Include/intermediate.h" #include "../Include/intermediate.h"
#include "../Public/ShaderLang.h" #include "../Public/ShaderLang.h"
#include "SymbolTable.h"
#include "Versions.h" #include "Versions.h"
class TInfoSink;
namespace glslang { namespace glslang {
struct TVectorFields { struct TVectorFields {
...@@ -47,14 +48,19 @@ struct TVectorFields { ...@@ -47,14 +48,19 @@ struct TVectorFields {
int num; int num;
}; };
class TSymbolTable;
class TVariable;
// //
// Set of helper functions to help parse and build the tree. // Set of helper functions to help parse and build the tree.
// //
class TIntermediate { class TIntermediate {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) 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); TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
...@@ -86,10 +92,12 @@ public: ...@@ -86,10 +92,12 @@ public:
void addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&);
void remove(TIntermNode*);
void outputTree(TIntermNode*, TInfoSink&); void outputTree(TInfoSink& infoSink);
void removeTree();
protected: protected:
TIntermNode* treeRoot;
EProfile profile; EProfile profile;
int version; int version;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment