From ceb06238230424c86427319cbc01097e0703d235 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 3 Jun 2013 04:15:57 +0000 Subject: [PATCH] Fix another problem with undefined macros needing to evaluate to 0 within a preprocessor expression, but not outside a preprocessor expression. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21815 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/cppSimple.vert | 52 ++++++++++++ glslang/MachineIndependent/preprocessor/cpp.c | 79 +++++++++++++------ glslang/MachineIndependent/preprocessor/cpp.h | 2 +- .../MachineIndependent/preprocessor/scanner.c | 2 +- 4 files changed, 107 insertions(+), 28 deletions(-) diff --git a/Test/cppSimple.vert b/Test/cppSimple.vert index f26c3076..2dd9c356 100644 --- a/Test/cppSimple.vert +++ b/Test/cppSimple.vert @@ -68,3 +68,55 @@ sum += 0.05; // sum should be 987600301.7 gl_Position = vec4(sum); } + +#define A 0 +#define B 0 +#define C 0 + +#if (A == B) || (A == C) +#error good1 +#endif + +#if A == B || (A == C) +#error good2 +#endif + +#if (A == B || (A == C)) +#error good3 +#endif + +#if (AA == BB) || (AA == CC) +#error good4 +#endif + +#if AA == BB || (AA == CC) +#error good5 +#endif + +#if ((AA == BB || (AA == CC))) +#error good6 +#endif + +#if (A == B || (A == C) +#error bad1 +#endif + +#if A == B || A == C) +#error bad2 +#endif + +#if (A == B || (A == C) +#error bad3 +#endif + +#if AA == BB) || (AA == CC) +#error bad4 +#endif + +#if AA == BB || (AA == CC +#error bad5 +#endif + +#if ((AA == BB || (AA == CC)))) +#error bad6 +#endif diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c index aba525ac..8f24b662 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.c +++ b/glslang/MachineIndependent/preprocessor/cpp.c @@ -477,24 +477,21 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } } else { - int macroReturn = MacroExpand(yylvalpp->sc_ident, yylvalpp); - if (macroReturn == 1) { - token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); - - return eval(token, prec, res, err, yylvalpp); - } else if (macroReturn == -1) { - *res = 0; - token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); - if (ShPpMacrosMustBeDefinedError()) - *err = 1; - - return token; - } else { + int macroReturn = MacroExpand(yylvalpp->sc_ident, yylvalpp, 1); + if (macroReturn == 0) { ShPpErrorToInfoLog("can't evaluate expression"); *err = 1; *res = 0; return token; + } else { + if (macroReturn == -1) { + if (ShPpMacrosMustBeDefinedError()) + *err = 1; + } + token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); + + return eval(token, prec, res, err, yylvalpp); } } } else if (token == CPP_INTCONSTANT) { @@ -531,7 +528,8 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) } } while (!*err) { - if (token == ')' || token == '\n') break; + if (token == ')' || token == '\n') + break; for (i = ALEN(binop) - 1; i >= 0; i--) { if (binop[i].token == token) break; @@ -931,7 +929,7 @@ static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp) { PushEofSrc(); ReadFromTokenStream(a, 0, 0); while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) { - if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp) == 1) + if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp, 0) == 1) continue; RecordToken(n, token, yylvalpp); } @@ -949,20 +947,26 @@ typedef struct MacroInputSrc { /* macro_scan --- ** return the next token for a macro expansion, handling macro args */ -static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) { +static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) +{ MacroInputSrc* in = (MacroInputSrc*)inInput; int i; int token = ReadToken(in->mac->body, yylvalpp); if (token == CPP_IDENTIFIER) { for (i = in->mac->argc-1; i>=0; i--) - if (in->mac->args[i] == yylvalpp->sc_ident) break; + if (in->mac->args[i] == yylvalpp->sc_ident) + break; if (i >= 0) { ReadFromTokenStream(in->args[i], yylvalpp->sc_ident, 0); + return cpp->currentInput->scan(cpp->currentInput, yylvalpp); } } - if (token > 0) return token; + + if (token > 0) + return token; + in->mac->busy = 0; cpp->currentInput = in->base.prev; if (in->args) { @@ -975,6 +979,21 @@ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) { return cpp->currentInput->scan(cpp->currentInput, yylvalpp); } // macro_scan +// return a zero, for scanning a macro that was never defined +static int zero_scan(InputSrc *inInput, yystypepp * yylvalpp) +{ + MacroInputSrc* in = (MacroInputSrc*)inInput; //?? need to free this? + + strcpy(yylvalpp->symbol_name, "0"); + yylvalpp->sc_int = 0; + + // pop input + cpp->currentInput = in->base.prev; + free(in); + + return CPP_INTCONSTANT; +} + /* MacroExpand ** Check an identifier (atom) to see if it is a macro that should be expanded. ** If it is, push an InputSrc that will produce the appropriate expansion @@ -983,7 +1002,7 @@ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) { ** expand to 0 and return -1. ** Otherwise, return 0. */ -int MacroExpand(int atom, yystypepp * yylvalpp) +int MacroExpand(int atom, yystypepp* yylvalpp, int expandUndef) { Symbol *sym = LookUpSymbol(macros, atom); MacroInputSrc *in; @@ -1015,19 +1034,27 @@ int MacroExpand(int atom, yystypepp * yylvalpp) return 1; } - if (! sym || sym->details.mac.undef) - - return -1; - - else if (sym->details.mac.busy) - + if (sym && sym->details.mac.busy) return 0; // no recursive expansions in = (MacroInputSrc*)malloc(sizeof(*in)); memset(in, 0, sizeof(*in)); - in->base.scan = macro_scan; in->base.line = cpp->currentInput->line; in->base.name = cpp->currentInput->name; + + if ((! sym || sym->details.mac.undef)) { + if (expandUndef) { + // push input + in->base.scan = zero_scan; + in->base.prev = cpp->currentInput; + cpp->currentInput = &in->base; + + return -1; + } else + return 0; + } + + in->base.scan = macro_scan; in->mac = &sym->details.mac; if (sym->details.mac.args) { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); diff --git a/glslang/MachineIndependent/preprocessor/cpp.h b/glslang/MachineIndependent/preprocessor/cpp.h index 8ea1f76e..aa8b6858 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.h +++ b/glslang/MachineIndependent/preprocessor/cpp.h @@ -96,7 +96,7 @@ typedef struct MacroSymbol { int InitCPP(void); int FinalCPP(void); int readCPPline(yystypepp * yylvalpp); -int MacroExpand(int atom, yystypepp * yylvalpp); +int MacroExpand(int atom, yystypepp * yylvalpp, int expandUndef); #ifdef __cplusplus extern "C" { diff --git a/glslang/MachineIndependent/preprocessor/scanner.c b/glslang/MachineIndependent/preprocessor/scanner.c index 39741d9e..3c30c116 100644 --- a/glslang/MachineIndependent/preprocessor/scanner.c +++ b/glslang/MachineIndependent/preprocessor/scanner.c @@ -749,7 +749,7 @@ int yylex_CPP(char* buf, int maxSize) } cpp->previous_token = token; // expand macros - if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp) == 1) { + if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp, 0) == 1) { cpp->notAVersionToken = 1; continue; }