ERROR: 0:46: 'xyxwx' : illegal vector field selection \r
ERROR: 0:46: 'xyxwx' : illegal vector field selection \r
ERROR: 0:66: '#define' : Macro redefined; different substitutions: BIG\r
-ERROR: 0:79: '' : missing #endif \r
-ERROR: 4 compilation errors. No code generated.\r
+ERROR: 0:81: 'preprocessor evaluation' : bad expression \r
+ERROR: 0:81: '#if' : unexpected tokens following directive \r
+ERROR: 0:82: '#error' : good macro \r
+ERROR: 0:89: 'macro expansion' : unexpected '#' foobar\r
+ERROR: 0:90: 'preprocessor evaluation' : bad expression \r
+ERROR: 0:94: 'macro expansion' : unexpected '#' foobar\r
+ERROR: 0:95: 'preprocessor evaluation' : bad expression \r
+ERROR: 0:100: 'preprocessor evaluation' : bad expression \r
+ERROR: 0:100: '#if' : unexpected tokens following directive \r
+ERROR: 0:103: 'macro expansion' : unexpected '#' foobar\r
+ERROR: 0:103: 'preprocessor evaluation' : undefined macro in expression \r
+ERROR: 0:103: '#if' : unexpected tokens following directive \r
+ERROR: 0:104: '' : missing #endif \r
+ERROR: 16 compilation errors. No code generated.\r
\r
\r
ERROR: node is still EOpNull!\r
0:47 1 (const int)\r
0:47 Constant:\r
0:47 3.000000\r
+0:97 Sequence\r
+0:97 move second child to first child (highp float)\r
+0:97 'c' (highp float)\r
+0:98 Constant:\r
+0:98 3.300000\r
0:? Linker Objects\r
0:? 'sum' (highp float)\r
+0:? 'c' (highp float)\r
0:? 'gl_VertexID' (gl_VertexId highp int)\r
0:? 'gl_InstanceID' (gl_InstanceId highp int)\r
\r
ERROR: 0:89: '#error' : good4 \r
ERROR: 0:93: '#error' : good5 \r
ERROR: 0:97: '#error' : good6 \r
-ERROR: 0:101: 'preprocessor' : expected ')' \r
+ERROR: 0:101: 'preprocessor evaluation' : expected ')' \r
ERROR: 0:101: '#error' : bad1 \r
ERROR: 0:104: '#if' : unexpected tokens following directive \r
ERROR: 0:105: '#error' : bad2 \r
-ERROR: 0:109: 'preprocessor' : expected ')' \r
+ERROR: 0:109: 'preprocessor evaluation' : expected ')' \r
ERROR: 0:109: '#error' : bad3 \r
ERROR: 0:112: '#if' : unexpected tokens following directive \r
ERROR: 0:113: '#error' : bad4 \r
-ERROR: 0:117: 'preprocessor' : expected ')' \r
+ERROR: 0:117: 'preprocessor evaluation' : expected ')' \r
ERROR: 0:117: '#error' : bad5 \r
ERROR: 0:120: '#if' : unexpected tokens following directive \r
ERROR: 0:121: '#error' : bad6 \r
ERROR: 0:196: '#define' : Macro redefined; different argument names: m9\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
+ERROR: 0:210: '#' : invalid directive \r
+ERROR: 0:211: '#' : invalid directive \r
+ERROR: 0:212: '#' : invalid directive \r
+ERROR: 0:213: '#' : invalid directive \r
+ERROR: 0:214: '#' : invalid directive \r
+ERROR: 0:215: '#' : invalid directive \r
+ERROR: 0:224: '#pragma' : optimize pragma syntax is incorrect \r
+ERROR: 0:225: '#pragma' : optimize pragma syntax is incorrect \r
+ERROR: 0:226: '#pragma' : debug pragma syntax is incorrect \r
+ERROR: 0:227: '#pragma' : debug pragma syntax is incorrect \r
+ERROR: 0:229: '#pragma' : optimize pragma syntax is incorrect \r
+ERROR: 0:230: '#pragma' : debug pragma syntax is incorrect \r
+ERROR: 0:233: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:235: 'line continuation' : not supported for this version or the enabled extensions \r
+ERROR: 0:236: '#error' : good continuation \r
+ERROR: 0:238: '#' : invalid directive: flizbit\r
+ERROR: 0:242: '#' : invalid directive: directive\r
+ERROR: 0:246: '' : missing #endif \r
+ERROR: 62 compilation errors. No code generated.\r
\r
\r
ERROR: node is still EOpNull!\r
#define BIGARGS3(aonthanotehu, bonthanotehu, conthanotehu, donthanotehu, eonthanotehu, fonthanotehu, gonthanotehu, honthanotehu, ionthanotehu, jonthanotehu, konthanotehu) jonthanotehu
#define BIGARGS4(aonthanotehu, bonthanotehu, conthanotehu, donthanotehu, eonthanotehu, fonthanotehu, gonthanotehu, honthanotehu, ionthanotehu, jonthanotehu, konthanotehu) jonthanotehu
+
+#define foobar(a, b) a + b
+
+#if foobar(1.1, 2.2)
+#error good macro
+#else
+#error bad macro
+#endif
+
+#if foobar(1
+;
+#
+#
+#endif
+#if foobar(1,
+;
+#
+#
+#endif
+float c = foobar(1.1, 2.2
+ );
+#if foobar(1.1, 2.2
+)
+#if foobar(1.1, 2.2
+
#if 0
// ERROR, EOF
\ No newline at end of file
}
#define A 0
-#define B 0
-#define C 0
+# define B 0
+ # define C 0
#if (A == B) || (A == C)
#error good1
#undef __VERSION__
#undef GL_ARB_texture_rectangle
+#
+ #
+ #
+##
+# #
+# 0x25
+####
+####ff
+#########ff fg 0x25
+#pragma
+#pragma(aoent)
+ # pragma
+#pragma STDGL
+#pragma optimize( on)
+#pragma optimize(off)
+#pragma debug( on)
+#pragma debug(off )
+#pragma optimize( on) anoteun
+#pragma optimize(off
+#pragma debug( on) (
+#pragma debug(off aoeua)
+#pragma optimize( on)
+#pragma optimize(off,)
+#pragma debug( on, aoeu)
+#pragma debugoff )
+#pragma aontheu natoeh uantheo uasotea noeahuonea uonethau onethuanoeth aunotehau noeth anthoeua anoethuantoeh uantoehu natoehu naoteh unotaehu noethua onetuh aou
+# \
+
+# \
+ error good continuation
+
+#flizbit
+
+#define directive error
+
+#directive directive was expanded
+
#if 1
#else
// ERROR, missing #endif
\ No newline at end of file
error(getCurrentLoc(), "", "", s, "");
}
-void TParseContext::handlePragma(const char **tokens, int numTokens)
+void TParseContext::handlePragma(TSourceLoc loc, const TVector<TString>& tokens)
{
- if (!strcmp(tokens[0], "optimize")) {
- if (numTokens != 4) {
- error(getCurrentLoc(), "optimize pragma syntax is incorrect", "#pragma", "");
+ if (tokens.size() == 0)
+ return;
+
+ if (tokens[0].compare("optimize") == 0) {
+ if (tokens.size() != 4) {
+ error(loc, "optimize pragma syntax is incorrect", "#pragma", "");
return;
}
- if (strcmp(tokens[1], "(")) {
- error(getCurrentLoc(), "\"(\" expected after 'optimize' keyword", "#pragma", "");
+ if (tokens[1].compare("(") != 0) {
+ error(loc, "\"(\" expected after 'optimize' keyword", "#pragma", "");
return;
}
- if (!strcmp(tokens[2], "on"))
+ if (tokens[2].compare("on") == 0)
contextPragma.optimize = true;
- else if (!strcmp(tokens[2], "off"))
+ else if (tokens[2].compare("off") == 0)
contextPragma.optimize = false;
else {
- error(getCurrentLoc(), "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
+ error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
return;
}
- if (strcmp(tokens[3], ")")) {
- error(getCurrentLoc(), "\")\" expected to end 'optimize' pragma", "#pragma", "");
+ if (tokens[3].compare(")") != 0) {
+ error(loc, "\")\" expected to end 'optimize' pragma", "#pragma", "");
return;
}
- } else if (!strcmp(tokens[0], "debug")) {
- if (numTokens != 4) {
- error(getCurrentLoc(), "debug pragma syntax is incorrect", "#pragma", "");
+ } else if (tokens[0].compare("debug") == 0) {
+ if (tokens.size() != 4) {
+ error(loc, "debug pragma syntax is incorrect", "#pragma", "");
return;
}
- if (strcmp(tokens[1], "(")) {
- error(getCurrentLoc(), "\"(\" expected after 'debug' keyword", "#pragma", "");
+ if (tokens[1].compare("(") != 0) {
+ error(loc, "\"(\" expected after 'debug' keyword", "#pragma", "");
return;
}
- if (!strcmp(tokens[2], "on"))
+ if (tokens[2].compare("on") == 0)
contextPragma.debug = true;
- else if (!strcmp(tokens[2], "off"))
+ else if (tokens[2].compare("off") == 0)
contextPragma.debug = false;
else {
- error(getCurrentLoc(), "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
+ error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
return;
}
- if (strcmp(tokens[3], ")")) {
- error(getCurrentLoc(), "\")\" expected to end 'debug' pragma", "#pragma", "");
+ if (tokens[3].compare(")") != 0) {
+ error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
return;
}
- } else {
-
-#ifdef PRAGMA_TABLE
- //
- // implementation specific pragma
- // use parseContext.contextPragma.pragmaTable to store the information about pragma
- // For now, just ignore the pragma that the implementation cannot recognize
- // An Example of one such implementation for a pragma that has a syntax like
- // #pragma pragmaname(pragmavalue)
- // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
- //
- if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
- TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable;
- TPragmaTable::iterator iter;
- iter = pragmaTable.find(TString(tokens[0]));
- if (iter != pragmaTable.end()) {
- iter->second = tokens[2];
- } else {
- pragmaTable[tokens[0]] = tokens[2];
- }
- } else if (numTokens >= 2) {
- TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable;
- TPragmaTable::iterator iter;
- iter = pragmaTable.find(TString(tokens[0]));
- if (iter != pragmaTable.end()) {
- iter->second = tokens[1];
- } else {
- pragmaTable[tokens[0]] = tokens[1];
- }
- }
-#endif // PRAGMA_TABLE
}
}
void lineContinuationCheck(TSourceLoc);
bool builtInName(const TString&);
- void handlePragma(const char **tokens, int numTokens);
+ void handlePragma(TSourceLoc, const TVector<TString>&);
TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
void checkIndex(TSourceLoc, const TType&, int& index);
#define ALEN(A) (sizeof(A)/sizeof(A[0]))
-int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken * ppToken)
+int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken* ppToken)
{
int i, val;
Symbol *s;
token = currentInput->scan(this, currentInput, ppToken);
}
if (token != CPP_IDENTIFIER) {
- parseContext.error(ppToken->loc, "incorrect directive, expected identifier", "preprocessor", "");
+ parseContext.error(ppToken->loc, "incorrect directive, expected identifier", "preprocessor evaluation", "");
*err = 1;
*res = 0;
token = currentInput->scan(this, currentInput, ppToken);
if (needclose) {
if (token != ')') {
- parseContext.error(ppToken->loc, "#else after #else", "", "");
+ parseContext.error(ppToken->loc, "#else after #else", "preprocessor evaluation", "");
*err = 1;
*res = 0;
} else {
int macroReturn = MacroExpand(ppToken->atom, ppToken, 1);
if (macroReturn == 0) {
- parseContext.error(ppToken->loc, "can't evaluate expression", "preprocessor", "");
+ parseContext.error(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
*err = 1;
*res = 0;
if (macroReturn == -1) {
if (parseContext.profile == EEsProfile) {
if (parseContext.messages & EShMsgRelaxedErrors)
- parseContext.warn(ppToken->loc, "undefined macro in expression not allowed in es profile", "preprocessor", "");
+ parseContext.warn(ppToken->loc, "undefined macro in expression not allowed in es profile", "preprocessor evaluation", "");
else {
- parseContext.error(ppToken->loc, "undefined macro in expression", "preprocessor", "");
+ parseContext.error(ppToken->loc, "undefined macro in expression", "preprocessor evaluation", "");
*err = 1;
}
token = eval(token, MIN_PREC, res, err, ppToken);
if (!*err) {
if (token != ')') {
- parseContext.error(ppToken->loc, "expected ')'", "preprocessor", "");
+ parseContext.error(ppToken->loc, "expected ')'", "preprocessor evaluation", "");
*err = 1;
*res = 0;
token = eval(token, UNARY, res, err, ppToken);
*res = unop[i].op(*res);
} else {
- parseContext.error(ppToken->loc, "", "bad expression", "");
+ parseContext.error(ppToken->loc, "bad expression", "preprocessor evaluation", "");
*err = 1;
*res = 0;
return '\n';
}
-int TPpContext::CPPpragma(TPpToken * ppToken)
+int TPpContext::CPPpragma(TPpToken* ppToken)
{
char SrcStrName[2];
- char** allTokens;
int tokenCount = 0;
int maxTokenCount = 10;
const char* SrcStr;
- int i;
+ TVector<TString> tokens;
+ TSourceLoc loc = ppToken->loc; // because we go to the next line before processing
int token = currentInput->scan(this, currentInput, ppToken);
-
- if (token=='\n') {
- parseContext.error(ppToken->loc, "must be followed by pragma arguments", "#pragma", "");
- return token;
- }
-
- allTokens = (char**)malloc(sizeof(char*) * maxTokenCount);
-
- while (token != '\n') {
- if (tokenCount >= maxTokenCount) {
- maxTokenCount *= 2;
- allTokens = (char**)realloc((char**)allTokens, sizeof(char*) * maxTokenCount);
- }
+ while (token != '\n' && token != EOF) {
switch (token) {
case CPP_IDENTIFIER:
SrcStr = GetAtomString(ppToken->atom);
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
+ tokens.push_back(SrcStr);
break;
case CPP_INTCONSTANT:
case CPP_UINTCONSTANT:
case CPP_FLOATCONSTANT:
case CPP_DOUBLECONSTANT:
SrcStr = ppToken->name;
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
+ tokens.push_back(SrcStr);
break;
- case EOF:
- parseContext.error(ppToken->loc, "directive must end with a newline", "#pragma", "");
- return token;
default:
SrcStrName[0] = token;
SrcStrName[1] = '\0';
- allTokens[tokenCount] = (char*)malloc(2);
- strcpy(allTokens[tokenCount++], SrcStrName);
+ tokens.push_back(SrcStrName);
}
token = currentInput->scan(this, currentInput, ppToken);
}
- currentInput->ungetch(this, currentInput, token, ppToken);
- parseContext.handlePragma((const char**)allTokens, tokenCount);
- token = currentInput->scan(this, currentInput, ppToken);
-
- for (i = 0; i < tokenCount; ++i) {
- free (allTokens[i]);
- }
- free (allTokens);
+ if (token == EOF)
+ parseContext.error(loc, "directive must end with a newline", "#pragma", "");
+ else
+ parseContext.handlePragma(loc, tokens);
return token;
-} // CPPpragma
+}
// This is just for error checking: the version and profile are decided before preprocessing starts
int TPpContext::CPPversion(TPpToken * ppToken)
} else if (ppToken->atom == extensionAtom) {
token = CPPextension(ppToken);
} else {
- parseContext.error(ppToken->loc, "Invalid Directive", "#", GetAtomString(ppToken->atom));
+ parseContext.error(ppToken->loc, "invalid directive:", "#", GetAtomString(ppToken->atom));
}
- }
+ } else if (token != '\n' && token > 0)
+ parseContext.error(ppToken->loc, "invalid directive", "#", "");
while (token != '\n' && token != 0 && token != EOF)
token = currentInput->scan(this, currentInput, ppToken);
{
Symbol *sym = LookUpSymbol(atom);
MacroInputSrc *in;
- int i, j, token;
+ int token;
int depth = 0;
if (atom == __LINE__Atom) {
return -1;
}
+ TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
in->scan = macro_scan;
in->mac = &sym->mac;
if (sym->mac.args) {
return 0;
}
in->args.resize(in->mac->argc);
- for (i = 0; i < in->mac->argc; i++)
+ for (int i = 0; i < in->mac->argc; i++)
in->args[i] = new TokenStream;
- i = 0;
- j = 0;
+ int arg = 0;
+ bool tokenRecorded = false;
do {
depth = 0;
while (1) {
token = currentInput->scan(this, currentInput, ppToken);
if (token <= 0) {
- parseContext.error(ppToken->loc, "EOF in macro", "preprocessor", GetAtomString(atom));
-
+ parseContext.error(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
+ return 1;
+ }
+ if (token == '\n') {
+ // TODO: Preprocessor functionality: Correctly handle new line and escaped new line, for expansions that are both in and not in another preprocessor directive
+
+ //if (in a pp line) {
+ // parseContext.error(loc, "missing ')':", "macro expansion", GetAtomString(atom));
+ // return 1;
+ //}
+ continue;
+ }
+ if (token == '#') {
+ parseContext.error(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
return 1;
}
- if ((in->mac->argc==0) && (token!=')')) break;
- if (depth == 0 && (token == ',' || token == ')')) break;
- if (token == '(') depth++;
- if (token == ')') depth--;
- RecordToken(in->args[i], token, ppToken);
- j=1;
+ if (in->mac->argc == 0 && token != ')')
+ break;
+ if (depth == 0 && (token == ',' || token == ')'))
+ break;
+ if (token == '(')
+ depth++;
+ if (token == ')')
+ depth--;
+ RecordToken(in->args[arg], token, ppToken);
+ tokenRecorded = true;
}
if (token == ')') {
- if ((in->mac->argc==1) &&j==0)
+ if (in->mac->argc == 1 && tokenRecorded == 0)
break;
- i++;
+ arg++;
break;
}
- i++;
- } while (i < in->mac->argc);
+ arg++;
+ } while (arg < in->mac->argc);
- if (i < in->mac->argc)
- parseContext.error(ppToken->loc, "Too few args in Macro", "preprocessor", GetAtomString(atom));
+ if (arg < in->mac->argc)
+ parseContext.error(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
else if (token != ')') {
depth=0;
while (token >= 0 && (depth > 0 || token != ')')) {
}
if (token <= 0) {
- parseContext.error(ppToken->loc, "EOF in macro", "preprocessor", GetAtomString(atom));
-
+ parseContext.error(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
return 1;
}
- parseContext.error(ppToken->loc, "Too many args in Macro", "preprocessor", GetAtomString(atom));
+ parseContext.error(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
}
- for (i = 0; i < in->mac->argc; i++)
+ for (int i = 0; i < in->mac->argc; i++)
in->args[i] = PrescanMacroArg(in->args[i], ppToken);
}