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
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index e66a315..cf58ed6 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -74,7 +74,7 @@
 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 @@
                 case 'l':
                     debugOptions |= EDebugOpMemoryLeakMode;
                     break;
+                case 'r':
+                    debugOptions |= EDebugOpRelaxedErrors;
+                    break;
                 case 's':
                     debugOptions |= EDebugOpSuppressInfolog;
                     break;
@@ -261,9 +264,12 @@
     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 @@
            "-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 07c5628..f26c307 100644
--- a/Test/cppSimple.vert
+++ b/Test/cppSimple.vert
@@ -32,7 +32,7 @@
 sum += 50000.0;
 #endif
 
-#ifndef(OFF)
+#ifndef OFF
 //yes
 sum += 600000.0;
 #else
@@ -58,6 +58,13 @@
 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 29b114b..3c37f99 100644
--- a/glslang/MachineIndependent/glslang.l
+++ b/glslang/MachineIndependent/glslang.l
@@ -951,14 +951,14 @@
 

 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 @@
         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 @@
 

     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 @@
         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 @@
         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 @@
     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 @@
     // 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 @@
         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 3c9642c..2f43c48 100644
--- a/glslang/MachineIndependent/preprocessor/atom.c
+++ b/glslang/MachineIndependent/preprocessor/atom.c
@@ -470,14 +470,14 @@
                 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 @@
 
     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 577bfbb..aba525a 100644
--- a/glslang/MachineIndependent/preprocessor/cpp.c
+++ b/glslang/MachineIndependent/preprocessor/cpp.c
@@ -186,7 +186,7 @@
 int FinalCPP(void)
 {
 	if (cpp->ifdepth)
-		CPPErrorToInfoLog("#if mismatch");
+        ShPpErrorToInfoLog("missing #endif");
     return 1;
 }
 
@@ -200,7 +200,7 @@
     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 @@
         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 @@
             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 @@
     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 @@
                 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 @@
         symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
     }
     symb->details.mac = mac;
+
     return '\n';
 } // CPPdefine
 
@@ -282,21 +288,26 @@
 {
     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 @@
                 // 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 @@
                 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 @@
 {
     int         i, val;
     Symbol      *s;
+
     if (token == CPP_IDENTIFIER) {
         if (yylvalpp->sc_ident == definedAtom) {
             int needclose = 0;
@@ -444,21 +456,46 @@
                 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 @@
         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 @@
             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 @@
         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 @@
     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 @@
 {
     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 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 @@
 			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 @@
 		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 @@
 	
 	if (token=='\n') {
 		DecLineNumber();
-        CPPErrorToInfoLog("#pragma");
+        ShPpErrorToInfoLog("#pragma must be followed by pragma arguments");
         IncLineNumber();
 	    return token;
 	}
@@ -656,7 +696,7 @@
 			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 @@
     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 @@
         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 @@
 
     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 @@
 		return token;
 	}
 	else{
-        CPPErrorToInfoLog("#extension");
+        ShPpErrorToInfoLog("#extension");
 	}
     return token;
 } // CPPextension
@@ -781,25 +821,25 @@
         } 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 @@
 			 cpp->elsedepth[cpp->elsetracker] = 0;
 		     --cpp->elsetracker;
              if (!cpp->ifdepth){
-                 CPPErrorToInfoLog("#endif mismatch");
+                 ShPpErrorToInfoLog("#endif mismatch");
                  cpp->CompileError=1;
              }
              else
@@ -837,9 +877,9 @@
             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 @@
     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 @@
 } 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 @@
         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 @@
 		if (token != '(') {
             UngetToken(token, yylvalpp);
             yylvalpp->sc_ident = atom;
+
             return 0;
         }
         in->args = (TokenStream**)malloc(in->mac->argc * sizeof(TokenStream *));
         for (i=0; i<in->mac->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 @@
                 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 @@
 			
             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; i<in->mac->argc; i++) {
@@ -1057,6 +1117,7 @@
     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 91d31dc..8ea1f76 100644
--- a/glslang/MachineIndependent/preprocessor/cpp.h
+++ b/glslang/MachineIndependent/preprocessor/cpp.h
@@ -102,9 +102,11 @@
 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 dc99256..39741d9 100644
--- a/glslang/MachineIndependent/preprocessor/scanner.c
+++ b/glslang/MachineIndependent/preprocessor/scanner.c
@@ -258,7 +258,7 @@
                 }
                 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 @@
 
     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 @@
 				        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 @@
     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 @@
                     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 @@
             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 @@
                             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 @@
                              (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 @@
                         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 @@
                     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 @@
                     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 @@
                 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 @@
 
 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 @@
 {
    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 1bcb024..08f6307 100644
--- a/glslang/MachineIndependent/preprocessor/scanner.h
+++ b/glslang/MachineIndependent/preprocessor/scanner.h
@@ -111,7 +111,7 @@
 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 579779e..f48fbf4 100644
--- a/glslang/MachineIndependent/preprocessor/symbols.c
+++ b/glslang/MachineIndependent/preprocessor/symbols.c
@@ -220,7 +220,7 @@
         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 af18d74..316b9ce 100644
--- a/glslang/MachineIndependent/preprocessor/tokens.c
+++ b/glslang/MachineIndependent/preprocessor/tokens.c
@@ -470,7 +470,7 @@
                 snprintf(str, maxSize, "%c", token);
             break;
         }
-        CPPDebugLogMsg(str);
+        ShPpDebugLogMsg(str);
     }
 }
 
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index 781609d..b3cb1c6 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -231,7 +231,8 @@
 	EDebugOpLinkMaps           = 0x008,
 	EDebugOpSuppressInfolog    = 0x010,
 	EDebugOpMemoryLeakMode     = 0x020,
-    EDebugOpTexturePrototypes  = 0x040
+    EDebugOpTexturePrototypes  = 0x040,
+    EDebugOpRelaxedErrors      = 0x080
 };
 #ifdef __cplusplus
     }