Merge pull request #476 from steve-lunarg/string-literals

HLSL: Support string literals, e.g, for annotations
diff --git a/Test/baseResults/hlsl.stringtoken.frag.out b/Test/baseResults/hlsl.stringtoken.frag.out
new file mode 100644
index 0000000..cb2a491
--- /dev/null
+++ b/Test/baseResults/hlsl.stringtoken.frag.out
@@ -0,0 +1,90 @@
+hlsl.stringtoken.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:21  Function Definition: main( (global structure{temp 4-component vector of float Color})
+0:16    Function Parameters: 
+0:?     Sequence
+0:18      move second child to first child (temp 4-component vector of float)
+0:18        Color: direct index for structure (temp 4-component vector of float)
+0:18          'psout' (temp structure{temp 4-component vector of float Color})
+0:18          Constant:
+0:18            0 (const int)
+0:?         Constant:
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           1.000000
+0:19      Branch: Return with expression
+0:19        'psout' (temp structure{temp 4-component vector of float Color})
+0:?   Linker Objects
+0:?     'TestTexture' (uniform texture2D)
+0:?     'TestUF' (uniform 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:21  Function Definition: main( (global structure{temp 4-component vector of float Color})
+0:16    Function Parameters: 
+0:?     Sequence
+0:18      move second child to first child (temp 4-component vector of float)
+0:18        Color: direct index for structure (temp 4-component vector of float)
+0:18          'psout' (temp structure{temp 4-component vector of float Color})
+0:18          Constant:
+0:18            0 (const int)
+0:?         Constant:
+0:?           0.000000
+0:?           0.000000
+0:?           0.000000
+0:?           1.000000
+0:19      Branch: Return with expression
+0:19        'psout' (temp structure{temp 4-component vector of float Color})
+0:?   Linker Objects
+0:?     'TestTexture' (uniform texture2D)
+0:?     'TestUF' (uniform 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 25
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main"
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 8  "PS_OUTPUT"
+                              MemberName 8(PS_OUTPUT) 0  "Color"
+                              Name 10  "psout"
+                              Name 22  "TestTexture"
+                              Name 24  "TestUF"
+                              Decorate 22(TestTexture) DescriptorSet 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+    8(PS_OUTPUT):             TypeStruct 7(fvec4)
+               9:             TypePointer Function 8(PS_OUTPUT)
+              11:             TypeInt 32 1
+              12:     11(int) Constant 0
+              13:    6(float) Constant 0
+              14:    6(float) Constant 1065353216
+              15:    7(fvec4) ConstantComposite 13 13 13 14
+              16:             TypePointer Function 7(fvec4)
+              20:             TypeImage 6(float) 2D sampled format:Unknown
+              21:             TypePointer UniformConstant 20
+ 22(TestTexture):     21(ptr) Variable UniformConstant
+              23:             TypePointer UniformConstant 7(fvec4)
+      24(TestUF):     23(ptr) Variable UniformConstant
+         4(main):           2 Function None 3
+               5:             Label
+       10(psout):      9(ptr) Variable Function
+              17:     16(ptr) AccessChain 10(psout) 12
+                              Store 17 15
+              18:8(PS_OUTPUT) Load 10(psout)
+                              ReturnValue 18
+                              FunctionEnd
diff --git a/Test/hlsl.stringtoken.frag b/Test/hlsl.stringtoken.frag
new file mode 100644
index 0000000..fe785e6
--- /dev/null
+++ b/Test/hlsl.stringtoken.frag
@@ -0,0 +1,20 @@
+
+struct PS_OUTPUT
+{
+    float4 Color : SV_Target0;
+};
+
+Texture2D TestTexture <
+    string TestAttribute1 = "TestAttribute";
+    string TestAttribute2 = "false";
+    int    TestAttribute3 = 3;
+>;
+
+uniform float4 TestUF <string StrValue = "foo";>;
+
+PS_OUTPUT main()
+{
+   PS_OUTPUT psout;
+   psout.Color = float4(0,0,0,1);
+   return psout;
+}
diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
index fc1c301..dad4c42 100644
--- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
@@ -747,7 +747,12 @@
             tokenString = ppToken->name;
             break;
         case PpAtomConstString:
-            parseContext.ppError(ppToken->loc, "string literals not supported", "\"\"", "");
+            if (parseContext.intermediate.getSource() == EShSourceHlsl) {
+                // HLSL allows string literals.
+                tokenString = ppToken->name;
+            } else {
+                parseContext.ppError(ppToken->loc, "string literals not supported", "\"\"", "");
+            }
             break;
         case '\'':
             parseContext.ppError(ppToken->loc, "character literals not supported", "\'", "");
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index 3ea6fc1..a98dd87 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -151,6 +151,7 @@
         {"hlsl.samplelevel.offsetarray.dx10.frag", "main"},
         {"hlsl.semicolons.frag", "main"},
         {"hlsl.shapeConv.frag", "main"},
+        {"hlsl.stringtoken.frag", "main"},
         {"hlsl.intrinsics.vert", "VertexShaderFunction"},
         {"hlsl.matType.frag", "PixelShaderFunction"},
         {"hlsl.max.frag", "PixelShaderFunction"},
diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp
index a3be6fa..009210f 100755
--- a/hlsl/hlslScanContext.cpp
+++ b/hlsl/hlslScanContext.cpp
@@ -411,6 +411,11 @@
             return token;
         }
 
+        case PpAtomConstString: {
+            parserToken->string = NewPoolTString(ppToken.name);
+            return EHTokStringConstant;
+        }
+
         case EndOfInput:               return EHTokNone;
 
         default:
diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h
index b54a757..db3b097 100755
--- a/hlsl/hlslTokens.h
+++ b/hlsl/hlslTokens.h
@@ -223,6 +223,7 @@
     EHTokIntConstant,
     EHTokUintConstant,
     EHTokBoolConstant,
+    EHTokStringConstant,
 
     // control flow
     EHTokFor,