HLSL non-functional: Generalize namespace nesting.
Also use this to move deferred member-function-body parsing to a better place. This should also be well poised for implementing the 'namespace' keyword.
This commit is contained in:
@@ -1788,7 +1788,7 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
||||
postDeclQualifier.clear();
|
||||
bool postDeclsFound = acceptPostDecls(postDeclQualifier);
|
||||
|
||||
// LEFT_BRACE
|
||||
// LEFT_BRACE, or
|
||||
// struct_type IDENTIFIER
|
||||
if (! acceptTokenClass(EHTokLeftBrace)) {
|
||||
if (structName.size() > 0 && !postDeclsFound && parseContext.lookupUserType(structName, type) != nullptr) {
|
||||
@@ -1800,9 +1800,17 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// struct_declaration_list
|
||||
TTypeList* typeList;
|
||||
if (! acceptStructDeclarationList(typeList, nodeList, structName)) {
|
||||
// Save each member function so they can be processed after we have a fully formed 'this'.
|
||||
TVector<TFunctionDeclarator> functionDeclarators;
|
||||
|
||||
parseContext.pushNamespace(structName);
|
||||
bool acceptedList = acceptStructDeclarationList(typeList, nodeList, structName, functionDeclarators);
|
||||
parseContext.popNamespace();
|
||||
|
||||
if (! acceptedList) {
|
||||
expected("struct member declarations");
|
||||
return false;
|
||||
}
|
||||
@@ -1823,7 +1831,20 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
||||
|
||||
parseContext.declareStruct(token.loc, structName, type);
|
||||
|
||||
return true;
|
||||
// All member functions get parsed inside the class/struct namespace and with the
|
||||
// class/struct members in a symbol-table level.
|
||||
parseContext.pushNamespace(structName);
|
||||
bool deferredSuccess = true;
|
||||
for (int b = 0; b < (int)functionDeclarators.size() && deferredSuccess; ++b) {
|
||||
// parse body
|
||||
pushTokenStream(functionDeclarators[b].body);
|
||||
if (! acceptFunctionBody(functionDeclarators[b], nodeList))
|
||||
deferredSuccess = false;
|
||||
popTokenStream();
|
||||
}
|
||||
parseContext.popNamespace();
|
||||
|
||||
return deferredSuccess;
|
||||
}
|
||||
|
||||
// struct_buffer
|
||||
@@ -1934,16 +1955,12 @@ bool HlslGrammar::acceptStructBufferType(TType& type)
|
||||
// | IDENTIFIER array_specifier post_decls
|
||||
// | IDENTIFIER function_parameters post_decls // member-function prototype
|
||||
//
|
||||
bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*& nodeList, const TString& typeName)
|
||||
bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*& nodeList, const TString& typeName,
|
||||
TVector<TFunctionDeclarator>& declarators)
|
||||
{
|
||||
typeList = new TTypeList();
|
||||
HlslToken idToken;
|
||||
|
||||
// Save these away for each member function so they can be processed after
|
||||
// all member variables/types have been declared.
|
||||
TVector<TVector<HlslToken>*> memberBodies;
|
||||
TVector<TFunctionDeclarator> declarators;
|
||||
|
||||
do {
|
||||
// success on seeing the RIGHT_BRACE coming up
|
||||
if (peekTokenClass(EHTokRightBrace))
|
||||
@@ -1973,11 +1990,8 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
||||
if (!declarator_list) {
|
||||
declarators.resize(declarators.size() + 1);
|
||||
// request a token stream for deferred processing
|
||||
TVector<HlslToken>* deferredTokens = new TVector<HlslToken>;
|
||||
functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, typeName, memberType,
|
||||
*idToken.string, declarators.back(),
|
||||
deferredTokens);
|
||||
memberBodies.push_back(deferredTokens);
|
||||
functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, memberType, *idToken.string,
|
||||
declarators.back());
|
||||
if (functionDefinitionAccepted)
|
||||
break;
|
||||
}
|
||||
@@ -2030,14 +2044,6 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
||||
|
||||
} while (true);
|
||||
|
||||
// parse member-function bodies now
|
||||
for (int b = 0; b < (int)memberBodies.size(); ++b) {
|
||||
pushTokenStream(memberBodies[b]);
|
||||
if (! acceptFunctionBody(declarators[b], nodeList))
|
||||
return false;
|
||||
popTokenStream();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2046,15 +2052,12 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
||||
//
|
||||
// Expects type to have EvqGlobal for a static member and
|
||||
// EvqTemporary for non-static member.
|
||||
bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TString& typeName,
|
||||
const TType& type, const TString& memberName,
|
||||
TFunctionDeclarator& declarator, TVector<HlslToken>* deferredTokens)
|
||||
bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType& type, const TString& memberName,
|
||||
TFunctionDeclarator& declarator)
|
||||
{
|
||||
// watch early returns...
|
||||
parseContext.pushThis(typeName);
|
||||
bool accepted = false;
|
||||
|
||||
TString* functionName = parseContext.getFullMemberFunctionName(memberName, type.getQualifier().storage == EvqGlobal);
|
||||
TString* functionName = parseContext.getFullNamespaceName(memberName);
|
||||
declarator.function = new TFunction(functionName, type);
|
||||
|
||||
// function_parameters
|
||||
@@ -2070,12 +2073,12 @@ bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const T
|
||||
}
|
||||
|
||||
declarator.loc = token.loc;
|
||||
accepted = acceptFunctionDefinition(declarator, nodeList, deferredTokens);
|
||||
declarator.body = new TVector<HlslToken>;
|
||||
accepted = acceptFunctionDefinition(declarator, nodeList, declarator.body);
|
||||
}
|
||||
} else
|
||||
expected("function parameter list");
|
||||
|
||||
parseContext.popThis();
|
||||
return accepted;
|
||||
}
|
||||
|
||||
@@ -2781,13 +2784,8 @@ bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, T
|
||||
functionName = callToken.string;
|
||||
else {
|
||||
functionName = NewPoolTString("");
|
||||
if (baseObject != nullptr) {
|
||||
functionName->append(baseObject->getType().getTypeName().c_str());
|
||||
functionName->append(".");
|
||||
} else if (baseType != nullptr) {
|
||||
functionName->append(baseType->getType().getTypeName());
|
||||
functionName->append("::");
|
||||
}
|
||||
functionName->append(baseType->getType().getTypeName());
|
||||
parseContext.addScopeMangler(*functionName);
|
||||
functionName->append(*callToken.string);
|
||||
}
|
||||
|
||||
@@ -2795,7 +2793,6 @@ bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, T
|
||||
TFunction* function = new TFunction(functionName, TType(EbtVoid));
|
||||
|
||||
// arguments
|
||||
// Non-static member functions have an implicit first argument of the base object.
|
||||
TIntermTyped* arguments = nullptr;
|
||||
if (baseObject != nullptr)
|
||||
parseContext.handleFunctionArgument(function, arguments, baseObject);
|
||||
|
||||
Reference in New Issue
Block a user