ERROR: 0:6: '#error' : e1 \r
ERROR: 0:11: '#error' : e2 \r
ERROR: 0:18: '#error' : e3 \r
-ERROR: 3 compilation errors. No code generated.\r
+ERROR: 0:42: '\' : illegal use of escape character \r
+ERROR: 0:43: '@' : unexpected token \r
+ERROR: 0:44: '$' : unexpected token \r
+ERROR: 0:45: '\' : illegal use of escape character \r
+ERROR: 0:47: '\' : illegal use of escape character \r
+ERROR: 0:48: '\' : illegal use of escape character \r
+ERROR: 0:49: '$' : unexpected token \r
+ERROR: 0:50: '@' : unexpected token \r
+ERROR: 0:55: '#error' : good continuation \r
+ERROR: 12 compilation errors. No code generated.\r
\r
\r
ERROR: node is still EOpNull!\r
0:24 'a' (in highp 4-component vector of float)\r
0:25 Branch: Return with expression\r
0:25 'b' (highp 4-component vector of float)\r
+0:42 Sequence\r
+0:42 move second child to first child (highp int)\r
+0:42 'a1' (highp int)\r
+0:42 Constant:\r
+0:42 4 (const int)\r
+0:43 Sequence\r
+0:43 move second child to first child (highp int)\r
+0:43 'a2' (highp int)\r
+0:43 Constant:\r
+0:43 3 (const int)\r
+0:44 Sequence\r
+0:44 move second child to first child (highp int)\r
+0:44 'a3' (highp int)\r
+0:44 Constant:\r
+0:44 4 (const int)\r
+0:45 Sequence\r
+0:45 move second child to first child (highp int)\r
+0:45 'a4' (highp int)\r
+0:45 'a2' (highp int)\r
+0:47 Sequence\r
+0:47 move second child to first child (highp int)\r
+0:47 'q1' (highp int)\r
+0:47 Constant:\r
+0:47 1 (const int)\r
+0:48 Sequence\r
+0:48 move second child to first child (highp int)\r
+0:48 'q2' (highp int)\r
+0:48 Constant:\r
+0:48 1 (const int)\r
+0:49 Sequence\r
+0:49 move second child to first child (highp int)\r
+0:49 'q3' (highp int)\r
+0:49 Constant:\r
+0:49 1 (const int)\r
+0:50 Sequence\r
+0:50 move second child to first child (highp int)\r
+0:50 'q4' (highp int)\r
+0:50 Constant:\r
+0:50 1 (const int)\r
0:? Linker Objects\r
0:? 'foo' (highp float)\r
0:? 'goodDecl' (highp int)\r
+0:? 'a1' (highp int)\r
+0:? 'a2' (highp int)\r
+0:? 'a3' (highp int)\r
+0:? 'a4' (highp int)\r
+0:? 'q1' (highp int)\r
+0:? 'q2' (highp int)\r
+0:? 'q3' (highp int)\r
+0:? 'q4' (highp int)\r
0:? 'gl_VertexID' (gl_VertexId highp int)\r
0:? 'gl_InstanceID' (gl_InstanceId highp int)\r
\r
ERROR: 0:15: 'line continuation' : not supported for this version or the enabled extensions \r
ERROR: 0:18: '#error' : e3 \r
ERROR: 0:24: 'line continuation' : not supported for this version or the enabled extensions \r
-ERROR: 8 compilation errors. No code generated.\r
+ERROR: 0:40: '\' : illegal use of escape character \r
+ERROR: 0:41: '@' : unexpected token \r
+ERROR: 0:42: '$' : unexpected token \r
+ERROR: 0:43: '\' : illegal use of escape character \r
+ERROR: 0:45: '\' : illegal use of escape character \r
+ERROR: 0:46: '\' : illegal use of escape character \r
+ERROR: 0:47: '$' : unexpected token \r
+ERROR: 0:48: '@' : unexpected token \r
+ERROR: 0:50: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:52: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:53: '#error' : bad continuation \r
+ERROR: 19 compilation errors. No code generated.\r
\r
\r
ERROR: node is still EOpNull!\r
0:24 'a' (in highp 4-component vector of float)\r
0:25 Branch: Return with expression\r
0:25 'b' (highp 4-component vector of float)\r
+0:40 Sequence\r
+0:40 move second child to first child (highp int)\r
+0:40 'a1' (highp int)\r
+0:40 Constant:\r
+0:40 4 (const int)\r
+0:41 Sequence\r
+0:41 move second child to first child (highp int)\r
+0:41 'a2' (highp int)\r
+0:41 Constant:\r
+0:41 3 (const int)\r
+0:42 Sequence\r
+0:42 move second child to first child (highp int)\r
+0:42 'a3' (highp int)\r
+0:42 Constant:\r
+0:42 4 (const int)\r
+0:43 Sequence\r
+0:43 move second child to first child (highp int)\r
+0:43 'a4' (highp int)\r
+0:43 'a2' (highp int)\r
+0:45 Sequence\r
+0:45 move second child to first child (highp int)\r
+0:45 'q1' (highp int)\r
+0:45 Constant:\r
+0:45 1 (const int)\r
+0:46 Sequence\r
+0:46 move second child to first child (highp int)\r
+0:46 'q2' (highp int)\r
+0:46 Constant:\r
+0:46 1 (const int)\r
+0:47 Sequence\r
+0:47 move second child to first child (highp int)\r
+0:47 'q3' (highp int)\r
+0:47 Constant:\r
+0:47 1 (const int)\r
+0:48 Sequence\r
+0:48 move second child to first child (highp int)\r
+0:48 'q4' (highp int)\r
+0:48 Constant:\r
+0:48 1 (const int)\r
0:? Linker Objects\r
0:? 'foo' (highp float)\r
+0:? 'a1' (highp int)\r
+0:? 'a2' (highp int)\r
+0:? 'a3' (highp int)\r
+0:? 'a4' (highp int)\r
+0:? 'q1' (highp int)\r
+0:? 'q2' (highp int)\r
+0:? 'q3' (highp int)\r
+0:? 'q4' (highp int)\r
\r
\r
Linked vertex stage:\r
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
/*@*/\r
/* *@/*/\r
//@\r
+\r
+#define A int q1 = \ 1\r
+#define B int q2 = \1\r
+#define C int q3 = $ 1\r
+#define D int q4 = @ 1\r
+\r
+int a1 = \ 4; // ERROR\r
+int a2 = @ 3; // ERROR\r
+int a3 = $4; // ERROR\r
+int a4 = a2\; // ERROR\r
+\r
+A;\r
+B;\r
+C;\r
+D;\r
+\r
+# \\r
+\r
+# \\r
+ error bad continuation
\ No newline at end of file
// source have to figure out how to create revision.h just to get a build\r
// going. However, if it is not updated, it can be a version behind.\r
\r
-#define GLSLANG_REVISION "24518"\r
-#define GLSLANG_DATE "2013/12/13 11:38:43"\r
+#define GLSLANG_REVISION "24522"\r
+#define GLSLANG_DATE "2013/12/13 12:26:54"\r
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);
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()
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)
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);
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') ||