PP/HLSL: Fix #1424: support comma in nested curly braces for macro arg
authorJohn Kessenich <cepheus@frii.com>
Mon, 2 Jul 2018 16:40:32 +0000 (10:40 -0600)
committerJohn Kessenich <cepheus@frii.com>
Mon, 2 Jul 2018 16:40:32 +0000 (10:40 -0600)
Test/baseResults/hlsl.pp.expand.frag.err [new file with mode: 0644]
Test/baseResults/hlsl.pp.expand.frag.out [new file with mode: 0644]
Test/hlsl.pp.expand.frag [new file with mode: 0755]
Test/runtests
glslang/MachineIndependent/preprocessor/Pp.cpp [changed mode: 0644->0755]

diff --git a/Test/baseResults/hlsl.pp.expand.frag.err b/Test/baseResults/hlsl.pp.expand.frag.err
new file mode 100644 (file)
index 0000000..1b5681f
--- /dev/null
@@ -0,0 +1,3 @@
+ERROR: HLSL currently only supported when requesting SPIR-V for Vulkan.
+ERROR: HLSL currently only supported when requesting SPIR-V for Vulkan.
+
diff --git a/Test/baseResults/hlsl.pp.expand.frag.out b/Test/baseResults/hlsl.pp.expand.frag.out
new file mode 100644 (file)
index 0000000..7197891
--- /dev/null
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+struct A
+{
+    float4 a;
+    float4 b;
+    float4 c = { 1, 2, 3, 4 };
+    float4 d = {({ {(({ 1, 2, 3, 4 }))} })}, { { 1, 2, 3, 4 } };
+};
+
+void main()
+{
+}
+
diff --git a/Test/hlsl.pp.expand.frag b/Test/hlsl.pp.expand.frag
new file mode 100755 (executable)
index 0000000..765d17e
--- /dev/null
@@ -0,0 +1,17 @@
+#define EMP1(a)\r
+#define EMP2(a, b)\r
+\r
+#define EXP1(a) = a\r
+#define EXP2(a, b) = a, b\r
+\r
+struct A\r
+{\r
+    float4 a EMP1({1,2,3,4});                           // No PP arg errors\r
+    float4 b EMP2({({{(({1,2,3,4}))}})}, {{1,2,3,4}});  // No PP arg errors\r
+    float4 c EXP1({1,2,3,4});                           // ERROR: No PP arg errors, but init error\r
+    float4 d EXP2({({{(({1,2,3,4}))}})}, {{1,2,3,4}});  // ERROR: No PP arg errors, but init error\r
+};\r
+\r
+void main()\r
+{\r
+}\r
index a084cb5..390acfc 100755 (executable)
@@ -216,6 +216,13 @@ $EXE -H -e main -D -Od -fhlsl_functionality1 hlsl.noSemantic.functionality1.comp
 diff -b $BASEDIR/hlsl.noSemantic.functionality1.comp.out $TARGETDIR/hlsl.noSemantic.functionality1.comp.out || HASERROR=1
 
 #
+# Testing HLSL-specific PP feature expansion
+#
+$EXE -D -E hlsl.pp.expand.frag > $TARGETDIR/hlsl.pp.expand.frag.out 2> $TARGETDIR/hlsl.pp.expand.frag.err
+diff -b $BASEDIR/hlsl.pp.expand.frag.out $TARGETDIR/hlsl.pp.expand.frag.out || HASERROR=1
+diff -b $BASEDIR/hlsl.pp.expand.frag.err $TARGETDIR/hlsl.pp.expand.frag.err || HASERROR=1
+
+#
 # Final checking
 #
 if [ $HASERROR -eq 0 ]
old mode 100644 (file)
new mode 100755 (executable)
index 8048fa5..0a151ed
@@ -1153,7 +1153,6 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
     }
 
     MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);
-    int depth = 0;
 
     // no recursive expansions
     if (macro != nullptr && macro->busy)
@@ -1193,8 +1192,8 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
         size_t arg = 0;
         bool tokenRecorded = false;
         do {
-            depth = 0;
-            while (1) {
+            TVector<char> nestStack;
+            while (true) {
                 token = scanToken(ppToken);
                 if (token == EndOfInput || token == tMarkerInput::marker) {
                     parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
@@ -1216,16 +1215,21 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
                 }
                 if (in->mac->args.size() == 0 && token != ')')
                     break;
-                if (depth == 0 && (token == ',' || token == ')'))
+                if (nestStack.size() == 0 && (token == ',' || token == ')'))
                     break;
                 if (token == '(')
-                    depth++;
-                if (token == ')')
-                    depth--;
+                    nestStack.push_back(')');
+                else if (token == '{' && parseContext.isReadingHLSL())
+                    nestStack.push_back('}');
+                else if (nestStack.size() > 0 && token == nestStack.back())
+                    nestStack.pop_back();
                 in->args[arg]->putToken(token, ppToken);
                 tokenRecorded = true;
             }
+            // end of single argument scan
+
             if (token == ')') {
+                // closing paren of call
                 if (in->mac->args.size() == 1 && tokenRecorded == 0)
                     break;
                 arg++;
@@ -1233,16 +1237,18 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
             }
             arg++;
         } while (arg < in->mac->args.size());
+        // end of all arguments scan
 
         if (arg < in->mac->args.size())
             parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
         else if (token != ')') {
-            depth=0;
+            // Error recover code; find end of call, if possible
+            int depth = 0;
             while (token != EndOfInput && (depth > 0 || token != ')')) {
-                if (token == ')')
+                if (token == ')' || token == '}')
                     depth--;
                 token = scanToken(ppToken);
-                if (token == '(')
+                if (token == '(' || token == '{')
                     depth++;
             }