From: John Kessenich Date: Mon, 16 Dec 2013 23:58:15 +0000 (+0000) Subject: 1) Allow '\' before a non-newline as a token in the preprocessor, and 2) localize... X-Git-Tag: upstream/0.1~770 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bd958191234553a55d9fa52b52ae1f30e99724bd;p=platform%2Fupstream%2Fglslang.git 1) Allow '\' before a non-newline as a token in the preprocessor, and 2) localize line-continuation to just the pp scanner. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24530 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- diff --git a/Install/Windows/glslangValidator.exe b/Install/Windows/glslangValidator.exe index 0c00fc8..d138589 100644 Binary files a/Install/Windows/glslangValidator.exe and b/Install/Windows/glslangValidator.exe differ diff --git a/Test/baseResults/lineContinuation.vert.out b/Test/baseResults/lineContinuation.vert.out index 344099b..c41ee1b 100644 --- a/Test/baseResults/lineContinuation.vert.out +++ b/Test/baseResults/lineContinuation.vert.out @@ -3,7 +3,16 @@ WARNING: 0:3: 'line continuation' : used at end of comment; the following line i ERROR: 0:6: '#error' : e1 ERROR: 0:11: '#error' : e2 ERROR: 0:18: '#error' : e3 -ERROR: 3 compilation errors. No code generated. +ERROR: 0:42: '\' : illegal use of escape character +ERROR: 0:43: '@' : unexpected token +ERROR: 0:44: '$' : unexpected token +ERROR: 0:45: '\' : illegal use of escape character +ERROR: 0:47: '\' : illegal use of escape character +ERROR: 0:48: '\' : illegal use of escape character +ERROR: 0:49: '$' : unexpected token +ERROR: 0:50: '@' : unexpected token +ERROR: 0:55: '#error' : good continuation +ERROR: 12 compilation errors. No code generated. ERROR: node is still EOpNull! @@ -24,9 +33,56 @@ ERROR: node is still EOpNull! 0:24 'a' (in highp 4-component vector of float) 0:25 Branch: Return with expression 0:25 'b' (highp 4-component vector of float) +0:42 Sequence +0:42 move second child to first child (highp int) +0:42 'a1' (highp int) +0:42 Constant: +0:42 4 (const int) +0:43 Sequence +0:43 move second child to first child (highp int) +0:43 'a2' (highp int) +0:43 Constant: +0:43 3 (const int) +0:44 Sequence +0:44 move second child to first child (highp int) +0:44 'a3' (highp int) +0:44 Constant: +0:44 4 (const int) +0:45 Sequence +0:45 move second child to first child (highp int) +0:45 'a4' (highp int) +0:45 'a2' (highp int) +0:47 Sequence +0:47 move second child to first child (highp int) +0:47 'q1' (highp int) +0:47 Constant: +0:47 1 (const int) +0:48 Sequence +0:48 move second child to first child (highp int) +0:48 'q2' (highp int) +0:48 Constant: +0:48 1 (const int) +0:49 Sequence +0:49 move second child to first child (highp int) +0:49 'q3' (highp int) +0:49 Constant: +0:49 1 (const int) +0:50 Sequence +0:50 move second child to first child (highp int) +0:50 'q4' (highp int) +0:50 Constant: +0:50 1 (const int) 0:? Linker Objects 0:? 'foo' (highp float) 0:? 'goodDecl' (highp int) +0:? 'a1' (highp int) +0:? 'a2' (highp int) +0:? 'a3' (highp int) +0:? 'a4' (highp int) +0:? 'q1' (highp int) +0:? 'q2' (highp int) +0:? 'q3' (highp int) +0:? 'q4' (highp int) 0:? 'gl_VertexID' (gl_VertexId highp int) 0:? 'gl_InstanceID' (gl_InstanceId highp int) diff --git a/Test/baseResults/lineContinuation100.vert.out b/Test/baseResults/lineContinuation100.vert.out index 7519146..6312793 100644 --- a/Test/baseResults/lineContinuation100.vert.out +++ b/Test/baseResults/lineContinuation100.vert.out @@ -8,7 +8,18 @@ ERROR: 0:14: 'line continuation' : not supported for this version or the enabled ERROR: 0:15: 'line continuation' : not supported for this version or the enabled extensions ERROR: 0:18: '#error' : e3 ERROR: 0:24: 'line continuation' : not supported for this version or the enabled extensions -ERROR: 8 compilation errors. No code generated. +ERROR: 0:40: '\' : illegal use of escape character +ERROR: 0:41: '@' : unexpected token +ERROR: 0:42: '$' : unexpected token +ERROR: 0:43: '\' : illegal use of escape character +ERROR: 0:45: '\' : illegal use of escape character +ERROR: 0:46: '\' : illegal use of escape character +ERROR: 0:47: '$' : unexpected token +ERROR: 0:48: '@' : unexpected token +ERROR: 0:50: 'line continuation' : not supported for this version or the enabled extensions +ERROR: 0:52: 'line continuation' : not supported for this version or the enabled extensions +ERROR: 0:53: '#error' : bad continuation +ERROR: 19 compilation errors. No code generated. ERROR: node is still EOpNull! @@ -29,8 +40,55 @@ ERROR: node is still EOpNull! 0:24 'a' (in highp 4-component vector of float) 0:25 Branch: Return with expression 0:25 'b' (highp 4-component vector of float) +0:40 Sequence +0:40 move second child to first child (highp int) +0:40 'a1' (highp int) +0:40 Constant: +0:40 4 (const int) +0:41 Sequence +0:41 move second child to first child (highp int) +0:41 'a2' (highp int) +0:41 Constant: +0:41 3 (const int) +0:42 Sequence +0:42 move second child to first child (highp int) +0:42 'a3' (highp int) +0:42 Constant: +0:42 4 (const int) +0:43 Sequence +0:43 move second child to first child (highp int) +0:43 'a4' (highp int) +0:43 'a2' (highp int) +0:45 Sequence +0:45 move second child to first child (highp int) +0:45 'q1' (highp int) +0:45 Constant: +0:45 1 (const int) +0:46 Sequence +0:46 move second child to first child (highp int) +0:46 'q2' (highp int) +0:46 Constant: +0:46 1 (const int) +0:47 Sequence +0:47 move second child to first child (highp int) +0:47 'q3' (highp int) +0:47 Constant: +0:47 1 (const int) +0:48 Sequence +0:48 move second child to first child (highp int) +0:48 'q4' (highp int) +0:48 Constant: +0:48 1 (const int) 0:? Linker Objects 0:? 'foo' (highp float) +0:? 'a1' (highp int) +0:? 'a2' (highp int) +0:? 'a3' (highp int) +0:? 'a4' (highp int) +0:? 'q1' (highp int) +0:? 'q2' (highp int) +0:? 'q3' (highp int) +0:? 'q4' (highp int) Linked vertex stage: diff --git a/Test/lineContinuation.vert b/Test/lineContinuation.vert index a70b625..7c0e29b 100644 --- a/Test/lineContinuation.vert +++ b/Test/lineContinuation.vert @@ -34,3 +34,24 @@ vec4 foo2(vec4 a) FOO +#define A int q1 = \ 1 +#define B int q2 = \1 +#define C int q3 = $ 1 +#define D int q4 = @ 1 + +int a1 = \ 4; // ERROR +int a2 = @ 3; // ERROR +int a3 = $4; // ERROR +int a4 = a2\; // ERROR + +A; +B; +C; +D; + +# \ + +# \ + error good continuation + +#define AA a \ b diff --git a/Test/lineContinuation100.vert b/Test/lineContinuation100.vert index b68b715..5bb112a 100644 --- a/Test/lineContinuation100.vert +++ b/Test/lineContinuation100.vert @@ -31,3 +31,23 @@ vec4 foo2(vec4 a) /*@*/ /* *@/*/ //@ + +#define A int q1 = \ 1 +#define B int q2 = \1 +#define C int q3 = $ 1 +#define D int q4 = @ 1 + +int a1 = \ 4; // ERROR +int a2 = @ 3; // ERROR +int a3 = $4; // ERROR +int a4 = a2\; // ERROR + +A; +B; +C; +D; + +# \ + +# \ + error bad continuation \ No newline at end of file diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index d5b74af..9f79c7f 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -9,5 +9,5 @@ // source have to figure out how to create revision.h just to get a build // going. However, if it is not updated, it can be a version behind. -#define GLSLANG_REVISION "24518" -#define GLSLANG_DATE "2013/12/13 11:38:43" +#define GLSLANG_REVISION "24522" +#define GLSLANG_DATE "2013/12/13 12:26:54" diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 0f4e6d7..d208056 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -1484,6 +1484,7 @@ bool TParseContext::lineContinuationCheck(TSourceLoc loc, bool endOfComment) if (messages & EShMsgRelaxedErrors) { warn(loc, "not allowed in this version", message, ""); + return true; } else { requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, message); profileRequires(loc, EEsProfile, 300, 0, message); diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index 2c1eb54..9077ca6 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -478,74 +478,82 @@ void TScanContext::fillInKeywordMap() int TScanContext::tokenize(TPpContext* pp, TParserToken& token) { - parserToken = &token; - TPpToken ppToken; - tokenText = pp->tokenize(&ppToken); - if (tokenText == 0) - return 0; + do { + parserToken = &token; + TPpToken ppToken; + tokenText = pp->tokenize(&ppToken); + if (tokenText == 0) + return 0; + + loc = ppToken.loc; + parserToken->sType.lex.loc = loc; + switch (ppToken.token) { + case ';': afterType = false; return SEMICOLON; + case ',': afterType = false; return COMMA; + case ':': return COLON; + case '=': afterType = false; return EQUAL; + case '(': afterType = false; return LEFT_PAREN; + case ')': afterType = false; return RIGHT_PAREN; + case '.': field = true; return DOT; + case '!': return BANG; + case '-': return DASH; + case '~': return TILDE; + case '+': return PLUS; + case '*': return STAR; + case '/': return SLASH; + case '%': return PERCENT; + case '<': return LEFT_ANGLE; + case '>': return RIGHT_ANGLE; + case '|': return VERTICAL_BAR; + case '^': return CARET; + case '&': return AMPERSAND; + case '?': return QUESTION; + case '[': return LEFT_BRACKET; + case ']': return RIGHT_BRACKET; + case '{': return LEFT_BRACE; + case '}': return RIGHT_BRACE; + case '\\': + parseContext.error(loc, "illegal use of escape character", "\\", ""); + break; - loc = ppToken.loc; - parserToken->sType.lex.loc = loc; - switch (ppToken.token) { - case ';': afterType = false; return SEMICOLON; - case ',': afterType = false; return COMMA; - case ':': return COLON; - case '=': afterType = false; return EQUAL; - case '(': afterType = false; return LEFT_PAREN; - case ')': afterType = false; return RIGHT_PAREN; - case '.': field = true; return DOT; - case '!': return BANG; - case '-': return DASH; - case '~': return TILDE; - case '+': return PLUS; - case '*': return STAR; - case '/': return SLASH; - case '%': return PERCENT; - case '<': return LEFT_ANGLE; - case '>': return RIGHT_ANGLE; - case '|': return VERTICAL_BAR; - case '^': return CARET; - case '&': return AMPERSAND; - case '?': return QUESTION; - case '[': return LEFT_BRACKET; - case ']': return RIGHT_BRACKET; - case '{': return LEFT_BRACE; - case '}': return RIGHT_BRACE; - - case CPP_AND_OP: return AND_OP; - case CPP_SUB_ASSIGN: return SUB_ASSIGN; - case CPP_MOD_ASSIGN: return MOD_ASSIGN; - case CPP_ADD_ASSIGN: return ADD_ASSIGN; - case CPP_DIV_ASSIGN: return DIV_ASSIGN; - case CPP_MUL_ASSIGN: return MUL_ASSIGN; - case CPP_EQ_OP: return EQ_OP; - case CPP_XOR_OP: return XOR_OP; - case CPP_GE_OP: return GE_OP; - case CPP_RIGHT_OP: return RIGHT_OP; - case CPP_LE_OP: return LE_OP; - case CPP_LEFT_OP: return LEFT_OP; - case CPP_DEC_OP: return DEC_OP; - case CPP_NE_OP: return NE_OP; - case CPP_OR_OP: return OR_OP; - case CPP_INC_OP: return INC_OP; - case CPP_RIGHT_ASSIGN: return RIGHT_ASSIGN; - case CPP_LEFT_ASSIGN: return LEFT_ASSIGN; - case CPP_AND_ASSIGN: return AND_ASSIGN; - case CPP_OR_ASSIGN: return OR_ASSIGN; - case CPP_XOR_ASSIGN: return XOR_ASSIGN; + case CPP_AND_OP: return AND_OP; + case CPP_SUB_ASSIGN: return SUB_ASSIGN; + case CPP_MOD_ASSIGN: return MOD_ASSIGN; + case CPP_ADD_ASSIGN: return ADD_ASSIGN; + case CPP_DIV_ASSIGN: return DIV_ASSIGN; + case CPP_MUL_ASSIGN: return MUL_ASSIGN; + case CPP_EQ_OP: return EQ_OP; + case CPP_XOR_OP: return XOR_OP; + case CPP_GE_OP: return GE_OP; + case CPP_RIGHT_OP: return RIGHT_OP; + case CPP_LE_OP: return LE_OP; + case CPP_LEFT_OP: return LEFT_OP; + case CPP_DEC_OP: return DEC_OP; + case CPP_NE_OP: return NE_OP; + case CPP_OR_OP: return OR_OP; + case CPP_INC_OP: return INC_OP; + case CPP_RIGHT_ASSIGN: return RIGHT_ASSIGN; + case CPP_LEFT_ASSIGN: return LEFT_ASSIGN; + case CPP_AND_ASSIGN: return AND_ASSIGN; + case CPP_OR_ASSIGN: return OR_ASSIGN; + case CPP_XOR_ASSIGN: return XOR_ASSIGN; - case CPP_INTCONSTANT: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; - case CPP_UINTCONSTANT: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; - case CPP_FLOATCONSTANT: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; - case CPP_DOUBLECONSTANT: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; - case CPP_IDENTIFIER: return tokenizeIdentifier(); + case CPP_INTCONSTANT: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; + case CPP_UINTCONSTANT: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; + case CPP_FLOATCONSTANT: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; + case CPP_DOUBLECONSTANT: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; + case CPP_IDENTIFIER: return tokenizeIdentifier(); - case EOF: return 0; + case EOF: return 0; - default: - parseContext.infoSink.info.message(EPrefixInternalError, "Unknown PP token", loc); - return 0; - } + default: + char buf[2]; + buf[0] = ppToken.token; + buf[1] = 0; + parseContext.error(loc, "unexpected token", buf, ""); + break; + } + } while (true); } int TScanContext::tokenizeIdentifier() diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index 7fa5b92..7cb5a38 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -190,12 +190,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken) TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors mac.body = new TokenStream; while (token != '\n') { - if (token == '\\') { - parseContext.lineContinuationCheck(ppToken->loc, false); - token = currentInput->scan(this, currentInput, ppToken); - if (token == '\n' || token == '\r') - token = currentInput->scan(this, currentInput, ppToken); - } RecordToken(mac.body, token, ppToken); token = currentInput->scan(this, currentInput, ppToken); if (token != '\n' && ppToken->space) diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp index 1add7a2..82eaf26 100644 --- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -281,20 +281,29 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken) case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': case '\\' : + case 'z': case '\\': do { if (ch == '\\') { // escaped character - pp->parseContext.lineContinuationCheck(ppToken->loc, false); ch = pp->currentInput->getch(pp, pp->currentInput, ppToken); if (ch == '\r' || ch == '\n') { + pp->parseContext.lineContinuationCheck(ppToken->loc, false); int nextch = pp->currentInput->getch(pp, pp->currentInput, ppToken); if (ch == '\r' && nextch == '\n') ch = pp->currentInput->getch(pp, pp->currentInput, ppToken); else ch = nextch; - } else - pp->parseContext.error(ppToken->loc, "can only escape newlines", "\\", ""); + } else { + // Not an escaped newline. + // Put back whatever it was + pp->currentInput->ungetch(pp, pp->currentInput, ch, ppToken); + // If not in the middle of an identifier, the \ is our token + if (len == 0) + return '\\'; + // Otherwise, put back the \ character, leave it for the next call + ch = '\\'; // for the upcoming unget(...ch...); + break; + } } else if (len < TPpToken::maxTokenLength) { tokenText[len++] = ch; ch = pp->currentInput->getch(pp, pp->currentInput, ppToken); @@ -303,7 +312,7 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken) pp->parseContext.error(ppToken->loc, "name too long", "", ""); AlreadyComplained = 1; } - ch = pp->currentInput->getch(pp, pp->currentInput, ppToken); + ch = pp->currentInput->getch(pp, pp->currentInput, ppToken); } } while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||