Ver Fonte

PP: Don't report certain error about '#' when #if'd out

Don't report the following error when scanning inactive code (e.g. code inside #if 0):
"error: '#' : (#) can be preceded in its line only by spaces or horizontal tab"
Adds a variable to PpContext to say whether we're currently skipping over an inactive #if/#ifdef/#elif/#else, and don't report the error inside scanToken if true.

fixes 3704
U-NVIDIA.COM\rjennings há 11 meses atrás
pai
commit
9cd7ca26a2

+ 0 - 0
Test/baseResults/preprocess.inactive_stringify.vert.err


+ 29 - 0
Test/baseResults/preprocess.inactive_stringify.vert.out

@@ -0,0 +1,29 @@
+#version 460
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void main()
+{
+    gl_Position = vec4(1.0);
+}
+

+ 28 - 0
Test/preprocess.inactive_stringify.vert

@@ -0,0 +1,28 @@
+#version 460
+
+// This tests that the preprocessor error
+// "error: '#' : (#) can be preceded in its line only by spaces or horizontal tab"
+// isn't enforced when inactive (e.g. inside #if 0)
+
+#if 0
+#define STRINGIFY(X) #X
+#endif
+
+#define C 0
+
+#if 1
+#ifdef A
+#elif defined B
+#elif C
+// OK, since preprocessor evaluates to inactive
+#define STRINGIFY(X) #X
+#endif
+#endif
+
+// OK in comments
+// #define STRINGIFY(X) #X
+
+void main()
+{
+    gl_Position = vec4(1.0);
+}

+ 4 - 2
glslang/MachineIndependent/preprocessor/Pp.cpp

@@ -241,6 +241,7 @@ int TPpContext::CPPundef(TPpToken* ppToken)
 */
 int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
 {
+    inElseSkip = true;
     int depth = 0;
     int token = scanToken(ppToken);
 
@@ -297,7 +298,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
                     elseSeen[elsetracker] = false;
                     --elsetracker;
                 }
-
+                inElseSkip = false;
                 return CPPif(ppToken);
             }
         } else if (nextAtom == PpAtomElse) {
@@ -311,7 +312,8 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
                 parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
         }
     }
-
+    
+    inElseSkip = false;
     return token;
 }
 

+ 2 - 1
glslang/MachineIndependent/preprocessor/PpContext.cpp

@@ -88,7 +88,8 @@ TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, T
     preamble(nullptr), strings(nullptr), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
     rootFileName(rootFileName),
     currentSourceFile(rootFileName),
-    disableEscapeSequences(false)
+    disableEscapeSequences(false),
+    inElseSkip(false)
 {
     ifdepth = 0;
     for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)

+ 4 - 1
glslang/MachineIndependent/preprocessor/PpContext.h

@@ -371,7 +371,7 @@ protected:
                 break;
             popInput();
         }
-        if (!inputStack.empty() && inputStack.back()->isStringInput()) {
+        if (!inputStack.empty() && inputStack.back()->isStringInput() && !inElseSkip) {
             if (token == '\n') {
                 bool seenNumSign = false;
                 for (int i = 0; i < (int)lastLineTokens.size() - 1;) {
@@ -732,6 +732,9 @@ protected:
 
     std::istringstream strtodStream;
     bool disableEscapeSequences;
+    // True if we're skipping a section enclosed by #if/#ifdef/#elif/#else which was evaluated to
+    // be inactive, e.g. #if 0
+    bool inElseSkip;
 };
 
 } // end namespace glslang

+ 1 - 0
gtests/Pp.FromFile.cpp

@@ -69,6 +69,7 @@ INSTANTIATE_TEST_SUITE_P(
         "preprocessor.eof_missing.vert",
         "preprocess.arb_shading_language_include.vert",
         "preprocess.include_directive_missing_extension.vert",
+        "preprocess.inactive_stringify.vert"
     })),
     FileNameAsCustomTestSuffix
 );