Fixes to scanning:
authorJohn Kessenich <cepheus@frii.com>
Tue, 12 Nov 2013 03:31:24 +0000 (03:31 +0000)
committerJohn Kessenich <cepheus@frii.com>
Tue, 12 Nov 2013 03:31:24 +0000 (03:31 +0000)
 - do version checking for the line-continuation character
 - check for built-in names in #undef
 - bug fix for #elif after #else
 - do version checking for use of floating point suffixes (f, LF, etc.)

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24011 e7fa87d3-cd2b-0410-9028-fcbf551c1848

21 files changed:
Install/Windows/glslangValidator.exe
Test/100.frag
Test/120.frag
Test/300.vert
Test/baseResults/100.frag.out
Test/baseResults/cppNest.vert.out
Test/baseResults/cppSimple.vert.out
Test/baseResults/lineContinuation100.vert.out [new file with mode: 0644]
Test/baseResults/versionsErrors.frag.out
Test/cppNest.vert
Test/cppSimple.vert
Test/lineContinuation100.vert [new file with mode: 0644]
Test/precision.frag
Test/sample.frag
Test/testlist
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/preprocessor/Pp.cpp
glslang/MachineIndependent/preprocessor/PpContext.cpp
glslang/MachineIndependent/preprocessor/PpContext.h
glslang/MachineIndependent/preprocessor/PpScanner.cpp

index b647163..ebdec87 100644 (file)
Binary files a/Install/Windows/glslangValidator.exe and b/Install/Windows/glslangValidator.exe differ
index cb78f8b..9daa026 100644 (file)
@@ -146,4 +146,7 @@ int foo203940(int a, float b, float a)  // ERROR, a redefined
     return a;\r
 }\r
 \r
+float f123 = 4.0f;   // ERROR\r
+float f124 = 5e10F;  // ERROR\r
+\r
 uniform samplerExternalOES badExt;  // syntax ERROR\r
index e6ed62a..ac70c20 100644 (file)
@@ -36,7 +36,7 @@ void main()
     f += a;
     f = a - f;
     v3 *= iv3;
-    v3 = iv3 / 2.0;
+    v3 = iv3 / 2.0f;
     v3 = 3.0 * iv3;
     v3 = 2 * v3;
     v3 = v3 - 2;
@@ -102,7 +102,7 @@ int foo(out float a)    // ERROR
 
 bool gen(vec3 v)
 {
-    if (abs(v[0]) < 1e-4 && abs(v[1]) < 1e-4)
+    if (abs(v[0]) < 1e-4F && abs(v[1]) < 1e-4)
         return true;
 }
 
index 1d9d631..cdbfa8e 100644 (file)
@@ -65,7 +65,7 @@ uniform ub {
     int a[];        // ERROR
 } ubInst[];         // ERROR
 void foo(int a[]);  // ERROR
-float okayA[] = float[](3.0, 4.0);  // Okay
+float okayA[] = float[](3.0f, 4.0F);  // Okay
 
 out vec3 newV;
 void newVFun()
index 2507e06..1c08f35 100644 (file)
@@ -57,8 +57,10 @@ ERROR: 0:137: 'bitwise not' : not supported for this version or the enabled exte
 ERROR: 0:138: 'bitwise inclusive or' : not supported for this version or the enabled extensions \r
 ERROR: 0:139: 'bitwise and' : not supported for this version or the enabled extensions \r
 ERROR: 0:144: 'a' : redefinition \r
-ERROR: 0:149: '' :  syntax error\r
-ERROR: 53 compilation errors.  No code generated.\r
+ERROR: 0:149: 'floating-point suffix' : not supported for this version or the enabled extensions \r
+ERROR: 0:150: 'floating-point suffix' : not supported for this version or the enabled extensions \r
+ERROR: 0:152: '' :  syntax error\r
+ERROR: 55 compilation errors.  No code generated.\r
 \r
 ERROR: node is still EOpNull!\r
 0:3  Sequence\r
@@ -245,6 +247,16 @@ ERROR: node is still EOpNull!
 0:146    Sequence\r
 0:146      Branch: Return with expression\r
 0:146        'a' (in mediump int)\r
+0:149  Sequence\r
+0:149    move second child to first child (mediump float)\r
+0:149      'f123' (mediump float)\r
+0:149      Constant:\r
+0:149        4.000000\r
+0:150  Sequence\r
+0:150    move second child to first child (mediump float)\r
+0:150      'f124' (mediump float)\r
+0:150      Constant:\r
+0:150        50000000000.000000\r
 0:?   Linker Objects\r
 0:?     'a' (3-element array of mediump int)\r
 0:?     'uint' (mediump int)\r
@@ -264,4 +276,6 @@ ERROR: node is still EOpNull!
 0:?     'sExt' (uniform lowp samplerExternalOES)\r
 0:?     'mediumExt' (uniform mediump samplerExternalOES)\r
 0:?     'highExt' (uniform highp samplerExternalOES)\r
+0:?     'f123' (mediump float)\r
+0:?     'f124' (mediump float)\r
 \r
index 918f832..95f28f4 100644 (file)
 0:86        'gl_Position' (gl_Position 4-component vector of float)\r
 0:86        Construct vec4 (4-component vector of float)\r
 0:86          'sum' (float)\r
+0:103  Sequence\r
+0:103    move second child to first child (int)\r
+0:103      'selected4' (int)\r
+0:103      Constant:\r
+0:103        4 (const int)\r
+0:115  Sequence\r
+0:115    move second child to first child (int)\r
+0:115      'selected2' (int)\r
+0:115      Constant:\r
+0:115        2 (const int)\r
+0:133  Sequence\r
+0:133    move second child to first child (int)\r
+0:133      'selected3' (int)\r
+0:133      Constant:\r
+0:133        3 (const int)\r
 0:?   Linker Objects\r
 0:?     'sum' (float)\r
+0:?     'selected4' (int)\r
+0:?     'selected2' (int)\r
+0:?     'selected3' (int)\r
 \r
index a0c313c..a5d18f2 100644 (file)
@@ -24,11 +24,11 @@ ERROR: 0:136: 'length' : no matching overloaded function found
 ERROR: 0:136: '=' :  cannot convert from 'const float' to 'int'\r
 ERROR: 0:138: ''' : character literals not supported \r
 ERROR: 0:138: ''' : character literals not supported \r
-ERROR: 0:141: '#define' : reserved built-in name prefix: GL_\r
-ERROR: 0:142: '#define' : reserved built-in name prefix: GL_\r
-ERROR: 0:143: '#define' : names containing consecutive underscores are reserved \r
-ERROR: 0:144: '#define' : names containing consecutive underscores are reserved \r
-ERROR: 0:145: '#define' : names containing consecutive underscores are reserved \r
+ERROR: 0:141: '#define' : can't use with built-in names ("GL_" prefix) \r
+ERROR: 0:142: '#define' : can't use with built-in names ("GL_" prefix) \r
+ERROR: 0:143: '#define' : can't use with built-in names (containing consecutive underscores) \r
+ERROR: 0:144: '#define' : can't use with built-in names (containing consecutive underscores) \r
+ERROR: 0:145: '#define' : can't use with built-in names (containing consecutive underscores) \r
 ERROR: 0:148: '#else' : unexpected tokens following directive \r
 ERROR: 0:149: '#else' : #elif after #else \r
 ERROR: 0:155: '#else' : unexpected tokens following directive \r
@@ -41,8 +41,10 @@ ERROR: 0:182: '#define' : Macro redefined; different number of arguments: m6
 ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7\r
 ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8\r
 ERROR: 0:196: '#define' : Macro redefined; different argument names: m9\r
-ERROR: 0:206: '' : missing #endif \r
-ERROR: 43 compilation errors.  No code generated.\r
+ERROR: 0:204: '#undef' : can't use with built-in names (containing consecutive underscores) \r
+ERROR: 0:205: '#undef' : can't use with built-in names ("GL_" prefix) \r
+ERROR: 0:209: '' : missing #endif \r
+ERROR: 45 compilation errors.  No code generated.\r
 \r
 ERROR: node is still EOpNull!\r
 0:5  Sequence\r
diff --git a/Test/baseResults/lineContinuation100.vert.out b/Test/baseResults/lineContinuation100.vert.out
new file mode 100644 (file)
index 0000000..640dbee
--- /dev/null
@@ -0,0 +1,21 @@
+ERROR: 0:3: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:6: '#error' : e1  \r
+ERROR: 0:8: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:11: '#error' : e2  \r
+ERROR: 0:13: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:14: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:15: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:18: '#error' : e3  \r
+ERROR: 8 compilation errors.  No code generated.\r
+\r
+ERROR: node is still EOpNull!\r
+0:20  Function Definition: main( (void)\r
+0:20    Function Parameters: \r
+0:20    Sequence\r
+0:20      move second child to first child (highp 4-component vector of float)\r
+0:20        'gl_Position' (gl_Position highp 4-component vector of float)\r
+0:20        Construct vec4 (highp 4-component vector of float)\r
+0:20          'foo' (highp float)\r
+0:?   Linker Objects\r
+0:?     'foo' (highp float)\r
+\r
index b339567..cde4e28 100644 (file)
@@ -2,7 +2,8 @@ ERROR: #version: versions before 150 do not allow a profile token
 ERROR: 0:38: 'attribute' : not supported in this stage: fragment\r
 ERROR: 0:40: 'sampler2DRect' : Reserved word. \r
 ERROR: 0:40: 'rectangle texture' : not supported for this version or the enabled extensions \r
-ERROR: 4 compilation errors.  No code generated.\r
+ERROR: 0:44: 'floating-point suffix' : not supported for this version or the enabled extensions \r
+ERROR: 5 compilation errors.  No code generated.\r
 \r
 ERROR: node is still EOpNull!\r
 0:42  Function Definition: main( (void)\r
index 41c5a6a..a3dc5fa 100644 (file)
@@ -85,3 +85,52 @@ sum += 600000.0;
 // sum should be 987600301.0
     gl_Position = vec4(sum);
 }
+
+#define  A 1
+#define  C 0
+#define  E 0
+#define  F 1
+#if A
+    #if C
+        #if E
+            int selected4 = 1;
+        #elif F
+            int selected4 = 2;
+        #else
+            int selected4 = 3;
+        #endif
+    #endif
+    int selected4 = 4;
+#endif
+
+#define  ZA 1
+#define  ZC 1
+#define  ZE 0
+#define  ZF 1
+#if ZA
+    #if ZC
+        #if ZE
+            int selected2 = 1;
+        #elif ZF
+            int selected2 = 2;
+        #else
+            int selected2 = 3;
+        #endif
+    #endif
+#endif
+
+#define  AZA 1
+#define  AZC 1
+#define  AZE 0
+#define  AZF 0
+#if AZA
+    #if AZC
+        #if AZE
+            int selected3 = 1;
+        #elif AZF
+            int selected3 = 2;
+        #else
+            int selected3 = 3;
+        #endif
+    #endif
+#endif
index f200fbe..59854fd 100644 (file)
@@ -201,6 +201,9 @@ int n = n1;
 #define f1 .08e-2Lf
 double f = f1;
 
+#undef __VERSION__
+#undef GL_ARB_texture_rectangle
+
 #if 1
 #else
 // ERROR, missing #endif
\ No newline at end of file
diff --git a/Test/lineContinuation100.vert b/Test/lineContinuation100.vert
new file mode 100644 (file)
index 0000000..0b0cc30
--- /dev/null
@@ -0,0 +1,20 @@
+#version 100\r
+\r
+// this file cont\\r
+ains no errors other than the #error which are there to see if line numbering for errors is correct\r
+\r
+#error e1\r
+\r
+float f\\r
+oo;  // same as 'float foo;'\r
+\r
+#error e2\r
+\r
+#define MAIN void main() \\r
+{                        \\r
+gl_Position = vec4(foo); \\r
+} \r
+\r
+#error e3\r
+\r
+MAIN\r
index 0531322..e24fa52 100644 (file)
@@ -26,7 +26,7 @@ void main()
 {\r
     lowp int sum = global_medium + global_high;\r
 \r
-    gl_FragColor = vec4(color, 1.0f);\r
+    gl_FragColor = vec4(color, 1.0);\r
 \r
     int level1_high;\r
     sum += level1_high;\r
index 540b4a7..d9b9f5c 100644 (file)
@@ -37,5 +37,5 @@ varying vec3 color;
 \r
 void main()\r
 {\r
-    gl_FragColor = vec4(color, 1.0f);\r
+    gl_FragColor = vec4(color, 1.0);\r
 }\r
index 74d5d84..f79b118 100644 (file)
@@ -50,6 +50,7 @@ tokenLength.vert
 420.vert
 420.geom
 430scope.vert
+lineContinuation100.vert
 lineContinuation.vert
 numeral.frag
 400.geom
index 12fb3eb..f23b37e 100644 (file)
@@ -1370,6 +1370,35 @@ bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier
     return false;
 }
 
+//
+// Reserved errors for the preprocessor.
+//
+void TParseContext::reservedPpErrorCheck(TSourceLoc loc, const char* identifier, const char* op)
+{
+    // "All macro names containing two consecutive underscores ( __ ) are reserved for future use as predefined 
+    // macro names. All macro names prefixed with "GL_" ("GL" followed by a single underscore) are also 
+    // reserved."
+    if (strncmp(identifier, "GL_", 3) == 0)
+        error(loc, "can't use with built-in names (\"GL_\" prefix)", op, "");
+    else if (strstr(identifier, "__") != 0)
+        error(loc, "can't use with built-in names (containing consecutive underscores)", op, "");
+}
+
+//
+// See if this version/profile allows use of the line-continuation character '\'.
+//
+void TParseContext::lineContinuationCheck(TSourceLoc loc)
+{
+    const char* message = "line continuation";
+    if (messages & EShMsgRelaxedErrors) {
+        warn(loc, "not allowed in this version", message, "");
+    } else {
+        requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, message);
+        profileRequires(loc, EEsProfile, 300, 0, message);
+        profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 0, message);
+    }
+}
+
 bool TParseContext::builtInName(const TString& identifier)
 {
     return identifier.compare(0, 3, "gl_") == 0;
index c7680ba..81426be 100644 (file)
@@ -75,6 +75,8 @@ public:
     void C_DECL  warn(TSourceLoc, const char *szReason, const char *szToken,
                       const char *szExtraInfoFormat, ...);
     bool reservedErrorCheck(TSourceLoc, const TString&);
+    void reservedPpErrorCheck(TSourceLoc, const char* name, const char* op);
+    void lineContinuationCheck(TSourceLoc);
     bool builtInName(const TString&);
 
     void handlePragma(const char **tokens, int numTokens);
index dd2b68a..af62318 100644 (file)
@@ -151,13 +151,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
     const char* definedName = GetAtomString(atom);
     if (ppToken->loc.string >= 0) {
         // We are in user code; check for reserved name use:
-        // "All macro names containing two consecutive underscores ( __ ) are reserved for future use as predefined 
-        // macro names. All macro names prefixed with "GL_" ("GL" followed by a single underscore) are also 
-        // reserved."
-        if (strncmp(definedName, "GL_", 3) == 0)
-            parseContext.error(ppToken->loc, "reserved built-in name prefix:", "#define", "GL_");
-        else if (strstr(definedName, "__") != 0)
-            parseContext.error(ppToken->loc, "names containing consecutive underscores are reserved", "#define", "");
+        parseContext.reservedPpErrorCheck(ppToken->loc, definedName, "#define");
     }
     token = currentInput->scan(this, currentInput, ppToken);
     if (token == '(' && !ppToken->ival) {
@@ -203,6 +197,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
     mac.body = NewTokenStream(pool);
     while (token != '\n') {
         if (token == '\\') {
+            parseContext.lineContinuationCheck(ppToken->loc);
             token = currentInput->scan(this, currentInput, ppToken);
             if (token == '\n')
                 token = currentInput->scan(this, currentInput, ppToken);
@@ -253,21 +248,19 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
     return '\n';
 }
 
-int TPpContext::CPPundef(TPpToken * ppToken)
+int TPpContext::CPPundef(TPpToken* ppToken)
 {
     int token = currentInput->scan(this, currentInput, ppToken);
     Symbol *symb;
-    if (token == '\n') {
-        parseContext.error(ppToken->loc, "must be followed by macro name", "#undef", "");
-
-        return token;
-    }
     if (token != CPP_IDENTIFIER) {
         parseContext.error(ppToken->loc, "must be followed by macro name", "#undef", "");
 
         return token;
     }
 
+    const char* name = GetAtomString(ppToken->atom); // TODO preprocessor simplification: the token text should have been built into the ppToken during currentInput->scan()
+    parseContext.reservedPpErrorCheck(ppToken->loc, name, "#undef");
+
     symb = LookUpSymbol(ppToken->atom);
     if (symb) {
         symb->mac.undef = 1;
@@ -311,7 +304,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
             elsetracker++;
         } else if (atom == endifAtom) {
             token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
-            elsedepth[elsetracker] = 0;
+            elseSeen[elsetracker] = false;
             --elsetracker;
             if (depth == 0) {
                 // found the #endif we are looking for
@@ -331,21 +324,21 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
                 * it and we really want to leave it alone */
                 if (ifdepth) {
                     --ifdepth;
-                    elsedepth[elsetracker] = 0;
+                    elseSeen[elsetracker] = false;
                     --elsetracker;
                 }
 
                 return CPPif(ppToken);
             }
-        } else if (atom == elseAtom || atom == elifAtom) {
-            if (! ChkCorrectElseNesting()) {
-                if (atom == elseAtom)
-                    parseContext.error(ppToken->loc, "#else after #else", "#else", "");
-                else
-                    parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
-            }
-            if (atom == elseAtom)
-                token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
+        } else if (atom == elseAtom) {
+            if (elseSeen[elsetracker])
+                parseContext.error(ppToken->loc, "#else after #else", "#else", "");
+            else
+                elseSeen[elsetracker] = true;
+            token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
+        } else if (atom == elifAtom) {
+            if (elseSeen[elsetracker])
+                parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
         }
     }
 
@@ -807,7 +800,8 @@ int TPpContext::readCPPline(TPpToken * ppToken)
         if (ppToken->atom == defineAtom) {
             token = CPPdefine(ppToken);
         } else if (ppToken->atom == elseAtom) {
-            if (ChkCorrectElseNesting()) {
+            if (! elsetracker[elseSeen]) {
+                elsetracker[elseSeen] = true;
                 if (! ifdepth)
                     parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
                 token = extraTokenCheck(elseAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
@@ -826,7 +820,7 @@ int TPpContext::readCPPline(TPpToken * ppToken)
                 token = currentInput->scan(this, currentInput, ppToken);
             token = CPPelse(0, ppToken);
         } else if (ppToken->atom == endifAtom) {
-            elsedepth[elsetracker] = 0;
+            elseSeen[elsetracker] = false;
             --elsetracker;
             if (! ifdepth)
                 parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
@@ -1106,15 +1100,4 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
     return 1;
 }
 
-int TPpContext::ChkCorrectElseNesting()
-{
-    if (elsedepth[elsetracker] == 0) {
-        elsedepth[elsetracker] = 1;
-
-        return 1;
-    }
-
-    return 0;
-}
-
 } // end namespace glslang
\ No newline at end of file
index 29af6bb..21af119 100644 (file)
@@ -91,7 +91,7 @@ TPpContext::TPpContext(TParseContext& pc) :
 
     ifdepth = 0;
     for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
-        elsedepth[elsetracker] = 0;
+        elseSeen[elsetracker] = false;
     elsetracker = 0;
 }
 
index 22b35be..5982ce0 100644 (file)
@@ -196,9 +196,9 @@ protected:
     static const int maxMacroArgs = 64;
     static const int maxIfNesting = 64;
 
-    int ifdepth;                 // current #if-#else-#endif nesting in the cpp.c file (pre-processor)    
-    int elsedepth[maxIfNesting]; // Keep a track of #if depth..Max allowed is 64.   
-    int elsetracker;             // #if-#else and #endif constructs...Counter.
+    int ifdepth;                  // current #if-#else-#endif nesting in the cpp.c file (pre-processor)    
+    bool elseSeen[maxIfNesting];  // Keep a track of whether an else has been seen at a particular depth
+    int elsetracker;              // #if-#else and #endif constructs...Counter.
     const char *ErrMsg;
 
     struct MacroInputSrc {
@@ -262,7 +262,6 @@ protected:
     static int macro_scan(TPpContext* pp, InputSrc *inInput, TPpToken * ppToken); 
     static int zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken * ppToken); 
     int MacroExpand(int atom, TPpToken* ppToken, int expandUndef);
-    int ChkCorrectElseNesting();
 
     //
     // from PpSymbols.cpp
index 57cc502..aed147c 100644 (file)
@@ -202,6 +202,7 @@ int TPpContext::lFloatConst(char* str, int len, int ch, TPpToken* ppToken)
         strcpy(str, "0.0");
     } else {
         if (ch == 'l' || ch == 'L') {
+            parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
             if (! HasDecimalOrExponent)
                 parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
             int ch2 = currentInput->getch(this, currentInput, ppToken);
@@ -219,6 +220,8 @@ int TPpContext::lFloatConst(char* str, int len, int ch, TPpToken* ppToken)
                 }
             }
         } else if (ch == 'f' || ch == 'F') {
+            parseContext.profileRequires(ppToken->loc,  EEsProfile, 300, 0, "floating-point suffix");
+            parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, 0, "floating-point suffix");
             if (! HasDecimalOrExponent)
                 parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
             if (len < TPpToken::maxTokenLength)
@@ -230,7 +233,7 @@ int TPpContext::lFloatConst(char* str, int len, int ch, TPpToken* ppToken)
         } else 
             currentInput->ungetch(this, currentInput, ch, ppToken);
 
-        str[len]='\0';      
+        str[len]='\0';
 
         ppToken->dval = strtod(str, 0);
     }
@@ -282,6 +285,7 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
             do {
                 if (ch == '\\') {
                     // escaped character
+                    pp->parseContext.lineContinuationCheck(ppToken->loc);
                     ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
                     if (ch == '\r' || ch == '\n') {
                         int nextch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
@@ -631,6 +635,7 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
                     ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
                     if (ch == '\\') {
                         // allow an escaped newline, otherwise escapes in comments are meaningless
+                        pp->parseContext.lineContinuationCheck(ppToken->loc);
                         ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
                         if (ch == '\r' || ch == '\n') {
                             int nextch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
@@ -678,7 +683,8 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
         case '"':
             ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
             while (ch != '"' && ch != '\n' && ch != EOF) {
-                if (ch == '\\') {
+                if (ch == '\\') {                    
+                    pp->parseContext.lineContinuationCheck(ppToken->loc);
                     ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
                     if (ch == '\n' || ch == EOF) {
                         break;