Add the GL_ES macro for ES personalities, along with a general mechanism for adding preambles in front of shaders without effecting line numbers, etc.


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21122 e7fa87d3-cd2b-0410-9028-fcbf551c1848
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 18e9c54..e7d0800 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -89,7 +89,7 @@
 // Set up the per compile resources
 //
 void GenerateResources(TBuiltInResource& resources)
-{    
+{
     resources.maxLights = 32;
     resources.maxClipPlanes = 6;
     resources.maxTextureUnits = 32;
diff --git a/Test/140.frag b/Test/140.frag
index 045983d..140c0c6 100644
--- a/Test/140.frag
+++ b/Test/140.frag
@@ -8,3 +8,8 @@
 void main()
 {
 }
+#ifdef GL_ES
+#error GL_ES is set
+#else
+#error GL_ES is not set
+#endif
diff --git a/Test/300.vert b/Test/300.vert
index 5db2be1..7e7a525 100644
--- a/Test/300.vert
+++ b/Test/300.vert
@@ -7,7 +7,7 @@
 in vec3 v3;
 in vec2 v2;
 
-in vec4 bad[10];
+in vec4 bad[10];  // ERROR
 
 void main()
 {
@@ -30,4 +30,10 @@
     mat3x3 im = inverse(m33);
 
     mat3x2 op = outerProduct(v2, v3);
+
+#ifdef GL_ES
+#error GL_ES is set
+#else
+#error GL_ES is not set
+#endif
 }
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 8c24c26..b247cbf 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -77,6 +77,16 @@
     defaultGlobalQualification.layoutSlotLocation = 0;
 }
 
+// Get code that is not part of a shared symbol table, specific to this shader
+// or needed by CPP (which does not have a shared symbol table).
+const char* TParseContext::getPreamble()
+{
+    if (profile == EEsProfile)
+        return "#define GL_ES 1\n";
+    else
+        return 0;
+}
+
 ///////////////////////////////////////////////////////////////////////
 //
 // Sub- vector and matrix fields
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index 6950413..66c75ec 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -96,6 +96,7 @@
     bool AfterEOF;
 
     void initializeExtensionBehavior();
+    const char* getPreamble();
 
     void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
                       const char *szExtraInfoFormat, ...);
@@ -159,7 +160,7 @@
     void doubleCheck(int line, const char* op);
 };
 
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
+int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&, const char* preamble);
 int PaParseComment(int &lineno, TParseContext&);
 void ResetFlex();
 
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index 6b77f37..ea4a31d 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -132,7 +132,7 @@
         builtInShaders[0] = (*i).c_str();
         builtInLengths[0] = (int) (*i).size();
 
-        if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0) {
+        if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext, 0) != 0) {
             infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
 
             return false;
@@ -548,7 +548,7 @@
     if (parseContext.insertBuiltInArrayAtGlobalLevel())
         success = false;
 
-    int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext);
+    int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext, parseContext.getPreamble());
     if (ret)
         success = false;
 
diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l
index 0e22616..e4e01a2 100644
--- a/glslang/MachineIndependent/glslang.l
+++ b/glslang/MachineIndependent/glslang.l
@@ -470,15 +470,8 @@
 //

 // Returns 0 for success, as per yyparse().

 //

-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal)

+int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal, const char* preamble)

 {

-    int argv0len;

-

-    ScanFromString(argv[0]);

-

-    //Storing the Current Compiler Parse context into the cpp structure.

-	cpp->pC = (void*)&parseContextLocal;

-	

 	if (!argv || argc == 0)

         return 1;

 

@@ -490,13 +483,27 @@
         }

     }

 

+    // set up all the cpp fields...

+	cpp->pC = (void*)&parseContextLocal;

+    char *writeablePreamble = 0;

+    if (preamble) {

+        // preAmble could be a hard-coded string; make writable copy

+        // TODO: CPP: make it not need writable strings

+        int size = strlen(preamble) + 1;

+        writeablePreamble = new char[size];

+        memcpy(writeablePreamble, preamble, size);

+        ScanFromString(writeablePreamble);

+        cpp->PaWhichStr = -1;

+    } else {

+        ScanFromString(argv[0]);

+        cpp->PaWhichStr = 0;

+    }

     if (! strLen) {

-        argv0len = (int) strlen(argv[0]);

+        int argv0len = (int) strlen(argv[0]);

         strLen   = &argv0len;

     }

     yyrestart(0);

     (&parseContextLocal)->AfterEOF = false;

-    cpp->PaWhichStr = 0;

     cpp->PaArgv     = argv;

     cpp->PaArgc     = argc;

     cpp->PaStrLen   = strLen;

@@ -508,9 +515,10 @@
     while (argv[0][len] == ' '  ||

            argv[0][len] == '\t' ||

            argv[0][len] == '\n' ||

-           argv[0][len] == '\r')

+           argv[0][len] == '\r') {

         if (++len >= strLen[0])

             return 0;

+    }

 

     if (*cpp->PaStrLen > 0) {

         int ret;

@@ -519,12 +527,16 @@
         #else

             ret = yyparse((void*)(&parseContextLocal));

         #endif

+        delete writeablePreamble;

         if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)

              return 1;

         else

              return 0;

-    } else

-        return 0;

+    } 

+

+    delete writeablePreamble;

+

+    return 0;

 }

 

 void yyerror(const char *s)

diff --git a/glslang/MachineIndependent/preprocessor/scanner.c b/glslang/MachineIndependent/preprocessor/scanner.c
index 964b078..dc99256 100644
--- a/glslang/MachineIndependent/preprocessor/scanner.c
+++ b/glslang/MachineIndependent/preprocessor/scanner.c
@@ -168,23 +168,26 @@
  */
 static int str_getch(StringInputSrc *in)
 {
-	for(;;){
-	   if (*in->p){
+	for(;;) {
+	   if (*in->p) {
 	      if (*in->p == '\n') {
              in->base.line++;
              IncLineNumber();
           }
           return *in->p++;
 	   }
-	   if(++(cpp->PaWhichStr) < cpp->PaArgc){
+       if (cpp->PaWhichStr < 0) {
+           // we only parsed the built-in pre-amble; start with clean slate for user code
+            cpp->notAVersionToken = 0;
+       }
+	   if (++(cpp->PaWhichStr) < cpp->PaArgc) {
 		  free(in);
 		  SetStringNumber(cpp->PaWhichStr);
     	  SetLineNumber(1);
 		  ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
 		  in=(StringInputSrc*)cpp->currentInput;
 	      continue;             
-	   }
-	   else{
+	   } else {
 	      cpp->currentInput = in->base.prev;
 	      cpp->PaWhichStr=0;
           free(in);