HLSL: Add typedef grammar and production.
This commit is contained in:
parent
d5ed0b6982
commit
5e69ec683d
132
Test/baseResults/hlsl.typedef.frag.out
Executable file
132
Test/baseResults/hlsl.typedef.frag.out
Executable file
@ -0,0 +1,132 @@
|
|||||||
|
hlsl.typedef.frag
|
||||||
|
Shader version: 450
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:12 Function Definition: ShaderFunction(vf4;i1; (global 4-component vector of float)
|
||||||
|
0:4 Function Parameters:
|
||||||
|
0:4 'input' (in 4-component vector of float)
|
||||||
|
0:4 'ii' (in int)
|
||||||
|
0:? Sequence
|
||||||
|
0:6 Sequence
|
||||||
|
0:6 move second child to first child (temp 4-component vector of float)
|
||||||
|
0:6 'a1' (temp 4-component vector of float)
|
||||||
|
0:6 Constant:
|
||||||
|
0:6 1.000000
|
||||||
|
0:6 1.000000
|
||||||
|
0:6 1.000000
|
||||||
|
0:6 1.000000
|
||||||
|
0:7 Sequence
|
||||||
|
0:7 move second child to first child (temp int)
|
||||||
|
0:7 'i' (temp int)
|
||||||
|
0:7 Constant:
|
||||||
|
0:7 2 (const int)
|
||||||
|
0:9 Sequence
|
||||||
|
0:9 move second child to first child (temp int)
|
||||||
|
0:9 'j' (temp int)
|
||||||
|
0:9 'ii' (in int)
|
||||||
|
0:10 Branch: Return with expression
|
||||||
|
0:10 add (temp 4-component vector of float)
|
||||||
|
0:10 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:10 'input' (in 4-component vector of float)
|
||||||
|
0:10 'a1' (temp 4-component vector of float)
|
||||||
|
0:10 Construct vec4 (global 4-component vector of float)
|
||||||
|
0:10 Convert int to float (temp float)
|
||||||
|
0:10 add (temp int)
|
||||||
|
0:10 'i' (temp int)
|
||||||
|
0:10 'j' (temp int)
|
||||||
|
0:? Linker Objects
|
||||||
|
|
||||||
|
|
||||||
|
Linked fragment stage:
|
||||||
|
|
||||||
|
|
||||||
|
Shader version: 450
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:12 Function Definition: ShaderFunction(vf4;i1; (global 4-component vector of float)
|
||||||
|
0:4 Function Parameters:
|
||||||
|
0:4 'input' (in 4-component vector of float)
|
||||||
|
0:4 'ii' (in int)
|
||||||
|
0:? Sequence
|
||||||
|
0:6 Sequence
|
||||||
|
0:6 move second child to first child (temp 4-component vector of float)
|
||||||
|
0:6 'a1' (temp 4-component vector of float)
|
||||||
|
0:6 Constant:
|
||||||
|
0:6 1.000000
|
||||||
|
0:6 1.000000
|
||||||
|
0:6 1.000000
|
||||||
|
0:6 1.000000
|
||||||
|
0:7 Sequence
|
||||||
|
0:7 move second child to first child (temp int)
|
||||||
|
0:7 'i' (temp int)
|
||||||
|
0:7 Constant:
|
||||||
|
0:7 2 (const int)
|
||||||
|
0:9 Sequence
|
||||||
|
0:9 move second child to first child (temp int)
|
||||||
|
0:9 'j' (temp int)
|
||||||
|
0:9 'ii' (in int)
|
||||||
|
0:10 Branch: Return with expression
|
||||||
|
0:10 add (temp 4-component vector of float)
|
||||||
|
0:10 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:10 'input' (in 4-component vector of float)
|
||||||
|
0:10 'a1' (temp 4-component vector of float)
|
||||||
|
0:10 Construct vec4 (global 4-component vector of float)
|
||||||
|
0:10 Convert int to float (temp float)
|
||||||
|
0:10 add (temp int)
|
||||||
|
0:10 'i' (temp int)
|
||||||
|
0:10 'j' (temp int)
|
||||||
|
0:? Linker Objects
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80001
|
||||||
|
// Id's are bound by 34
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "PixelShaderFunction"
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source HLSL 450
|
||||||
|
Name 4 "PixelShaderFunction"
|
||||||
|
Name 14 "ShaderFunction(vf4;i1;"
|
||||||
|
Name 12 "input"
|
||||||
|
Name 13 "ii"
|
||||||
|
Name 16 "a1"
|
||||||
|
Name 19 "i"
|
||||||
|
Name 21 "j"
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeFloat 32
|
||||||
|
7: TypeVector 6(float) 4
|
||||||
|
8: TypePointer Function 7(fvec4)
|
||||||
|
9: TypeInt 32 1
|
||||||
|
10: TypePointer Function 9(int)
|
||||||
|
11: TypeFunction 7(fvec4) 8(ptr) 10(ptr)
|
||||||
|
17: 6(float) Constant 1065353216
|
||||||
|
18: 7(fvec4) ConstantComposite 17 17 17 17
|
||||||
|
20: 9(int) Constant 2
|
||||||
|
4(PixelShaderFunction): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
FunctionEnd
|
||||||
|
14(ShaderFunction(vf4;i1;): 7(fvec4) Function None 11
|
||||||
|
12(input): 8(ptr) FunctionParameter
|
||||||
|
13(ii): 10(ptr) FunctionParameter
|
||||||
|
15: Label
|
||||||
|
16(a1): 8(ptr) Variable Function
|
||||||
|
19(i): 10(ptr) Variable Function
|
||||||
|
21(j): 10(ptr) Variable Function
|
||||||
|
Store 16(a1) 18
|
||||||
|
Store 19(i) 20
|
||||||
|
22: 9(int) Load 13(ii)
|
||||||
|
Store 21(j) 22
|
||||||
|
23: 7(fvec4) Load 12(input)
|
||||||
|
24: 7(fvec4) Load 16(a1)
|
||||||
|
25: 7(fvec4) FMul 23 24
|
||||||
|
26: 9(int) Load 19(i)
|
||||||
|
27: 9(int) Load 21(j)
|
||||||
|
28: 9(int) IAdd 26 27
|
||||||
|
29: 6(float) ConvertSToF 28
|
||||||
|
30: 7(fvec4) CompositeConstruct 29 29 29 29
|
||||||
|
31: 7(fvec4) FAdd 25 30
|
||||||
|
ReturnValue 31
|
||||||
|
FunctionEnd
|
11
Test/hlsl.typedef.frag
Normal file
11
Test/hlsl.typedef.frag
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
typedef float4 myVec4;
|
||||||
|
|
||||||
|
float4 ShaderFunction(float4 input, int ii) : COLOR0
|
||||||
|
{
|
||||||
|
typedef int myInt;
|
||||||
|
myVec4 a1 = myVec4(1.0);
|
||||||
|
myInt i = 2;
|
||||||
|
typedef myInt myInt2;
|
||||||
|
myInt2 j = ii;
|
||||||
|
return input * a1 + myVec4(i + j);
|
||||||
|
}
|
@ -104,6 +104,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
{"hlsl.switch.frag", "PixelShaderFunction"},
|
{"hlsl.switch.frag", "PixelShaderFunction"},
|
||||||
{"hlsl.swizzle.frag", "PixelShaderFunction"},
|
{"hlsl.swizzle.frag", "PixelShaderFunction"},
|
||||||
{"hlsl.templatetypes.frag", "PixelShaderFunction"},
|
{"hlsl.templatetypes.frag", "PixelShaderFunction"},
|
||||||
|
{"hlsl.typedef.frag", "PixelShaderFunction"},
|
||||||
{"hlsl.whileLoop.frag", "PixelShaderFunction"},
|
{"hlsl.whileLoop.frag", "PixelShaderFunction"},
|
||||||
{"hlsl.void.frag", "PixelShaderFunction"},
|
{"hlsl.void.frag", "PixelShaderFunction"},
|
||||||
}),
|
}),
|
||||||
|
@ -108,6 +108,7 @@ bool HlslGrammar::acceptCompilationUnit()
|
|||||||
// declaration
|
// declaration
|
||||||
// : fully_specified_type declarator_list SEMICOLON
|
// : fully_specified_type declarator_list SEMICOLON
|
||||||
// | fully_specified_type identifier function_parameters post_decls compound_statement // function definition
|
// | fully_specified_type identifier function_parameters post_decls compound_statement // function definition
|
||||||
|
// | typedef declaration
|
||||||
//
|
//
|
||||||
// declarator_list
|
// declarator_list
|
||||||
// : declarator COMMA declarator COMMA declarator... // zero or more declarators
|
// : declarator COMMA declarator COMMA declarator... // zero or more declarators
|
||||||
@ -130,6 +131,9 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
|||||||
node = nullptr;
|
node = nullptr;
|
||||||
bool list = false;
|
bool list = false;
|
||||||
|
|
||||||
|
// typedef
|
||||||
|
bool typedefDecl = acceptTokenClass(EHTokTypedef);
|
||||||
|
|
||||||
// fully_specified_type
|
// fully_specified_type
|
||||||
TType type;
|
TType type;
|
||||||
if (! acceptFullySpecifiedType(type))
|
if (! acceptFullySpecifiedType(type))
|
||||||
@ -150,9 +154,14 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
|||||||
if (peekTokenClass(EHTokLeftBrace)) {
|
if (peekTokenClass(EHTokLeftBrace)) {
|
||||||
if (list)
|
if (list)
|
||||||
parseContext.error(idToken.loc, "function body can't be in a declarator list", "{", "");
|
parseContext.error(idToken.loc, "function body can't be in a declarator list", "{", "");
|
||||||
|
if (typedefDecl)
|
||||||
|
parseContext.error(idToken.loc, "function body can't be in a typedef", "{", "");
|
||||||
return acceptFunctionDefinition(*function, node);
|
return acceptFunctionDefinition(*function, node);
|
||||||
} else
|
} else {
|
||||||
|
if (typedefDecl)
|
||||||
|
parseContext.error(idToken.loc, "function typedefs not implemented", "{", "");
|
||||||
parseContext.handleFunctionDeclarator(idToken.loc, *function, true);
|
parseContext.handleFunctionDeclarator(idToken.loc, *function, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// a variable declaration
|
// a variable declaration
|
||||||
|
|
||||||
@ -166,19 +175,25 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
|||||||
// EQUAL assignment_expression
|
// EQUAL assignment_expression
|
||||||
TIntermTyped* expressionNode = nullptr;
|
TIntermTyped* expressionNode = nullptr;
|
||||||
if (acceptTokenClass(EHTokAssign)) {
|
if (acceptTokenClass(EHTokAssign)) {
|
||||||
|
if (typedefDecl)
|
||||||
|
parseContext.error(idToken.loc, "can't have an initializer", "typedef", "");
|
||||||
if (! acceptAssignmentExpression(expressionNode)) {
|
if (! acceptAssignmentExpression(expressionNode)) {
|
||||||
expected("initializer");
|
expected("initializer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare the variable and add any initializer code to the AST.
|
if (typedefDecl)
|
||||||
// The top-level node is always made into an aggregate, as that's
|
parseContext.declareTypedef(idToken.loc, *idToken.string, type, arraySizes);
|
||||||
// historically how the AST has been.
|
else {
|
||||||
node = intermediate.growAggregate(node,
|
// Declare the variable and add any initializer code to the AST.
|
||||||
parseContext.declareVariable(idToken.loc, *idToken.string, type,
|
// The top-level node is always made into an aggregate, as that's
|
||||||
arraySizes, expressionNode),
|
// historically how the AST has been.
|
||||||
idToken.loc);
|
node = intermediate.growAggregate(node,
|
||||||
|
parseContext.declareVariable(idToken.loc, *idToken.string, type,
|
||||||
|
arraySizes, expressionNode),
|
||||||
|
idToken.loc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acceptTokenClass(EHTokComma)) {
|
if (acceptTokenClass(EHTokComma)) {
|
||||||
|
@ -3018,6 +3018,27 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
|
|||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do everything necessary to handle a typedef declaration, for a single symbol.
|
||||||
|
//
|
||||||
|
// 'parseType' is the type part of the declaration (to the left)
|
||||||
|
// 'arraySizes' is the arrayness tagged on the identifier (to the right)
|
||||||
|
//
|
||||||
|
void HlslParseContext::declareTypedef(const TSourceLoc& loc, TString& identifier, const TType& parseType, TArraySizes* arraySizes)
|
||||||
|
{
|
||||||
|
TType type;
|
||||||
|
type.deepCopy(parseType);
|
||||||
|
|
||||||
|
// Arrayness is potentially coming both from the type and from the
|
||||||
|
// variable: "int[] a[];" or just one or the other.
|
||||||
|
// Merge it all to the type, so all arrayness is part of the type.
|
||||||
|
arrayDimMerge(type, arraySizes);
|
||||||
|
|
||||||
|
TVariable* typeSymbol = new TVariable(&identifier, type, true);
|
||||||
|
if (! symbolTable.insert(*typeSymbol))
|
||||||
|
error(loc, "name already defined", "typedef", identifier.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Do everything necessary to handle a variable (non-block) declaration.
|
// Do everything necessary to handle a variable (non-block) declaration.
|
||||||
// Either redeclaring a variable, or making a new one, updating the symbol
|
// Either redeclaring a variable, or making a new one, updating the symbol
|
||||||
@ -3026,7 +3047,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
|
|||||||
// Returns a subtree node that computes an initializer, if needed.
|
// Returns a subtree node that computes an initializer, if needed.
|
||||||
// Returns nullptr if there is no code to execute for initialization.
|
// Returns nullptr if there is no code to execute for initialization.
|
||||||
//
|
//
|
||||||
// 'publicType' is the type part of the declaration (to the left)
|
// 'parseType' is the type part of the declaration (to the left)
|
||||||
// 'arraySizes' is the arrayness tagged on the identifier (to the right)
|
// 'arraySizes' is the arrayness tagged on the identifier (to the right)
|
||||||
//
|
//
|
||||||
TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TType& parseType, TArraySizes* arraySizes, TIntermTyped* initializer)
|
TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TType& parseType, TArraySizes* arraySizes, TIntermTyped* initializer)
|
||||||
@ -3036,7 +3057,7 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& i
|
|||||||
if (type.isImplicitlySizedArray()) {
|
if (type.isImplicitlySizedArray()) {
|
||||||
// Because "int[] a = int[2](...), b = int[3](...)" makes two arrays a and b
|
// Because "int[] a = int[2](...), b = int[3](...)" makes two arrays a and b
|
||||||
// of different sizes, for this case sharing the shallow copy of arrayness
|
// of different sizes, for this case sharing the shallow copy of arrayness
|
||||||
// with the publicType oversubscribes it, so get a deep copy of the arrayness.
|
// with the parseType oversubscribes it, so get a deep copy of the arrayness.
|
||||||
type.newArraySizes(*parseType.getArraySizes());
|
type.newArraySizes(*parseType.getArraySizes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3045,7 +3066,7 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& i
|
|||||||
|
|
||||||
// Check for redeclaration of built-ins and/or attempting to declare a reserved name
|
// Check for redeclaration of built-ins and/or attempting to declare a reserved name
|
||||||
bool newDeclaration = false; // true if a new entry gets added to the symbol table
|
bool newDeclaration = false; // true if a new entry gets added to the symbol table
|
||||||
TSymbol* symbol = nullptr; // = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers, newDeclaration);
|
TSymbol* symbol = nullptr; // = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), parseType.shaderQualifiers, newDeclaration);
|
||||||
|
|
||||||
inheritGlobalDefaults(type.getQualifier());
|
inheritGlobalDefaults(type.getQualifier());
|
||||||
|
|
||||||
|
@ -126,6 +126,7 @@ public:
|
|||||||
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
||||||
|
|
||||||
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
||||||
|
void declareTypedef(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0);
|
||||||
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||||
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
|
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
|
||||||
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user