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
This commit is contained in:
parent
807b8e3b82
commit
2f1eb37d82
@ -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
|
|||||||
//
|
//
|
||||||
// This deletes the tree.
|
// This deletes the tree.
|
||||||
//
|
//
|
||||||
void TIntermediate::remove(TIntermNode* root)
|
void TIntermediate::removeTree()
|
||||||
{
|
{
|
||||||
if (root)
|
if (treeRoot)
|
||||||
RemoveAllTreeNodes(root);
|
RemoveAllTreeNodes(treeRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
@ -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 {
|
|||||||
|
|
||||||
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),
|
|
||||||
structNestingLevel(0), inTypeParen(false), parsingBuiltins(pb),
|
|
||||||
version(v), profile(p), forwardCompatible(fc), messages(m),
|
version(v), profile(p), forwardCompatible(fc), messages(m),
|
||||||
contextPragma(true, false), afterEOF(false), tokensBeforeEOF(false)
|
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
|
||||||
|
linkage(0), tokensBeforeEOF(false),
|
||||||
|
parsingBuiltins(pb), numErrors(0), afterEOF(false)
|
||||||
{
|
{
|
||||||
currentLoc.line = 1;
|
currentLoc.line = 1;
|
||||||
currentLoc.string = 0;
|
currentLoc.string = 0;
|
||||||
|
@ -69,50 +69,10 @@ 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, ...);
|
||||||
@ -120,6 +80,8 @@ public:
|
|||||||
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:
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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
|
|||||||
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()
|
|||||||
// 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(
|
|||||||
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(
|
|||||||
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
|
|||||||
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 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#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
|
|||||||
// 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)
|
|||||||
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 @@
|
|||||||
|
|
||||||
#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 {
|
|||||||
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) { }
|
||||||
|
|
||||||
|
void setTreeRoot(TIntermNode* r) { treeRoot = r; }
|
||||||
|
TIntermNode* getTreeRoot() const { return treeRoot; }
|
||||||
|
|
||||||
TIntermediate(int v, EProfile p) : version(v), profile(p) { }
|
|
||||||
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:
|
|||||||
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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user