HLSL: Fix #1432: Globally initialize local static variables.
This commit is contained in:
@@ -126,8 +126,6 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
|
||||
//
|
||||
bool HlslGrammar::acceptCompilationUnit()
|
||||
{
|
||||
TIntermNode* unitNode = nullptr;
|
||||
|
||||
if (! acceptDeclarationList(unitNode))
|
||||
return false;
|
||||
|
||||
@@ -324,7 +322,7 @@ bool HlslGrammar::acceptSamplerDeclarationDX9(TType& /*type*/)
|
||||
// node for all the initializers. Each function created is a top-level node to grow
|
||||
// into the passed-in nodeList.
|
||||
//
|
||||
// If 'nodeList' is passed in as non-null, it must an aggregate to extend for
|
||||
// If 'nodeList' is passed in as non-null, it must be an aggregate to extend for
|
||||
// each top-level node the declaration creates. Otherwise, if only one top-level
|
||||
// node in generated here, that is want is returned in nodeList.
|
||||
//
|
||||
@@ -489,7 +487,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
|
||||
// Declare the variable and add any initializer code to the AST.
|
||||
// The top-level node is always made into an aggregate, as that's
|
||||
// historically how the AST has been.
|
||||
initializers = intermediate.growAggregate(initializers,
|
||||
initializers = intermediate.growAggregate(initializers,
|
||||
parseContext.declareVariable(idToken.loc, *fullName, variableType, expressionNode),
|
||||
idToken.loc);
|
||||
}
|
||||
@@ -506,11 +504,16 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
|
||||
if (initializers != nullptr)
|
||||
initializers->setOperator(EOpSequence);
|
||||
|
||||
// Add the initializers' aggregate to the nodeList we were handed.
|
||||
if (nodeList)
|
||||
nodeList = intermediate.growAggregate(nodeList, initializers);
|
||||
else
|
||||
nodeList = initializers;
|
||||
// if we have a locally scoped static, it needs a globally scoped initializer
|
||||
if (declaredType.getQualifier().storage == EvqGlobal && !parseContext.symbolTable.atGlobalLevel()) {
|
||||
unitNode = intermediate.growAggregate(unitNode, initializers, idToken.loc);
|
||||
} else {
|
||||
// Add the initializers' aggregate to the nodeList we were handed.
|
||||
if (nodeList)
|
||||
nodeList = intermediate.growAggregate(nodeList, initializers);
|
||||
else
|
||||
nodeList = initializers;
|
||||
}
|
||||
|
||||
// SEMICOLON
|
||||
if (! acceptTokenClass(EHTokSemicolon)) {
|
||||
@@ -651,7 +654,7 @@ bool HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||
do {
|
||||
switch (peek()) {
|
||||
case EHTokStatic:
|
||||
qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
|
||||
qualifier.storage = EvqGlobal;
|
||||
break;
|
||||
case EHTokExtern:
|
||||
// TODO: no meaning in glslang?
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace glslang {
|
||||
public:
|
||||
HlslGrammar(HlslScanContext& scanner, HlslParseContext& parseContext)
|
||||
: HlslTokenStream(scanner), parseContext(parseContext), intermediate(parseContext.intermediate),
|
||||
typeIdentifiers(false) { }
|
||||
typeIdentifiers(false), unitNode(nullptr) { }
|
||||
virtual ~HlslGrammar() { }
|
||||
|
||||
bool parse();
|
||||
@@ -133,6 +133,7 @@ namespace glslang {
|
||||
HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate
|
||||
TIntermediate& intermediate; // the final product, the intermediate representation, includes the AST
|
||||
bool typeIdentifiers; // shader uses some types as identifiers
|
||||
TIntermNode* unitNode;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
@@ -7866,6 +7866,8 @@ TVariable* HlslParseContext::declareNonArray(const TSourceLoc& loc, const TStrin
|
||||
// Returning nullptr just means there is no code to execute to handle the
|
||||
// initializer, which will, for example, be the case for constant initializers.
|
||||
//
|
||||
// Returns a subtree that accomplished the initialization.
|
||||
//
|
||||
TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
|
||||
{
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user