HLSL: allow scalar type keywords as identifiers, and add half type support.
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Tue, 27 Dec 2016 01:45:52 +0000 (18:45 -0700)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Tue, 27 Dec 2016 18:26:45 +0000 (11:26 -0700)
HLSL allows type keywords to also be identifiers, so a sequence such as "float half = 3" is
valid, or more bizzarely, something like "float.float = int.uint + bool;"

There are places this is not supported.  E.g, it's permitted for struct members, but not struct
names or functions.  Also, vector or matrix types such as "float3" are not permitted as
identifiers.

This PR adds that support, as well as support for the "half" type.  In production shaders,
this was seen with variables named "half".  The PR attempts to support this without breaking
useful grammar errors such as "; expected" at the end of unterminated statements, so it errs
on that side at the possible expense of failing to accept valid constructs containing a type
keyword identifier.  If others are discovered, they can be added.

Also, half is now accepted as a valid type, alongside the min*float types.

Test/baseResults/hlsl.type.half.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.type.identifier.frag.out [new file with mode: 0644]
Test/hlsl.type.half.frag [new file with mode: 0644]
Test/hlsl.type.identifier.frag [new file with mode: 0644]
gtests/Hlsl.FromFile.cpp
hlsl/hlslGrammar.cpp
hlsl/hlslScanContext.cpp
hlsl/hlslTokens.h

diff --git a/Test/baseResults/hlsl.type.half.frag.out b/Test/baseResults/hlsl.type.half.frag.out
new file mode 100644 (file)
index 0000000..2848351
--- /dev/null
@@ -0,0 +1,161 @@
+hlsl.type.half.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:3  Function Definition: main( (temp 4-component vector of float)
+0:3    Function Parameters: 
+0:?     Sequence
+0:4      Sequence
+0:4        move second child to first child (temp mediump float)
+0:4          'h0' (temp mediump float)
+0:4          Constant:
+0:4            0.000000
+0:5      Sequence
+0:5        move second child to first child (temp mediump 1-component vector of float)
+0:5          'h1' (temp mediump 1-component vector of float)
+0:5          Constant:
+0:5            1.000000
+0:6      Sequence
+0:6        move second child to first child (temp mediump 2-component vector of float)
+0:6          'h2' (temp mediump 2-component vector of float)
+0:6          Constant:
+0:6            2.000000
+0:6            2.000000
+0:7      Sequence
+0:7        move second child to first child (temp mediump 3-component vector of float)
+0:7          'h3' (temp mediump 3-component vector of float)
+0:7          Constant:
+0:7            3.000000
+0:7            3.000000
+0:7            3.000000
+0:8      Sequence
+0:8        move second child to first child (temp mediump 4-component vector of float)
+0:8          'h4' (temp mediump 4-component vector of float)
+0:8          Constant:
+0:8            4.000000
+0:8            4.000000
+0:8            4.000000
+0:8            4.000000
+0:10      Sequence
+0:10        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:10          Constant:
+0:10            0.000000
+0:10            0.000000
+0:10            0.000000
+0:10            0.000000
+0:10        Branch: Return
+0:?   Linker Objects
+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:3  Function Definition: main( (temp 4-component vector of float)
+0:3    Function Parameters: 
+0:?     Sequence
+0:4      Sequence
+0:4        move second child to first child (temp mediump float)
+0:4          'h0' (temp mediump float)
+0:4          Constant:
+0:4            0.000000
+0:5      Sequence
+0:5        move second child to first child (temp mediump 1-component vector of float)
+0:5          'h1' (temp mediump 1-component vector of float)
+0:5          Constant:
+0:5            1.000000
+0:6      Sequence
+0:6        move second child to first child (temp mediump 2-component vector of float)
+0:6          'h2' (temp mediump 2-component vector of float)
+0:6          Constant:
+0:6            2.000000
+0:6            2.000000
+0:7      Sequence
+0:7        move second child to first child (temp mediump 3-component vector of float)
+0:7          'h3' (temp mediump 3-component vector of float)
+0:7          Constant:
+0:7            3.000000
+0:7            3.000000
+0:7            3.000000
+0:8      Sequence
+0:8        move second child to first child (temp mediump 4-component vector of float)
+0:8          'h4' (temp mediump 4-component vector of float)
+0:8          Constant:
+0:8            4.000000
+0:8            4.000000
+0:8            4.000000
+0:8            4.000000
+0:10      Sequence
+0:10        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:10          Constant:
+0:10            0.000000
+0:10            0.000000
+0:10            0.000000
+0:10            0.000000
+0:10        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 31
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 28
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 8  "h0"
+                              Name 10  "h1"
+                              Name 14  "h2"
+                              Name 19  "h3"
+                              Name 24  "h4"
+                              Name 28  "@entryPointOutput"
+                              Decorate 8(h0) RelaxedPrecision
+                              Decorate 10(h1) RelaxedPrecision
+                              Decorate 14(h2) RelaxedPrecision
+                              Decorate 19(h3) RelaxedPrecision
+                              Decorate 24(h4) RelaxedPrecision
+                              Decorate 28(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypePointer Function 6(float)
+               9:    6(float) Constant 0
+              11:    6(float) Constant 1065353216
+              12:             TypeVector 6(float) 2
+              13:             TypePointer Function 12(fvec2)
+              15:    6(float) Constant 1073741824
+              16:   12(fvec2) ConstantComposite 15 15
+              17:             TypeVector 6(float) 3
+              18:             TypePointer Function 17(fvec3)
+              20:    6(float) Constant 1077936128
+              21:   17(fvec3) ConstantComposite 20 20 20
+              22:             TypeVector 6(float) 4
+              23:             TypePointer Function 22(fvec4)
+              25:    6(float) Constant 1082130432
+              26:   22(fvec4) ConstantComposite 25 25 25 25
+              27:             TypePointer Output 22(fvec4)
+28(@entryPointOutput):     27(ptr) Variable Output
+              29:   22(fvec4) ConstantComposite 9 9 9 9
+         4(main):           2 Function None 3
+               5:             Label
+           8(h0):      7(ptr) Variable Function
+          10(h1):      7(ptr) Variable Function
+          14(h2):     13(ptr) Variable Function
+          19(h3):     18(ptr) Variable Function
+          24(h4):     23(ptr) Variable Function
+                              Store 8(h0) 9
+                              Store 10(h1) 11
+                              Store 14(h2) 16
+                              Store 19(h3) 21
+                              Store 24(h4) 26
+                              Store 28(@entryPointOutput) 29
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.type.identifier.frag.out b/Test/baseResults/hlsl.type.identifier.frag.out
new file mode 100644 (file)
index 0000000..73d8969
--- /dev/null
@@ -0,0 +1,382 @@
+hlsl.type.identifier.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:6  Function Definition: fn(f1; (temp float)
+0:6    Function Parameters: 
+0:6      'float' (in float)
+0:?     Sequence
+0:6      Branch: Return with expression
+0:6        'float' (in float)
+0:9  Function Definition: main( (temp 4-component vector of float)
+0:9    Function Parameters: 
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child (temp float)
+0:10          'float' (temp float)
+0:10          Constant:
+0:10            7.000000
+0:11      Sequence
+0:11        move second child to first child (temp 2-element array of bool)
+0:11          'bool' (temp 2-element array of bool)
+0:11          Construct bool (temp 2-element array of bool)
+0:11            Convert float to bool (temp bool)
+0:11              'float' (temp float)
+0:11            Convert float to bool (temp bool)
+0:11              'float' (temp float)
+0:12      Sequence
+0:12        move second child to first child (temp int)
+0:12          'int' (temp int)
+0:12          Convert bool to int (temp int)
+0:12            direct index (temp bool)
+0:12              'bool' (temp 2-element array of bool)
+0:12              Constant:
+0:12                1 (const int)
+0:13      Sequence
+0:13        move second child to first child (temp uint)
+0:13          'uint' (temp uint)
+0:13          Convert float to uint (temp uint)
+0:13            add (temp float)
+0:13              'float' (temp float)
+0:13              Convert int to float (temp float)
+0:13                'int' (temp int)
+0:14      Sequence
+0:14        move second child to first child (temp mediump float)
+0:14          'min16float' (temp mediump float)
+0:14          Convert uint to float (temp mediump float)
+0:14            'uint' (temp mediump uint)
+0:15      Sequence
+0:15        move second child to first child (temp mediump float)
+0:15          'min10float' (temp mediump float)
+0:15          'min16float' (temp mediump float)
+0:16      Sequence
+0:16        move second child to first child (temp mediump float)
+0:16          'half' (temp mediump float)
+0:16          Constant:
+0:16            0.500000
+0:?       Sequence
+0:20        move second child to first child (temp float)
+0:20          float: direct index for structure (temp float)
+0:20            'float' (temp structure{temp float float})
+0:20            Constant:
+0:20              0 (const int)
+0:20          Constant:
+0:20            42.000000
+0:23      move second child to first child (temp bool)
+0:23        direct index (temp bool)
+0:23          'bool' (temp 2-element array of bool)
+0:23          Constant:
+0:23            0 (const int)
+0:23        direct index (temp bool)
+0:23          'bool' (temp 2-element array of bool)
+0:23          Constant:
+0:23            1 (const int)
+0:25      move second child to first child (temp mediump float)
+0:25        'float' (temp mediump float)
+0:25        add (temp mediump float)
+0:25          add (temp mediump float)
+0:25            add (temp mediump float)
+0:25              add (temp mediump float)
+0:25                add (temp mediump float)
+0:25                  add (temp mediump float)
+0:25                    'float' (temp mediump float)
+0:25                    Convert int to float (temp mediump float)
+0:25                      'int' (temp mediump int)
+0:25                  Convert uint to float (temp mediump float)
+0:25                    'uint' (temp mediump uint)
+0:25                'min16float' (temp mediump float)
+0:25              'min10float' (temp mediump float)
+0:25            Test condition and select (temp mediump float)
+0:25              Condition
+0:25              direct index (temp bool)
+0:25                'bool' (temp 2-element array of bool)
+0:25                Constant:
+0:25                  0 (const int)
+0:25              true case
+0:25              Convert int to float (temp mediump float)
+0:25                'int' (temp mediump int)
+0:25              false case
+0:25              'float' (temp mediump float)
+0:25          Function Call: fn(f1; (temp mediump float)
+0:25            'float' (temp mediump float)
+0:27      Sequence
+0:27        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:27          Construct vec4 (temp 4-component vector of float)
+0:27            'float' (temp float)
+0:27        Branch: Return
+0:?   Linker Objects
+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:6  Function Definition: fn(f1; (temp float)
+0:6    Function Parameters: 
+0:6      'float' (in float)
+0:?     Sequence
+0:6      Branch: Return with expression
+0:6        'float' (in float)
+0:9  Function Definition: main( (temp 4-component vector of float)
+0:9    Function Parameters: 
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child (temp float)
+0:10          'float' (temp float)
+0:10          Constant:
+0:10            7.000000
+0:11      Sequence
+0:11        move second child to first child (temp 2-element array of bool)
+0:11          'bool' (temp 2-element array of bool)
+0:11          Construct bool (temp 2-element array of bool)
+0:11            Convert float to bool (temp bool)
+0:11              'float' (temp float)
+0:11            Convert float to bool (temp bool)
+0:11              'float' (temp float)
+0:12      Sequence
+0:12        move second child to first child (temp int)
+0:12          'int' (temp int)
+0:12          Convert bool to int (temp int)
+0:12            direct index (temp bool)
+0:12              'bool' (temp 2-element array of bool)
+0:12              Constant:
+0:12                1 (const int)
+0:13      Sequence
+0:13        move second child to first child (temp uint)
+0:13          'uint' (temp uint)
+0:13          Convert float to uint (temp uint)
+0:13            add (temp float)
+0:13              'float' (temp float)
+0:13              Convert int to float (temp float)
+0:13                'int' (temp int)
+0:14      Sequence
+0:14        move second child to first child (temp mediump float)
+0:14          'min16float' (temp mediump float)
+0:14          Convert uint to float (temp mediump float)
+0:14            'uint' (temp mediump uint)
+0:15      Sequence
+0:15        move second child to first child (temp mediump float)
+0:15          'min10float' (temp mediump float)
+0:15          'min16float' (temp mediump float)
+0:16      Sequence
+0:16        move second child to first child (temp mediump float)
+0:16          'half' (temp mediump float)
+0:16          Constant:
+0:16            0.500000
+0:?       Sequence
+0:20        move second child to first child (temp float)
+0:20          float: direct index for structure (temp float)
+0:20            'float' (temp structure{temp float float})
+0:20            Constant:
+0:20              0 (const int)
+0:20          Constant:
+0:20            42.000000
+0:23      move second child to first child (temp bool)
+0:23        direct index (temp bool)
+0:23          'bool' (temp 2-element array of bool)
+0:23          Constant:
+0:23            0 (const int)
+0:23        direct index (temp bool)
+0:23          'bool' (temp 2-element array of bool)
+0:23          Constant:
+0:23            1 (const int)
+0:25      move second child to first child (temp mediump float)
+0:25        'float' (temp mediump float)
+0:25        add (temp mediump float)
+0:25          add (temp mediump float)
+0:25            add (temp mediump float)
+0:25              add (temp mediump float)
+0:25                add (temp mediump float)
+0:25                  add (temp mediump float)
+0:25                    'float' (temp mediump float)
+0:25                    Convert int to float (temp mediump float)
+0:25                      'int' (temp mediump int)
+0:25                  Convert uint to float (temp mediump float)
+0:25                    'uint' (temp mediump uint)
+0:25                'min16float' (temp mediump float)
+0:25              'min10float' (temp mediump float)
+0:25            Test condition and select (temp mediump float)
+0:25              Condition
+0:25              direct index (temp bool)
+0:25                'bool' (temp 2-element array of bool)
+0:25                Constant:
+0:25                  0 (const int)
+0:25              true case
+0:25              Convert int to float (temp mediump float)
+0:25                'int' (temp mediump int)
+0:25              false case
+0:25              'float' (temp mediump float)
+0:25          Function Call: fn(f1; (temp mediump float)
+0:25            'float' (temp mediump float)
+0:27      Sequence
+0:27        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:27          Construct vec4 (temp 4-component vector of float)
+0:27            'float' (temp float)
+0:27        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 92
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 88
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 10  "fn(f1;"
+                              Name 9  "float"
+                              Name 15  "float"
+                              Name 22  "bool"
+                              Name 31  "int"
+                              Name 39  "uint"
+                              Name 45  "min16float"
+                              Name 48  "min10float"
+                              Name 50  "half"
+                              Name 52  "foo_t"
+                              MemberName 52(foo_t) 0  "float"
+                              Name 54  "float"
+                              Name 82  "param"
+                              Name 88  "@entryPointOutput"
+                              Decorate 45(min16float) RelaxedPrecision
+                              Decorate 46 RelaxedPrecision
+                              Decorate 47 RelaxedPrecision
+                              Decorate 48(min10float) RelaxedPrecision
+                              Decorate 49 RelaxedPrecision
+                              Decorate 50(half) RelaxedPrecision
+                              Decorate 60 RelaxedPrecision
+                              Decorate 61 RelaxedPrecision
+                              Decorate 62 RelaxedPrecision
+                              Decorate 63 RelaxedPrecision
+                              Decorate 64 RelaxedPrecision
+                              Decorate 65 RelaxedPrecision
+                              Decorate 66 RelaxedPrecision
+                              Decorate 67 RelaxedPrecision
+                              Decorate 68 RelaxedPrecision
+                              Decorate 69 RelaxedPrecision
+                              Decorate 70 RelaxedPrecision
+                              Decorate 76 RelaxedPrecision
+                              Decorate 77 RelaxedPrecision
+                              Decorate 79 RelaxedPrecision
+                              Decorate 80 RelaxedPrecision
+                              Decorate 81 RelaxedPrecision
+                              Decorate 83 RelaxedPrecision
+                              Decorate 84 RelaxedPrecision
+                              Decorate 85 RelaxedPrecision
+                              Decorate 88(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypePointer Function 6(float)
+               8:             TypeFunction 6(float) 7(ptr)
+              16:    6(float) Constant 1088421888
+              17:             TypeBool
+              18:             TypeInt 32 0
+              19:     18(int) Constant 2
+              20:             TypeArray 17(bool) 19
+              21:             TypePointer Function 20
+              24:    6(float) Constant 0
+              29:             TypeInt 32 1
+              30:             TypePointer Function 29(int)
+              32:     29(int) Constant 1
+              33:             TypePointer Function 17(bool)
+              36:     29(int) Constant 0
+              38:             TypePointer Function 18(int)
+              51:    6(float) Constant 1056964608
+       52(foo_t):             TypeStruct 6(float)
+              53:             TypePointer Function 52(foo_t)
+              55:    6(float) Constant 1109917696
+              86:             TypeVector 6(float) 4
+              87:             TypePointer Output 86(fvec4)
+88(@entryPointOutput):     87(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       15(float):      7(ptr) Variable Function
+        22(bool):     21(ptr) Variable Function
+         31(int):     30(ptr) Variable Function
+        39(uint):     38(ptr) Variable Function
+  45(min16float):      7(ptr) Variable Function
+  48(min10float):      7(ptr) Variable Function
+        50(half):      7(ptr) Variable Function
+       54(float):     53(ptr) Variable Function
+              71:      7(ptr) Variable Function
+       82(param):      7(ptr) Variable Function
+                              Store 15(float) 16
+              23:    6(float) Load 15(float)
+              25:    17(bool) FOrdNotEqual 23 24
+              26:    6(float) Load 15(float)
+              27:    17(bool) FOrdNotEqual 26 24
+              28:          20 CompositeConstruct 25 27
+                              Store 22(bool) 28
+              34:     33(ptr) AccessChain 22(bool) 32
+              35:    17(bool) Load 34
+              37:     29(int) Select 35 32 36
+                              Store 31(int) 37
+              40:    6(float) Load 15(float)
+              41:     29(int) Load 31(int)
+              42:    6(float) ConvertSToF 41
+              43:    6(float) FAdd 40 42
+              44:     18(int) ConvertFToU 43
+                              Store 39(uint) 44
+              46:     18(int) Load 39(uint)
+              47:    6(float) ConvertUToF 46
+                              Store 45(min16float) 47
+              49:    6(float) Load 45(min16float)
+                              Store 48(min10float) 49
+                              Store 50(half) 51
+              56:      7(ptr) AccessChain 54(float) 36
+                              Store 56 55
+              57:     33(ptr) AccessChain 22(bool) 32
+              58:    17(bool) Load 57
+              59:     33(ptr) AccessChain 22(bool) 36
+                              Store 59 58
+              60:    6(float) Load 15(float)
+              61:     29(int) Load 31(int)
+              62:    6(float) ConvertSToF 61
+              63:    6(float) FAdd 60 62
+              64:     18(int) Load 39(uint)
+              65:    6(float) ConvertUToF 64
+              66:    6(float) FAdd 63 65
+              67:    6(float) Load 45(min16float)
+              68:    6(float) FAdd 66 67
+              69:    6(float) Load 48(min10float)
+              70:    6(float) FAdd 68 69
+              72:     33(ptr) AccessChain 22(bool) 36
+              73:    17(bool) Load 72
+                              SelectionMerge 75 None
+                              BranchConditional 73 74 78
+              74:               Label
+              76:     29(int)   Load 31(int)
+              77:    6(float)   ConvertSToF 76
+                                Store 71 77
+                                Branch 75
+              78:               Label
+              79:    6(float)   Load 15(float)
+                                Store 71 79
+                                Branch 75
+              75:             Label
+              80:    6(float) Load 71
+              81:    6(float) FAdd 70 80
+              83:    6(float) Load 15(float)
+                              Store 82(param) 83
+              84:    6(float) FunctionCall 10(fn(f1;) 82(param)
+              85:    6(float) FAdd 81 84
+                              Store 15(float) 85
+              89:    6(float) Load 15(float)
+              90:   86(fvec4) CompositeConstruct 89 89 89 89
+                              Store 88(@entryPointOutput) 90
+                              Return
+                              FunctionEnd
+      10(fn(f1;):    6(float) Function None 8
+        9(float):      7(ptr) FunctionParameter
+              11:             Label
+              12:    6(float) Load 9(float)
+                              ReturnValue 12
+                              FunctionEnd
diff --git a/Test/hlsl.type.half.frag b/Test/hlsl.type.half.frag
new file mode 100644 (file)
index 0000000..f082039
--- /dev/null
@@ -0,0 +1,11 @@
+
+float4 main() : SV_Target0
+{
+    half  h0 = 0;
+    half1 h1 = 1;
+    half2 h2 = 2;
+    half3 h3 = 3;
+    half4 h4 = 4;
+
+    return 0.0;
+}
diff --git a/Test/hlsl.type.identifier.frag b/Test/hlsl.type.identifier.frag
new file mode 100644 (file)
index 0000000..25ba457
--- /dev/null
@@ -0,0 +1,28 @@
+
+struct foo_t {
+    float float;
+};
+
+float fn(float float) { return float; }
+
+float4 main() : SV_Target0
+{
+    float float = 7;
+    bool bool[2] = { float, float };
+    int int   = bool[1];
+    uint uint = float + int;
+    min16float min16float = uint;
+    min10float min10float = min16float;
+    half half = 0.5;
+
+    {
+        foo_t float;
+        float.float = 42;
+    }
+
+    bool[0] = bool[1];
+
+    float = float + int + uint + min16float + min10float + (bool[0] ? int : float) + fn(float);
+
+    return float;
+}
index f0332aa..9f5bd62 100644 (file)
@@ -221,6 +221,8 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.swizzle.frag", "PixelShaderFunction"},
         {"hlsl.templatetypes.frag", "PixelShaderFunction"},
         {"hlsl.tx.bracket.frag", "main"},
+        {"hlsl.type.half.frag", "main"},
+        {"hlsl.type.identifier.frag", "main"},
         {"hlsl.typedef.frag", "PixelShaderFunction"},
         {"hlsl.whileLoop.frag", "PixelShaderFunction"},
         {"hlsl.void.frag", "PixelShaderFunction"},
index b874aa8..b5dfddd 100755 (executable)
@@ -85,21 +85,36 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
         return true;
     }
 
-    // Even though "sample" is a keyword (for interpolation modifiers), it IS still accepted as
-    // an identifier.  This appears to be a solitary exception: other interp modifier keywords such
-    // as "linear" or "centroid" NOT valid identifiers.  This code special cases "sample",
-    // so e.g, "int sample;" is accepted.
-    if (peekTokenClass(EHTokSample)) {
-        token.string     = NewPoolTString("sample");
-        token.tokenClass = EHTokIdentifier;
-        token.symbol     = nullptr;
-
-        idToken          = token;
-        advanceToken();
-        return true;
+    // Even though "sample", "bool", "float", etc keywords (for types, interpolation modifiers),
+    // they ARE still accepted as identifiers.  This is not a dense space: e.g, "void" is not a
+    // valid identifier, nor is "linear".  This code special cases the known instances of this, so
+    // e.g, "int sample;" or "float float;" is accepted.  Other cases can be added here if needed.
+    
+    TString* idString = nullptr;
+    switch (peek()) {
+    case EHTokSample:     idString = NewPoolTString("sample");     break;
+    case EHTokHalf:       idString = NewPoolTString("half");       break;
+    case EHTokBool:       idString = NewPoolTString("bool");       break;
+    case EHTokFloat:      idString = NewPoolTString("float");      break;
+    case EHTokDouble:     idString = NewPoolTString("double");     break;
+    case EHTokInt:        idString = NewPoolTString("int");        break;
+    case EHTokUint:       idString = NewPoolTString("uint");       break;
+    case EHTokMin16float: idString = NewPoolTString("min16float"); break;
+    case EHTokMin10float: idString = NewPoolTString("min10float"); break;
+    case EHTokMin16int:   idString = NewPoolTString("min16int");   break;
+    case EHTokMin12int:   idString = NewPoolTString("min12int");   break;
+    default:
+        return false;
     }
 
-    return false;
+    token.string     = idString;
+    token.tokenClass = EHTokIdentifier;
+    token.symbol     = nullptr;
+    idToken          = token;
+
+    advanceToken();
+
+    return true;
 }
 
 // compilationUnit
@@ -418,7 +433,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
 
     // SEMICOLON
     if (! acceptTokenClass(EHTokSemicolon)) {
-        expected(";");
+        // This may have been a false detection of what appeared to be a declaration, but
+        // was actually an assignment such as "float = 4", where "float" is an identifier.
+        // We put the token back to let further parsing happen for cases where that may
+        // happen.  This errors on the side of caution, and mostly triggers the error.
+
+        if (peek() == EHTokAssign || peek() == EHTokLeftBracket || peek() == EHTokDot || peek() == EHTokComma)
+            recedeToken();
+        else
+            expected(";");
         return false;
     }
     
@@ -1086,6 +1109,7 @@ bool HlslGrammar::acceptType(TType& type)
     // changes, e.g, to use native halfs.
     static const TBasicType min16float_bt = EbtFloat;
     static const TBasicType min10float_bt = EbtFloat;
+    static const TBasicType half_bt       = EbtFloat;
     static const TBasicType min16int_bt   = EbtInt;
     static const TBasicType min12int_bt   = EbtInt;
     static const TBasicType min16uint_bt  = EbtUint;
@@ -1255,6 +1279,23 @@ bool HlslGrammar::acceptType(TType& type)
         new(&type) TType(EbtBool, EvqTemporary, 4);
         break;
 
+    case EHTokHalf:
+        new(&type) TType(half_bt, EvqTemporary, EpqMedium);
+        break;
+    case EHTokHalf1:
+        new(&type) TType(half_bt, EvqTemporary, EpqMedium);
+        type.makeVector();
+        break;
+    case EHTokHalf2:
+        new(&type) TType(half_bt, EvqTemporary, EpqMedium, 2);
+        break;
+    case EHTokHalf3:
+        new(&type) TType(half_bt, EvqTemporary, EpqMedium, 3);
+        break;
+    case EHTokHalf4:
+        new(&type) TType(half_bt, EvqTemporary, EpqMedium, 4);
+        break;
+        
     case EHTokMin16float:
         new(&type) TType(min16float_bt, EvqTemporary, EpqMedium);
         break;
@@ -1683,6 +1724,7 @@ bool HlslGrammar::acceptStruct(TType& type)
 bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
 {
     typeList = new TTypeList();
+    HlslToken idToken;
 
     do {
         // success on seeing the RIGHT_BRACE coming up
@@ -1700,8 +1742,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
 
         // struct_declarator COMMA struct_declarator ...
         do {
-            // peek IDENTIFIER
-            if (! peekTokenClass(EHTokIdentifier)) {
+            if (! acceptIdentifier(idToken)) {
                 expected("member name");
                 return false;
             }
@@ -1709,12 +1750,9 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
             // add it to the list of members
             TTypeLoc member = { new TType(EbtVoid), token.loc };
             member.type->shallowCopy(memberType);
-            member.type->setFieldName(*token.string);
+            member.type->setFieldName(*idToken.string);
             typeList->push_back(member);
 
-            // accept IDENTIFIER
-            advanceToken();
-
             // array_specifier
             TArraySizes* arraySizes = nullptr;
             acceptArraySpecifier(arraySizes);
@@ -2322,7 +2360,9 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
         // arguments
         TIntermTyped* arguments = nullptr;
         if (! acceptArguments(constructorFunction, arguments)) {
-            expected("constructor arguments");
+            // It's possible this is a type keyword used as an identifier.  Put the token back
+            // for later use.
+            recedeToken();
             return false;
         }
 
index 3ae19fc..5fa1a1b 100755 (executable)
@@ -169,6 +169,10 @@ void HlslScanContext::fillInKeywordMap()
     (*KeywordMap)["uint3"] =                   EHTokUint3;
     (*KeywordMap)["uint4"] =                   EHTokUint4;
 
+    (*KeywordMap)["half1"] =                   EHTokHalf1;
+    (*KeywordMap)["half2"] =                   EHTokHalf2;
+    (*KeywordMap)["half3"] =                   EHTokHalf3;
+    (*KeywordMap)["half4"] =                   EHTokHalf4;
     (*KeywordMap)["min16float1"] =             EHTokMin16float1;
     (*KeywordMap)["min16float2"] =             EHTokMin16float2;
     (*KeywordMap)["min16float3"] =             EHTokMin16float3;
@@ -579,6 +583,10 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
     case EHTokUint2:
     case EHTokUint3:
     case EHTokUint4:
+    case EHTokHalf1:
+    case EHTokHalf2:
+    case EHTokHalf3:
+    case EHTokHalf4:
     case EHTokMin16float1:
     case EHTokMin16float2:
     case EHTokMin16float3:
index 6902070..43bf8b7 100755 (executable)
@@ -120,6 +120,10 @@ enum EHlslTokenClass {
     EHTokUint2,
     EHTokUint3,
     EHTokUint4,
+    EHTokHalf1,
+    EHTokHalf2,
+    EHTokHalf3,
+    EHTokHalf4,
     EHTokMin16float1,
     EHTokMin16float2,
     EHTokMin16float3,