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.
This commit is contained in:
		
							parent
							
								
									057df2935a
								
							
						
					
					
						commit
						ca71d946d7
					
				@ -2,5 +2,5 @@
 | 
				
			|||||||
// For the version, it uses the latest git tag followed by the number of commits.
 | 
					// 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).
 | 
					// For the date, it uses the current date (when then script is run).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GLSLANG_REVISION "Overload400-PrecQual.1881"
 | 
					#define GLSLANG_REVISION "Overload400-PrecQual.1882"
 | 
				
			||||||
#define GLSLANG_DATE "06-Mar-2017"
 | 
					#define GLSLANG_DATE "07-Mar-2017"
 | 
				
			||||||
 | 
				
			|||||||
@ -1158,15 +1158,15 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
 | 
				
			|||||||
        return nullptr;
 | 
					        return nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TIntermAggregate* aggNode = nullptr;
 | 
					    TIntermAggregate* aggNode = nullptr;
 | 
				
			||||||
    if (left)
 | 
					    if (left != nullptr)
 | 
				
			||||||
        aggNode = left->getAsAggregate();
 | 
					        aggNode = left->getAsAggregate();
 | 
				
			||||||
    if (! aggNode || aggNode->getOp() != EOpNull) {
 | 
					    if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
 | 
				
			||||||
        aggNode = new TIntermAggregate;
 | 
					        aggNode = new TIntermAggregate;
 | 
				
			||||||
        if (left)
 | 
					        if (left != nullptr)
 | 
				
			||||||
            aggNode->getSequence().push_back(left);
 | 
					            aggNode->getSequence().push_back(left);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (right)
 | 
					    if (right != nullptr)
 | 
				
			||||||
        aggNode->getSequence().push_back(right);
 | 
					        aggNode->getSequence().push_back(right);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return aggNode;
 | 
					    return aggNode;
 | 
				
			||||||
 | 
				
			|||||||
@ -131,18 +131,13 @@ bool HlslGrammar::acceptCompilationUnit()
 | 
				
			|||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // externalDeclaration
 | 
					        // externalDeclaration
 | 
				
			||||||
        TIntermNode* declarationNode1;
 | 
					        if (! acceptDeclaration(unitNode))
 | 
				
			||||||
        TIntermNode* declarationNode2 = nullptr;  // sometimes the grammar for a single declaration creates two
 | 
					 | 
				
			||||||
        if (! acceptDeclaration(declarationNode1, declarationNode2))
 | 
					 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // hook it up
 | 
					 | 
				
			||||||
        unitNode = intermediate.growAggregate(unitNode, declarationNode1);
 | 
					 | 
				
			||||||
        if (declarationNode2 != nullptr)
 | 
					 | 
				
			||||||
            unitNode = intermediate.growAggregate(unitNode, declarationNode2);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // set root of AST
 | 
					    // set root of AST
 | 
				
			||||||
 | 
					    if (unitNode && !unitNode->getAsAggregate())
 | 
				
			||||||
 | 
					        unitNode = intermediate.growAggregate(nullptr, unitNode);
 | 
				
			||||||
    intermediate.setTreeRoot(unitNode);
 | 
					    intermediate.setTreeRoot(unitNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    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
 | 
					// as above.  (The 'identifier' in the first item in init_declarator list is the
 | 
				
			||||||
// same as 'identifier' for function declarations.)
 | 
					// same as 'identifier' for function declarations.)
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// 'node' could get populated if the declaration creates code, like an initializer
 | 
					// This can generate more than one subtree, one per initializer or a function body.
 | 
				
			||||||
// 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
 | 
					// If 'nodeList' is passed in as non-null, it must an aggregate to extend for
 | 
				
			||||||
// leads to two subtrees that need to be peers higher up.
 | 
					// 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;
 | 
					    bool list = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // attributes
 | 
					    // attributes
 | 
				
			||||||
@ -324,9 +315,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2)
 | 
				
			|||||||
    // HLSL shaders, this will have to be a master level switch
 | 
					    // 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
 | 
					    // 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
 | 
					    // For that reason, this line is commented out
 | 
				
			||||||
 | 
					    // if (acceptSamplerDeclarationDX9(declaredType))
 | 
				
			||||||
   // if (acceptSamplerDeclarationDX9(declaredType))
 | 
					    //     return true;
 | 
				
			||||||
   //     return true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fully_specified_type
 | 
					    // fully_specified_type
 | 
				
			||||||
    if (! acceptFullySpecifiedType(declaredType))
 | 
					    if (! acceptFullySpecifiedType(declaredType))
 | 
				
			||||||
@ -334,6 +324,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // identifier
 | 
					    // identifier
 | 
				
			||||||
    HlslToken idToken;
 | 
					    HlslToken idToken;
 | 
				
			||||||
 | 
					    TIntermAggregate* initializers = nullptr;
 | 
				
			||||||
    while (acceptIdentifier(idToken)) {
 | 
					    while (acceptIdentifier(idToken)) {
 | 
				
			||||||
        TString* fnName = idToken.string;
 | 
					        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", "{", "");
 | 
					                    parseContext.error(idToken.loc, "function body can't be in a declarator list", "{", "");
 | 
				
			||||||
                if (typedefDecl)
 | 
					                if (typedefDecl)
 | 
				
			||||||
                    parseContext.error(idToken.loc, "function body can't be in a typedef", "{", "");
 | 
					                    parseContext.error(idToken.loc, "function body can't be in a typedef", "{", "");
 | 
				
			||||||
                return acceptFunctionDefinition(function, node, node2, attributes);
 | 
					                return acceptFunctionDefinition(function, nodeList, attributes);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if (typedefDecl)
 | 
					                if (typedefDecl)
 | 
				
			||||||
                    parseContext.error(idToken.loc, "function typedefs not implemented", "{", "");
 | 
					                    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.
 | 
					                        // Declare the variable and add any initializer code to the AST.
 | 
				
			||||||
                        // The top-level node is always made into an aggregate, as that's
 | 
					                        // The top-level node is always made into an aggregate, as that's
 | 
				
			||||||
                        // historically how the AST has been.
 | 
					                        // historically how the AST has been.
 | 
				
			||||||
                        node = intermediate.growAggregate(node,
 | 
					                        initializers = intermediate.growAggregate(initializers,
 | 
				
			||||||
                                                          parseContext.declareVariable(idToken.loc, *idToken.string, variableType,
 | 
					                            parseContext.declareVariable(idToken.loc, *idToken.string, variableType, expressionNode),
 | 
				
			||||||
                                                                                       expressionNode),
 | 
					                            idToken.loc);
 | 
				
			||||||
                                                          idToken.loc);
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -436,9 +426,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node, TIntermNode*& node2)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The top-level node is a sequence.
 | 
					    // The top-level initializer node is a sequence.
 | 
				
			||||||
    if (node != nullptr)
 | 
					    if (initializers != nullptr)
 | 
				
			||||||
        node->getAsAggregate()->setOperator(EOpSequence);
 | 
					        initializers->setOperator(EOpSequence);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add the initializers' aggregate to the nodeList we were handed.
 | 
				
			||||||
 | 
					    if (nodeList)
 | 
				
			||||||
 | 
					        nodeList = intermediate.growAggregate(nodeList, initializers);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        nodeList = initializers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // SEMICOLON
 | 
					    // SEMICOLON
 | 
				
			||||||
    if (! acceptTokenClass(EHTokSemicolon)) {
 | 
					    if (! acceptTokenClass(EHTokSemicolon)) {
 | 
				
			||||||
@ -989,7 +985,7 @@ bool HlslGrammar::acceptAnnotations(TQualifier&)
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // declaration
 | 
					        // declaration
 | 
				
			||||||
        TIntermNode* node;
 | 
					        TIntermNode* node = nullptr;
 | 
				
			||||||
        if (! acceptDeclaration(node)) {
 | 
					        if (! acceptDeclaration(node)) {
 | 
				
			||||||
            expected("declaration in annotation");
 | 
					            expected("declaration in annotation");
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
@ -2114,20 +2110,28 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Do the work to create the function definition in addition to
 | 
					// Do the work to create the function definition in addition to
 | 
				
			||||||
// parsing the body (compound_statement).
 | 
					// 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 */);
 | 
					    TFunction& functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */);
 | 
				
			||||||
    TSourceLoc loc = token.loc;
 | 
					    TSourceLoc loc = token.loc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // we might get back and entry-point
 | 
				
			||||||
 | 
					    TIntermNode* entryPointNode = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // This does a pushScope()
 | 
					    // This does a pushScope()
 | 
				
			||||||
    node = parseContext.handleFunctionDefinition(loc, functionDeclarator, attributes, node2);
 | 
					    TIntermNode* functionNode = parseContext.handleFunctionDefinition(loc, functionDeclarator, attributes,
 | 
				
			||||||
 | 
					                                                                      entryPointNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // compound_statement
 | 
					    // compound_statement
 | 
				
			||||||
    TIntermNode* functionBody = nullptr;
 | 
					    TIntermNode* functionBody = nullptr;
 | 
				
			||||||
    if (! acceptCompoundStatement(functionBody))
 | 
					    if (! acceptCompoundStatement(functionBody))
 | 
				
			||||||
        return false;
 | 
					        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;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -2528,7 +2532,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
 | 
				
			|||||||
        ~tFinalize() { parseContext.finalizeFlattening(); }
 | 
					        ~tFinalize() { parseContext.finalizeFlattening(); }
 | 
				
			||||||
        HlslParseContext& parseContext;
 | 
					        HlslParseContext& parseContext;
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        const tFinalize& operator=(const tFinalize& f) { return *this; }
 | 
					        const tFinalize& operator=(const tFinalize&) { return *this; }
 | 
				
			||||||
        tFinalize(const tFinalize& f) : parseContext(f.parseContext) { }
 | 
					        tFinalize(const tFinalize& f) : parseContext(f.parseContext) { }
 | 
				
			||||||
    } finalize(parseContext);
 | 
					    } finalize(parseContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,6 @@ namespace glslang {
 | 
				
			|||||||
        bool acceptIdentifier(HlslToken&);
 | 
					        bool acceptIdentifier(HlslToken&);
 | 
				
			||||||
        bool acceptCompilationUnit();
 | 
					        bool acceptCompilationUnit();
 | 
				
			||||||
        bool acceptDeclaration(TIntermNode*&);
 | 
					        bool acceptDeclaration(TIntermNode*&);
 | 
				
			||||||
        bool acceptDeclaration(TIntermNode*& node1, TIntermNode*& node2);
 | 
					 | 
				
			||||||
        bool acceptControlDeclaration(TIntermNode*& node);
 | 
					        bool acceptControlDeclaration(TIntermNode*& node);
 | 
				
			||||||
        bool acceptSamplerDeclarationDX9(TType&);
 | 
					        bool acceptSamplerDeclarationDX9(TType&);
 | 
				
			||||||
        bool acceptSamplerState();
 | 
					        bool acceptSamplerState();
 | 
				
			||||||
@ -88,7 +87,7 @@ namespace glslang {
 | 
				
			|||||||
        bool acceptStructDeclarationList(TTypeList*&);
 | 
					        bool acceptStructDeclarationList(TTypeList*&);
 | 
				
			||||||
        bool acceptFunctionParameters(TFunction&);
 | 
					        bool acceptFunctionParameters(TFunction&);
 | 
				
			||||||
        bool acceptParameterDeclaration(TFunction&);
 | 
					        bool acceptParameterDeclaration(TFunction&);
 | 
				
			||||||
        bool acceptFunctionDefinition(TFunction&, TIntermNode*& node1, TIntermNode*& node2, const TAttributeMap&);
 | 
					        bool acceptFunctionDefinition(TFunction&, TIntermNode*& nodeList, const TAttributeMap&);
 | 
				
			||||||
        bool acceptParenExpression(TIntermTyped*&);
 | 
					        bool acceptParenExpression(TIntermTyped*&);
 | 
				
			||||||
        bool acceptExpression(TIntermTyped*&);
 | 
					        bool acceptExpression(TIntermTyped*&);
 | 
				
			||||||
        bool acceptInitializer(TIntermTyped*&);
 | 
					        bool acceptInitializer(TIntermTyped*&);
 | 
				
			||||||
 | 
				
			|||||||
@ -1521,6 +1521,8 @@ void HlslParseContext::addInterstageIoToLinkage()
 | 
				
			|||||||
// Handle seeing the function prototype in front of a function definition in the grammar.
 | 
					// Handle seeing the function prototype in front of a function definition in the grammar.
 | 
				
			||||||
// The body is handled after this function returns.
 | 
					// The body is handled after this function returns.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Returns an aggregate of parameter-symbol nodes.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function,
 | 
					TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function,
 | 
				
			||||||
                                                             const TAttributeMap& attributes, TIntermNode*& entryPointTree)
 | 
					                                                             const TAttributeMap& attributes, TIntermNode*& entryPointTree)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user