HLSL: Fix #758: Support character literals (except for numeric escape sequences).
authorJohn Kessenich <cepheus@frii.com>
Wed, 12 Apr 2017 22:31:15 +0000 (16:31 -0600)
committerJohn Kessenich <cepheus@frii.com>
Wed, 12 Apr 2017 22:58:30 +0000 (16:58 -0600)
Test/baseResults/hlsl.charLit.vert.out [new file with mode: 0755]
Test/hlsl.charLit.vert [new file with mode: 0755]
glslang/Include/revision.h
glslang/MachineIndependent/preprocessor/PpContext.h
glslang/MachineIndependent/preprocessor/PpScanner.cpp
gtests/Hlsl.FromFile.cpp

diff --git a/Test/baseResults/hlsl.charLit.vert.out b/Test/baseResults/hlsl.charLit.vert.out
new file mode 100755 (executable)
index 0000000..cc8388a
--- /dev/null
@@ -0,0 +1,233 @@
+hlsl.charLit.vert
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp 4-component vector of float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:3      Sequence
+0:3        move second child to first child ( temp uint)
+0:3          'a1' ( temp uint)
+0:3          Constant:
+0:3            65 (const uint)
+0:4      Sequence
+0:4        move second child to first child ( temp int)
+0:4          'a2' ( temp int)
+0:4          Constant:
+0:4            48 (const int)
+0:6      Sequence
+0:6        move second child to first child ( temp int)
+0:6          'a3' ( temp int)
+0:6          Constant:
+0:6            7 (const int)
+0:7      add second child into first child ( temp int)
+0:7        'a3' ( temp int)
+0:7        Constant:
+0:7          8 (const int)
+0:8      add second child into first child ( temp int)
+0:8        'a3' ( temp int)
+0:8        Constant:
+0:8          9 (const int)
+0:9      add second child into first child ( temp int)
+0:9        'a3' ( temp int)
+0:9        Constant:
+0:9          10 (const int)
+0:10      add second child into first child ( temp int)
+0:10        'a3' ( temp int)
+0:10        Constant:
+0:10          11 (const int)
+0:11      add second child into first child ( temp int)
+0:11        'a3' ( temp int)
+0:11        Constant:
+0:11          12 (const int)
+0:12      add second child into first child ( temp int)
+0:12        'a3' ( temp int)
+0:12        Constant:
+0:12          13 (const int)
+0:14      Sequence
+0:14        move second child to first child ( temp int)
+0:14          'a10' ( temp int)
+0:14          Constant:
+0:14            99 (const int)
+0:16      Branch: Return with expression
+0:16        Construct vec4 ( temp 4-component vector of float)
+0:16          Convert uint to float ( temp float)
+0:16            add ( temp uint)
+0:16              add ( temp uint)
+0:16                add ( temp uint)
+0:16                  'a1' ( temp uint)
+0:16                  Convert int to uint ( temp uint)
+0:16                    'a2' ( temp int)
+0:16                Convert int to uint ( temp uint)
+0:16                  'a3' ( temp int)
+0:16              Convert int to uint ( temp uint)
+0:16                'a10' ( temp int)
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' ( out 4-component vector of float Position)
+0:2        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out 4-component vector of float Position)
+
+
+Linked vertex stage:
+
+
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp 4-component vector of float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:3      Sequence
+0:3        move second child to first child ( temp uint)
+0:3          'a1' ( temp uint)
+0:3          Constant:
+0:3            65 (const uint)
+0:4      Sequence
+0:4        move second child to first child ( temp int)
+0:4          'a2' ( temp int)
+0:4          Constant:
+0:4            48 (const int)
+0:6      Sequence
+0:6        move second child to first child ( temp int)
+0:6          'a3' ( temp int)
+0:6          Constant:
+0:6            7 (const int)
+0:7      add second child into first child ( temp int)
+0:7        'a3' ( temp int)
+0:7        Constant:
+0:7          8 (const int)
+0:8      add second child into first child ( temp int)
+0:8        'a3' ( temp int)
+0:8        Constant:
+0:8          9 (const int)
+0:9      add second child into first child ( temp int)
+0:9        'a3' ( temp int)
+0:9        Constant:
+0:9          10 (const int)
+0:10      add second child into first child ( temp int)
+0:10        'a3' ( temp int)
+0:10        Constant:
+0:10          11 (const int)
+0:11      add second child into first child ( temp int)
+0:11        'a3' ( temp int)
+0:11        Constant:
+0:11          12 (const int)
+0:12      add second child into first child ( temp int)
+0:12        'a3' ( temp int)
+0:12        Constant:
+0:12          13 (const int)
+0:14      Sequence
+0:14        move second child to first child ( temp int)
+0:14          'a10' ( temp int)
+0:14          Constant:
+0:14            99 (const int)
+0:16      Branch: Return with expression
+0:16        Construct vec4 ( temp 4-component vector of float)
+0:16          Convert uint to float ( temp float)
+0:16            add ( temp uint)
+0:16              add ( temp uint)
+0:16                add ( temp uint)
+0:16                  'a1' ( temp uint)
+0:16                  Convert int to uint ( temp uint)
+0:16                    'a2' ( temp int)
+0:16                Convert int to uint ( temp uint)
+0:16                  'a3' ( temp int)
+0:16              Convert int to uint ( temp uint)
+0:16                'a10' ( temp int)
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' ( out 4-component vector of float Position)
+0:2        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out 4-component vector of float Position)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 58
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 56
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 9  "@main("
+                              Name 13  "a1"
+                              Name 17  "a2"
+                              Name 19  "a3"
+                              Name 39  "a10"
+                              Name 56  "@entryPointOutput"
+                              Decorate 56(@entryPointOutput) BuiltIn Position
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeFunction 7(fvec4)
+              11:             TypeInt 32 0
+              12:             TypePointer Function 11(int)
+              14:     11(int) Constant 65
+              15:             TypeInt 32 1
+              16:             TypePointer Function 15(int)
+              18:     15(int) Constant 48
+              20:     15(int) Constant 7
+              21:     15(int) Constant 8
+              24:     15(int) Constant 9
+              27:     15(int) Constant 10
+              30:     15(int) Constant 11
+              33:     15(int) Constant 12
+              36:     15(int) Constant 13
+              40:     15(int) Constant 99
+              55:             TypePointer Output 7(fvec4)
+56(@entryPointOutput):     55(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              57:    7(fvec4) FunctionCall 9(@main()
+                              Store 56(@entryPointOutput) 57
+                              Return
+                              FunctionEnd
+       9(@main():    7(fvec4) Function None 8
+              10:             Label
+          13(a1):     12(ptr) Variable Function
+          17(a2):     16(ptr) Variable Function
+          19(a3):     16(ptr) Variable Function
+         39(a10):     16(ptr) Variable Function
+                              Store 13(a1) 14
+                              Store 17(a2) 18
+                              Store 19(a3) 20
+              22:     15(int) Load 19(a3)
+              23:     15(int) IAdd 22 21
+                              Store 19(a3) 23
+              25:     15(int) Load 19(a3)
+              26:     15(int) IAdd 25 24
+                              Store 19(a3) 26
+              28:     15(int) Load 19(a3)
+              29:     15(int) IAdd 28 27
+                              Store 19(a3) 29
+              31:     15(int) Load 19(a3)
+              32:     15(int) IAdd 31 30
+                              Store 19(a3) 32
+              34:     15(int) Load 19(a3)
+              35:     15(int) IAdd 34 33
+                              Store 19(a3) 35
+              37:     15(int) Load 19(a3)
+              38:     15(int) IAdd 37 36
+                              Store 19(a3) 38
+                              Store 39(a10) 40
+              41:     11(int) Load 13(a1)
+              42:     15(int) Load 17(a2)
+              43:     11(int) Bitcast 42
+              44:     11(int) IAdd 41 43
+              45:     15(int) Load 19(a3)
+              46:     11(int) Bitcast 45
+              47:     11(int) IAdd 44 46
+              48:     15(int) Load 39(a10)
+              49:     11(int) Bitcast 48
+              50:     11(int) IAdd 47 49
+              51:    6(float) ConvertUToF 50
+              52:    7(fvec4) CompositeConstruct 51 51 51 51
+                              ReturnValue 52
+                              FunctionEnd
diff --git a/Test/hlsl.charLit.vert b/Test/hlsl.charLit.vert
new file mode 100755 (executable)
index 0000000..36c4a1e
--- /dev/null
@@ -0,0 +1,17 @@
+float4 main() : SV_Position\r
+{\r
+    uint a1 =  'A';\r
+    int  a2 =  '0';\r
+\r
+    int  a3 = '\a';\r
+    a3     += '\b';\r
+    a3     += '\t';\r
+    a3     += '\n';\r
+    a3     += '\v';\r
+    a3     += '\f';\r
+    a3     += '\r';\r
+\r
+    int a10 = '\c';\r
+\r
+    return a1 + a2 + a3 + a10;\r
+}\r
index 5c9566b..a7b6230 100644 (file)
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "Overload400-PrecQual.1996"
+#define GLSLANG_REVISION "Overload400-PrecQual.1998"
 #define GLSLANG_DATE "12-Apr-2017"
index c14f22e..a459d9a 100644 (file)
@@ -588,6 +588,7 @@ protected:
     int ScanFromString(char* s);
     void missingEndifCheck();
     int lFloatConst(int len, int ch, TPpToken* ppToken);
+    int characterLiteral(TPpToken* ppToken);
 
     void push_include(TShader::Includer::IncludeResult* result)
     {
index f711ad6..e72efc0 100644 (file)
@@ -245,6 +245,82 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
         return PpAtomConstFloat;
 }
 
+// Recognize a character literal.
+//
+// The first ' has already been accepted, read the rest, through the closing '.
+//
+// Always returns PpAtomConstInt.
+//
+int TPpContext::characterLiteral(TPpToken* ppToken)
+{
+    ppToken->name[0] = 0;
+    ppToken->ival = 0;
+
+    if (parseContext.intermediate.getSource() != EShSourceHlsl) {
+        // illegal, except in macro definition, for which case we report the character
+        return '\'';
+    }
+
+    int ch = getChar();
+    switch (ch) {
+    case '\'':
+        // As empty sequence:  ''
+        parseContext.ppError(ppToken->loc, "unexpected", "\'", "");
+        return PpAtomConstInt;
+    case '\\':
+        // As escape sequence:  '\XXX'
+        switch (ch = getChar()) {
+        case 'a':
+            ppToken->ival = 7;
+            break;
+        case 'b':
+            ppToken->ival = 8;
+            break;
+        case 't':
+            ppToken->ival = 9;
+            break;
+        case 'n':
+            ppToken->ival = 10;
+            break;
+        case 'v':
+            ppToken->ival = 11;
+            break;
+        case 'f':
+            ppToken->ival = 12;
+            break;
+        case 'r':
+            ppToken->ival = 13;
+            break;
+        case 'x':
+        case '0':
+            parseContext.ppError(ppToken->loc, "octal and hex sequences not supported", "\\", "");
+            break;
+        default:
+            // This catches '\'', '\"', '\?', etc.
+            // Also, things like '\C' mean the same thing as 'C'
+            // (after the above cases are filtered out).
+            ppToken->ival = ch;
+            break;
+        }
+        break;
+    default:
+        ppToken->ival = ch;
+        break;
+    }
+    ppToken->name[0] = (char)ppToken->ival;
+    ppToken->name[1] = '\0';
+    ch = getChar();
+    if (ch != '\'') {
+        parseContext.ppError(ppToken->loc, "expected", "\'", "");
+        // Look ahead for a closing '
+        do {
+            ch = getChar();
+        } while (ch != '\'' && ch != EndOfInput && ch != '\n');
+    }
+
+    return PpAtomConstInt;
+}
+
 //
 // Scanner used to tokenize source stream.
 //
@@ -701,6 +777,8 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
                 return '/';
             }
             break;
+        case '\'':
+            return pp->characterLiteral(ppToken);
         case '"':
             // TODO: If this gets enhanced to handle escape sequences, or
             // anything that is different than what #include needs, then
index 22368c1..59c09f8 100644 (file)
@@ -93,6 +93,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.calculatelod.dx10.frag", "main"},
         {"hlsl.calculatelodunclamped.dx10.frag", "main"},
         {"hlsl.cast.frag", "PixelShaderFunction"},
+        {"hlsl.charLit.vert", "main"},
         {"hlsl.clip.frag", "main"},
         {"hlsl.comparison.vec.frag", "main"},
         {"hlsl.conditional.frag", "PixelShaderFunction"},