From 71351de8792f933383d7ff1fabb67c9efa27d4f6 Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Wed, 8 Jun 2016 12:50:56 -0600
Subject: [PATCH] HLSL: Add all int/float/bool/uint matrix types, void for
 functions, and a few others.

---
 .../hlsl.intrinsics.negative.frag.out         |   8 +-
 .../hlsl.intrinsics.negative.vert.out         |   8 +-
 Test/baseResults/hlsl.void.frag.out           |  64 +++++++
 Test/hlsl.void.frag                           |   8 +
 gtests/Hlsl.FromFile.cpp                      |   1 +
 hlsl/hlslGrammar.cpp                          | 178 ++++++++++++++++--
 hlsl/hlslScanContext.cpp                      |  32 ++++
 hlsl/hlslTokens.h                             |  32 ++++
 8 files changed, 308 insertions(+), 23 deletions(-)
 create mode 100755 Test/baseResults/hlsl.void.frag.out
 create mode 100644 Test/hlsl.void.frag

diff --git a/Test/baseResults/hlsl.intrinsics.negative.frag.out b/Test/baseResults/hlsl.intrinsics.negative.frag.out
index 9ac398510..d1f9b429b 100644
--- a/Test/baseResults/hlsl.intrinsics.negative.frag.out
+++ b/Test/baseResults/hlsl.intrinsics.negative.frag.out
@@ -144,12 +144,12 @@ ERROR: node is still EOpNull!
 0:32      Branch: Return with expression
 0:32        Constant:
 0:32          0.000000
-0:44  Function Definition: PixelShaderFunction(vf1;vf1;vf1;i1; (temp 1-component vector of float)
+0:44  Function Definition: PixelShaderFunction(vf1;vf1;vf1;vi1; (temp 1-component vector of float)
 0:36    Function Parameters: 
 0:36      'inF0' (temp 1-component vector of float)
 0:36      'inF1' (temp 1-component vector of float)
 0:36      'inF2' (temp 1-component vector of float)
-0:36      'inI0' (temp int)
+0:36      'inI0' (temp 1-component vector of int)
 0:?     Sequence
 0:39      Constant:
 0:39        0.000000
@@ -448,12 +448,12 @@ ERROR: node is still EOpNull!
 0:32      Branch: Return with expression
 0:32        Constant:
 0:32          0.000000
-0:44  Function Definition: PixelShaderFunction(vf1;vf1;vf1;i1; (temp 1-component vector of float)
+0:44  Function Definition: PixelShaderFunction(vf1;vf1;vf1;vi1; (temp 1-component vector of float)
 0:36    Function Parameters: 
 0:36      'inF0' (temp 1-component vector of float)
 0:36      'inF1' (temp 1-component vector of float)
 0:36      'inF2' (temp 1-component vector of float)
-0:36      'inI0' (temp int)
+0:36      'inI0' (temp 1-component vector of int)
 0:?     Sequence
 0:39      Constant:
 0:39        0.000000
diff --git a/Test/baseResults/hlsl.intrinsics.negative.vert.out b/Test/baseResults/hlsl.intrinsics.negative.vert.out
index 6fc87bf36..de711e9b0 100644
--- a/Test/baseResults/hlsl.intrinsics.negative.vert.out
+++ b/Test/baseResults/hlsl.intrinsics.negative.vert.out
@@ -236,12 +236,12 @@ ERROR: node is still EOpNull!
 0:46      Branch: Return with expression
 0:46        Constant:
 0:46          0.000000
-0:58  Function Definition: VertexShaderFunction(vf1;vf1;vf1;i1; (temp 1-component vector of float)
+0:58  Function Definition: VertexShaderFunction(vf1;vf1;vf1;vi1; (temp 1-component vector of float)
 0:50    Function Parameters: 
 0:50      'inF0' (temp 1-component vector of float)
 0:50      'inF1' (temp 1-component vector of float)
 0:50      'inF2' (temp 1-component vector of float)
-0:50      'inI0' (temp int)
+0:50      'inI0' (temp 1-component vector of int)
 0:?     Sequence
 0:53      Constant:
 0:53        0.000000
@@ -681,12 +681,12 @@ ERROR: node is still EOpNull!
 0:46      Branch: Return with expression
 0:46        Constant:
 0:46          0.000000
-0:58  Function Definition: VertexShaderFunction(vf1;vf1;vf1;i1; (temp 1-component vector of float)
+0:58  Function Definition: VertexShaderFunction(vf1;vf1;vf1;vi1; (temp 1-component vector of float)
 0:50    Function Parameters: 
 0:50      'inF0' (temp 1-component vector of float)
 0:50      'inF1' (temp 1-component vector of float)
 0:50      'inF2' (temp 1-component vector of float)
-0:50      'inI0' (temp int)
+0:50      'inI0' (temp 1-component vector of int)
 0:?     Sequence
 0:53      Constant:
 0:53        0.000000
diff --git a/Test/baseResults/hlsl.void.frag.out b/Test/baseResults/hlsl.void.frag.out
new file mode 100755
index 000000000..a6e923174
--- /dev/null
+++ b/Test/baseResults/hlsl.void.frag.out
@@ -0,0 +1,64 @@
+hlsl.void.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:2  Function Definition: foo1( (temp void)
+0:1    Function Parameters: 
+0:4  Function Definition: foo2( (temp void)
+0:2    Function Parameters: 
+0:8  Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:5    Function Parameters: 
+0:5      'input' (temp 4-component vector of float)
+0:?     Sequence
+0:6      Function Call: foo1( (temp void)
+0:7      Function Call: foo2( (temp void)
+0:?   Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:2  Function Definition: foo1( (temp void)
+0:1    Function Parameters: 
+0:4  Function Definition: foo2( (temp void)
+0:2    Function Parameters: 
+0:8  Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:5    Function Parameters: 
+0:5      'input' (temp 4-component vector of float)
+0:?     Sequence
+0:6      Function Call: foo1( (temp void)
+0:7      Function Call: foo2( (temp void)
+0:?   Linker Objects
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 12
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "PixelShaderFunction"
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 450
+                              Name 4  "PixelShaderFunction"
+                              Name 6  "foo1("
+                              Name 8  "foo2("
+               2:             TypeVoid
+               3:             TypeFunction 2
+4(PixelShaderFunction):           2 Function None 3
+               5:             Label
+              10:           2 FunctionCall 6(foo1()
+              11:           2 FunctionCall 8(foo2()
+                              Return
+                              FunctionEnd
+        6(foo1():           2 Function None 3
+               7:             Label
+                              Return
+                              FunctionEnd
+        8(foo2():           2 Function None 3
+               9:             Label
+                              Return
+                              FunctionEnd
diff --git a/Test/hlsl.void.frag b/Test/hlsl.void.frag
new file mode 100644
index 000000000..9bf06b726
--- /dev/null
+++ b/Test/hlsl.void.frag
@@ -0,0 +1,8 @@
+void foo1() {}
+void foo2(void) {}
+
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+    foo1();
+    foo2();
+}
\ No newline at end of file
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index 3b61dc005..4a127c1fb 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -90,6 +90,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.precedence2.frag", "PixelShaderFunction"},
         {"hlsl.sin.frag", "PixelShaderFunction"},
         {"hlsl.whileLoop.frag", "PixelShaderFunction"},
+        {"hlsl.void.frag", "PixelShaderFunction"},
     }),
     FileNameAsCustomTestSuffix
 );
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index c1600e4da..b7cb84230 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -213,20 +213,17 @@ bool HlslGrammar::acceptType(TType& type)
         return false;
 
     switch (peek()) {
-    case EHTokInt:
-    case EHTokInt1:
-    case EHTokDword:
-        new(&type) TType(EbtInt);
+    case EHTokVoid:
+        new(&type) TType(EbtVoid);
         break;
+
     case EHTokFloat:
         new(&type) TType(EbtFloat);
         break;
-
     case EHTokFloat1:
         new(&type) TType(EbtFloat);
         type.makeVector();
         break;
-
     case EHTokFloat2:
         new(&type) TType(EbtFloat, EvqTemporary, 2);
         break;
@@ -237,6 +234,31 @@ bool HlslGrammar::acceptType(TType& type)
         new(&type) TType(EbtFloat, EvqTemporary, 4);
         break;
 
+    case EHTokDouble:
+        new(&type) TType(EbtDouble);
+        break;
+    case EHTokDouble1:
+        new(&type) TType(EbtDouble);
+        type.makeVector();
+        break;
+    case EHTokDouble2:
+        new(&type) TType(EbtDouble, EvqTemporary, 2);
+        break;
+    case EHTokDouble3:
+        new(&type) TType(EbtDouble, EvqTemporary, 3);
+        break;
+    case EHTokDouble4:
+        new(&type) TType(EbtDouble, EvqTemporary, 4);
+        break;
+
+    case EHTokInt:
+    case EHTokDword:
+        new(&type) TType(EbtInt);
+        break;
+    case EHTokInt1:
+        new(&type) TType(EbtInt);
+        type.makeVector();
+        break;
     case EHTokInt2:
         new(&type) TType(EbtInt, EvqTemporary, 2);
         break;
@@ -247,6 +269,30 @@ bool HlslGrammar::acceptType(TType& type)
         new(&type) TType(EbtInt, EvqTemporary, 4);
         break;
 
+    case EHTokUint:
+        new(&type) TType(EbtUint);
+        break;
+    case EHTokUint1:
+        new(&type) TType(EbtUint);
+        type.makeVector();
+        break;
+    case EHTokUint2:
+        new(&type) TType(EbtUint, EvqTemporary, 2);
+        break;
+    case EHTokUint3:
+        new(&type) TType(EbtUint, EvqTemporary, 3);
+        break;
+    case EHTokUint4:
+        new(&type) TType(EbtUint, EvqTemporary, 4);
+        break;
+
+    case EHTokBool:
+        new(&type) TType(EbtBool);
+        break;
+    case EHTokBool1:
+        new(&type) TType(EbtBool);
+        type.makeVector();
+        break;
     case EHTokBool2:
         new(&type) TType(EbtBool, EvqTemporary, 2);
         break;
@@ -306,6 +352,104 @@ bool HlslGrammar::acceptType(TType& type)
         new(&type) TType(EbtInt, EvqTemporary, 0, 4, 4);
         break;
 
+    case EHTokUint1x1:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 1, 1);
+        break;
+    case EHTokUint1x2:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 2, 1);
+        break;
+    case EHTokUint1x3:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 3, 1);
+        break;
+    case EHTokUint1x4:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 4, 1);
+        break;
+    case EHTokUint2x1:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 1, 2);
+        break;
+    case EHTokUint2x2:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 2, 2);
+        break;
+    case EHTokUint2x3:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 3, 2);
+        break;
+    case EHTokUint2x4:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 4, 2);
+        break;
+    case EHTokUint3x1:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 1, 3);
+        break;
+    case EHTokUint3x2:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 2, 3);
+        break;
+    case EHTokUint3x3:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 3, 3);
+        break;
+    case EHTokUint3x4:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 4, 3);
+        break;
+    case EHTokUint4x1:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 1, 4);
+        break;
+    case EHTokUint4x2:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 2, 4);
+        break;
+    case EHTokUint4x3:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 3, 4);
+        break;
+    case EHTokUint4x4:
+        new(&type) TType(EbtUint, EvqTemporary, 0, 4, 4);
+        break;
+
+    case EHTokBool1x1:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 1, 1);
+        break;
+    case EHTokBool1x2:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 2, 1);
+        break;
+    case EHTokBool1x3:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 3, 1);
+        break;
+    case EHTokBool1x4:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 4, 1);
+        break;
+    case EHTokBool2x1:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 1, 2);
+        break;
+    case EHTokBool2x2:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 2, 2);
+        break;
+    case EHTokBool2x3:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 3, 2);
+        break;
+    case EHTokBool2x4:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 4, 2);
+        break;
+    case EHTokBool3x1:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 1, 3);
+        break;
+    case EHTokBool3x2:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 2, 3);
+        break;
+    case EHTokBool3x3:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 3, 3);
+        break;
+    case EHTokBool3x4:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 4, 3);
+        break;
+    case EHTokBool4x1:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 1, 4);
+        break;
+    case EHTokBool4x2:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 2, 4);
+        break;
+    case EHTokBool4x3:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 3, 4);
+        break;
+    case EHTokBool4x4:
+        new(&type) TType(EbtBool, EvqTemporary, 0, 4, 4);
+        break;
+
     case EHTokFloat1x1:
         new(&type) TType(EbtFloat, EvqTemporary, 0, 1, 1);
         break;
@@ -415,6 +559,7 @@ bool HlslGrammar::acceptType(TType& type)
 
 // function_parameters
 //      : LEFT_PAREN parameter_declaration COMMA parameter_declaration ... RIGHT_PAREN
+//      | LEFT_PAREN VOID RIGHT_PAREN
 //
 bool HlslGrammar::acceptFunctionParameters(TFunction& function)
 {
@@ -422,15 +567,18 @@ bool HlslGrammar::acceptFunctionParameters(TFunction& function)
     if (! acceptTokenClass(EHTokLeftParen))
         return false;
 
-    do {
-        // parameter_declaration
-        if (! acceptParameterDeclaration(function))
-            break;
-
-        // COMMA
-        if (! acceptTokenClass(EHTokComma))
-            break;
-    } while (true);
+    // VOID RIGHT_PAREN
+    if (! acceptTokenClass(EHTokVoid)) {
+        do {
+            // parameter_declaration
+            if (! acceptParameterDeclaration(function))
+                break;
+
+            // COMMA
+            if (! acceptTokenClass(EHTokComma))
+                break;
+        } while (true);
+    }
 
     // RIGHT_PAREN
     if (! acceptTokenClass(EHTokRightParen)) {
diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp
index ab96bad6a..38e765ab7 100755
--- a/hlsl/hlslScanContext.cpp
+++ b/hlsl/hlslScanContext.cpp
@@ -168,6 +168,38 @@ void HlslScanContext::fillInKeywordMap()
     (*KeywordMap)["int4x2"] =                  EHTokInt4x2;
     (*KeywordMap)["int4x3"] =                  EHTokInt4x3;
     (*KeywordMap)["int4x4"] =                  EHTokInt4x4;
+    (*KeywordMap)["uint1x1"] =                 EHTokUint1x1;
+    (*KeywordMap)["uint1x2"] =                 EHTokUint1x2;
+    (*KeywordMap)["uint1x3"] =                 EHTokUint1x3;
+    (*KeywordMap)["uint1x4"] =                 EHTokUint1x4;
+    (*KeywordMap)["uint2x1"] =                 EHTokUint2x1;
+    (*KeywordMap)["uint2x2"] =                 EHTokUint2x2;
+    (*KeywordMap)["uint2x3"] =                 EHTokUint2x3;
+    (*KeywordMap)["uint2x4"] =                 EHTokUint2x4;
+    (*KeywordMap)["uint3x1"] =                 EHTokUint3x1;
+    (*KeywordMap)["uint3x2"] =                 EHTokUint3x2;
+    (*KeywordMap)["uint3x3"] =                 EHTokUint3x3;
+    (*KeywordMap)["uint3x4"] =                 EHTokUint3x4;
+    (*KeywordMap)["uint4x1"] =                 EHTokUint4x1;
+    (*KeywordMap)["uint4x2"] =                 EHTokUint4x2;
+    (*KeywordMap)["uint4x3"] =                 EHTokUint4x3;
+    (*KeywordMap)["uint4x4"] =                 EHTokUint4x4;
+    (*KeywordMap)["bool1x1"] =                 EHTokBool1x1;
+    (*KeywordMap)["bool1x2"] =                 EHTokBool1x2;
+    (*KeywordMap)["bool1x3"] =                 EHTokBool1x3;
+    (*KeywordMap)["bool1x4"] =                 EHTokBool1x4;
+    (*KeywordMap)["bool2x1"] =                 EHTokBool2x1;
+    (*KeywordMap)["bool2x2"] =                 EHTokBool2x2;
+    (*KeywordMap)["bool2x3"] =                 EHTokBool2x3;
+    (*KeywordMap)["bool2x4"] =                 EHTokBool2x4;
+    (*KeywordMap)["bool3x1"] =                 EHTokBool3x1;
+    (*KeywordMap)["bool3x2"] =                 EHTokBool3x2;
+    (*KeywordMap)["bool3x3"] =                 EHTokBool3x3;
+    (*KeywordMap)["bool3x4"] =                 EHTokBool3x4;
+    (*KeywordMap)["bool4x1"] =                 EHTokBool4x1;
+    (*KeywordMap)["bool4x2"] =                 EHTokBool4x2;
+    (*KeywordMap)["bool4x3"] =                 EHTokBool4x3;
+    (*KeywordMap)["bool4x4"] =                 EHTokBool4x4;
     (*KeywordMap)["float1x1"] =                EHTokFloat1x1;
     (*KeywordMap)["float1x2"] =                EHTokFloat1x2;
     (*KeywordMap)["float1x3"] =                EHTokFloat1x3;
diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h
index bc472fec0..9e6795b92 100755
--- a/hlsl/hlslTokens.h
+++ b/hlsl/hlslTokens.h
@@ -119,6 +119,38 @@ enum EHlslTokenClass {
     EHTokInt4x2,
     EHTokInt4x3,
     EHTokInt4x4,
+    EHTokUint1x1,
+    EHTokUint1x2,
+    EHTokUint1x3,
+    EHTokUint1x4,
+    EHTokUint2x1,
+    EHTokUint2x2,
+    EHTokUint2x3,
+    EHTokUint2x4,
+    EHTokUint3x1,
+    EHTokUint3x2,
+    EHTokUint3x3,
+    EHTokUint3x4,
+    EHTokUint4x1,
+    EHTokUint4x2,
+    EHTokUint4x3,
+    EHTokUint4x4,
+    EHTokBool1x1,
+    EHTokBool1x2,
+    EHTokBool1x3,
+    EHTokBool1x4,
+    EHTokBool2x1,
+    EHTokBool2x2,
+    EHTokBool2x3,
+    EHTokBool2x4,
+    EHTokBool3x1,
+    EHTokBool3x2,
+    EHTokBool3x3,
+    EHTokBool3x4,
+    EHTokBool4x1,
+    EHTokBool4x2,
+    EHTokBool4x3,
+    EHTokBool4x4,
     EHTokFloat1x1,
     EHTokFloat1x2,
     EHTokFloat1x3,
-- 
GitLab