--- /dev/null
+hlsl.namespace.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:5 Function Definition: N1::getVec( ( temp 4-component vector of float)
+0:5 Function Parameters:
+0:? Sequence
+0:5 Branch: Return with expression
+0:5 'v1' ( global 4-component vector of float)
+0:10 Function Definition: N2::getVec( ( temp 4-component vector of float)
+0:10 Function Parameters:
+0:? Sequence
+0:10 Branch: Return with expression
+0:10 'v2' ( global 4-component vector of float)
+0:12 Function Definition: N2::N3::getVec( ( temp 4-component vector of float)
+0:12 Function Parameters:
+0:? Sequence
+0:12 Branch: Return with expression
+0:12 'v2' ( global 4-component vector of float)
+0:15 Function Definition: N2::N3::C1::getVec( ( temp 4-component vector of float)
+0:15 Function Parameters:
+0:15 '@this' ( temp structure{})
+0:? Sequence
+0:15 Branch: Return with expression
+0:15 'v2' ( global 4-component vector of float)
+0:21 Function Definition: @main( ( temp 4-component vector of float)
+0:21 Function Parameters:
+0:? Sequence
+0:22 Branch: Return with expression
+0:22 add ( temp 4-component vector of float)
+0:22 add ( temp 4-component vector of float)
+0:22 add ( temp 4-component vector of float)
+0:22 Function Call: N1::getVec( ( temp 4-component vector of float)
+0:22 Function Call: N2::getVec( ( temp 4-component vector of float)
+0:22 Function Call: N2::N3::getVec( ( temp 4-component vector of float)
+0:22 vector-scale ( temp 4-component vector of float)
+0:22 Function Call: N2::N3::C1::getVec( ( temp 4-component vector of float)
+0:22 'N2::gf' ( global float)
+0:21 Function Definition: main( ( temp void)
+0:21 Function Parameters:
+0:? Sequence
+0:21 move second child to first child ( temp 4-component vector of float)
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:21 Function Call: @main( ( temp 4-component vector of float)
+0:? Linker Objects
+0:? 'v1' ( global 4-component vector of float)
+0:? 'v2' ( global 4-component vector of float)
+0:? 'N2::gf' ( global float)
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:5 Function Definition: N1::getVec( ( temp 4-component vector of float)
+0:5 Function Parameters:
+0:? Sequence
+0:5 Branch: Return with expression
+0:5 'v1' ( global 4-component vector of float)
+0:10 Function Definition: N2::getVec( ( temp 4-component vector of float)
+0:10 Function Parameters:
+0:? Sequence
+0:10 Branch: Return with expression
+0:10 'v2' ( global 4-component vector of float)
+0:12 Function Definition: N2::N3::getVec( ( temp 4-component vector of float)
+0:12 Function Parameters:
+0:? Sequence
+0:12 Branch: Return with expression
+0:12 'v2' ( global 4-component vector of float)
+0:15 Function Definition: N2::N3::C1::getVec( ( temp 4-component vector of float)
+0:15 Function Parameters:
+0:15 '@this' ( temp structure{})
+0:? Sequence
+0:15 Branch: Return with expression
+0:15 'v2' ( global 4-component vector of float)
+0:21 Function Definition: @main( ( temp 4-component vector of float)
+0:21 Function Parameters:
+0:? Sequence
+0:22 Branch: Return with expression
+0:22 add ( temp 4-component vector of float)
+0:22 add ( temp 4-component vector of float)
+0:22 add ( temp 4-component vector of float)
+0:22 Function Call: N1::getVec( ( temp 4-component vector of float)
+0:22 Function Call: N2::getVec( ( temp 4-component vector of float)
+0:22 Function Call: N2::N3::getVec( ( temp 4-component vector of float)
+0:22 vector-scale ( temp 4-component vector of float)
+0:22 Function Call: N2::N3::C1::getVec( ( temp 4-component vector of float)
+0:22 'N2::gf' ( global float)
+0:21 Function Definition: main( ( temp void)
+0:21 Function Parameters:
+0:? Sequence
+0:21 move second child to first child ( temp 4-component vector of float)
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:21 Function Call: @main( ( temp 4-component vector of float)
+0:? Linker Objects
+0:? 'v1' ( global 4-component vector of float)
+0:? 'v2' ( global 4-component vector of float)
+0:? 'N2::gf' ( global float)
+0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 54
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main" 52
+ ExecutionMode 4 OriginUpperLeft
+ Name 4 "main"
+ Name 9 "N1::getVec("
+ Name 11 "N2::getVec("
+ Name 13 "N2::N3::getVec("
+ Name 15 "C1"
+ Name 19 "N2::N3::C1::getVec("
+ Name 18 "@this"
+ Name 21 "@main("
+ Name 24 "v1"
+ Name 28 "v2"
+ Name 45 "N2::gf"
+ Name 52 "@entryPointOutput"
+ Decorate 52(@entryPointOutput) Location 0
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8: TypeFunction 7(fvec4)
+ 15(C1): TypeStruct
+ 16: TypePointer Function 15(C1)
+ 17: TypeFunction 7(fvec4) 16(ptr)
+ 23: TypePointer Private 7(fvec4)
+ 24(v1): 23(ptr) Variable Private
+ 28(v2): 23(ptr) Variable Private
+ 44: TypePointer Private 6(float)
+ 45(N2::gf): 44(ptr) Variable Private
+ 51: TypePointer Output 7(fvec4)
+52(@entryPointOutput): 51(ptr) Variable Output
+ 4(main): 2 Function None 3
+ 5: Label
+ 53: 7(fvec4) FunctionCall 21(@main()
+ Store 52(@entryPointOutput) 53
+ Return
+ FunctionEnd
+ 9(N1::getVec(): 7(fvec4) Function None 8
+ 10: Label
+ 25: 7(fvec4) Load 24(v1)
+ ReturnValue 25
+ FunctionEnd
+ 11(N2::getVec(): 7(fvec4) Function None 8
+ 12: Label
+ 29: 7(fvec4) Load 28(v2)
+ ReturnValue 29
+ FunctionEnd
+13(N2::N3::getVec(): 7(fvec4) Function None 8
+ 14: Label
+ 32: 7(fvec4) Load 28(v2)
+ ReturnValue 32
+ FunctionEnd
+19(N2::N3::C1::getVec(): 7(fvec4) Function None 17
+ 18(@this): 16(ptr) FunctionParameter
+ 20: Label
+ 35: 7(fvec4) Load 28(v2)
+ ReturnValue 35
+ FunctionEnd
+ 21(@main(): 7(fvec4) Function None 8
+ 22: Label
+ 38: 7(fvec4) FunctionCall 9(N1::getVec()
+ 39: 7(fvec4) FunctionCall 11(N2::getVec()
+ 40: 7(fvec4) FAdd 38 39
+ 41: 7(fvec4) FunctionCall 13(N2::N3::getVec()
+ 42: 7(fvec4) FAdd 40 41
+ 43: 7(fvec4) FunctionCall 19(N2::N3::C1::getVec()
+ 46: 6(float) Load 45(N2::gf)
+ 47: 7(fvec4) VectorTimesScalar 43 46
+ 48: 7(fvec4) FAdd 42 47
+ ReturnValue 48
+ FunctionEnd
}
// compilationUnit
-// : list of externalDeclaration
-// | SEMICOLONS
+// : declaration_list EOF
//
bool HlslGrammar::acceptCompilationUnit()
{
TIntermNode* unitNode = nullptr;
- while (! peekTokenClass(EHTokNone)) {
- // HLSL allows semicolons between global declarations, e.g, between functions.
- if (acceptTokenClass(EHTokSemicolon))
- continue;
+ if (! acceptDeclarationList(unitNode))
+ return false;
- // externalDeclaration
- if (! acceptDeclaration(unitNode))
- return false;
- }
+ if (! peekTokenClass(EHTokNone))
+ return false;
// set root of AST
if (unitNode && !unitNode->getAsAggregate())
return true;
}
+// Recognize the following, but with the extra condition that it can be
+// successfully terminated by EOF or '}'.
+//
+// declaration_list
+// : list of declaration_or_semicolon followed by EOF or RIGHT_BRACE
+//
+// declaration_or_semicolon
+// : declaration
+// : SEMICOLON
+//
+bool HlslGrammar::acceptDeclarationList(TIntermNode*& nodeList)
+{
+ do {
+ // HLSL allows extra semicolons between global declarations
+ do { } while (acceptTokenClass(EHTokSemicolon));
+
+ // EOF or RIGHT_BRACE
+ if (peekTokenClass(EHTokNone) || peekTokenClass(EHTokRightBrace))
+ return true;
+
+ // declaration
+ if (! acceptDeclaration(nodeList))
+ return false;
+ } while (true);
+
+ return true;
+}
+
// sampler_state
// : LEFT_BRACE [sampler_state_assignment ... ] RIGHT_BRACE
//
// | fully_specified_type identifier function_parameters post_decls compound_statement // function definition
// | fully_specified_type identifier sampler_state post_decls compound_statement // sampler definition
// | typedef declaration
+// | NAMESPACE IDENTIFIER LEFT_BRACE declaration_list RIGHT_BRACE
//
// declarator_list
// : declarator COMMA declarator COMMA declarator... // zero or more declarators
//
bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
{
+ // NAMESPACE IDENTIFIER LEFT_BRACE declaration_list RIGHT_BRACE
+ if (acceptTokenClass(EHTokNamespace)) {
+ HlslToken namespaceToken;
+ if (!acceptIdentifier(namespaceToken)) {
+ expected("namespace name");
+ return false;
+ }
+ parseContext.pushNamespace(*namespaceToken.string);
+ if (!acceptTokenClass(EHTokLeftBrace)) {
+ expected("{");
+ return false;
+ }
+ if (!acceptDeclarationList(nodeList)) {
+ expected("declaration list");
+ return false;
+ }
+ if (!acceptTokenClass(EHTokRightBrace)) {
+ expected("}");
+ return false;
+ }
+ parseContext.popNamespace();
+ return true;
+ }
+
bool declarator_list = false; // true when processing comma separation
// attributes
HlslToken idToken;
TIntermAggregate* initializers = nullptr;
while (acceptIdentifier(idToken)) {
+ const TString *fullName = idToken.string;
+ if (parseContext.symbolTable.atGlobalLevel())
+ parseContext.getFullNamespaceName(fullName);
if (peekTokenClass(EHTokLeftParen)) {
// looks like function parameters
- const TString* fnName = idToken.string;
// Potentially rename shader entry point function. No-op most of the time.
- parseContext.renameShaderFunction(fnName);
+ parseContext.renameShaderFunction(fullName);
// function_parameters
- declarator.function = new TFunction(fnName, declaredType);
+ declarator.function = new TFunction(fullName, declaredType);
if (!acceptFunctionParameters(*declarator.function)) {
expected("function parameter list");
return false;
// TODO: strings are not yet handled.
if (variableType.getBasicType() != EbtString && parseContext.getAnnotationNestingLevel() == 0) {
if (typedefDecl)
- parseContext.declareTypedef(idToken.loc, *idToken.string, variableType);
+ parseContext.declareTypedef(idToken.loc, *fullName, variableType);
else if (variableType.getBasicType() == EbtBlock)
- parseContext.declareBlock(idToken.loc, variableType, idToken.string);
+ parseContext.declareBlock(idToken.loc, variableType, fullName);
else {
if (variableType.getQualifier().storage == EvqUniform && ! variableType.containsOpaque()) {
// this isn't really an individual variable, but a member of the $Global buffer
- parseContext.growGlobalUniformBlock(idToken.loc, variableType, *idToken.string);
+ parseContext.growGlobalUniformBlock(idToken.loc, variableType, *fullName);
} else {
// Declare the variable and add any initializer code to the AST.
// The top-level node is always made into an aggregate, as that's
// historically how the AST has been.
initializers = intermediate.growAggregate(initializers,
- parseContext.declareVariable(idToken.loc, *idToken.string, variableType, expressionNode),
+ parseContext.declareVariable(idToken.loc, *fullName, variableType, expressionNode),
idToken.loc);
}
}
// : LEFT_PAREN expression RIGHT_PAREN
// | literal
// | constructor
-// | identifier
+// | IDENTIFIER [ COLONCOLON IDENTIFIER [ COLONCOLON IDENTIFIER ... ] ]
// | function_call
// | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET
// | postfix_expression DOT IDENTIFIER
// | postfix_expression DOT IDENTIFIER arguments
-// | postfix_expression COLONCOLON IDENTIFIER arguments
+// | postfix_expression arguments
// | postfix_expression INC_OP
// | postfix_expression DEC_OP
//
// idToken will pick up either a variable or a function name in a function call
HlslToken idToken;
- // scopeBase will pick up the type symbol on the left of '::'
- TSymbol* scope = nullptr;
-
// Find something before the postfix operations, as they can't operate
// on nothing. So, no "return true", they fall through, only "return false".
if (acceptTokenClass(EHTokLeftParen)) {
return false;
}
} else if (acceptLiteral(node)) {
- // literal (nothing else to do yet), go on to the
+ // literal (nothing else to do yet)
} else if (acceptConstructor(node)) {
// constructor (nothing else to do yet)
} else if (acceptIdentifier(idToken)) {
- // user-type, identifier, or function name
- if (peekTokenClass(EHTokColonColon)) {
- TType type;
- scope = parseContext.lookupUserType(*idToken.string, type);
- if (scope == nullptr) {
- expected("type left of ::");
+ // user-type, namespace name, variable, or function name
+ TString* fullName = idToken.string;
+ while (acceptTokenClass(EHTokColonColon)) {
+ // user-type or namespace name
+ fullName = NewPoolTString(fullName->c_str());
+ fullName->append(parseContext.scopeMangler);
+ if (acceptIdentifier(idToken))
+ fullName->append(*idToken.string);
+ else {
+ expected("identifier after ::");
return false;
}
- } else if (! peekTokenClass(EHTokLeftParen)) {
- node = parseContext.handleVariable(idToken.loc, idToken.string);
- } else if (acceptFunctionCall(idToken, node)) {
+ }
+ if (! peekTokenClass(EHTokLeftParen)) {
+ node = parseContext.handleVariable(idToken.loc, fullName);
+ } else if (acceptFunctionCall(idToken.loc, *fullName, node, nullptr)) {
// function_call (nothing else to do yet)
} else {
expected("function call arguments");
TIntermTyped* thisNode = node;
// arguments
- if (! acceptFunctionCall(field, node, thisNode, scope)) {
+ if (! acceptFunctionCall(field.loc, *field.string, node, thisNode)) {
expected("function parameters");
return false;
}
// function_call
// : [idToken] arguments
//
-bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, TIntermTyped* baseObject,
- const TSymbol* scope)
+bool HlslGrammar::acceptFunctionCall(const TSourceLoc& loc, TString& name, TIntermTyped*& node, TIntermTyped* baseObject)
{
// name
TString* functionName = nullptr;
- if ((baseObject == nullptr && scope == nullptr)) {
- functionName = callToken.string;
- } else if (parseContext.isBuiltInMethod(callToken.loc, baseObject, *callToken.string)) {
+ if (baseObject == nullptr) {
+ functionName = &name;
+ } else if (parseContext.isBuiltInMethod(loc, baseObject, name)) {
// Built-in methods are not in the symbol table as methods, but as global functions
// taking an explicit 'this' as the first argument.
functionName = NewPoolTString(BUILTIN_PREFIX);
- functionName->append(*callToken.string);
+ functionName->append(name);
} else {
+ if (! baseObject->getType().isStruct()) {
+ expected("structure");
+ return false;
+ }
functionName = NewPoolTString("");
- if (baseObject != nullptr)
- functionName->append(baseObject->getType().getTypeName());
- else if (scope != nullptr)
- functionName->append(scope->getType().getTypeName());
+ functionName->append(baseObject->getType().getTypeName());
parseContext.addScopeMangler(*functionName);
- functionName->append(*callToken.string);
+ functionName->append(name);
}
// function
return false;
// call
- node = parseContext.handleFunctionCall(callToken.loc, function, arguments);
+ node = parseContext.handleFunctionCall(loc, function, arguments);
return true;
}