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:
parent
e751bca75c
commit
f3d88bd498
@ -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.1920"
|
#define GLSLANG_REVISION "Overload400-PrecQual.1921"
|
||||||
#define GLSLANG_DATE "16-Mar-2017"
|
#define GLSLANG_DATE "19-Mar-2017"
|
||||||
|
@ -145,6 +145,8 @@ public:
|
|||||||
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||||
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||||
|
|
||||||
|
const char* const scopeMangler = "::";
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TParseContextBase(TParseContextBase&);
|
TParseContextBase(TParseContextBase&);
|
||||||
TParseContextBase& operator=(TParseContextBase&);
|
TParseContextBase& operator=(TParseContextBase&);
|
||||||
|
@ -95,9 +95,11 @@ namespace glslang {
|
|||||||
|
|
||||||
class TFunctionDeclarator {
|
class TFunctionDeclarator {
|
||||||
public:
|
public:
|
||||||
|
TFunctionDeclarator() : function(nullptr), body(nullptr) { }
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
TFunction* function;
|
TFunction* function;
|
||||||
TAttributeMap attributes;
|
TAttributeMap attributes;
|
||||||
|
TVector<HlslToken>* body;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
@ -1788,7 +1788,7 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
|||||||
postDeclQualifier.clear();
|
postDeclQualifier.clear();
|
||||||
bool postDeclsFound = acceptPostDecls(postDeclQualifier);
|
bool postDeclsFound = acceptPostDecls(postDeclQualifier);
|
||||||
|
|
||||||
// LEFT_BRACE
|
// LEFT_BRACE, or
|
||||||
// struct_type IDENTIFIER
|
// struct_type IDENTIFIER
|
||||||
if (! acceptTokenClass(EHTokLeftBrace)) {
|
if (! acceptTokenClass(EHTokLeftBrace)) {
|
||||||
if (structName.size() > 0 && !postDeclsFound && parseContext.lookupUserType(structName, type) != nullptr) {
|
if (structName.size() > 0 && !postDeclsFound && parseContext.lookupUserType(structName, type) != nullptr) {
|
||||||
@ -1800,9 +1800,17 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// struct_declaration_list
|
// struct_declaration_list
|
||||||
TTypeList* typeList;
|
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");
|
expected("struct member declarations");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1823,7 +1831,20 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
|
|||||||
|
|
||||||
parseContext.declareStruct(token.loc, structName, type);
|
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
|
// struct_buffer
|
||||||
@ -1934,16 +1955,12 @@ bool HlslGrammar::acceptStructBufferType(TType& type)
|
|||||||
// | IDENTIFIER array_specifier post_decls
|
// | IDENTIFIER array_specifier post_decls
|
||||||
// | IDENTIFIER function_parameters post_decls // member-function prototype
|
// | 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();
|
typeList = new TTypeList();
|
||||||
HlslToken idToken;
|
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 {
|
do {
|
||||||
// success on seeing the RIGHT_BRACE coming up
|
// success on seeing the RIGHT_BRACE coming up
|
||||||
if (peekTokenClass(EHTokRightBrace))
|
if (peekTokenClass(EHTokRightBrace))
|
||||||
@ -1973,11 +1990,8 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
|||||||
if (!declarator_list) {
|
if (!declarator_list) {
|
||||||
declarators.resize(declarators.size() + 1);
|
declarators.resize(declarators.size() + 1);
|
||||||
// request a token stream for deferred processing
|
// request a token stream for deferred processing
|
||||||
TVector<HlslToken>* deferredTokens = new TVector<HlslToken>;
|
functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, memberType, *idToken.string,
|
||||||
functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, typeName, memberType,
|
declarators.back());
|
||||||
*idToken.string, declarators.back(),
|
|
||||||
deferredTokens);
|
|
||||||
memberBodies.push_back(deferredTokens);
|
|
||||||
if (functionDefinitionAccepted)
|
if (functionDefinitionAccepted)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2030,14 +2044,6 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
|||||||
|
|
||||||
} while (true);
|
} 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2046,15 +2052,12 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
|||||||
//
|
//
|
||||||
// Expects type to have EvqGlobal for a static member and
|
// Expects type to have EvqGlobal for a static member and
|
||||||
// EvqTemporary for non-static member.
|
// EvqTemporary for non-static member.
|
||||||
bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TString& typeName,
|
bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType& type, const TString& memberName,
|
||||||
const TType& type, const TString& memberName,
|
TFunctionDeclarator& declarator)
|
||||||
TFunctionDeclarator& declarator, TVector<HlslToken>* deferredTokens)
|
|
||||||
{
|
{
|
||||||
// watch early returns...
|
|
||||||
parseContext.pushThis(typeName);
|
|
||||||
bool accepted = false;
|
bool accepted = false;
|
||||||
|
|
||||||
TString* functionName = parseContext.getFullMemberFunctionName(memberName, type.getQualifier().storage == EvqGlobal);
|
TString* functionName = parseContext.getFullNamespaceName(memberName);
|
||||||
declarator.function = new TFunction(functionName, type);
|
declarator.function = new TFunction(functionName, type);
|
||||||
|
|
||||||
// function_parameters
|
// function_parameters
|
||||||
@ -2070,12 +2073,12 @@ bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const T
|
|||||||
}
|
}
|
||||||
|
|
||||||
declarator.loc = token.loc;
|
declarator.loc = token.loc;
|
||||||
accepted = acceptFunctionDefinition(declarator, nodeList, deferredTokens);
|
declarator.body = new TVector<HlslToken>;
|
||||||
|
accepted = acceptFunctionDefinition(declarator, nodeList, declarator.body);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
expected("function parameter list");
|
expected("function parameter list");
|
||||||
|
|
||||||
parseContext.popThis();
|
|
||||||
return accepted;
|
return accepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2781,13 +2784,8 @@ bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, T
|
|||||||
functionName = callToken.string;
|
functionName = callToken.string;
|
||||||
else {
|
else {
|
||||||
functionName = NewPoolTString("");
|
functionName = NewPoolTString("");
|
||||||
if (baseObject != nullptr) {
|
functionName->append(baseType->getType().getTypeName());
|
||||||
functionName->append(baseObject->getType().getTypeName().c_str());
|
parseContext.addScopeMangler(*functionName);
|
||||||
functionName->append(".");
|
|
||||||
} else if (baseType != nullptr) {
|
|
||||||
functionName->append(baseType->getType().getTypeName());
|
|
||||||
functionName->append("::");
|
|
||||||
}
|
|
||||||
functionName->append(*callToken.string);
|
functionName->append(*callToken.string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2795,7 +2793,6 @@ bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, T
|
|||||||
TFunction* function = new TFunction(functionName, TType(EbtVoid));
|
TFunction* function = new TFunction(functionName, TType(EbtVoid));
|
||||||
|
|
||||||
// arguments
|
// arguments
|
||||||
// Non-static member functions have an implicit first argument of the base object.
|
|
||||||
TIntermTyped* arguments = nullptr;
|
TIntermTyped* arguments = nullptr;
|
||||||
if (baseObject != nullptr)
|
if (baseObject != nullptr)
|
||||||
parseContext.handleFunctionArgument(function, arguments, baseObject);
|
parseContext.handleFunctionArgument(function, arguments, baseObject);
|
||||||
|
@ -87,10 +87,10 @@ namespace glslang {
|
|||||||
bool acceptTextureType(TType&);
|
bool acceptTextureType(TType&);
|
||||||
bool acceptStructBufferType(TType&);
|
bool acceptStructBufferType(TType&);
|
||||||
bool acceptStruct(TType&, TIntermNode*& nodeList);
|
bool acceptStruct(TType&, TIntermNode*& nodeList);
|
||||||
bool acceptStructDeclarationList(TTypeList*&, TIntermNode*& nodeList, const TString& typeName);
|
bool acceptStructDeclarationList(TTypeList*&, TIntermNode*& nodeList, const TString& typeName,
|
||||||
bool acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TString& typeName,
|
TVector<TFunctionDeclarator>&);
|
||||||
const TType&, const TString& memberName, TFunctionDeclarator&,
|
bool acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType&, const TString& memberName,
|
||||||
TVector<HlslToken>* deferredTokens);
|
TFunctionDeclarator&);
|
||||||
bool acceptFunctionParameters(TFunction&);
|
bool acceptFunctionParameters(TFunction&);
|
||||||
bool acceptParameterDeclaration(TFunction&);
|
bool acceptParameterDeclaration(TFunction&);
|
||||||
bool acceptFunctionDefinition(TFunctionDeclarator&, TIntermNode*& nodeList, TVector<HlslToken>* deferredTokens);
|
bool acceptFunctionDefinition(TFunctionDeclarator&, TIntermNode*& nodeList, TVector<HlslToken>* deferredTokens);
|
||||||
|
@ -7085,7 +7085,7 @@ TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* ex
|
|||||||
return switchNode;
|
return switchNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track levels of class/struct nesting with a prefix string using
|
// Track levels of class/struct/namespace nesting with a prefix string using
|
||||||
// the type names separated by the scoping operator. E.g., two levels
|
// the type names separated by the scoping operator. E.g., two levels
|
||||||
// would look like:
|
// would look like:
|
||||||
//
|
//
|
||||||
@ -7093,41 +7093,43 @@ TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* ex
|
|||||||
//
|
//
|
||||||
// The string is empty when at normal global level.
|
// The string is empty when at normal global level.
|
||||||
//
|
//
|
||||||
void HlslParseContext::pushThis(const TString& typeName)
|
void HlslParseContext::pushNamespace(const TString& typeName)
|
||||||
{
|
{
|
||||||
// make new type prefix
|
// make new type prefix
|
||||||
TString newPrefix;
|
TString newPrefix;
|
||||||
if (currentTypePrefix.size() > 0) {
|
if (currentTypePrefix.size() > 0) {
|
||||||
newPrefix = currentTypePrefix.back();
|
newPrefix = currentTypePrefix.back();
|
||||||
newPrefix.append("::");
|
newPrefix.append(scopeMangler);
|
||||||
}
|
}
|
||||||
newPrefix.append(typeName);
|
newPrefix.append(typeName);
|
||||||
currentTypePrefix.push_back(newPrefix);
|
currentTypePrefix.push_back(newPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opposite of pushThis(), see above
|
// Opposite of pushNamespace(), see above
|
||||||
void HlslParseContext::popThis()
|
void HlslParseContext::popNamespace()
|
||||||
{
|
{
|
||||||
currentTypePrefix.pop_back();
|
currentTypePrefix.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the class/struct nesting string to create a global name for
|
// Use the class/struct nesting string to create a global name for
|
||||||
// a member of a class/struct. Static members use "::" for the final
|
// a member of a class/struct.
|
||||||
// step, while non-static members use ".".
|
TString* HlslParseContext::getFullNamespaceName(const TString& localName) const
|
||||||
TString* HlslParseContext::getFullMemberFunctionName(const TString& memberName, bool isStatic) const
|
|
||||||
{
|
{
|
||||||
TString* name = NewPoolTString("");
|
TString* name = NewPoolTString("");
|
||||||
if (currentTypePrefix.size() > 0)
|
if (currentTypePrefix.size() > 0)
|
||||||
name->append(currentTypePrefix.back());
|
name->append(currentTypePrefix.back());
|
||||||
if (isStatic)
|
name->append(scopeMangler);
|
||||||
name->append("::");
|
name->append(localName);
|
||||||
else
|
|
||||||
name->append(".");
|
|
||||||
name->append(memberName);
|
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to add the namespace scope mangling syntax to a string.
|
||||||
|
void HlslParseContext::addScopeMangler(TString& name)
|
||||||
|
{
|
||||||
|
name.append(scopeMangler);
|
||||||
|
}
|
||||||
|
|
||||||
// Potentially rename shader entry point function
|
// Potentially rename shader entry point function
|
||||||
void HlslParseContext::renameShaderFunction(TString*& name) const
|
void HlslParseContext::renameShaderFunction(TString*& name) const
|
||||||
{
|
{
|
||||||
|
@ -160,9 +160,10 @@ public:
|
|||||||
void pushScope() { symbolTable.push(); }
|
void pushScope() { symbolTable.push(); }
|
||||||
void popScope() { symbolTable.pop(0); }
|
void popScope() { symbolTable.pop(0); }
|
||||||
|
|
||||||
void pushThis(const TString& name);
|
void pushNamespace(const TString& name);
|
||||||
void popThis();
|
void popNamespace();
|
||||||
TString* getFullMemberFunctionName(const TString& name, bool isStatic) const;
|
TString* getFullNamespaceName(const TString& localName) const;
|
||||||
|
void addScopeMangler(TString&);
|
||||||
|
|
||||||
void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); }
|
void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); }
|
||||||
void popSwitchSequence() { switchSequenceStack.pop_back(); }
|
void popSwitchSequence() { switchSequenceStack.pop_back(); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user