diff --git a/Install/Windows/glslangValidator.exe b/Install/Windows/glslangValidator.exe index b6471638..ebdec876 100644 Binary files a/Install/Windows/glslangValidator.exe and b/Install/Windows/glslangValidator.exe differ diff --git a/Test/100.frag b/Test/100.frag index cb78f8bf..9daa0267 100644 --- a/Test/100.frag +++ b/Test/100.frag @@ -146,4 +146,7 @@ int foo203940(int a, float b, float a) // ERROR, a redefined return a; } +float f123 = 4.0f; // ERROR +float f124 = 5e10F; // ERROR + uniform samplerExternalOES badExt; // syntax ERROR diff --git a/Test/120.frag b/Test/120.frag index e6ed62a6..ac70c20a 100644 --- a/Test/120.frag +++ b/Test/120.frag @@ -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; } diff --git a/Test/300.vert b/Test/300.vert index 1d9d6316..cdbfa8ee 100644 --- a/Test/300.vert +++ b/Test/300.vert @@ -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() diff --git a/Test/baseResults/100.frag.out b/Test/baseResults/100.frag.out index 2507e06f..1c08f355 100644 --- a/Test/baseResults/100.frag.out +++ b/Test/baseResults/100.frag.out @@ -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 ERROR: 0:139: 'bitwise and' : not supported for this version or the enabled extensions ERROR: 0:144: 'a' : redefinition -ERROR: 0:149: '' : syntax error -ERROR: 53 compilation errors. No code generated. +ERROR: 0:149: 'floating-point suffix' : not supported for this version or the enabled extensions +ERROR: 0:150: 'floating-point suffix' : not supported for this version or the enabled extensions +ERROR: 0:152: '' : syntax error +ERROR: 55 compilation errors. No code generated. ERROR: node is still EOpNull! 0:3 Sequence @@ -245,6 +247,16 @@ ERROR: node is still EOpNull! 0:146 Sequence 0:146 Branch: Return with expression 0:146 'a' (in mediump int) +0:149 Sequence +0:149 move second child to first child (mediump float) +0:149 'f123' (mediump float) +0:149 Constant: +0:149 4.000000 +0:150 Sequence +0:150 move second child to first child (mediump float) +0:150 'f124' (mediump float) +0:150 Constant: +0:150 50000000000.000000 0:? Linker Objects 0:? 'a' (3-element array of mediump int) 0:? 'uint' (mediump int) @@ -264,4 +276,6 @@ ERROR: node is still EOpNull! 0:? 'sExt' (uniform lowp samplerExternalOES) 0:? 'mediumExt' (uniform mediump samplerExternalOES) 0:? 'highExt' (uniform highp samplerExternalOES) +0:? 'f123' (mediump float) +0:? 'f124' (mediump float) diff --git a/Test/baseResults/cppNest.vert.out b/Test/baseResults/cppNest.vert.out index 918f832e..95f28f4b 100644 --- a/Test/baseResults/cppNest.vert.out +++ b/Test/baseResults/cppNest.vert.out @@ -35,6 +35,24 @@ 0:86 'gl_Position' (gl_Position 4-component vector of float) 0:86 Construct vec4 (4-component vector of float) 0:86 'sum' (float) +0:103 Sequence +0:103 move second child to first child (int) +0:103 'selected4' (int) +0:103 Constant: +0:103 4 (const int) +0:115 Sequence +0:115 move second child to first child (int) +0:115 'selected2' (int) +0:115 Constant: +0:115 2 (const int) +0:133 Sequence +0:133 move second child to first child (int) +0:133 'selected3' (int) +0:133 Constant: +0:133 3 (const int) 0:? Linker Objects 0:? 'sum' (float) +0:? 'selected4' (int) +0:? 'selected2' (int) +0:? 'selected3' (int) diff --git a/Test/baseResults/cppSimple.vert.out b/Test/baseResults/cppSimple.vert.out index a0c313cf..a5d18f22 100644 --- a/Test/baseResults/cppSimple.vert.out +++ b/Test/baseResults/cppSimple.vert.out @@ -24,11 +24,11 @@ ERROR: 0:136: 'length' : no matching overloaded function found ERROR: 0:136: '=' : cannot convert from 'const float' to 'int' ERROR: 0:138: ''' : character literals not supported ERROR: 0:138: ''' : character literals not supported -ERROR: 0:141: '#define' : reserved built-in name prefix: GL_ -ERROR: 0:142: '#define' : reserved built-in name prefix: GL_ -ERROR: 0:143: '#define' : names containing consecutive underscores are reserved -ERROR: 0:144: '#define' : names containing consecutive underscores are reserved -ERROR: 0:145: '#define' : names containing consecutive underscores are reserved +ERROR: 0:141: '#define' : can't use with built-in names ("GL_" prefix) +ERROR: 0:142: '#define' : can't use with built-in names ("GL_" prefix) +ERROR: 0:143: '#define' : can't use with built-in names (containing consecutive underscores) +ERROR: 0:144: '#define' : can't use with built-in names (containing consecutive underscores) +ERROR: 0:145: '#define' : can't use with built-in names (containing consecutive underscores) ERROR: 0:148: '#else' : unexpected tokens following directive ERROR: 0:149: '#else' : #elif after #else ERROR: 0:155: '#else' : unexpected tokens following directive @@ -41,8 +41,10 @@ ERROR: 0:182: '#define' : Macro redefined; different number of arguments: m6 ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7 ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8 ERROR: 0:196: '#define' : Macro redefined; different argument names: m9 -ERROR: 0:206: '' : missing #endif -ERROR: 43 compilation errors. No code generated. +ERROR: 0:204: '#undef' : can't use with built-in names (containing consecutive underscores) +ERROR: 0:205: '#undef' : can't use with built-in names ("GL_" prefix) +ERROR: 0:209: '' : missing #endif +ERROR: 45 compilation errors. No code generated. ERROR: node is still EOpNull! 0:5 Sequence diff --git a/Test/baseResults/lineContinuation100.vert.out b/Test/baseResults/lineContinuation100.vert.out new file mode 100644 index 00000000..640dbee0 --- /dev/null +++ b/Test/baseResults/lineContinuation100.vert.out @@ -0,0 +1,21 @@ +ERROR: 0:3: 'line continuation' : not supported for this version or the enabled extensions +ERROR: 0:6: '#error' : e1 +ERROR: 0:8: 'line continuation' : not supported for this version or the enabled extensions +ERROR: 0:11: '#error' : e2 +ERROR: 0:13: 'line continuation' : not supported for this version or the enabled extensions +ERROR: 0:14: 'line continuation' : not supported for this version or the enabled extensions +ERROR: 0:15: 'line continuation' : not supported for this version or the enabled extensions +ERROR: 0:18: '#error' : e3 +ERROR: 8 compilation errors. No code generated. + +ERROR: node is still EOpNull! +0:20 Function Definition: main( (void) +0:20 Function Parameters: +0:20 Sequence +0:20 move second child to first child (highp 4-component vector of float) +0:20 'gl_Position' (gl_Position highp 4-component vector of float) +0:20 Construct vec4 (highp 4-component vector of float) +0:20 'foo' (highp float) +0:? Linker Objects +0:? 'foo' (highp float) + diff --git a/Test/baseResults/versionsErrors.frag.out b/Test/baseResults/versionsErrors.frag.out index b339567b..cde4e280 100644 --- a/Test/baseResults/versionsErrors.frag.out +++ b/Test/baseResults/versionsErrors.frag.out @@ -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 ERROR: 0:40: 'sampler2DRect' : Reserved word. ERROR: 0:40: 'rectangle texture' : not supported for this version or the enabled extensions -ERROR: 4 compilation errors. No code generated. +ERROR: 0:44: 'floating-point suffix' : not supported for this version or the enabled extensions +ERROR: 5 compilation errors. No code generated. ERROR: node is still EOpNull! 0:42 Function Definition: main( (void) diff --git a/Test/cppNest.vert b/Test/cppNest.vert index 41c5a6a4..a3dc5fa5 100644 --- a/Test/cppNest.vert +++ b/Test/cppNest.vert @@ -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 diff --git a/Test/cppSimple.vert b/Test/cppSimple.vert index f200fbe8..59854fd2 100644 --- a/Test/cppSimple.vert +++ b/Test/cppSimple.vert @@ -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 index 00000000..0b0cc30a --- /dev/null +++ b/Test/lineContinuation100.vert @@ -0,0 +1,20 @@ +#version 100 + +// this file cont\ +ains no errors other than the #error which are there to see if line numbering for errors is correct + +#error e1 + +float f\ +oo; // same as 'float foo;' + +#error e2 + +#define MAIN void main() \ +{ \ +gl_Position = vec4(foo); \ +} + +#error e3 + +MAIN diff --git a/Test/precision.frag b/Test/precision.frag index 0531322e..e24fa52c 100644 --- a/Test/precision.frag +++ b/Test/precision.frag @@ -26,7 +26,7 @@ void main() { lowp int sum = global_medium + global_high; - gl_FragColor = vec4(color, 1.0f); + gl_FragColor = vec4(color, 1.0); int level1_high; sum += level1_high; diff --git a/Test/sample.frag b/Test/sample.frag index 540b4a74..d9b9f5cc 100644 --- a/Test/sample.frag +++ b/Test/sample.frag @@ -37,5 +37,5 @@ varying vec3 color; void main() { - gl_FragColor = vec4(color, 1.0f); + gl_FragColor = vec4(color, 1.0); } diff --git a/Test/testlist b/Test/testlist index 74d5d84b..f79b1183 100644 --- a/Test/testlist +++ b/Test/testlist @@ -50,6 +50,7 @@ tokenLength.vert 420.vert 420.geom 430scope.vert +lineContinuation100.vert lineContinuation.vert numeral.frag 400.geom diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 12fb3eb4..f23b37e9 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -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; diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index c7680ba3..81426be4 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -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); diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index dd2b68a6..af623181 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -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 diff --git a/glslang/MachineIndependent/preprocessor/PpContext.cpp b/glslang/MachineIndependent/preprocessor/PpContext.cpp index 29af6bb1..21af119e 100644 --- a/glslang/MachineIndependent/preprocessor/PpContext.cpp +++ b/glslang/MachineIndependent/preprocessor/PpContext.cpp @@ -91,7 +91,7 @@ TPpContext::TPpContext(TParseContext& pc) : ifdepth = 0; for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++) - elsedepth[elsetracker] = 0; + elseSeen[elsetracker] = false; elsetracker = 0; } diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h index 22b35bed..5982ce06 100644 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -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 diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp index 57cc502a..aed147cc 100644 --- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -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;