Commit 4960baaf by John Kessenich

HLSL: Basic turn on of non-static member functions.

Still need: pass by reference in SPIR-V and symbol-table level for accessing 'this' members from member functions.
parent dfbdd9eb
...@@ -2747,7 +2747,8 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF ...@@ -2747,7 +2747,8 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
const glslang::TType& paramType = parameters[p]->getAsTyped()->getType(); const glslang::TType& paramType = parameters[p]->getAsTyped()->getType();
spv::Id typeId = convertGlslangToSpvType(paramType); spv::Id typeId = convertGlslangToSpvType(paramType);
if (paramType.containsOpaque() || if (paramType.containsOpaque() ||
(paramType.getBasicType() == glslang::EbtBlock && paramType.getQualifier().storage == glslang::EvqBuffer)) (paramType.getBasicType() == glslang::EbtBlock &&
paramType.getQualifier().storage == glslang::EvqBuffer))
typeId = builder.makePointer(TranslateStorageClass(paramType), typeId); typeId = builder.makePointer(TranslateStorageClass(paramType), typeId);
else if (paramType.getQualifier().storage != glslang::EvqConstReadOnly) else if (paramType.getQualifier().storage != glslang::EvqConstReadOnly)
typeId = builder.makePointer(spv::StorageClassFunction, typeId); typeId = builder.makePointer(spv::StorageClassFunction, typeId);
......
struct Test
{
float4 memVar;
float4 memFun(float4 a) : SV_Position
{
return 2 * a;
}
int memFun(int a) : SV_Position
{
return 2 + a;
}
int i;
};
float4 main() : SV_Target0
{
Test test;
float4 f4 = float4(1.0,1.0,1.0,1.0);
f4 += test.memFun(float4(5.0f,5.0f,5.0f,5.0f));
f4 += test.memFun(7);
return f4;
}
...@@ -2,5 +2,5 @@ ...@@ -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.1921" #define GLSLANG_REVISION "Overload400-PrecQual.1922"
#define GLSLANG_DATE "19-Mar-2017" #define GLSLANG_DATE "19-Mar-2017"
...@@ -164,6 +164,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -164,6 +164,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.multiEntry.vert", "RealEntrypoint"}, {"hlsl.multiEntry.vert", "RealEntrypoint"},
{"hlsl.multiReturn.frag", "main"}, {"hlsl.multiReturn.frag", "main"},
{"hlsl.matrixindex.frag", "main"}, {"hlsl.matrixindex.frag", "main"},
{"hlsl.nonstaticMemberFunction.frag", "main"},
{"hlsl.numericsuffixes.frag", "main"}, {"hlsl.numericsuffixes.frag", "main"},
{"hlsl.numthreads.comp", "main_aux1"}, {"hlsl.numthreads.comp", "main_aux1"},
{"hlsl.overload.frag", "PixelShaderFunction"}, {"hlsl.overload.frag", "PixelShaderFunction"},
......
...@@ -1831,6 +1831,15 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList) ...@@ -1831,6 +1831,15 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
parseContext.declareStruct(token.loc, structName, type); parseContext.declareStruct(token.loc, structName, type);
// For member functions: now that we know the type of 'this', go back and
// - add their implicit argument with 'this' (not to the mangling, just the argument list)
// - parse the functions, their tokens were saved for deferred parsing (now)
for (int b = 0; b < (int)functionDeclarators.size(); ++b) {
// update signature
if (functionDeclarators[b].function->hasImplicitThis())
functionDeclarators[b].function->addThisParameter(type);
}
// All member functions get parsed inside the class/struct namespace and with the // All member functions get parsed inside the class/struct namespace and with the
// class/struct members in a symbol-table level. // class/struct members in a symbol-table level.
parseContext.pushNamespace(structName); parseContext.pushNamespace(structName);
...@@ -2059,6 +2068,8 @@ bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const T ...@@ -2059,6 +2068,8 @@ bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const T
TString* functionName = parseContext.getFullNamespaceName(memberName); TString* functionName = parseContext.getFullNamespaceName(memberName);
declarator.function = new TFunction(functionName, type); declarator.function = new TFunction(functionName, type);
if (type.getQualifier().storage == EvqTemporary)
declarator.function->setImplicitThis();
// function_parameters // function_parameters
if (acceptFunctionParameters(*declarator.function)) { if (acceptFunctionParameters(*declarator.function)) {
...@@ -2067,11 +2078,6 @@ bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const T ...@@ -2067,11 +2078,6 @@ bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const T
// compound_statement (function body definition) // compound_statement (function body definition)
if (peekTokenClass(EHTokLeftBrace)) { if (peekTokenClass(EHTokLeftBrace)) {
if (declarator.function->getType().getQualifier().storage != EvqGlobal) {
expected("only static member functions are accepted");
return false;
}
declarator.loc = token.loc; declarator.loc = token.loc;
declarator.body = new TVector<HlslToken>; declarator.body = new TVector<HlslToken>;
accepted = acceptFunctionDefinition(declarator, nodeList, declarator.body); accepted = acceptFunctionDefinition(declarator, nodeList, declarator.body);
...@@ -2221,7 +2227,7 @@ bool HlslGrammar::acceptFunctionDefinition(TFunctionDeclarator& declarator, TInt ...@@ -2221,7 +2227,7 @@ bool HlslGrammar::acceptFunctionDefinition(TFunctionDeclarator& declarator, TInt
if (deferredTokens) if (deferredTokens)
return captureBlockTokens(*deferredTokens); return captureBlockTokens(*deferredTokens);
else else
return acceptFunctionBody(declarator, nodeList); return acceptFunctionBody(declarator, nodeList);
} }
bool HlslGrammar::acceptFunctionBody(TFunctionDeclarator& declarator, TIntermNode*& nodeList) bool HlslGrammar::acceptFunctionBody(TFunctionDeclarator& declarator, TIntermNode*& nodeList)
...@@ -2609,7 +2615,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) ...@@ -2609,7 +2615,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
HlslToken idToken; HlslToken idToken;
// scopeBase will pick up the type symbol on the left of '::' // scopeBase will pick up the type symbol on the left of '::'
TSymbol* scopeBase = nullptr; TSymbol* scope = nullptr;
// Find something before the postfix operations, as they can't operate // Find something before the postfix operations, as they can't operate
// on nothing. So, no "return true", they fall through, only "return false". // on nothing. So, no "return true", they fall through, only "return false".
...@@ -2631,8 +2637,8 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) ...@@ -2631,8 +2637,8 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
// user-type, identifier, or function name // user-type, identifier, or function name
if (peekTokenClass(EHTokColonColon)) { if (peekTokenClass(EHTokColonColon)) {
TType type; TType type;
scopeBase = parseContext.lookupUserType(*idToken.string, type); scope = parseContext.lookupUserType(*idToken.string, type);
if (scopeBase == nullptr) { if (scope == nullptr) {
expected("type left of ::"); expected("type left of ::");
return false; return false;
} }
...@@ -2702,7 +2708,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) ...@@ -2702,7 +2708,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
TIntermTyped* thisNode = node; TIntermTyped* thisNode = node;
// arguments // arguments
if (! acceptFunctionCall(field, node, thisNode, scopeBase)) { if (! acceptFunctionCall(field, node, thisNode, scope)) {
expected("function parameters"); expected("function parameters");
return false; return false;
} }
...@@ -2775,16 +2781,21 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node) ...@@ -2775,16 +2781,21 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
// : [idToken] arguments // : [idToken] arguments
// //
bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, TIntermTyped* baseObject, bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, TIntermTyped* baseObject,
const TSymbol* baseType) const TSymbol* scope)
{ {
// name // name
TString* functionName = nullptr; TString* functionName = nullptr;
if ((baseObject == nullptr && baseType == nullptr) if ((baseObject == nullptr && scope == nullptr) ||
|| parseContext.isBuiltInMethod(callToken.loc, baseObject, *callToken.string)) parseContext.isBuiltInMethod(callToken.loc, baseObject, *callToken.string)) {
// Built-in methods are not in the symbol table as methods, but as global functions
// taking an explicit 'this' as the first argument.
functionName = callToken.string; functionName = callToken.string;
else { } else {
functionName = NewPoolTString(""); functionName = NewPoolTString("");
functionName->append(baseType->getType().getTypeName()); if (baseObject != nullptr)
functionName->append(baseObject->getType().getTypeName());
else if (scope != nullptr)
functionName->append(scope->getType().getTypeName());
parseContext.addScopeMangler(*functionName); parseContext.addScopeMangler(*functionName);
functionName->append(*callToken.string); functionName->append(*callToken.string);
} }
......
...@@ -105,7 +105,7 @@ namespace glslang { ...@@ -105,7 +105,7 @@ namespace glslang {
bool acceptPostfixExpression(TIntermTyped*&); bool acceptPostfixExpression(TIntermTyped*&);
bool acceptConstructor(TIntermTyped*&); bool acceptConstructor(TIntermTyped*&);
bool acceptFunctionCall(HlslToken, TIntermTyped*&, TIntermTyped* objectBase = nullptr, bool acceptFunctionCall(HlslToken, TIntermTyped*&, TIntermTyped* objectBase = nullptr,
const TSymbol* typeBase = nullptr); const TSymbol* scope = nullptr);
bool acceptArguments(TFunction*, TIntermTyped*&); bool acceptArguments(TFunction*, TIntermTyped*&);
bool acceptLiteral(TIntermTyped*&); bool acceptLiteral(TIntermTyped*&);
bool acceptCompoundStatement(TIntermNode*&); bool acceptCompoundStatement(TIntermNode*&);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment