From ca71d946d75abe70bead7549f9d0349196c7c4b6 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Tue, 7 Mar 2017 20:44:09 -0700 Subject: [PATCH] HLSL: Grammar: Generalize accepting a declaration to accept an aggregate of subtrees. This is slightly cleaner today for entry-point wrapping, which sometimes made two subtrees for a function definition instead of just one subtree. It will be critical though for recognizing a struct with multiple member functions. --- glslang/Include/revision.h | 4 +- glslang/MachineIndependent/Intermediate.cpp | 8 +-- hlsl/hlslGrammar.cpp | 76 +++++++++++++++-------------- hlsl/hlslGrammar.h | 3 +- hlsl/hlslParseHelper.cpp | 2 + 5 files changed, 49 insertions(+), 44 deletions(-) diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 5c5c46f..ad84448 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "Overload400-PrecQual.1881" -#define GLSLANG_DATE "06-Mar-2017" +#define GLSLANG_REVISION "Overload400-PrecQual.1882" +#define GLSLANG_DATE "07-Mar-2017" diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 2ebd741..8abd9e3 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -1158,15 +1158,15 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r return nullptr; TIntermAggregate* aggNode = nullptr; - if (left) + if (left != nullptr) aggNode = left->getAsAggregate(); - if (! aggNode || aggNode->getOp() != EOpNull) { + if (aggNode == nullptr || aggNode->getOp() != EOpNull) { aggNode = new TIntermAggregate; - if (left) + if (left != nullptr) aggNode->getSequence().push_back(left); } - if (right) + if (right != nullptr) aggNode->getSequence().push_back(right); return aggNode; diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index f88ad3b..9641e31 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -131,18 +131,13 @@ bool HlslGrammar::acceptCompilationUnit() continue; // externalDeclaration - TIntermNode* declarationNode1; - TIntermNode* declarationNode2 = nullptr; // sometimes the grammar for a single declaration creates two - if (! acceptDeclaration(declarationNode1, declarationNode2)) + if (! acceptDeclaration(unitNode)) return false; - - // hook it up - unitNode = intermediate.growAggregate(unitNode, declarationNode1); - if (declarationNode2 != nullptr) - unitNode = intermediate.growAggregate(unitNode, declarationNode2); } // set root of AST + if (unitNode && !unitNode->getAsAggregate()) + unitNode = intermediate.growAggregate(nullptr, unitNode); intermediate.setTreeRoot(unitNode); return true; @@ -292,21 +287,17 @@ bool HlslGrammar::acceptSamplerDeclarationDX9(TType& /*type*/) // as above. (The 'identifier' in the first item in init_declarator list is the // same as 'identifier' for function declarations.) // -// 'node' could get populated if the declaration creates code, like an initializer -// or a function body. +// This can generate more than one subtree, one per initializer or a function body. +// All initializer subtrees are put in their own aggregate node, making one top-level +// node for all the initializers. Each function created is a top-level node to grow +// into the passed-in nodeList. // -// 'node2' could get populated with a second decoration tree if a single source declaration -// leads to two subtrees that need to be peers higher up. +// If 'nodeList' is passed in as non-null, it must 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. // -bool HlslGrammar::acceptDeclaration(TIntermNode*& node) +bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList) { - TIntermNode* node2; - return acceptDeclaration(node, node2); -} -bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2) -{ - node = nullptr; - node2 = nullptr; bool list = false; // attributes @@ -324,9 +315,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2) // HLSL shaders, this will have to be a master level switch // As such, the sampler keyword in D3D10+ turns into an automatic sampler type, and is commonly used // For that reason, this line is commented out - - // if (acceptSamplerDeclarationDX9(declaredType)) - // return true; + // if (acceptSamplerDeclarationDX9(declaredType)) + // return true; // fully_specified_type if (! acceptFullySpecifiedType(declaredType)) @@ -334,6 +324,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2) // identifier HlslToken idToken; + TIntermAggregate* initializers = nullptr; while (acceptIdentifier(idToken)) { TString* fnName = idToken.string; @@ -352,7 +343,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2) parseContext.error(idToken.loc, "function body can't be in a declarator list", "{", ""); if (typedefDecl) parseContext.error(idToken.loc, "function body can't be in a typedef", "{", ""); - return acceptFunctionDefinition(function, node, node2, attributes); + return acceptFunctionDefinition(function, nodeList, attributes); } else { if (typedefDecl) parseContext.error(idToken.loc, "function typedefs not implemented", "{", ""); @@ -421,10 +412,9 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2) // 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. - node = intermediate.growAggregate(node, - parseContext.declareVariable(idToken.loc, *idToken.string, variableType, - expressionNode), - idToken.loc); + initializers = intermediate.growAggregate(initializers, + parseContext.declareVariable(idToken.loc, *idToken.string, variableType, expressionNode), + idToken.loc); } } } @@ -436,9 +426,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2) } }; - // The top-level node is a sequence. - if (node != nullptr) - node->getAsAggregate()->setOperator(EOpSequence); + // The top-level initializer node is a sequence. + 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; // SEMICOLON if (! acceptTokenClass(EHTokSemicolon)) { @@ -989,7 +985,7 @@ bool HlslGrammar::acceptAnnotations(TQualifier&) break; // declaration - TIntermNode* node; + TIntermNode* node = nullptr; if (! acceptDeclaration(node)) { expected("declaration in annotation"); return false; @@ -2114,20 +2110,28 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function) // Do the work to create the function definition in addition to // parsing the body (compound_statement). -bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& node, TIntermNode*& node2, const TAttributeMap& attributes) +bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& nodeList, const TAttributeMap& attributes) { TFunction& functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */); TSourceLoc loc = token.loc; + // we might get back and entry-point + TIntermNode* entryPointNode = nullptr; + // This does a pushScope() - node = parseContext.handleFunctionDefinition(loc, functionDeclarator, attributes, node2); + TIntermNode* functionNode = parseContext.handleFunctionDefinition(loc, functionDeclarator, attributes, + entryPointNode); // compound_statement TIntermNode* functionBody = nullptr; if (! acceptCompoundStatement(functionBody)) return false; - parseContext.handleFunctionBody(loc, functionDeclarator, functionBody, node); + parseContext.handleFunctionBody(loc, functionDeclarator, functionBody, functionNode); + + // Hook up the 1 or 2 function definitions. + nodeList = intermediate.growAggregate(nodeList, functionNode); + nodeList = intermediate.growAggregate(nodeList, entryPointNode); return true; } @@ -2528,7 +2532,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) ~tFinalize() { parseContext.finalizeFlattening(); } HlslParseContext& parseContext; private: - const tFinalize& operator=(const tFinalize& f) { return *this; } + const tFinalize& operator=(const tFinalize&) { return *this; } tFinalize(const tFinalize& f) : parseContext(f.parseContext) { } } finalize(parseContext); diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 07080e4..8ff4e2e 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -65,7 +65,6 @@ namespace glslang { bool acceptIdentifier(HlslToken&); bool acceptCompilationUnit(); bool acceptDeclaration(TIntermNode*&); - bool acceptDeclaration(TIntermNode*& node1, TIntermNode*& node2); bool acceptControlDeclaration(TIntermNode*& node); bool acceptSamplerDeclarationDX9(TType&); bool acceptSamplerState(); @@ -88,7 +87,7 @@ namespace glslang { bool acceptStructDeclarationList(TTypeList*&); bool acceptFunctionParameters(TFunction&); bool acceptParameterDeclaration(TFunction&); - bool acceptFunctionDefinition(TFunction&, TIntermNode*& node1, TIntermNode*& node2, const TAttributeMap&); + bool acceptFunctionDefinition(TFunction&, TIntermNode*& nodeList, const TAttributeMap&); bool acceptParenExpression(TIntermTyped*&); bool acceptExpression(TIntermTyped*&); bool acceptInitializer(TIntermTyped*&); diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 563005a..af1c804 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1521,6 +1521,8 @@ void HlslParseContext::addInterstageIoToLinkage() // Handle seeing the function prototype in front of a function definition in the grammar. // The body is handled after this function returns. // +// Returns an aggregate of parameter-symbol nodes. +// TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function, const TAttributeMap& attributes, TIntermNode*& entryPointTree) { -- 2.7.4