HLSL: Non-functional: consolidate function declarator information.

This commit is contained in:
John Kessenich 2017-03-11 17:55:28 -07:00
parent c04c6a4067
commit 088d52bac2
6 changed files with 43 additions and 33 deletions

View File

@ -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.1899"
#define GLSLANG_REVISION "Overload400-PrecQual.1901"
#define GLSLANG_DATE "11-Mar-2017"

View File

@ -92,6 +92,14 @@ namespace glslang {
std::unordered_map<TAttributeType, TIntermAggregate*> attributes;
};
class TFunctionDeclarator {
public:
TSourceLoc loc;
TFunction* function;
TAttributeMap attributes;
};
} // end namespace glslang

View File

@ -301,8 +301,8 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
bool declarator_list = false; // true when processing comma separation
// attributes
TAttributeMap attributes;
acceptAttributes(attributes);
TFunctionDeclarator declarator;
acceptAttributes(declarator.attributes);
// typedef
bool typedefDecl = acceptTokenClass(EHTokTypedef);
@ -334,26 +334,27 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
parseContext.renameShaderFunction(fnName);
// function_parameters
TFunction& function = *new TFunction(fnName, declaredType);
if (!acceptFunctionParameters(function)) {
declarator.function = new TFunction(fnName, declaredType);
if (!acceptFunctionParameters(*declarator.function)) {
expected("function parameter list");
return false;
}
// post_decls
acceptPostDecls(function.getWritableType().getQualifier());
acceptPostDecls(declarator.function->getWritableType().getQualifier());
// compound_statement (function body definition) or just a prototype?
declarator.loc = token.loc;
if (peekTokenClass(EHTokLeftBrace)) {
if (declarator_list)
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, nodeList, attributes);
return acceptFunctionDefinition(declarator, nodeList);
} else {
if (typedefDecl)
parseContext.error(idToken.loc, "function typedefs not implemented", "{", "");
parseContext.handleFunctionDeclarator(idToken.loc, function, true);
parseContext.handleFunctionDeclarator(declarator.loc, *declarator.function, true);
}
} else {
// A variable declaration. Fix the storage qualifier if it's a global.
@ -1962,7 +1963,8 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
if (peekTokenClass(EHTokLeftParen)) {
// function_parameters
if (!declarator_list) {
functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, typeName, memberType, *idToken.string);
functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, typeName, memberType,
*idToken.string);
if (functionDefinitionAccepted)
break;
}
@ -2029,22 +2031,23 @@ bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const T
bool accepted = false;
TString* functionName = parseContext.getFullMemberFunctionName(memberName, type.getQualifier().storage == EvqGlobal);
TFunction& function = *new TFunction(functionName, type);
TFunctionDeclarator declarator;
declarator.function = new TFunction(functionName, type);
// function_parameters
if (acceptFunctionParameters(function)) {
if (acceptFunctionParameters(*declarator.function)) {
// post_decls
acceptPostDecls(function.getWritableType().getQualifier());
acceptPostDecls(declarator.function->getWritableType().getQualifier());
// compound_statement (function body definition)
if (peekTokenClass(EHTokLeftBrace)) {
if (function.getType().getQualifier().storage != EvqGlobal) {
if (declarator.function->getType().getQualifier().storage != EvqGlobal) {
expected("only static member functions are accepted");
return false;
}
TAttributeMap attributes;
accepted = acceptFunctionDefinition(function, nodeList, attributes);
declarator.loc = token.loc;
accepted = acceptFunctionDefinition(declarator, nodeList);
}
} else
expected("function parameter list");
@ -2180,17 +2183,21 @@ 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*& nodeList, const TAttributeMap& attributes)
bool HlslGrammar::acceptFunctionDefinition(TFunctionDeclarator& declarator, TIntermNode*& nodeList)
{
TFunction& functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */);
TSourceLoc loc = token.loc;
parseContext.handleFunctionDeclarator(declarator.loc, *declarator.function, false /* not prototype */);
// we might get back and entry-point
return acceptFunctionBody(declarator, nodeList);
}
bool HlslGrammar::acceptFunctionBody(TFunctionDeclarator& declarator, TIntermNode*& nodeList)
{
// we might get back an entry-point
TIntermNode* entryPointNode = nullptr;
// This does a pushScope()
TIntermNode* functionNode = parseContext.handleFunctionDefinition(loc, functionDeclarator, attributes,
entryPointNode);
TIntermNode* functionNode = parseContext.handleFunctionDefinition(declarator.loc, *declarator.function,
declarator.attributes, entryPointNode);
// compound_statement
TIntermNode* functionBody = nullptr;
@ -2198,7 +2205,7 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no
return false;
// this does a popScope()
parseContext.handleFunctionBody(loc, functionDeclarator, functionBody, functionNode);
parseContext.handleFunctionBody(declarator.loc, *declarator.function, functionBody, functionNode);
// Hook up the 1 or 2 function definitions.
nodeList = intermediate.growAggregate(nodeList, functionNode);

View File

@ -43,7 +43,8 @@
namespace glslang {
class TAttributeMap; // forward declare
class TAttributeMap;
class TFunctionDeclarator;
// Should just be the grammar aspect of HLSL.
// Described in more detail in hlslGrammar.cpp.
@ -91,7 +92,8 @@ namespace glslang {
const TType&, const TString& memberName);
bool acceptFunctionParameters(TFunction&);
bool acceptParameterDeclaration(TFunction&);
bool acceptFunctionDefinition(TFunction&, TIntermNode*& nodeList, const TAttributeMap&);
bool acceptFunctionDefinition(TFunctionDeclarator&, TIntermNode*& nodeList);
bool acceptFunctionBody(TFunctionDeclarator& declarator, TIntermNode*& nodeList);
bool acceptParenExpression(TIntermTyped*&);
bool acceptExpression(TIntermTyped*&);
bool acceptInitializer(TIntermTyped*&);

View File

@ -1414,7 +1414,7 @@ void HlslParseContext::assignLocations(TVariable& variable)
// Handle seeing a function declarator in the grammar. This is the precursor
// to recognizing a function prototype or function definition.
//
TFunction& HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype)
void HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype)
{
//
// Multiple declarations of the same function name are allowed.
@ -1442,13 +1442,6 @@ TFunction& HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFu
// other forms of name collisions.
if (! symbolTable.insert(function))
error(loc, "function name is redeclaration of existing name", function.getName().c_str(), "");
//
// If this is a redeclaration, it could also be a definition,
// in which case, we need to use the parameter names from this one, and not the one that's
// being redeclared. So, pass back this declaration, not the one in the symbol table.
//
return function;
}
// Add interstage IO variables to the linkage in canonical order.

View File

@ -72,7 +72,7 @@ public:
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
bool isBuiltInMethod(const TSourceLoc&, TIntermTyped* base, const TString& field);
void assignLocations(TVariable& variable);
TFunction& handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
void handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&, const TAttributeMap&, TIntermNode*& entryPointTree);
TIntermNode* transformEntryPoint(const TSourceLoc&, TFunction&, const TAttributeMap&);
void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node);