diff --git a/Test/baseResults/hlsl.discard.frag.out b/Test/baseResults/hlsl.discard.frag.out new file mode 100755 index 00000000..9f5b6c3d --- /dev/null +++ b/Test/baseResults/hlsl.discard.frag.out @@ -0,0 +1,149 @@ +hlsl.discard.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:7 Function Definition: foo(f1; (temp void) +0:2 Function Parameters: +0:2 'f' (in float) +0:? Sequence +0:3 Test condition and select (temp void) +0:3 Condition +0:3 Compare Less Than (temp bool) +0:3 'f' (in float) +0:3 Constant: +0:3 1.000000 +0:3 true case +0:4 Branch: Kill +0:15 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:8 Function Parameters: +0:8 'input' (in 4-component vector of float) +0:? Sequence +0:9 Function Call: foo(f1; (temp void) +0:9 direct index (temp float) +0:9 'input' (in 4-component vector of float) +0:9 Constant: +0:9 2 (const int) +0:10 Test condition and select (temp void) +0:10 Condition +0:10 direct index (temp float) +0:10 'input' (in 4-component vector of float) +0:10 Constant: +0:10 0 (const int) +0:10 true case +0:11 Branch: Kill +0:12 move second child to first child (temp float) +0:12 'f' (temp float) +0:12 direct index (temp float) +0:12 'input' (in 4-component vector of float) +0:12 Constant: +0:12 0 (const int) +0:13 Branch: Kill +0:? Linker Objects + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:7 Function Definition: foo(f1; (temp void) +0:2 Function Parameters: +0:2 'f' (in float) +0:? Sequence +0:3 Test condition and select (temp void) +0:3 Condition +0:3 Compare Less Than (temp bool) +0:3 'f' (in float) +0:3 Constant: +0:3 1.000000 +0:3 true case +0:4 Branch: Kill +0:15 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:8 Function Parameters: +0:8 'input' (in 4-component vector of float) +0:? Sequence +0:9 Function Call: foo(f1; (temp void) +0:9 direct index (temp float) +0:9 'input' (in 4-component vector of float) +0:9 Constant: +0:9 2 (const int) +0:10 Test condition and select (temp void) +0:10 Condition +0:10 direct index (temp float) +0:10 'input' (in 4-component vector of float) +0:10 Constant: +0:10 0 (const int) +0:10 true case +0:11 Branch: Kill +0:12 move second child to first child (temp float) +0:12 'f' (temp float) +0:12 direct index (temp float) +0:12 'input' (in 4-component vector of float) +0:12 Constant: +0:12 0 (const int) +0:13 Branch: Kill +0:? Linker Objects + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 39 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "PixelShaderFunction" 21 + ExecutionMode 4 OriginUpperLeft + Source HLSL 450 + Name 4 "PixelShaderFunction" + Name 10 "foo(f1;" + Name 9 "f" + Name 21 "input" + Name 22 "param" + Name 35 "f" + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypePointer Function 6(float) + 8: TypeFunction 2 7(ptr) + 13: 6(float) Constant 1065353216 + 14: TypeBool + 19: TypeVector 6(float) 4 + 20: TypePointer Input 19(fvec4) + 21(input): 20(ptr) Variable Input + 23: TypeInt 32 0 + 24: 23(int) Constant 2 + 25: TypePointer Input 6(float) + 29: 23(int) Constant 0 +4(PixelShaderFunction): 2 Function None 3 + 5: Label + 22(param): 7(ptr) Variable Function + 35(f): 7(ptr) Variable Function + 26: 25(ptr) AccessChain 21(input) 24 + 27: 6(float) Load 26 + Store 22(param) 27 + 28: 2 FunctionCall 10(foo(f1;) 22(param) + 30: 25(ptr) AccessChain 21(input) 29 + 31: 6(float) Load 30 + SelectionMerge 33 None + BranchConditional 31 32 33 + 32: Label + Kill + 33: Label + 36: 25(ptr) AccessChain 21(input) 29 + 37: 6(float) Load 36 + Store 35(f) 37 + Kill + FunctionEnd + 10(foo(f1;): 2 Function None 8 + 9(f): 7(ptr) FunctionParameter + 11: Label + 12: 6(float) Load 9(f) + 15: 14(bool) FOrdLessThan 12 13 + SelectionMerge 17 None + BranchConditional 15 16 17 + 16: Label + Kill + 17: Label + Return + FunctionEnd diff --git a/Test/baseResults/hlsl.forLoop.frag.out b/Test/baseResults/hlsl.forLoop.frag.out index 8e2b7922..b073cbd6 100755 --- a/Test/baseResults/hlsl.forLoop.frag.out +++ b/Test/baseResults/hlsl.forLoop.frag.out @@ -2,7 +2,7 @@ hlsl.forLoop.frag Shader version: 450 gl_FragCoord origin is upper left 0:? Sequence -0:9 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:14 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) 0:2 Function Parameters: 0:2 'input' (in 4-component vector of float) 0:? Sequence @@ -52,6 +52,61 @@ gl_FragCoord origin is upper left 0:7 'input' (in 4-component vector of float) 0:7 Constant: 0:7 2.000000 +0:? Sequence +0:8 Loop with condition tested first +0:8 No loop condition +0:8 Loop Body +0:8 Test condition and select (temp void) +0:8 Condition +0:8 Compare Greater Than (temp bool) +0:8 direct index (temp float) +0:8 'input' (in 4-component vector of float) +0:8 Constant: +0:8 0 (const int) +0:8 Constant: +0:8 2.000000 +0:8 true case +0:8 Branch: Break +0:? Sequence +0:9 Loop with condition tested first +0:9 No loop condition +0:9 Loop Body +0:9 Test condition and select (temp void) +0:9 Condition +0:9 Compare Greater Than (temp bool) +0:9 direct index (temp float) +0:9 'input' (in 4-component vector of float) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 2.000000 +0:9 true case +0:9 Branch: Continue +0:11 Sequence +0:11 move second child to first child (temp int) +0:11 'ii' (temp int) +0:11 Constant: +0:11 -1 (const int) +0:11 Loop with condition tested first +0:11 Loop Condition +0:11 Compare Less Than (temp bool) +0:11 'ii' (temp int) +0:11 Constant: +0:11 3 (const int) +0:11 Loop Body +0:11 Test condition and select (temp void) +0:11 Condition +0:11 Compare Equal (temp bool) +0:11 'ii' (temp int) +0:11 Constant: +0:11 2 (const int) +0:11 true case +0:11 Branch: Continue +0:11 Loop Terminal Expression +0:11 Pre-Increment (temp int) +0:11 'ii' (temp int) +0:12 Pre-Decrement (temp float) +0:12 'ii' (temp float) 0:? Linker Objects @@ -61,7 +116,7 @@ Linked fragment stage: Shader version: 450 gl_FragCoord origin is upper left 0:? Sequence -0:9 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:14 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) 0:2 Function Parameters: 0:2 'input' (in 4-component vector of float) 0:? Sequence @@ -111,11 +166,66 @@ gl_FragCoord origin is upper left 0:7 'input' (in 4-component vector of float) 0:7 Constant: 0:7 2.000000 +0:? Sequence +0:8 Loop with condition tested first +0:8 No loop condition +0:8 Loop Body +0:8 Test condition and select (temp void) +0:8 Condition +0:8 Compare Greater Than (temp bool) +0:8 direct index (temp float) +0:8 'input' (in 4-component vector of float) +0:8 Constant: +0:8 0 (const int) +0:8 Constant: +0:8 2.000000 +0:8 true case +0:8 Branch: Break +0:? Sequence +0:9 Loop with condition tested first +0:9 No loop condition +0:9 Loop Body +0:9 Test condition and select (temp void) +0:9 Condition +0:9 Compare Greater Than (temp bool) +0:9 direct index (temp float) +0:9 'input' (in 4-component vector of float) +0:9 Constant: +0:9 0 (const int) +0:9 Constant: +0:9 2.000000 +0:9 true case +0:9 Branch: Continue +0:11 Sequence +0:11 move second child to first child (temp int) +0:11 'ii' (temp int) +0:11 Constant: +0:11 -1 (const int) +0:11 Loop with condition tested first +0:11 Loop Condition +0:11 Compare Less Than (temp bool) +0:11 'ii' (temp int) +0:11 Constant: +0:11 3 (const int) +0:11 Loop Body +0:11 Test condition and select (temp void) +0:11 Condition +0:11 Compare Equal (temp bool) +0:11 'ii' (temp int) +0:11 Constant: +0:11 2 (const int) +0:11 true case +0:11 Branch: Continue +0:11 Loop Terminal Expression +0:11 Pre-Increment (temp int) +0:11 'ii' (temp int) +0:12 Pre-Decrement (temp float) +0:12 'ii' (temp float) 0:? Linker Objects // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 64 +// Id's are bound by 112 Capability Shader 1: ExtInstImport "GLSL.std.450" @@ -125,6 +235,8 @@ gl_FragCoord origin is upper left Source HLSL 450 Name 4 "PixelShaderFunction" Name 13 "input" + Name 89 "ii" + Name 109 "ii" 2: TypeVoid 3: TypeFunction 2 10: TypeFloat 32 @@ -135,8 +247,20 @@ gl_FragCoord origin is upper left 29: TypeBool 30: TypeVector 29(bool) 4 60: 10(float) Constant 1073741824 + 68: TypeInt 32 0 + 69: 68(int) Constant 0 + 70: TypePointer Input 10(float) + 87: TypeInt 32 1 + 88: TypePointer Function 87(int) + 90: 87(int) Constant 4294967295 + 97: 87(int) Constant 3 + 100: 87(int) Constant 2 + 106: 87(int) Constant 1 + 108: TypePointer Function 10(float) 4(PixelShaderFunction): 2 Function None 3 5: Label + 89(ii): 88(ptr) Variable Function + 109(ii): 108(ptr) Variable Function Branch 6 6: Label LoopMerge 8 9 None @@ -216,5 +340,66 @@ gl_FragCoord origin is upper left Store 13(input) 63 Branch 48 50: Label + Branch 64 + 64: Label + LoopMerge 66 67 None + Branch 65 + 65: Label + 71: 70(ptr) AccessChain 13(input) 69 + 72: 10(float) Load 71 + 73: 29(bool) FOrdGreaterThan 72 60 + SelectionMerge 75 None + BranchConditional 73 74 75 + 74: Label + Branch 66 + 75: Label + Branch 67 + 67: Label + Branch 64 + 66: Label + Branch 77 + 77: Label + LoopMerge 79 80 None + Branch 78 + 78: Label + 81: 70(ptr) AccessChain 13(input) 69 + 82: 10(float) Load 81 + 83: 29(bool) FOrdGreaterThan 82 60 + SelectionMerge 85 None + BranchConditional 83 84 85 + 84: Label + Branch 80 + 85: Label + Branch 80 + 80: Label + Branch 77 + 79: Label + Store 89(ii) 90 + Branch 91 + 91: Label + LoopMerge 93 94 None + Branch 95 + 95: Label + 96: 87(int) Load 89(ii) + 98: 29(bool) SLessThan 96 97 + BranchConditional 98 92 93 + 92: Label + 99: 87(int) Load 89(ii) + 101: 29(bool) IEqual 99 100 + SelectionMerge 103 None + BranchConditional 101 102 103 + 102: Label + Branch 94 + 103: Label + Branch 94 + 94: Label + 105: 87(int) Load 89(ii) + 107: 87(int) IAdd 105 106 + Store 89(ii) 107 + Branch 91 + 93: Label + 110: 10(float) Load 109(ii) + 111: 10(float) FSub 110 15 + Store 109(ii) 111 Return FunctionEnd diff --git a/Test/baseResults/hlsl.if.frag.out b/Test/baseResults/hlsl.if.frag.out index a5a6a67e..ad9f2bac 100755 --- a/Test/baseResults/hlsl.if.frag.out +++ b/Test/baseResults/hlsl.if.frag.out @@ -2,7 +2,7 @@ hlsl.if.frag Shader version: 450 gl_FragCoord origin is upper left 0:? Sequence -0:29 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:34 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) 0:2 Function Parameters: 0:2 'input' (in 4-component vector of float) 0:? Sequence @@ -61,6 +61,19 @@ gl_FragCoord origin is upper left 0:26 Branch: Return with expression 0:26 Negate value (temp 4-component vector of float) 0:26 'input' (in 4-component vector of float) +0:30 Test condition and select (temp void) +0:30 Condition +0:30 move second child to first child (temp float) +0:30 'ii' (temp float) +0:30 direct index (temp float) +0:30 'input' (in 4-component vector of float) +0:30 Constant: +0:30 2 (const int) +0:30 true case +0:31 Pre-Increment (temp float) +0:31 'ii' (temp float) +0:32 Pre-Increment (temp int) +0:32 'ii' (temp int) 0:? Linker Objects @@ -70,7 +83,7 @@ Linked fragment stage: Shader version: 450 gl_FragCoord origin is upper left 0:? Sequence -0:29 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) +0:34 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float) 0:2 Function Parameters: 0:2 'input' (in 4-component vector of float) 0:? Sequence @@ -129,11 +142,24 @@ gl_FragCoord origin is upper left 0:26 Branch: Return with expression 0:26 Negate value (temp 4-component vector of float) 0:26 'input' (in 4-component vector of float) +0:30 Test condition and select (temp void) +0:30 Condition +0:30 move second child to first child (temp float) +0:30 'ii' (temp float) +0:30 direct index (temp float) +0:30 'input' (in 4-component vector of float) +0:30 Constant: +0:30 2 (const int) +0:30 true case +0:31 Pre-Increment (temp float) +0:31 'ii' (temp float) +0:32 Pre-Increment (temp int) +0:32 'ii' (temp int) 0:? Linker Objects // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 64 +// Id's are bound by 82 Capability Shader 1: ExtInstImport "GLSL.std.450" @@ -143,6 +169,8 @@ gl_FragCoord origin is upper left Source HLSL 450 Name 4 "PixelShaderFunction" Name 9 "input" + Name 65 "ii" + Name 78 "ii" 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -151,8 +179,18 @@ gl_FragCoord origin is upper left 9(input): 8(ptr) Variable Input 12: TypeBool 13: TypeVector 12(bool) 4 + 64: TypePointer Function 6(float) + 66: TypeInt 32 0 + 67: 66(int) Constant 2 + 68: TypePointer Input 6(float) + 74: 6(float) Constant 1065353216 + 76: TypeInt 32 1 + 77: TypePointer Function 76(int) + 80: 76(int) Constant 1 4(PixelShaderFunction): 2 Function None 3 5: Label + 65(ii): 64(ptr) Variable Function + 78(ii): 77(ptr) Variable Function 10: 7(fvec4) Load 9(input) 11: 7(fvec4) Load 9(input) 14: 13(bvec4) FOrdEqual 10 11 @@ -219,5 +257,19 @@ gl_FragCoord origin is upper left 62: 7(fvec4) FNegate 61 ReturnValue 62 57: Label + 69: 68(ptr) AccessChain 9(input) 67 + 70: 6(float) Load 69 + Store 65(ii) 70 + SelectionMerge 72 None + BranchConditional 70 71 72 + 71: Label + 73: 6(float) Load 65(ii) + 75: 6(float) FAdd 73 74 + Store 65(ii) 75 + Branch 72 + 72: Label + 79: 76(int) Load 78(ii) + 81: 76(int) IAdd 79 80 + Store 78(ii) 81 Return FunctionEnd diff --git a/Test/hlsl.discard.frag b/Test/hlsl.discard.frag new file mode 100644 index 00000000..e8b52679 --- /dev/null +++ b/Test/hlsl.discard.frag @@ -0,0 +1,14 @@ +void foo(float f) +{ + if (f < 1.0) + discard; +} + +float4 PixelShaderFunction(float4 input) : COLOR0 +{ + foo(input.z); + if (input.x) + discard; + float f = input.x; + discard; +} diff --git a/Test/hlsl.forLoop.frag b/Test/hlsl.forLoop.frag index 9109de79..2495e6e1 100644 --- a/Test/hlsl.forLoop.frag +++ b/Test/hlsl.forLoop.frag @@ -5,4 +5,9 @@ float4 PixelShaderFunction(float4 input) : COLOR0 [unroll] for (; input != input; ) {} for (; input != input; ) { return -input; } for (--input; input != input; input += 2) { return -input; } + for (;;) if (input.x > 2.0) break; + for (;;) if (input.x > 2.0) continue; + float ii; + for (int ii = -1; ii < 3; ++ii) if (ii == 2) continue; + --ii; } diff --git a/Test/hlsl.if.frag b/Test/hlsl.if.frag index 1f0dde71..1f6dc415 100644 --- a/Test/hlsl.if.frag +++ b/Test/hlsl.if.frag @@ -25,4 +25,9 @@ float4 PixelShaderFunction(float4 input) : COLOR0 } else { return -input; } + + int ii; + if (float ii = input.z) + ++ii; + ++ii; } diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 51be6f71..5492ff8f 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -76,6 +76,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.assoc.frag", "PixelShaderFunction"}, {"hlsl.attribute.frag", "PixelShaderFunction"}, {"hlsl.cast.frag", "PixelShaderFunction"}, + {"hlsl.discard.frag", "PixelShaderFunction"}, {"hlsl.doLoop.frag", "PixelShaderFunction"}, {"hlsl.float1.frag", "PixelShaderFunction"}, {"hlsl.float4.frag", "PixelShaderFunction"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 17ec8208..ae978190 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -106,7 +106,7 @@ bool HlslGrammar::acceptCompilationUnit() // declaration // : SEMICOLON -// : fully_specified_type SEMICOLON +// | fully_specified_type SEMICOLON // | fully_specified_type identifier array_specifier post_decls (EQUAL expression)opt SEMICOLON // | fully_specified_type identifier function_parameters post_decls SEMICOLON // function prototype // | fully_specified_type identifier function_parameters post_decls compound_statement // function definition @@ -173,6 +173,43 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) return true; } +// control_declaration +// : fully_specified_type identifier EQUAL expression +// +bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node) +{ + node = nullptr; + + // fully_specified_type + TType type; + if (! acceptFullySpecifiedType(type)) + return false; + + // identifier + HlslToken idToken; + if (! acceptIdentifier(idToken)) { + expected("identifier"); + return false; + } + + // EQUAL + TIntermTyped* expressionNode = nullptr; + if (! acceptTokenClass(EHTokAssign)) { + expected("="); + return false; + } + + // expression + if (! acceptExpression(expressionNode)) { + expected("initializer"); + return false; + } + + node = parseContext.declareVariable(idToken.loc, *idToken.string, type, 0, expressionNode); + + return true; +} + // fully_specified_type // : type_specifier // | type_qualifier type_specifier @@ -833,7 +870,9 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no // Accept an expression with parenthesis around it, where // the parenthesis ARE NOT expression parenthesis, but the -// syntactically required ones like in "if ( expression )" +// syntactically required ones like in "if ( expression )". +// +// Also accepts a declaration expression; "if (int a = expression)". // // Note this one is not set up to be speculative; as it gives // errors if not found. @@ -844,9 +883,21 @@ bool HlslGrammar::acceptParenExpression(TIntermTyped*& expression) if (! acceptTokenClass(EHTokLeftParen)) expected("("); - if (! acceptExpression(expression)) { - expected("expression"); - return false; + bool decl = false; + TIntermNode* declNode = nullptr; + decl = acceptControlDeclaration(declNode); + if (decl) { + if (declNode == nullptr || declNode->getAsTyped() == nullptr) { + expected("initialized declaration"); + return false; + } else + expression = declNode->getAsTyped(); + } else { + // no declaration + if (! acceptExpression(expression)) { + expected("expression"); + return false; + } } // RIGHT_PAREN @@ -1567,9 +1618,14 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement) // of the for sub-statement parseContext.pushScope(); - // initializer SEMI_COLON - TIntermTyped* initializer = nullptr; // TODO, "for (initializer" needs to support decl. statement - acceptExpression(initializer); + // initializer + TIntermNode* initNode = nullptr; + if (! acceptControlDeclaration(initNode)) { + TIntermTyped* initExpr = nullptr; + acceptExpression(initExpr); + initNode = initExpr; + } + // SEMI_COLON if (! acceptTokenClass(EHTokSemicolon)) expected(";"); @@ -1592,7 +1648,7 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement) return false; } - statement = intermediate.addForLoop(statement, initializer, condition, iterator, true, loc); + statement = intermediate.addForLoop(statement, initNode, condition, iterator, true, loc); parseContext.popScope(); parseContext.unnestLooping(); @@ -1614,38 +1670,53 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement) // bool HlslGrammar::acceptJumpStatement(TIntermNode*& statement) { - switch (peek()) { + EHlslTokenClass jump = peek(); + switch (jump) { case EHTokContinue: case EHTokBreak: case EHTokDiscard: - // TODO - return false; - case EHTokReturn: - // return - if (acceptTokenClass(EHTokReturn)) { - // expression - TIntermTyped* node; - if (acceptExpression(node)) { - // hook it up - statement = intermediate.addBranch(EOpReturn, node, token.loc); - } else - statement = intermediate.addBranch(EOpReturn, token.loc); - - // SEMICOLON - if (! acceptTokenClass(EHTokSemicolon)) { - expected(";"); - return false; - } - - return true; - } - + advanceToken(); + break; default: + // not something we handle in this function return false; } -} + switch (jump) { + case EHTokContinue: + statement = intermediate.addBranch(EOpContinue, token.loc); + break; + case EHTokBreak: + statement = intermediate.addBranch(EOpBreak, token.loc); + break; + case EHTokDiscard: + statement = intermediate.addBranch(EOpKill, token.loc); + break; + + case EHTokReturn: + { + // expression + TIntermTyped* node; + if (acceptExpression(node)) { + // hook it up + statement = intermediate.addBranch(EOpReturn, node, token.loc); + } else + statement = intermediate.addBranch(EOpReturn, token.loc); + break; + } + + default: + assert(0); + return false; + } + + // SEMICOLON + if (! acceptTokenClass(EHTokSemicolon)) + expected(";"); + + return true; +} bool HlslGrammar::acceptCaseLabel(TIntermNode*& statement) { diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index b4a948f2..baeb686e 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -58,6 +58,7 @@ namespace glslang { bool acceptIdentifier(HlslToken&); bool acceptCompilationUnit(); bool acceptDeclaration(TIntermNode*& node); + bool acceptControlDeclaration(TIntermNode*& node); bool acceptFullySpecifiedType(TType&); void acceptQualifier(TQualifier&); bool acceptType(TType&);