From c59d0cd9e6f7bdaea65d253a2ad67a7cf7a574c9 Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Mon, 17 Jun 2013 21:47:23 +0000
Subject: [PATCH] Encapsulate warnings like errors.  Add warning for missing
 #version.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22041 e7fa87d3-cd2b-0410-9028-fcbf551c1848
---
 glslang/MachineIndependent/ParseHelper.cpp    | 22 +++++++-
 glslang/MachineIndependent/ParseHelper.h      |  4 +-
 glslang/MachineIndependent/ShaderLang.cpp     |  7 ++-
 glslang/MachineIndependent/glslang.l          | 56 +++++++------------
 glslang/MachineIndependent/preprocessor/cpp.c |  8 +--
 glslang/Public/ShaderLang.h                   |  3 +-
 6 files changed, 55 insertions(+), 45 deletions(-)

diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index fe030fd96..9d9ba5a42 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -207,7 +207,6 @@ void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const c
     
     safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
     
-    /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
     infoSink.info.prefix(EPrefixError);
     infoSink.info.location(nLine);
     infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
@@ -217,6 +216,27 @@ void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const c
     ++numErrors;
 }
 
+void C_DECL TParseContext::warn(TSourceLoc nLine, const char *szReason, const char *szToken, 
+                                 const char *szExtraInfoFormat, ...)
+{
+    if (messages & EShMsgSuppressWarnings)
+        return;
+
+    const int maxSize = GlslangMaxTokenLength + 200;
+    char szExtraInfo[maxSize];
+    va_list marker;
+    
+    va_start(marker, szExtraInfoFormat);
+    
+    safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
+    
+    infoSink.info.prefix(EPrefixWarning);
+    infoSink.info.location(nLine);
+    infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
+    
+    va_end(marker);
+}
+
 TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString* string)
 {
     TIntermTyped* node = 0;
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index dcef72152..d25d3c829 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -99,9 +99,11 @@ struct TParseContext {
 
     void initializeExtensionBehavior();
     const char* getPreamble();
-
+    
     void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
                       const char *szExtraInfoFormat, ...);
+    void C_DECL  warn(TSourceLoc, const char *szReason, const char *szToken,
+                      const char *szExtraInfoFormat, ...);
     bool reservedErrorCheck(int line, const TString& identifier);
 
     TIntermTyped* handleVariable(int line, TSymbol* symbol, TString* string);
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index e3d17350e..fe3ff88a2 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -506,9 +506,12 @@ int ShCompile(
 
     int version;
     EProfile profile;
+    bool versionStatementMissing = false;
     ScanVersion(shaderStrings, numStrings, version, profile);
-    if (version == 0)
+    if (version == 0) {
         version = defaultVersion;
+        versionStatementMissing = true;
+    }
     bool goodProfile = DeduceProfile(compiler->infoSink, version, profile);
 
     TIntermediate intermediate(compiler->infoSink, version, profile);
@@ -528,6 +531,8 @@ int ShCompile(
         parseContext.error(1, "incorrect", "#version", "");
 
     parseContext.initializeExtensionBehavior();
+    if (versionStatementMissing)
+        parseContext.warn(1, "statement missing: use #version on first line of shader", "#version", "");
 
     GlobalParseContext = &parseContext;
     
diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l
index 8160ae8de..14a7ab934 100644
--- a/glslang/MachineIndependent/glslang.l
+++ b/glslang/MachineIndependent/glslang.l
@@ -763,10 +763,8 @@ int PaIdentOrReserved(bool reserved, TParseContext& pc, int line, const char* te
         return 0;
     }
 
-    if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-        pc.infoSink.info.message(EPrefixWarning, yytext, yylineno);
-        pc.infoSink.info.message(EPrefixWarning, "using future reserved keyword", yylineno);
-    }
+    if (pc.forwardCompatible)
+        pc.warn(yylineno, "using future reserved keyword", text, "");
 
     return PaIdentOrType(text, pc, pyylval);
 }
@@ -779,10 +777,8 @@ int PaES30ReservedFromGLSL(int version, TParseContext& pc, int line, const char*
 
     if (pc.profile == EEsProfile && pc.version < 300 ||
         pc.profile != EEsProfile && pc.version < version) {
-            if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-                pc.infoSink.info.message(EPrefixWarning, text, yylineno);
-                pc.infoSink.info.message(EPrefixWarning, "future reserved word in ES 300 and keyword in GLSL", yylineno);
-            }
+            if (pc.forwardCompatible)
+                pc.warn(yylineno, "future reserved word in ES 300 and keyword in GLSL", text, "");
 
             return PaIdentOrType(text, pc, pyylval);
     } else if (pc.profile == EEsProfile && pc.version >= 300)
@@ -799,10 +795,8 @@ int PaNonreservedKeyword(int esVersion, int nonEsVersion, TParseContext& pc, int
 
     if (pc.profile == EEsProfile && pc.version < esVersion ||
         pc.profile != EEsProfile && pc.version < nonEsVersion) {
-        if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-            pc.infoSink.info.message(EPrefixWarning, text, yylineno);
-            pc.infoSink.info.message(EPrefixWarning, "using future keyword", yylineno);
-        }
+        if (pc.forwardCompatible)
+            pc.warn(yylineno, "using future keyword", text, "");
 
         return PaIdentOrType(text, pc, pyylval);
     }
@@ -817,10 +811,8 @@ int PaPrecisionKeyword(TParseContext& pc, int line, const char* text, YYSTYPE* p
     if (pc.profile == EEsProfile || pc.version >= 130)
         return keyword;
 
-    if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-        pc.infoSink.info.message(EPrefixWarning, text, yylineno);
-        pc.infoSink.info.message(EPrefixWarning, "using ES precision qualifier keyword", yylineno);
-    }
+    if (pc.forwardCompatible)
+        pc.warn(yylineno, "using ES precision qualifier keyword", text, "");
 
     return PaIdentOrType(text, pc, pyylval);
 }
@@ -833,10 +825,8 @@ int PaMatNxM(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, in
     if (pc.version > 110)
         return keyword;
 
-    if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-        pc.infoSink.info.message(EPrefixWarning, text, yylineno);
-        pc.infoSink.info.message(EPrefixWarning, "using future non-square matrix type keyword", yylineno);
-    }
+    if (pc.forwardCompatible)
+        pc.warn(yylineno, "using future non-square matrix type keyword", text, "");
 
     return PaIdentOrType(text, pc, pyylval);
 }
@@ -855,10 +845,8 @@ int PaDMat(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int
     if (pc.profile != EEsProfile && pc.version >= 400)
         return keyword;
 
-    if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-        pc.infoSink.info.message(EPrefixWarning, text, yylineno);
-        pc.infoSink.info.message(EPrefixWarning, "using future type keyword", yylineno);
-    }
+    if (pc.forwardCompatible)
+        pc.warn(yylineno, "using future type keyword", text, "");
 
     return PaIdentOrType(text, pc, pyylval);
 }
@@ -878,10 +866,8 @@ int Pa1stGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE*
         return keyword;
     }
 
-    if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-        pc.infoSink.info.message(EPrefixWarning, text, yylineno);
-        pc.infoSink.info.message(EPrefixWarning, "using future type keyword", yylineno);
-    }
+    if (pc.forwardCompatible)
+        pc.warn(yylineno, "using future type keyword", text, "");
 
     return PaIdentOrType(text, pc, pyylval);
 }
@@ -894,10 +880,8 @@ int Pa2ndGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE*
     if (pc.profile != EEsProfile && pc.version >= 420)
         return keyword;
 
-    if (pc.forwardCompatible && ! (pc.messages & EShMsgSuppressWarnings)) {
-        pc.infoSink.info.message(EPrefixWarning, text, yylineno);
-        pc.infoSink.info.message(EPrefixWarning, "using future type keyword", yylineno);
-    }
+    if (pc.forwardCompatible)
+        pc.warn(yylineno, "using future type keyword", text, "");
 
     return PaIdentOrType(text, pc, pyylval);
 }
@@ -946,15 +930,14 @@ void ShPpWarningToInfoLog(const char *msg)
 {
     TParseContext& pc = *((TParseContext *)cpp->pC);
 
-    if (! (pc.messages & EShMsgSuppressWarnings))
-        pc.infoSink.info.message(EPrefixWarning, msg, yylineno);
+    pc.warn(yylineno, msg, "Preprocessor", "");
 }
 
 void ShPpErrorToInfoLog(const char *msg)
 {
     TParseContext& pc = *((TParseContext *)cpp->pC);
 
-    pc.error(yylineno, "", "Preprocessor", msg, "");
+    pc.error(yylineno, msg, "Preprocessor", "");
 }
 
 // return 1 if error
@@ -1185,8 +1168,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
             case EBhEnable:
             case EBhWarn:
             case EBhDisable:
-                msg = TString("extension '") + extName + "' is not supported";
-                pc.infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
+                pc.warn(yylineno, "extension not supported", extName, "");
                 break;
             default:
                 assert(0 && "unexpected behaviorVal");
diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c
index 77416511b..51872a01e 100644
--- a/glslang/MachineIndependent/preprocessor/cpp.c
+++ b/glslang/MachineIndependent/preprocessor/cpp.c
@@ -355,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') {
-                    ShPpWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
+                    ShPpWarningToInfoLog("unexpected tokens following #else directive - expected a newline");
                     while (token != '\n')
                         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                 } 
@@ -558,7 +558,7 @@ static int CPPif(yystypepp * yylvalpp)
 	}
 	token = eval(token, MIN_PREC, &res, &err, yylvalpp);
     if (token != '\n') {
-        ShPpWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
+        ShPpWarningToInfoLog("unexpected tokens following directive - expected a newline");
         while (token != '\n')
             token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
     } 
@@ -584,7 +584,7 @@ static int CPPifdef(int defined, yystypepp * yylvalpp)
         Symbol *s = LookUpSymbol(macros, name);
         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
         if (token != '\n') {
-            ShPpWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
+            ShPpWarningToInfoLog("unexpected tokens following #ifdef - expected a newline");
             while (token != '\n')
                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
         }
@@ -824,7 +824,7 @@ int readCPPline(yystypepp * yylvalpp)
                  }
                  token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                  if (token != '\n') {
-                     ShPpWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
+                     ShPpWarningToInfoLog("unexpected tokens following #else - expected a newline");
                      while (token != '\n')
                          token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                  }
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index b3cb1c69c..df9dcdf95 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -232,7 +232,8 @@ enum TDebugOptions {
 	EDebugOpSuppressInfolog    = 0x010,
 	EDebugOpMemoryLeakMode     = 0x020,
     EDebugOpTexturePrototypes  = 0x040,
-    EDebugOpRelaxedErrors      = 0x080
+    EDebugOpRelaxedErrors      = 0x080,
+    EDebugOpGiveWarnings       = 0x100,
 };
 #ifdef __cplusplus
     }
-- 
GitLab