From 52ac67e913f9a3c7fbf1002b6e55c5a84321415a Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sun, 5 May 2013 23:46:22 +0000 Subject: [PATCH] Make the PP report an error on undefined macro in "#if ..." for ES profiles, unless relaxed error checking is requested. Still works as normal CPP on non-ES. Also, improved error reporting in general for the PP. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21417 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- StandAlone/StandAlone.cpp | 13 +- Test/cppSimple.vert | 9 +- glslang/MachineIndependent/glslang.l | 47 ++-- .../MachineIndependent/preprocessor/atom.c | 12 +- glslang/MachineIndependent/preprocessor/cpp.c | 263 +++++++++++------- glslang/MachineIndependent/preprocessor/cpp.h | 8 +- .../MachineIndependent/preprocessor/scanner.c | 54 ++-- .../MachineIndependent/preprocessor/scanner.h | 2 +- .../MachineIndependent/preprocessor/symbols.c | 2 +- .../MachineIndependent/preprocessor/tokens.c | 2 +- glslang/Public/ShaderLang.h | 3 +- 11 files changed, 252 insertions(+), 163 deletions(-) diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index e66a315b6..cf58ed695 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -74,7 +74,7 @@ ShBinding FixedAttributeBindings[] = { ShBindingTable FixedAttributeTable = { 3, FixedAttributeBindings }; static EShLanguage FindLanguage(char *lang); -bool CompileFile(const char *fileName, ShHandle, int, const TBuiltInResource*); +bool CompileFile(const char *fileName, ShHandle, int options, const TBuiltInResource*); void usage(); void FreeFileData(char **data); char** ReadFileData(const char *fileName); @@ -143,6 +143,9 @@ int C_DECL main(int argc, char* argv[]) case 'l': debugOptions |= EDebugOpMemoryLeakMode; break; + case 'r': + debugOptions |= EDebugOpRelaxedErrors; + break; case 's': debugOptions |= EDebugOpSuppressInfolog; break; @@ -261,9 +264,12 @@ bool CompileFile(const char *fileName, ShHandle compiler, int debugOptions, cons if (!data) return false; + EShMessages messages = EShMsgDefault; + if (debugOptions & EDebugOpRelaxedErrors) + messages = (EShMessages)(messages | EShMsgRelaxedErrors); for (int i = 0; i < ((debugOptions & EDebugOpMemoryLeakMode) ? 100 : 1); ++i) { for (int j = 0; j < ((debugOptions & EDebugOpMemoryLeakMode) ? 100 : 1); ++j) - ret = ShCompile(compiler, data, OutputMultipleStrings, EShOptNone, resources, debugOptions, 100, false, EShMsgDefault); + ret = ShCompile(compiler, data, OutputMultipleStrings, EShOptNone, resources, debugOptions, 100, false, messages); #ifdef _WIN32 if (debugOptions & EDebugOpMemoryLeakMode) { @@ -290,7 +296,8 @@ void usage() "-a: assembly dump (LLVM IR)\n" "-d: delay end (keeps output up in debugger, WIN32)\n" "-l: memory leak mode\n" - "-s: silent mode (no info log)\n"); + "-s: silent mode (no info log)\n" + "-r: relaxed semantic error checking mode\n"); } #ifndef _WIN32 diff --git a/Test/cppSimple.vert b/Test/cppSimple.vert index 07c5628f4..f26c3076c 100644 --- a/Test/cppSimple.vert +++ b/Test/cppSimple.vert @@ -32,7 +32,7 @@ sum += 4000.0; sum += 50000.0; #endif -#ifndef(OFF) +#ifndef OFF //yes sum += 600000.0; #else @@ -58,6 +58,13 @@ sum += 80000000.0; sum += 900000000.0; #endif +#if NEVER_DEFINED +//no +sum += 0.04; +#else +sum += 0.05; +#endif + // sum should be 987600301.7 gl_Position = vec4(sum); } diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l index 29b114bdf..3c37f99e3 100644 --- a/glslang/MachineIndependent/glslang.l +++ b/glslang/MachineIndependent/glslang.l @@ -951,14 +951,14 @@ int PaParseComment(int& lineno, TParseContext& parseContextLocal) extern "C" { -void CPPDebugLogMsg(const char *msg) +void ShPpDebugLogMsg(const char *msg) { TParseContext& pc = *((TParseContext *)cpp->pC); pc.infoSink.debug.message(EPrefixNone, msg); } -void CPPWarningToInfoLog(const char *msg) +void ShPpWarningToInfoLog(const char *msg) { TParseContext& pc = *((TParseContext *)cpp->pC); @@ -966,20 +966,31 @@ void CPPWarningToInfoLog(const char *msg) pc.infoSink.info.message(EPrefixWarning, msg, yylineno); } -void CPPShInfoLogMsg(const char *msg) +void ShPpErrorToInfoLog(const char *msg) { TParseContext& pc = *((TParseContext *)cpp->pC); - pc.error(yylineno,"", "",msg,""); + pc.error(yylineno, "", "Preprocessor", msg, ""); GlobalParseContext->recover(); } -void CPPErrorToInfoLog(const char *msg) +// return 1 if error +// return 0 if no error +int ShPpMacrosMustBeDefinedError() { TParseContext& pc = *((TParseContext *)cpp->pC); - pc.error(yylineno, "CPP error:", "", msg, ""); - GlobalParseContext->recover(); + if (pc.profile == EEsProfile) { + if (pc.messages & EShMsgRelaxedErrors) + ShPpWarningToInfoLog("undefined macro in expression not allowed in es profile"); + else { + ShPpErrorToInfoLog("undefined macro in expression"); + + return 1; + } + } + + return 0; } void SetLineNumber(int line) @@ -1021,12 +1032,12 @@ void HandlePragma(const char **tokens, int numTokens) if (!strcmp(tokens[0], "optimize")) { if (numTokens != 4) { - CPPShInfoLogMsg("optimize pragma syntax is incorrect"); + ShPpErrorToInfoLog("optimize pragma syntax is incorrect"); return; } if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword"); + ShPpErrorToInfoLog("\"(\" expected after 'optimize' keyword"); return; } @@ -1035,22 +1046,22 @@ void HandlePragma(const char **tokens, int numTokens) else if (!strcmp(tokens[2], "off")) pc.contextPragma.optimize = false; else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); + ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); return; } if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma"); + ShPpErrorToInfoLog("\")\" expected to end 'optimize' pragma"); return; } } else if (!strcmp(tokens[0], "debug")) { if (numTokens != 4) { - CPPShInfoLogMsg("debug pragma syntax is incorrect"); + ShPpErrorToInfoLog("debug pragma syntax is incorrect"); return; } if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'debug' keyword"); + ShPpErrorToInfoLog("\"(\" expected after 'debug' keyword"); return; } @@ -1059,12 +1070,12 @@ void HandlePragma(const char **tokens, int numTokens) else if (!strcmp(tokens[2], "off")) pc.contextPragma.debug = false; else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma"); + ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'debug' pragma"); return; } if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'debug' pragma"); + ShPpErrorToInfoLog("\")\" expected to end 'debug' pragma"); return; } } else { @@ -1153,7 +1164,7 @@ TBehavior GetBehavior(const char* behavior) else if (!strcmp("warn", behavior)) return EBhWarn; else { - CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str()); + ShPpErrorToInfoLog((TString("behavior '") + behavior + "' is not supported").c_str()); return EBhDisable; } } @@ -1168,7 +1179,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior) // special cased for all extension if (!strcmp(extName, "all")) { if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { - CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior"); + ShPpErrorToInfoLog("extension 'all' cannot have 'require' or 'enable' behavior"); return; } else { for (iter = pc.extensionBehavior.begin(); iter != pc.extensionBehavior.end(); ++iter) @@ -1179,7 +1190,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior) if (iter == pc.extensionBehavior.end()) { switch (behaviorVal) { case EBhRequire: - CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str()); + ShPpErrorToInfoLog((TString("extension '") + extName + "' is not supported").c_str()); break; case EBhEnable: case EBhWarn: diff --git a/glslang/MachineIndependent/preprocessor/atom.c b/glslang/MachineIndependent/preprocessor/atom.c index 3c9642c61..2f43c4809 100644 --- a/glslang/MachineIndependent/preprocessor/atom.c +++ b/glslang/MachineIndependent/preprocessor/atom.c @@ -470,14 +470,14 @@ static int FindHashLoc(AtomTable *atable, const char *s) char str[200]; sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***", HASH_TABLE_MAX_COLLISIONS); - CPPShInfoLogMsg(str); + ShPpErrorToInfoLog(str); sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta); - CPPShInfoLogMsg(str); + ShPpErrorToInfoLog(str); for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) { sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"", ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value)); - CPPShInfoLogMsg(str); + ShPpErrorToInfoLog(str); } } return -1; @@ -720,14 +720,14 @@ void PrintAtomTable(AtomTable *atable) for (ii = 0; ii < atable->nextFree; ii++) { sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]); - CPPDebugLogMsg(str); + ShPpDebugLogMsg(str); } sprintf(str, "Hash table: size=%d, entries=%d, collisions=", atable->htable.size, atable->htable.entries); - CPPDebugLogMsg(str); + ShPpDebugLogMsg(str); for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) { sprintf(str, " %d", atable->htable.counts[ii]); - CPPDebugLogMsg(str); + ShPpDebugLogMsg(str); } } // PrintAtomTable diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c index 577bfbb86..aba525ac9 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.c +++ b/glslang/MachineIndependent/preprocessor/cpp.c @@ -186,7 +186,7 @@ int FreeCPP(void) int FinalCPP(void) { if (cpp->ifdepth) - CPPErrorToInfoLog("#if mismatch"); + ShPpErrorToInfoLog("missing #endif"); return 1; } @@ -200,7 +200,7 @@ static int CPPdefine(yystypepp * yylvalpp) memset(&mac, 0, sizeof(mac)); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != CPP_IDENTIFIER) { - CPPErrorToInfoLog("#define"); + ShPpErrorToInfoLog("#define not followed by macro name"); return token; } name = yylvalpp->sc_ident; @@ -210,9 +210,11 @@ static int CPPdefine(yystypepp * yylvalpp) argc = 0; do { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); - if (argc == 0 && token == ')') break; + if (argc == 0 && token == ')') + break; if (token != CPP_IDENTIFIER) { - CPPErrorToInfoLog("#define"); + ShPpErrorToInfoLog("#define: bad argument"); + return token; } if (argc < MAX_MACRO_ARGS) @@ -220,7 +222,8 @@ static int CPPdefine(yystypepp * yylvalpp) token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } while (token == ','); if (token != ')') { - CPPErrorToInfoLog("#define"); + ShPpErrorToInfoLog("#define: missing parenthesis"); + return token; } mac.argc = argc; @@ -245,7 +248,8 @@ static int CPPdefine(yystypepp * yylvalpp) if (symb) { if (!symb->details.mac.undef) { // already defined -- need to make sure they are identical - if (symb->details.mac.argc != mac.argc) goto error; + if (symb->details.mac.argc != mac.argc) + goto error; for (argc=0; argc < mac.argc; argc++) if (symb->details.mac.args[argc] != mac.args[argc]) goto error; @@ -259,13 +263,14 @@ static int CPPdefine(yystypepp * yylvalpp) if (token != old_token || yylvalpp->sc_int != old_lval) { error: StoreStr("Macro Redefined"); - StoreStr(GetStringOfAtom(atable,name)); - message=GetStrfromTStr(); + StoreStr(GetStringOfAtom(atable, name)); + message = GetStrfromTStr(); DecLineNumber(); - CPPShInfoLogMsg(message); + ShPpErrorToInfoLog(message); IncLineNumber(); ResetTString(); - break; } + break; + } } while (token > 0); } //FreeMacro(&symb->details.mac); @@ -275,6 +280,7 @@ static int CPPdefine(yystypepp * yylvalpp) symb = AddSymbol(&dummyLoc, macros, name, MACRO_S); } symb->details.mac = mac; + return '\n'; } // CPPdefine @@ -282,21 +288,26 @@ static int CPPundef(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); Symbol *symb; - if(token == '\n'){ - CPPErrorToInfoLog("#undef"); + if (token == '\n') { + ShPpErrorToInfoLog("#undef must be followed by macro name"); + return token; } - if (token != CPP_IDENTIFIER) - goto error; + if (token != CPP_IDENTIFIER) { + ShPpErrorToInfoLog("#undef must be followed by macro name"); + + return token; + } + symb = LookUpSymbol(macros, yylvalpp->sc_ident); if (symb) { symb->details.mac.undef = 1; } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != '\n') { - error: - CPPErrorToInfoLog("#undef"); + ShPpErrorToInfoLog("#undef can only be followed by a single macro name"); } + return token; } // CPPundef @@ -344,7 +355,7 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp) // found the #else we are looking for token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != '\n') { - CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline"); + ShPpWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline"); while (token != '\n') token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } @@ -361,7 +372,7 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp) return CPPif(yylvalpp); } } else if((atom == elseAtom) && (!ChkCorrectElseNesting())) { - CPPErrorToInfoLog("#else after a #else"); + ShPpErrorToInfoLog("#else after #else"); cpp->CompileError = 1; } }; // end while @@ -436,6 +447,7 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) { int i, val; Symbol *s; + if (token == CPP_IDENTIFIER) { if (yylvalpp->sc_ident == definedAtom) { int needclose = 0; @@ -444,21 +456,46 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) needclose = 1; token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } - if (token != CPP_IDENTIFIER) - goto error; + if (token != CPP_IDENTIFIER) { + ShPpErrorToInfoLog("incorrect preprocessor directive"); + *err = 1; + *res = 0; + + return token; + } *res = (s = LookUpSymbol(macros, yylvalpp->sc_ident)) ? !s->details.mac.undef : 0; token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (needclose) { - if (token != ')') - goto error; + if (token != ')') { + ShPpErrorToInfoLog("missing ')'"); + *err = 1; + *res = 0; + + return token; + } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } - } else if (MacroExpand(yylvalpp->sc_ident, yylvalpp)) { - token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); - return eval(token, prec, res, err, yylvalpp); - } else { - goto error; + } 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 { + ShPpErrorToInfoLog("can't evaluate expression"); + *err = 1; + *res = 0; + + return token; + } } } else if (token == CPP_INTCONSTANT) { *res = yylvalpp->sc_int; @@ -467,8 +504,13 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); token = eval(token, MIN_PREC, res, err, yylvalpp); if (!*err) { - if (token != ')') - goto error; + if (token != ')') { + ShPpErrorToInfoLog("expected ')'"); + *err = 1; + *res = 0; + + return token; + } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } } else { @@ -481,7 +523,11 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) token = eval(token, UNARY, res, err, yylvalpp); *res = unop[i].op(*res); } else { - goto error; + ShPpErrorToInfoLog("bad expression"); + *err = 1; + *res = 0; + + return token; } } while (!*err) { @@ -497,11 +543,7 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) token = eval(token, binop[i].prec, res, err, yylvalpp); *res = binop[i].op(val, *res); } - return token; -error: - CPPErrorToInfoLog("incorrect preprocessor directive"); - *err = 1; - *res = 0; + return token; } // eval @@ -513,12 +555,12 @@ static int CPPif(yystypepp * yylvalpp) if (!cpp->ifdepth++) ifloc = *cpp->tokenLoc; if (cpp->ifdepth > MAX_IF_NESTING){ - CPPErrorToInfoLog("max #if nesting depth exceeded"); + ShPpErrorToInfoLog("max #if nesting depth exceeded"); return 0; } token = eval(token, MIN_PREC, &res, &err, yylvalpp); if (token != '\n') { - CPPWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline"); + ShPpWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline"); while (token != '\n') token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } @@ -533,18 +575,18 @@ static int CPPifdef(int defined, yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); int name = yylvalpp->sc_ident; - if(++cpp->ifdepth >MAX_IF_NESTING){ - CPPErrorToInfoLog("max #if nesting depth exceeded"); + if(++cpp->ifdepth > MAX_IF_NESTING){ + ShPpErrorToInfoLog("max #if nesting depth exceeded"); return 0; } cpp->elsetracker++; if (token != CPP_IDENTIFIER) { - defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef"); + defined ? ShPpErrorToInfoLog("#ifdef not followed by macro name") : ShPpErrorToInfoLog("#ifndef not followed by macro name"); } else { Symbol *s = LookUpSymbol(macros, name); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != '\n') { - CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline"); + ShPpWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline"); while (token != '\n') token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } @@ -557,9 +599,9 @@ static int CPPifdef(int defined, yystypepp * yylvalpp) static int CPPline(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); - if(token=='\n'){ + if (token=='\n') { DecLineNumber(); - CPPErrorToInfoLog("#line"); + ShPpErrorToInfoLog("#line must by followed by an integral literal"); IncLineNumber(); return token; } @@ -573,23 +615,21 @@ static int CPPline(yystypepp * yylvalpp) SetStringNumber(yylvalpp->sc_int); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if(token!='\n') - CPPErrorToInfoLog("#line"); + ShPpErrorToInfoLog("#line cannot be followed by more than two integral literals"); } - else if (token == '\n'){ + else if (token == '\n') + return token; - } - else{ - CPPErrorToInfoLog("#line"); - } - } - else{ - CPPErrorToInfoLog("#line"); - } + else + ShPpErrorToInfoLog("#line second argument can only be an integral literal"); + } else + ShPpErrorToInfoLog("#line first argument can only be an integral literal"); + return token; } -static int CPPerror(yystypepp * yylvalpp) { - +static int CPPerror(yystypepp * yylvalpp) +{ int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); const char *message; @@ -597,16 +637,16 @@ static int CPPerror(yystypepp * yylvalpp) { if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){ StoreStr(yylvalpp->symbol_name); }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){ - StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident)); + StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident)); }else { - StoreStr(GetStringOfAtom(atable,token)); + StoreStr(GetStringOfAtom(atable, token)); } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } DecLineNumber(); //store this msg into the shader's information log..set the Compile Error flag!!!! message=GetStrfromTStr(); - CPPShInfoLogMsg(message); + ShPpErrorToInfoLog(message); ResetTString(); cpp->CompileError=1; IncLineNumber(); @@ -626,7 +666,7 @@ static int CPPpragma(yystypepp * yylvalpp) if (token=='\n') { DecLineNumber(); - CPPErrorToInfoLog("#pragma"); + ShPpErrorToInfoLog("#pragma must be followed by pragma arguments"); IncLineNumber(); return token; } @@ -656,7 +696,7 @@ static int CPPpragma(yystypepp * yylvalpp) break; case -1: // EOF - CPPShInfoLogMsg("#pragma directive must end with a newline"); + ShPpErrorToInfoLog("#pragma directive must end with a newline"); return token; default: SrcStrName[0] = token; @@ -685,16 +725,16 @@ static int CPPversion(yystypepp * yylvalpp) int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (cpp->notAVersionToken == 1) - CPPShInfoLogMsg("#version must occur before any other statement in the program"); + ShPpErrorToInfoLog("#version must occur before any other statement in the program"); if(token=='\n'){ DecLineNumber(); - CPPErrorToInfoLog("#version"); + ShPpErrorToInfoLog("#version"); IncLineNumber(); return token; } if (token != CPP_INTCONSTANT) - CPPErrorToInfoLog("#version"); + ShPpErrorToInfoLog("#version"); yylvalpp->sc_int=atoi(yylvalpp->symbol_name); @@ -714,14 +754,14 @@ static int CPPversion(yystypepp * yylvalpp) else if (yylvalpp->sc_ident == esAtom) SetProfile(EEsProfile); else - CPPErrorToInfoLog("#version profile name"); + ShPpErrorToInfoLog("#version profile name"); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token == '\n') return token; else - CPPErrorToInfoLog("#version"); + ShPpErrorToInfoLog("#version"); } return token; @@ -735,25 +775,25 @@ static int CPPextension(yystypepp * yylvalpp) if(token=='\n'){ DecLineNumber(); - CPPShInfoLogMsg("extension name not specified"); + ShPpErrorToInfoLog("extension name not specified"); IncLineNumber(); return token; } if (token != CPP_IDENTIFIER) - CPPErrorToInfoLog("#extension"); + ShPpErrorToInfoLog("#extension"); strcpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident)); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != ':') { - CPPShInfoLogMsg("':' missing after extension name"); + ShPpErrorToInfoLog("':' missing after extension name"); return token; } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != CPP_IDENTIFIER) { - CPPShInfoLogMsg("behavior for extension not specified"); + ShPpErrorToInfoLog("behavior for extension not specified"); return token; } @@ -764,7 +804,7 @@ static int CPPextension(yystypepp * yylvalpp) return token; } else{ - CPPErrorToInfoLog("#extension"); + ShPpErrorToInfoLog("#extension"); } return token; } // CPPextension @@ -781,25 +821,25 @@ int readCPPline(yystypepp * yylvalpp) } else if (yylvalpp->sc_ident == elseAtom) { if (ChkCorrectElseNesting()) { if (! cpp->ifdepth) { - CPPErrorToInfoLog("#else mismatch"); + ShPpErrorToInfoLog("#else mismatch"); cpp->CompileError = 1; } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != '\n') { - CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline"); + ShPpWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline"); while (token != '\n') token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } token = CPPelse(0, yylvalpp); } else { - CPPErrorToInfoLog("#else after a #else"); + ShPpErrorToInfoLog("#else after a #else"); cpp->ifdepth = 0; cpp->notAVersionToken = 1; return 0; } } else if (yylvalpp->sc_ident == elifAtom) { if (!cpp->ifdepth){ - CPPErrorToInfoLog("#elif mismatch"); + ShPpErrorToInfoLog("#elif mismatch"); cpp->CompileError=1; } // this token is really a dont care, but we still need to eat the tokens @@ -811,7 +851,7 @@ int readCPPline(yystypepp * yylvalpp) cpp->elsedepth[cpp->elsetracker] = 0; --cpp->elsetracker; if (!cpp->ifdepth){ - CPPErrorToInfoLog("#endif mismatch"); + ShPpErrorToInfoLog("#endif mismatch"); cpp->CompileError=1; } else @@ -837,9 +877,9 @@ int readCPPline(yystypepp * yylvalpp) token = CPPextension(yylvalpp); } else { StoreStr("Invalid Directive"); - StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident)); + StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident)); message=GetStrfromTStr(); - CPPShInfoLogMsg(message); + ShPpErrorToInfoLog(message); ResetTString(); } } @@ -891,7 +931,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)) + if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp) == 1) continue; RecordToken(n, token, yylvalpp); } @@ -907,7 +947,7 @@ typedef struct MacroInputSrc { } MacroInputSrc; /* macro_scan --- -** return the next token for a macro expanion, handling macro args +** return the next token for a macro expansion, handling macro args */ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) { MacroInputSrc* in = (MacroInputSrc*)inInput; @@ -931,41 +971,58 @@ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp) { free(in->args); } free(in); + return cpp->currentInput->scan(cpp->currentInput, yylvalpp); } // macro_scan /* MacroExpand -** check an identifier (atom) to see if it a macro that should be expanded. +** 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 -** and return TRUE. If not, return FALSE. +** and return 1. +** If it is, but undefined, it should expand to 0, push an InputSrc that will +** expand to 0 and return -1. +** Otherwise, return 0. */ - int MacroExpand(int atom, yystypepp * yylvalpp) { - Symbol *sym = LookUpSymbol(macros, atom); - MacroInputSrc *in; - int i,j, token, depth=0; + Symbol *sym = LookUpSymbol(macros, atom); + MacroInputSrc *in; + int i, j, token; + int depth = 0; const char *message; + if (atom == __LINE__Atom) { yylvalpp->sc_int = GetLineNumber(); - sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int); + sprintf(yylvalpp->symbol_name, "%d", yylvalpp->sc_int); UngetToken(CPP_INTCONSTANT, yylvalpp); + return 1; } + if (atom == __FILE__Atom) { yylvalpp->sc_int = GetStringNumber(); - sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int); + sprintf(yylvalpp->symbol_name, "%d", yylvalpp->sc_int); UngetToken(CPP_INTCONSTANT, yylvalpp); + return 1; } + if (atom == __VERSION__Atom) { - strcpy(yylvalpp->symbol_name,"100"); + strcpy(yylvalpp->symbol_name, "100"); yylvalpp->sc_int = atoi(yylvalpp->symbol_name); UngetToken(CPP_INTCONSTANT, yylvalpp); + return 1; } - if (!sym || sym->details.mac.undef) return 0; - if (sym->details.mac.busy) return 0; // no recursive expansions + + if (! sym || sym->details.mac.undef) + + return -1; + + else if (sym->details.mac.busy) + + return 0; // no recursive expansions + in = (MacroInputSrc*)malloc(sizeof(*in)); memset(in, 0, sizeof(*in)); in->base.scan = macro_scan; @@ -977,22 +1034,24 @@ int MacroExpand(int atom, yystypepp * yylvalpp) if (token != '(') { UngetToken(token, yylvalpp); yylvalpp->sc_ident = atom; + return 0; } in->args = (TokenStream**)malloc(in->mac->argc * sizeof(TokenStream *)); for (i=0; imac->argc; i++) in->args[i] = NewTokenStream("macro arg", 0); i=0;j=0; - do{ + do { depth = 0; - while(1) { + while (1) { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token <= 0) { StoreStr("EOF in Macro "); - StoreStr(GetStringOfAtom(atable,atom)); + StoreStr(GetStringOfAtom(atable, atom)); message=GetStrfromTStr(); - CPPShInfoLogMsg(message); + ShPpErrorToInfoLog(message); ResetTString(); + return 1; } if((in->mac->argc==0) && (token!=')')) break; @@ -1009,13 +1068,13 @@ int MacroExpand(int atom, yystypepp * yylvalpp) break; } i++; - }while(i < in->mac->argc); + } while (i < in->mac->argc); if (i < in->mac->argc) { StoreStr("Too few args in Macro "); - StoreStr(GetStringOfAtom(atable,atom)); + StoreStr(GetStringOfAtom(atable, atom)); message=GetStrfromTStr(); - CPPShInfoLogMsg(message); + ShPpErrorToInfoLog(message); ResetTString(); } else if (token != ')') { depth=0; @@ -1027,16 +1086,17 @@ int MacroExpand(int atom, yystypepp * yylvalpp) if (token <= 0) { StoreStr("EOF in Macro "); - StoreStr(GetStringOfAtom(atable,atom)); + StoreStr(GetStringOfAtom(atable, atom)); message=GetStrfromTStr(); - CPPShInfoLogMsg(message); + ShPpErrorToInfoLog(message); ResetTString(); + return 1; } StoreStr("Too many args in Macro "); - StoreStr(GetStringOfAtom(atable,atom)); + StoreStr(GetStringOfAtom(atable, atom)); message=GetStrfromTStr(); - CPPShInfoLogMsg(message); + ShPpErrorToInfoLog(message); ResetTString(); } for (i=0; imac->argc; i++) { @@ -1057,6 +1117,7 @@ int MacroExpand(int atom, yystypepp * yylvalpp) sym->details.mac.busy = 1; RewindTokenStream(sym->details.mac.body); cpp->currentInput = &in->base; + return 1; } // MacroExpand diff --git a/glslang/MachineIndependent/preprocessor/cpp.h b/glslang/MachineIndependent/preprocessor/cpp.h index 91d31dc04..8ea1f76e1 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.h +++ b/glslang/MachineIndependent/preprocessor/cpp.h @@ -102,9 +102,11 @@ int MacroExpand(int atom, yystypepp * yylvalpp); extern "C" { #endif -void CPPDebugLogMsg(const char *msg); // Prints information into debug log -void CPPShInfoLogMsg(const char*); // Store cpp Err Msg into Sh.Info.Log -void CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log +void ShPpDebugLogMsg(const char *msg); // Prints information into debug log +void ShPpErrorToInfoLog(const char*); // Store cpp Err Msg into Sh.Info.Log +void ShPpWarningToInfoLog(const char *msg); // Prints warning messages into info log +int ShPpMacrosMustBeDefinedError(); + void HandlePragma(const char**, int numTokens); // #pragma directive container. void ResetTString(void); // #error Message as TString. void StoreStr(const char*); // Store the TString in Parse Context. diff --git a/glslang/MachineIndependent/preprocessor/scanner.c b/glslang/MachineIndependent/preprocessor/scanner.c index dc9925635..39741d9ed 100644 --- a/glslang/MachineIndependent/preprocessor/scanner.c +++ b/glslang/MachineIndependent/preprocessor/scanner.c @@ -258,7 +258,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } else { - CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + ShPpErrorToInfoLog("floating-point literal too long"); len = 1,str_len=1; } } @@ -268,7 +268,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) if (ch == 'e' || ch == 'E') { if (len >= MAX_SYMBOL_NAME_LEN) { - CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + ShPpErrorToInfoLog("floating-point literal too long"); len = 1,str_len=1; } else { ExpSign = 1; @@ -289,12 +289,12 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) str[len++]=ch; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } else { - CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + ShPpErrorToInfoLog("floating-point literal too long"); len = 1,str_len=1; } } } else { - CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT"); + ShPpErrorToInfoLog("bad character in exponent"); } exp *= ExpSign; } @@ -303,7 +303,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) if (len == 0) { yylvalpp->sc_fval = 0.0f; yylvalpp->sc_dval = 0.0; - strcpy(str,"0.0"); + strcpy(str, "0.0"); } else { if (ch == 'l' || ch == 'L') { int ch2 = cpp->currentInput->getch(cpp->currentInput, yylvalpp); @@ -315,7 +315,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) str[len++] = ch; str[len++] = ch2; } else { - CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + ShPpErrorToInfoLog("floating-point literal too long"); len = 1,str_len=1; } } @@ -323,7 +323,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) if (len < MAX_SYMBOL_NAME_LEN) str[len++] = ch; else { - CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + ShPpErrorToInfoLog("floating-point literal too long"); len = 1,str_len=1; } } else @@ -425,7 +425,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) ival = (ival << 4) | ii; } else { if (!AlreadyComplained) - CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW"); + ShPpErrorToInfoLog("hexidecimal literal too long"); AlreadyComplained = 1; } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); @@ -433,7 +433,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')); } else { - CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT"); + ShPpErrorToInfoLog("bad digit in hexidecimal literal"); } if (ch == 'u' || ch == 'U') yylvalpp->symbol_name[len++] = ch; @@ -452,7 +452,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) ival = (ival << 3) | ii; } else { if (!AlreadyComplained) - CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW"); + ShPpErrorToInfoLog("octal literal too long"); AlreadyComplained = 1; } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); @@ -496,7 +496,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) ch = yylvalpp->symbol_name[ii] - '0'; if ((ival > 429496729) || (ival == 429496729 && ch >= 6)) { if (! AlreadyComplained) - CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW"); + ShPpErrorToInfoLog("integral literal too long"); AlreadyComplained = 1; } ival = ival * 10 + ch; @@ -676,14 +676,14 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) while (ch != '*') { if (ch == '\n') nlcount++; if (ch == EOF) { - CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT"); + ShPpErrorToInfoLog("EOF in comment"); return -1; } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); if (ch == EOF) { - CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT"); + ShPpErrorToInfoLog("EOF in comment"); return -1; } } while (ch != '/'); @@ -718,7 +718,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) yylvalpp->sc_ident = LookUpAddString(atable, string_val); return CPP_STRCONSTANT; } else { - CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING"); + ShPpErrorToInfoLog("end of line in string"); return ERROR_SY; } } @@ -727,53 +727,53 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) int yylex_CPP(char* buf, int maxSize) { - yystypepp yylvalpp; + yystypepp yylvalpp; int token = '\n'; for(;;) { char* tokenString = 0; token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp); - if(check_EOF(token)) - return 0; + if(check_EOF(token)) + return 0; if (token == '#') { if (cpp->previous_token == '\n'|| cpp->previous_token == 0) { - token = readCPPline(&yylvalpp); + token = readCPPline(&yylvalpp); if(check_EOF(token)) return 0; - continue; + continue; } else { - CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line"); + ShPpErrorToInfoLog("preprocessor directive cannot be preceded by another token"); return 0; } } cpp->previous_token = token; // expand macros - if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) { + if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp) == 1) { cpp->notAVersionToken = 1; continue; } - + if (token == '\n') continue; - + if (token == CPP_IDENTIFIER) { cpp->notAVersionToken = 1; tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident); } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){ cpp->notAVersionToken = 1; tokenString = yylvalpp.symbol_name; - } else { + } else { cpp->notAVersionToken = 1; tokenString = GetStringOfAtom(atable,token); - } + } if (tokenString) { if ((signed)strlen(tokenString) >= maxSize) { cpp->tokensBeforeEOF = 1; return maxSize; } else if (strlen(tokenString) > 0) { - strcpy(buf, tokenString); + strcpy(buf, tokenString); cpp->tokensBeforeEOF = 1; return (int)strlen(tokenString); } @@ -790,7 +790,7 @@ int check_EOF(int token) { if(token==-1){ if(cpp->ifdepth >0){ - CPPErrorToInfoLog("#endif missing!! Compilation stopped"); + ShPpErrorToInfoLog("missing #endif"); cpp->CompileError=1; } return 1; diff --git a/glslang/MachineIndependent/preprocessor/scanner.h b/glslang/MachineIndependent/preprocessor/scanner.h index 1bcb02463..08f6307d5 100644 --- a/glslang/MachineIndependent/preprocessor/scanner.h +++ b/glslang/MachineIndependent/preprocessor/scanner.h @@ -111,7 +111,7 @@ typedef struct InputSrc { int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner. int ScanFromString(char *); // Start scanning the input from the string mentioned. int check_EOF(int); // check if we hit a EOF abruptly -void CPPErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log +void ShPpErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log void SetLineNumber(int); void SetStringNumber(int); void IncLineNumber(void); diff --git a/glslang/MachineIndependent/preprocessor/symbols.c b/glslang/MachineIndependent/preprocessor/symbols.c index 579779e79..f48fbf4ac 100644 --- a/glslang/MachineIndependent/preprocessor/symbols.c +++ b/glslang/MachineIndependent/preprocessor/symbols.c @@ -220,7 +220,7 @@ static void lAddToTree(Symbol **fSymbols, Symbol *fSymb) while (lSymb) { lrev = GetReversedAtom(atable, lSymb->name); if (lrev == frev) { - CPPErrorToInfoLog("GetAtomString(atable, fSymb->name)"); + ShPpErrorToInfoLog("GetAtomString(atable, fSymb->name)"); break; } else { if (lrev > frev) { diff --git a/glslang/MachineIndependent/preprocessor/tokens.c b/glslang/MachineIndependent/preprocessor/tokens.c index af18d7415..316b9ce0d 100644 --- a/glslang/MachineIndependent/preprocessor/tokens.c +++ b/glslang/MachineIndependent/preprocessor/tokens.c @@ -470,7 +470,7 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) { snprintf(str, maxSize, "%c", token); break; } - CPPDebugLogMsg(str); + ShPpDebugLogMsg(str); } } diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 781609d10..b3cb1c69c 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -231,7 +231,8 @@ enum TDebugOptions { EDebugOpLinkMaps = 0x008, EDebugOpSuppressInfolog = 0x010, EDebugOpMemoryLeakMode = 0x020, - EDebugOpTexturePrototypes = 0x040 + EDebugOpTexturePrototypes = 0x040, + EDebugOpRelaxedErrors = 0x080 }; #ifdef __cplusplus }