Eliminate flex as the GLSL lexical analyzer, going from two nested lexical analyzers...
authorJohn Kessenich <cepheus@frii.com>
Sat, 6 Jul 2013 19:54:21 +0000 (19:54 +0000)
committerJohn Kessenich <cepheus@frii.com>
Sat, 6 Jul 2013 19:54:21 +0000 (19:54 +0000)
Also:
 - change source locations from an int to TSourceLoc (shader number, line number) throughout
 - various improvements to the preprocessor

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22277 e7fa87d3-cd2b-0410-9028-fcbf551c1848

35 files changed:
Test/cppSimple.vert
Test/lineContinuation.vert
Test/tokenLength.vert
glslang.vcxproj
glslang.vcxproj.filters
glslang/Include/Common.h
glslang/Include/InfoSink.h
glslang/Include/Types.h
glslang/Include/intermediate.h
glslang/MachineIndependent/Constant.cpp
glslang/MachineIndependent/Initialize.h
glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/Scan.cpp
glslang/MachineIndependent/Scan.h
glslang/MachineIndependent/ScanContext.h [new file with mode: 0644]
glslang/MachineIndependent/ShaderLang.cpp
glslang/MachineIndependent/Versions.cpp
glslang/MachineIndependent/glslang.l [deleted file]
glslang/MachineIndependent/glslang.y
glslang/MachineIndependent/intermOut.cpp
glslang/MachineIndependent/localintermediate.h
glslang/MachineIndependent/parseConst.cpp
glslang/MachineIndependent/preprocessor/atom.c
glslang/MachineIndependent/preprocessor/compile.h [deleted file]
glslang/MachineIndependent/preprocessor/cpp.c
glslang/MachineIndependent/preprocessor/cpp.h
glslang/MachineIndependent/preprocessor/cppstruct.c
glslang/MachineIndependent/preprocessor/parser.h
glslang/MachineIndependent/preprocessor/preprocess.h
glslang/MachineIndependent/preprocessor/scanner.c
glslang/MachineIndependent/preprocessor/scanner.h
glslang/MachineIndependent/preprocessor/slglobals.h
glslang/MachineIndependent/preprocessor/tokens.c

index 2b48c01..d242de3 100644 (file)
@@ -125,5 +125,9 @@ int linenumber = __LINE__;
 int filenumber = __FILE__;
 int version = __VERSION__;
 
+#define PI (3.14)
+#define TWOPI (2.0 * PI)
+float twoPi = TWOPI;
+
 #define PASTE(a,b) a ## b
 float PASTE(tod, ay) = 17;
index c6222ef..eb2f819 100644 (file)
@@ -1,14 +1,20 @@
 #version 300 es
 
 // this file cont\
-ains no errors
+ains no errors other than the #error which are there to see if line numbering for errors is correct
+
+#error e1
 
 float f\
 oo;  // same as 'float foo;'
 
+#error e2
+
 #define MAIN void main() \
 {                        \
 gl_Position = vec4(foo); \
 } 
 
+#error e3
+
 MAIN
index 57e3b7f..dfec2b4 100644 (file)
@@ -14,13 +14,13 @@ int OE = 0777777777777777777777;  // ERROR
 int HE = 0x1234567890ABCDEF0;     // ERROR
 
 // 1023 character fraction
-float F = 1.012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012;
+float F = 1.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
 
 // 1024 character value
-float G = 1.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
+float G = 1.01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678890;
 
-// 1027 character fraction
-float E3 = 1.01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234;
+// 1025 character fraction
+float E3 = 1.012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012;
 
 void main()
 {
index 80024de..c50b18f 100644 (file)
@@ -150,7 +150,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <ClCompile Include="glslang\MachineIndependent\Constant.cpp" />\r
-    <ClCompile Include="glslang\MachineIndependent\gen_glslang.cpp" />\r
     <ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp" />\r
     <ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />\r
     <ClCompile Include="glslang\MachineIndependent\Initialize.cpp" />\r
@@ -192,7 +191,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
     <ClInclude Include="glslang\MachineIndependent\RemoveTree.h" />\r
     <ClInclude Include="glslang\MachineIndependent\localintermediate.h" />\r
     <ClInclude Include="glslang\MachineIndependent\preprocessor\atom.h" />\r
-    <ClInclude Include="glslang\MachineIndependent\preprocessor\compile.h" />\r
     <ClInclude Include="glslang\MachineIndependent\preprocessor\cpp.h" />\r
     <ClInclude Include="glslang\MachineIndependent\preprocessor\memory.h" />\r
     <ClInclude Include="glslang\MachineIndependent\preprocessor\parser.h" />\r
@@ -206,6 +204,7 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
     <ClInclude Include="glslang\Include\ConstantUnion.h" />\r
     <ClInclude Include="glslang\Include\InfoSink.h" />\r
     <ClInclude Include="glslang\MachineIndependent\Scan.h" />\r
+    <ClInclude Include="glslang\MachineIndependent\ScanContext.h" />\r
     <ClInclude Include="glslang\MachineIndependent\Versions.h" />\r
     <ClInclude Include="OGLCompilersDLL\InitializeDll.h" />\r
     <ClInclude Include="glslang\Include\InitializeGlobals.h" />\r
@@ -238,23 +237,6 @@ cd %(RootDir)%(Directory)
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RootDir)%(Directory)%(Filename)_tab.cpp;%(Outputs)</Outputs>\r
     </CustomBuild>\r
   </ItemGroup>\r
-  <ItemGroup>\r
-    <CustomBuild Include="glslang\MachineIndependent\glslang.l">\r
-      <FileType>Document</FileType>\r
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cd %(RootDir)%(Directory)\r
-%(RootDir)%(Directory)..\..\tools\flex.exe glslang.l\r
-</Command>\r
-      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Executing flex on glslang.l</Message>\r
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RootDir)%(Directory)gen_glslang.cpp</Outputs>\r
-      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RootDir)%(Directory)glslang_tab.cpp.h</AdditionalInputs>\r
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cd %(RootDir)%(Directory)\r
-%(RootDir)%(Directory)..\..\tools\flex.exe glslang.l\r
-</Command>\r
-      <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Executing flex on glslang.l</Message>\r
-      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RootDir)%(Directory)gen_glslang.cpp</Outputs>\r
-      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RootDir)%(Directory)glslang_tab.cpp.h</AdditionalInputs>\r
-    </CustomBuild>\r
-  </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
   </ImportGroup>\r
index 3e5cfbd..624bcaf 100644 (file)
@@ -97,9 +97,6 @@
     <ClCompile Include="glslang\OSDependent\Linux\ossource.cpp">\r
       <Filter>OSDependent\Linux</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="glslang\MachineIndependent\gen_glslang.cpp">\r
-      <Filter>Machine Independent\Generated Source</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp">\r
       <Filter>Machine Independent\Generated Source</Filter>\r
     </ClCompile>\r
     <ClInclude Include="glslang\MachineIndependent\preprocessor\atom.h">\r
       <Filter>Machine Independent\CPP</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="glslang\MachineIndependent\preprocessor\compile.h">\r
-      <Filter>Machine Independent\CPP</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="glslang\MachineIndependent\preprocessor\cpp.h">\r
       <Filter>Machine Independent\CPP</Filter>\r
     </ClInclude>\r
     <ClInclude Include="glslang\MachineIndependent\Scan.h">\r
       <Filter>Machine Independent</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="glslang\MachineIndependent\ScanContext.h">\r
+      <Filter>Machine Independent</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <CustomBuild Include="glslang\MachineIndependent\glslang.y">\r
       <Filter>Machine Independent</Filter>\r
     </CustomBuild>\r
-    <CustomBuild Include="glslang\MachineIndependent\glslang.l">\r
-      <Filter>Machine Independent</Filter>\r
-    </CustomBuild>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index dd74232..e936683 100644 (file)
@@ -66,8 +66,6 @@
 #include <stdio.h>
 #include <assert.h>
 
-typedef int TSourceLoc;
-
 #include "PoolAlloc.h"
 
 //
@@ -162,25 +160,10 @@ inline const TString String(const int i, const int base = 10)
     return text;
 }
 
-const unsigned int SourceLocLineMask = 0xffff;
-const unsigned int SourceLocStringShift = 16;
-
-__inline TPersistString FormatSourceLoc(const TSourceLoc loc)
-{
-       const int maxSize = 64;
-    char locText[maxSize];
-
-    int string = loc >> SourceLocStringShift;
-    int line = loc & SourceLocLineMask;
-
-    if (line)
-        snprintf(locText, maxSize, "%d:%d", string, line);
-    else
-        snprintf(locText, maxSize, "%d:? ", string);
-
-    return TPersistString(locText);
-}
-
+struct TSourceLoc {
+    int string;
+    int line;
+};
 
 typedef TMap<TString, TString> TPragmaTable;
 typedef TMap<TString, TString>::tAllocator TPragmaTableAllocator;
index be0f762..a251182 100644 (file)
@@ -94,7 +94,10 @@ public:
         }
     }
     void location(TSourceLoc loc) {
-        append(FormatSourceLoc(loc).c_str());
+           const int maxSize = 24;
+        char locText[maxSize];
+        snprintf(locText, maxSize, "%d:%d", loc.string, loc.line);
+        append(locText);
         append(": ");
     }
     void message(TPrefixType message, const char* s) {
index 1a7215d..4b7681a 100644 (file)
@@ -142,11 +142,11 @@ struct TSampler {
 // Need to have association of line numbers to types in a list for building structs.
 //
 class TType;
-struct TTypeLine {
+struct TTypeLoc {
     TType* type;
-    int line;
+    TSourceLoc loc;
 };
-typedef TVector<TTypeLine> TTypeList;
+typedef TVector<TTypeLoc> TTypeList;
 
 inline TTypeList* NewPoolTTypeList()
 {
@@ -347,9 +347,9 @@ public:
     int matrixRows : 4;
     TArraySizes arraySizes;
     const TType* userDef;
-    int line;
+    TSourceLoc loc;
 
-    void initType(int ln = 0)
+    void initType(TSourceLoc l)
     {
         basicType = EbtVoid;
         vectorSize = 1;
@@ -357,7 +357,7 @@ public:
         matrixCols = 0;
         arraySizes = 0;
         userDef = 0;
-        line = ln;
+        loc = l;
     }
 
     void initQualifiers(bool global = false)
@@ -367,9 +367,9 @@ public:
             qualifier.storage = EvqGlobal;
     }
 
-    void init(int line = 0, bool global = false)
+    void init(TSourceLoc loc, bool global = false)
     {
-        initType(line);
+        initType(loc);
         sampler.clear();
         initQualifiers(global);
     }
@@ -479,10 +479,10 @@ public:
                                // create the new structure here
                                structure = NewPoolTTypeList();
                                for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
-                                       TTypeLine typeLine;
-                                       typeLine.line = (*copyOf.structure)[i].line;
-                                       typeLine.type = (*copyOf.structure)[i].type->clone(remapper);
-                                       structure->push_back(typeLine);
+                                       TTypeLoc typeLoc;
+                                       typeLoc.loc = (*copyOf.structure)[i].loc;
+                                       typeLoc.type = (*copyOf.structure)[i].type->clone(remapper);
+                                       structure->push_back(typeLoc);
                                }
                        } else {
                                structure = iter->second;
index 725de03..6ced6a4 100644 (file)
@@ -320,9 +320,9 @@ class TIntermNode {
 public:
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
 
-    TIntermNode() : line(0) {}
-    virtual TSourceLoc getLine() const { return line; }
-    virtual void setLine(TSourceLoc l) { line = l; }
+    TIntermNode() { loc.line = 0; loc.string = 0; }
+    virtual TSourceLoc getLoc() const { return loc; }
+    virtual void setLoc(TSourceLoc l) { loc = l; }
     virtual void traverse(TIntermTraverser*) = 0;
     virtual TIntermTyped*     getAsTyped()         { return 0; }
     virtual TIntermConstantUnion*     getAsConstantUnion()         { return 0; }
@@ -336,7 +336,7 @@ public:
     virtual TIntermBranch*    getAsBranchNode()    { return 0; }
     virtual ~TIntermNode() { }
 protected:
-    TSourceLoc line;
+    TSourceLoc loc;
 };
 
 //
index f40a693..831f799 100644 (file)
@@ -195,7 +195,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
                     newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
                 break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
+                infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLoc());
                 return 0;
             }
         }
@@ -352,13 +352,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
         break;
 
     default:
-        infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
+        infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLoc());
 
         return 0;
     }
 
     TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
-    newNode->setLine(getLine());
+    newNode->setLoc(getLoc());
 
     return newNode;
 }
@@ -416,7 +416,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
             case EbtInt:   newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
             case EbtUint:  newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst())));  break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+                infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc());
                 return 0;
             }
             break;
@@ -425,7 +425,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
             switch (getType().getBasicType()) {
             case EbtBool:  newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+                infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc());
                 return 0;
             }
             break;
@@ -570,14 +570,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
         case EOpAll:
 
         default:
-            infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLine());
+            infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLoc());
             return 0;
         }
     }
 
     TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
     newNode->getTypePointer()->getQualifier().storage = EvqConst;
-    newNode->setLine(getLine());
+    newNode->setLoc(getLoc());
 
     return newNode;
 }
@@ -667,7 +667,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
     case EOpReflect:
     case EOpRefract:
     case EOpOuterProduct:
-        infoSink.info.message(EPrefixInternalError, "constant folding operation not implemented", aggrNode->getLine());
+        infoSink.info.message(EPrefixInternalError, "constant folding operation not implemented", aggrNode->getLoc());
         return aggrNode;
 
     default:
@@ -676,7 +676,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
 
     TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType());
     newNode->getTypePointer()->getQualifier().storage = EvqConst;
-    newNode->setLine(aggrNode->getLine());
+    newNode->setLoc(aggrNode->getLoc());
 
     return newNode;
 }
@@ -705,12 +705,12 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
 
     constUnion* unionArray = new constUnion[aggrNode->getType().getObjectSize()];
     if (aggrNode->getSequence().size() == 1)
-        returnVal = parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
+        returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
     else
-        returnVal = parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
+        returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
 
     if (returnVal)
         return aggrNode;
 
-    return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLine());
+    return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc());
 }
index b341b61..c3e9b0e 100644 (file)
@@ -70,7 +70,5 @@ protected:
 
 void IdentifyBuiltIns(int version, EProfile profile, EShLanguage, TSymbolTable&);
 void IdentifyBuiltIns(int version, EProfile profile, EShLanguage, TSymbolTable&, const TBuiltInResource &resources);
-extern "C" int InitPreprocessor(void);
-extern "C" int FinalizePreprocessor(void);
 
 #endif // _INITIALIZE_INCLUDED_
index 6a1e65f..dd9c1d7 100644 (file)
 //
 // Returns the added node.
 //
-TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
+TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc loc)
 {
     TIntermSymbol* node = new TIntermSymbol(id, name, type);
-    node->setLine(line);
+    node->setLoc(loc);
 
     return node;
 }
@@ -69,7 +69,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
 {
     // No operations work on blocks
     if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
@@ -92,9 +92,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
     // one and promote it to the right type.
     //
     TIntermBinary* node = new TIntermBinary(op);
-    if (line == 0)
-        line = right->getLine();
-    node->setLine(line);
+    if (loc.line == 0)
+        loc = right->getLoc();
+    node->setLoc(loc);
 
     node->setLeft(left);
     node->setRight(right);
@@ -114,7 +114,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
         if (folded)
             return folded;
         else
-            infoSink.info.message(EPrefixInternalError, "Constant folding failed", line);
+            infoSink.info.message(EPrefixInternalError, "Constant folding failed", loc);
     }
 
     return node;
@@ -125,7 +125,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
 {
     // No block assignment
     if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock)
@@ -136,9 +136,9 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
     // from right to left.
     //
     TIntermBinary* node = new TIntermBinary(op);
-    if (line == 0)
-        line = left->getLine();
-    node->setLine(line);
+    if (loc.line == 0)
+        loc = left->getLoc();
+    node->setLoc(loc);
 
     TIntermTyped* child = addConversion(op, left->getType(), right);
     if (child == 0)
@@ -161,12 +161,12 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
 // Returns the added node.
 // The caller should set the type of the returned node.
 //
-TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line)
+TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
 {
     TIntermBinary* node = new TIntermBinary(op);
-    if (line == 0)
-        line = index->getLine();
-    node->setLine(line);
+    if (loc.line == 0)
+        loc = index->getLoc();
+    node->setLoc(loc);
     node->setLeft(base);
     node->setRight(index);
 
@@ -180,7 +180,7 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line)
+TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc loc)
 {
     TIntermTyped* child = childNode->getAsTyped();
 
@@ -188,7 +188,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
         return 0;
 
     if (child == 0) {
-        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
+        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", loc);
         return 0;
     }
 
@@ -248,9 +248,9 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
     // Make a new node for the operator.
     //
     TIntermUnary* node = new TIntermUnary(op);
-    if (line == 0)
-        line = child->getLine();
-    node->setLine(line);
+    if (loc.line == 0)
+        loc = child->getLoc();
+    node->setLoc(loc);
     node->setOperand(child);
     
     if (! node->promote(infoSink))
@@ -274,7 +274,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
         //        
         TIntermTyped* child = childNode->getAsTyped();
         if (child == 0) {
-            infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", child->getLine());
+            infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", child->getLoc());
 
             return 0;
         }
@@ -284,7 +284,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
             return child->getAsConstantUnion()->fold(op, returnType, infoSink);
 
         TIntermUnary* node = new TIntermUnary(op);
-        node->setLine(child->getLine());
+        node->setLoc(child->getLoc());
         node->setOperand(child);
         node->setType(returnType);
 
@@ -299,7 +299,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
         return node;
     } else {
         // setAggregateOperater() calls fold() for constant folding
-        TIntermTyped* node = setAggregateOperator(childNode, op, returnType, childNode->getLine());
+        TIntermTyped* node = setAggregateOperator(childNode, op, returnType, childNode->getLoc());
         
         TPrecisionQualifier correctPrecision = returnType.getQualifier().precision;
         if (correctPrecision == EpqNone && profile == EEsProfile) {
@@ -328,7 +328,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI
 // Returns an aggregate node, which could be the one passed in if
 // it was already an aggregate.
 //
-TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc line)
+TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc)
 {
     TIntermAggregate* aggNode;
 
@@ -343,8 +343,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
             //
             aggNode = new TIntermAggregate();
             aggNode->getSequence().push_back(node);
-            if (line == 0)
-                line = node->getLine();
+            if (loc.line == 0)
+                loc = node->getLoc();
         }
     } else
         aggNode = new TIntermAggregate();
@@ -353,8 +353,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
     // Set the operator.
     //
     aggNode->setOperator(op);
-    if (line != 0)
-        aggNode->setLine(line);
+    if (loc.line != 0)
+        aggNode->setLoc(loc);
 
     aggNode->setType(type);
 
@@ -510,7 +510,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
             //case EbtBool:  newOp = EOpConvBoolToDouble;  break;
             //case EbtFloat: newOp = EOpConvFloatToDouble; break;
             //default:
-                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
                 return 0;
             //}
             break;
@@ -521,7 +521,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
             case EbtBool:   newOp = EOpConvBoolToFloat; break;
             case EbtDouble: newOp = EOpConvDoubleToFloat; break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
                 return 0;
             }
             break;
@@ -532,7 +532,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
             case EbtFloat:  newOp = EOpConvFloatToBool; break;
             case EbtDouble: newOp = EOpConvDoubleToBool; break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
                 return 0;
             }
             break;
@@ -543,7 +543,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
             case EbtFloat:  newOp = EOpConvFloatToInt; break;
             case EbtDouble: newOp = EOpConvDoubleToInt; break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
                 return 0;
             }
             break;
@@ -554,18 +554,18 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
             case EbtFloat:  newOp = EOpConvFloatToUint; break;
             case EbtDouble: newOp = EOpConvDoubleToUint; break;
             default:
-                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
                 return 0;
             }
             break;
         default: 
-            infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
+            infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLoc());
             return 0;
         }
 
         TType type(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
         newNode = new TIntermUnary(newOp, type);
-        newNode->setLine(node->getLine());
+        newNode->setLoc(node->getLoc());
         newNode->setOperand(node);
 
         return newNode;
@@ -628,7 +628,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to)
 // Returns the resulting aggregate, unless 0 was passed in for 
 // both existing nodes.
 //
-TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line)
+TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right)
 {
     if (left == 0 && right == 0)
         return 0;
@@ -645,8 +645,13 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
     if (right)
         aggNode->getSequence().push_back(right);
 
-    if (line != 0)
-        aggNode->setLine(line);
+    return aggNode;
+}
+
+TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc loc)
+{
+    TIntermAggregate* aggNode = growAggregate(left, right);
+    aggNode->setLoc(loc);
 
     return aggNode;
 }
@@ -656,18 +661,26 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
 //
 // Returns an aggregate, unless 0 was passed in for the existing node.
 //
-TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line)
+TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
 {
     if (node == 0)
         return 0;
 
     TIntermAggregate* aggNode = new TIntermAggregate;
     aggNode->getSequence().push_back(node);
+    aggNode->setLoc(node->getLoc());
+
+    return aggNode;
+}
 
-    if (line != 0)
-        aggNode->setLine(line);
-    else
-        aggNode->setLine(node->getLine());
+TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc loc)
+{
+    if (node == 0)
+        return 0;
+
+    TIntermAggregate* aggNode = new TIntermAggregate;
+    aggNode->getSequence().push_back(node);
+    aggNode->setLoc(loc);
 
     return aggNode;
 }
@@ -679,7 +692,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc lin
 //
 // Returns the selection node created.
 //
-TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
+TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc loc)
 {
     //
     // For compile time constant selections, prune the code and 
@@ -694,20 +707,20 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
     }
 
     TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
-    node->setLine(line);
+    node->setLoc(loc);
 
     return node;
 }
 
 
-TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc loc)
 {
     if (left->getType().getQualifier().storage == EvqConst && 
         right->getType().getQualifier().storage == EvqConst) {
 
         return right;
     } else {
-        TIntermTyped *commaAggregate = growAggregate(left, right, line);
+        TIntermTyped *commaAggregate = growAggregate(left, right, loc);
         commaAggregate->getAsAggregate()->setOperator(EOpComma);
         commaAggregate->setType(right->getType());
         commaAggregate->getTypePointer()->getQualifier().storage = EvqTemporary;
@@ -717,10 +730,10 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
     }
 }
 
-TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, TSourceLoc line)
+TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, TSourceLoc loc)
 {
     TIntermMethod* method = new TIntermMethod(object, type, *name);
-    method->setLine(line);
+    method->setLoc(loc);
 
     return method;
 }
@@ -732,7 +745,7 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
 //
 // Returns the selection node created, or 0 if one could not be.
 //
-TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
+TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc loc)
 {
     //
     // Get compatible types.
@@ -767,7 +780,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
     // Make a selection node.
     //
     TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
-    node->setLine(line);
+    node->setLoc(loc);
     node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
 
     return node;
@@ -779,20 +792,20 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
 // Returns the constant union node created.
 //
 
-TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc line)
+TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc loc)
 {
     TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
-    node->setLine(line);
+    node->setLoc(loc);
 
     return node;
 }
 
-TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
+TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc loc)
 {
     
     TIntermAggregate* node = new TIntermAggregate(EOpSequence);
 
-    node->setLine(line);
+    node->setLoc(loc);
     TIntermConstantUnion* constIntNode;
     TIntermSequence &sequenceVector = node->getSequence();
     constUnion* unionArray;
@@ -800,7 +813,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
     for (int i = 0; i < fields.num; i++) {
         unionArray = new constUnion[1];
         unionArray->setIConst(fields.offsets[i]);
-        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), line);
+        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc);
         sequenceVector.push_back(constIntNode);
     }
 
@@ -810,10 +823,10 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
 //
 // Create loop nodes.
 //
-TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line)
+TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc loc)
 {
     TIntermNode* node = new TIntermLoop(body, test, terminal, testFirst);
-    node->setLine(line);
+    node->setLoc(loc);
     
     return node;
 }
@@ -821,15 +834,15 @@ TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
 //
 // Add branches.
 //
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc loc)
 {
-    return addBranch(branchOp, 0, line);
+    return addBranch(branchOp, 0, loc);
 }
 
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc loc)
 {
     TIntermBranch* node = new TIntermBranch(branchOp, expression);
-    node->setLine(line);
+    node->setLoc(loc);
 
     return node;
 }
@@ -886,7 +899,7 @@ void TIntermediate::addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*&
         linkage->setOperator(EOpLinkerObjects);
 
         // Add a child to the root node for the linker objects
-        growAggregate(root, linkage, 0);
+        growAggregate(root, linkage);
     }
 }
 
@@ -900,7 +913,7 @@ void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTabl
 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable& variable)
 {
     TIntermSymbol* node = new TIntermSymbol(variable.getUniqueId(), variable.getName(), variable.getType());
-    linkage = growAggregate(linkage, node, 0);
+    linkage = growAggregate(linkage, node);
 }
 
 //
@@ -1218,7 +1231,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
                     setType(TType(basicType, EvqTemporary, right->getVectorSize()));
             }
         } else {
-            infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+            infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc());
             return false;
         }
         break;
@@ -1250,7 +1263,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
                 op = EOpVectorTimesScalarAssign;
             }
         } else {
-            infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+            infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc());
             return false;
         }
         break;      
@@ -1381,7 +1394,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) 
 {
     if (node->getType().isArray())
-        infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLine());
+        infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLoc());
 
     constUnion *rightUnionArray = node->getUnionArrayPointer();
     int size = node->getType().getObjectSize();
@@ -1408,7 +1421,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
                 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
                 break;
             default: 
-                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
                 return 0;
             }                
             break;
@@ -1428,7 +1441,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
                 leftUnionArray[i] = rightUnionArray[i];
                 break;
             default: 
-                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
                 return 0;
             }                
             break;
@@ -1448,7 +1461,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
                 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
                 break;
             default: 
-                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
                 return 0;
             }                
             break;
@@ -1468,7 +1481,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
                 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
                 break;
             default: 
-                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
                 return 0;
             }                
             break;
@@ -1488,12 +1501,12 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
                 leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0);
                 break;
             default: 
-                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc());
                 return 0;
             }
             break;
         default:
-            infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
+            infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLoc());
             return 0;
         }    
     }
@@ -1501,7 +1514,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
     const TType& t = node->getType();
     
     return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()), 
-                            node->getLine());
+                            node->getLoc());
 }
 
 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
index e6006c2..9c2efa9 100644 (file)
 #include <stdarg.h>
 #include <algorithm>
 
+extern "C" {
+  #include "./preprocessor/preprocess.h"
+}
+
 TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is,                             
                              bool fc, EShMessages m) : 
             intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0), linkage(0),
-            numErrors(0), lexAfterType(false), loopNestingLevel(0),
+            numErrors(0), loopNestingLevel(0),
             structNestingLevel(0), inTypeParen(false), parsingBuiltins(pb),
             version(v), profile(p), forwardCompatible(fc), messages(m),
             contextPragma(true, false)
@@ -77,7 +81,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
             defaultPrecision[EbtSampler] = EpqLow;
             break;
         default:
-            error(1, "INTERNAL ERROR", "unexpected language", "");
+            infoSink.info.message(EPrefixError, "unexpected language");
         }
     }
 
@@ -90,8 +94,8 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
     globalOutputDefaults.clear();
 }
 
-// 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).
+// Get code that is not part of a shared symbol table, is specific to this shader,
+// or needed by CPP (which does not use a shared symbol table).
 const char* TParseContext::getPreamble()
 {
     if (profile == EEsProfile)
@@ -100,6 +104,370 @@ const char* TParseContext::getPreamble()
         return 0;
 }
 
+TSourceLoc currentLine;  // TODO: thread: get this into the scan context, sort out with return from PP
+#ifdef _WIN32
+    extern int yyparse(TParseContext&);
+#else
+    extern int yyparse(void*);
+    #define parseContext (*((TParseContext*)(parseContextLocal)))              
+#endif
+
+//
+// Parse an array of strings using yyparse.  We set up globals used by
+// yywrap.
+//
+// Returns true for success, false for failure.
+//
+bool TParseContext::parseShaderStrings(char* strings[], int strLen[], int numStrings)
+{
+    if (! strings || numStrings == 0)
+        return false;
+
+    for (int i = 0; i < numStrings; ++i) {
+        if (! strings[i]) {
+            TSourceLoc loc;
+            loc.string = i;
+            loc.line = 1;
+            error(loc, "Null shader source string", "", "");
+
+            return false;
+        }
+    }
+
+    // set up all the cpp fields...
+    // TODO: thread safety: don't move 'this' into the global
+    cpp->pC = (void*)this;
+    const char* preamble = getPreamble();
+    char *writeablePreamble = 0;
+    if (preamble) {
+        // preAmble could be a hard-coded string; make writable copy
+        // TODO: efficiency PP: 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(strings[0]);
+        cpp->PaWhichStr = 0;
+    }
+
+    afterEOF = false;
+    cpp->PaArgv = strings;
+    cpp->PaArgc = numStrings;
+    int string0len;
+    if (! strLen) {
+        string0len = (int) strlen(strings[0]);
+        cpp->PaStrLen = &string0len;
+    } else
+        cpp->PaStrLen = strLen;
+    cpp->notAVersionToken = 0;
+    currentLine.string = 0;
+    currentLine.line = 1;
+
+    // TODO: desktop PP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens
+    int len = 0;
+    while (strings[0][len] == ' '  ||
+           strings[0][len] == '\t' ||
+           strings[0][len] == '\n' ||
+           strings[0][len] == '\r') {
+        if (++len >= strLen[0]) {
+            delete writeablePreamble;
+            return true;
+        }
+    }
+
+    if (*cpp->PaStrLen > 0) {
+        int ret;
+        #ifdef _WIN32
+            ret = yyparse(*this);
+        #else
+            ret = yyparse((void*)this);
+        #endif
+        delete writeablePreamble;
+        if (cpp->CompileError == 1 || numErrors > 0)
+             return false;
+        else
+             return true;
+    }
+
+    delete writeablePreamble;
+
+    return true;
+}
+
+// TODO: fix this for threads
+void yyerror(const char *s)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    if (pc.afterEOF) {
+        if (cpp->tokensBeforeEOF == 1)
+            ThreadLocalParseContext()->error(currentLine, "", "pre-mature EOF", s, "");
+    } else
+        ThreadLocalParseContext()->error(currentLine, "", "", s, "");
+}
+
+
+extern "C" {
+
+// Communications with the preprocess.
+// TODO: threads: this all needs redoing for thread safety
+
+void ShPpDebugLogMsg(const char *msg)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    pc.infoSink.debug.message(EPrefixNone, msg);
+}
+
+void ShPpWarningToInfoLog(const char *msg)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    pc.warn(currentLine, msg, "Preprocessor", "");
+}
+
+void ShPpErrorToInfoLog(const char *msg)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    pc.error(currentLine, msg, "Preprocessor", "");
+}
+
+// return 1 if error
+// return 0 if no error
+int ShPpMacrosMustBeDefinedError()
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    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;
+}
+
+// TODO: PP/threads: integrate this with location from token
+void SetLineNumber(int line)
+{
+    currentLine.line = line;
+}
+
+void SetStringNumber(int string)
+{
+    currentLine.string = string;
+}
+
+int GetStringNumber(void)
+{
+    return currentLine.string;
+}
+
+int GetLineNumber(void)
+{
+    return currentLine.line;
+}
+
+void IncLineNumber(void)
+{
+    ++currentLine.line;
+}
+
+void DecLineNumber(void)
+{
+    --currentLine.line;
+}
+
+void HandlePragma(const char **tokens, int numTokens)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    if (!strcmp(tokens[0], "optimize")) {
+        if (numTokens != 4) {
+            ShPpErrorToInfoLog("optimize pragma syntax is incorrect");
+            return;
+        }
+
+        if (strcmp(tokens[1], "(")) {
+            ShPpErrorToInfoLog("\"(\" expected after 'optimize' keyword");
+            return;
+        }
+
+        if (!strcmp(tokens[2], "on"))
+            pc.contextPragma.optimize = true;
+        else if (!strcmp(tokens[2], "off"))
+            pc.contextPragma.optimize = false;
+        else {
+            ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
+            return;
+        }
+
+        if (strcmp(tokens[3], ")")) {
+            ShPpErrorToInfoLog("\")\" expected to end 'optimize' pragma");
+            return;
+        }
+    } else if (!strcmp(tokens[0], "debug")) {
+        if (numTokens != 4) {
+            ShPpErrorToInfoLog("debug pragma syntax is incorrect");
+            return;
+        }
+
+        if (strcmp(tokens[1], "(")) {
+            ShPpErrorToInfoLog("\"(\" expected after 'debug' keyword");
+            return;
+        }
+
+        if (!strcmp(tokens[2], "on"))
+            pc.contextPragma.debug = true;
+        else if (!strcmp(tokens[2], "off"))
+            pc.contextPragma.debug = false;
+        else {
+            ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'debug' pragma");
+            return;
+        }
+
+        if (strcmp(tokens[3], ")")) {
+            ShPpErrorToInfoLog("\")\" expected to end 'debug' pragma");
+            return;
+        }
+    } else {
+
+#ifdef PRAGMA_TABLE
+        //
+        // implementation specific pragma
+        // use parseContext.contextPragma.pragmaTable to store the information about pragma
+        // For now, just ignore the pragma that the implementation cannot recognize
+        // An Example of one such implementation for a pragma that has a syntax like
+        // #pragma pragmaname(pragmavalue)
+        // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
+        //
+        if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
+            TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable;
+            TPragmaTable::iterator iter;
+            iter = pragmaTable.find(TString(tokens[0]));
+            if (iter != pragmaTable.end()) {
+                iter->second = tokens[2];
+            } else {
+                pragmaTable[tokens[0]] = tokens[2];
+            }
+        } else if (numTokens >= 2) {
+            TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable;
+            TPragmaTable::iterator iter;
+            iter = pragmaTable.find(TString(tokens[0]));
+            if (iter != pragmaTable.end()) {
+                iter->second = tokens[1];
+            } else {
+                pragmaTable[tokens[0]] = tokens[1];
+            }
+        }
+#endif // PRAGMA_TABLE
+    }
+}
+
+void StoreStr(const char *string)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    TString strSrc;
+    strSrc = TString(string);
+
+    pc.HashErrMsg = pc.HashErrMsg + " " + strSrc;
+}
+
+const char* GetStrfromTStr(void)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    cpp->ErrMsg = pc.HashErrMsg.c_str();
+    return cpp->ErrMsg;
+}
+
+void ResetTString(void)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+
+    pc.HashErrMsg = "";
+}
+
+void SetVersion(int version)
+{
+    // called by the CPP, but this functionality is currently
+    // taken over by ScanVersion() before parsing starts
+
+    // CPP should still report errors in semantics
+}
+
+int GetShaderVersion(void* cppPc)
+{
+    TParseContext& pc = *((TParseContext *)cppPc);
+
+    return pc.version;
+}
+
+TBehavior GetBehavior(const char* behavior)
+{
+    if (!strcmp("require", behavior))
+        return EBhRequire;
+    else if (!strcmp("enable", behavior))
+        return EBhEnable;
+    else if (!strcmp("disable", behavior))
+        return EBhDisable;
+    else if (!strcmp("warn", behavior))
+        return EBhWarn;
+    else {
+        ShPpErrorToInfoLog((TString("behavior '") + behavior + "' is not supported").c_str());
+        return EBhDisable;
+    }
+}
+
+void updateExtensionBehavior(const char* extName, const char* behavior)
+{
+    TParseContext& pc = *((TParseContext *)cpp->pC);
+    TBehavior behaviorVal = GetBehavior(behavior);
+    TMap<TString, TBehavior>:: iterator iter;
+    TString msg;
+
+    // special cased for all extension
+    if (!strcmp(extName, "all")) {
+        if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
+            ShPpErrorToInfoLog("extension 'all' cannot have 'require' or 'enable' behavior");
+            return;
+        } else {
+            for (iter = pc.extensionBehavior.begin(); iter != pc.extensionBehavior.end(); ++iter)
+                iter->second = behaviorVal;
+        }
+    } else {
+        iter = pc.extensionBehavior.find(TString(extName));
+        if (iter == pc.extensionBehavior.end()) {
+            switch (behaviorVal) {
+            case EBhRequire:
+                ShPpErrorToInfoLog((TString("extension '") + extName + "' is not supported").c_str());
+                break;
+            case EBhEnable:
+            case EBhWarn:
+            case EBhDisable:
+                pc.warn(currentLine, "extension not supported", extName, "");
+                break;
+            default:
+                assert(0 && "unexpected behaviorVal");
+            }
+
+            return;
+        } else
+            iter->second = behaviorVal;
+    }
+}
+
+}  // extern "C"
+
+
 ///////////////////////////////////////////////////////////////////////
 //
 // Sub- vector and matrix fields
@@ -112,11 +480,11 @@ const char* TParseContext::getPreamble()
 //
 // Returns true if there is no error.
 //
-bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line)
+bool TParseContext::parseVectorFields(TSourceLoc loc, const TString& compString, int vecSize, TVectorFields& fields)
 {
     fields.num = (int) compString.size();
     if (fields.num > 4) {
-        error(line, "illegal vector field selection", compString.c_str(), "");
+        error(loc, "illegal vector field selection", compString.c_str(), "");
         return false;
     }
 
@@ -178,20 +546,20 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
             fieldSet[i] = estpq;
             break;
         default:
-            error(line, "illegal vector field selection", compString.c_str(), "");
+            error(loc, "illegal vector field selection", compString.c_str(), "");
             return false;
         }
     }
 
     for (int i = 0; i < fields.num; ++i) {
         if (fields.offsets[i] >= vecSize) {
-            error(line, "vector field selection out of range",  compString.c_str(), "");
+            error(loc, "vector field selection out of range",  compString.c_str(), "");
             return false;
         }
 
         if (i > 0) {
             if (fieldSet[i] != fieldSet[i-1]) {
-                error(line, "illegal - vector component fields not from the same set", compString.c_str(), "");
+                error(loc, "illegal - vector component fields not from the same set", compString.c_str(), "");
                 return false;
             }
         }
@@ -209,7 +577,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
 //
 // Used to output syntax, parsing, and semantic errors.
 //
-void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, 
+void C_DECL TParseContext::error(TSourceLoc loc, const char *szReason, const char *szToken, 
                                  const char *szExtraInfoFormat, ...)
 {
     const int maxSize = GlslangMaxTokenLength + 200;
@@ -221,7 +589,7 @@ void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const c
     safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
     
     infoSink.info.prefix(EPrefixError);
-    infoSink.info.location(nLine);
+    infoSink.info.location(loc);
     infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
     
     va_end(marker);
@@ -229,7 +597,7 @@ 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, 
+void C_DECL TParseContext::warn(TSourceLoc loc, const char *szReason, const char *szToken, 
                                  const char *szExtraInfoFormat, ...)
 {
     if (messages & EShMsgSuppressWarnings)
@@ -244,13 +612,13 @@ void C_DECL TParseContext::warn(TSourceLoc nLine, const char *szReason, const ch
     safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
     
     infoSink.info.prefix(EPrefixWarning);
-    infoSink.info.location(nLine);
+    infoSink.info.location(loc);
     infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
     
     va_end(marker);
 }
 
-TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString* string)
+TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TString* string)
 {
     TIntermTyped* node = 0;
 
@@ -258,19 +626,19 @@ TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString*
     if (anon) {
         // it was a member of an anonymous container, have to insert its dereference
         TVariable* variable = anon->getAnonContainer().getAsVariable();
-        TIntermTyped* container = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
+        TIntermTyped* container = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
         constUnion* unionArray = new constUnion[1];
         unionArray->setUConst(anon->getMemberNumber());
-        TIntermTyped* constNode = intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), line);
+        TIntermTyped* constNode = intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc);
 
-        node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, line);
+        node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc);
         node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type);
     } else {
         // The symbol table search was done in the lexical phase, but
         // if this is a new symbol, it wouldn't have found it.
         const TVariable* variable = symbol ? symbol->getAsVariable() : 0;
         if (symbol && ! variable)
-            error(line, "variable name expected", string->c_str(), "");
+            error(loc, "variable name expected", string->c_str(), "");
 
         if (! variable)
             variable = new TVariable(string, TType(EbtVoid));
@@ -281,9 +649,9 @@ TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString*
         if (variable->getType().getQualifier().storage == EvqConst ) {
             constUnion* constArray = variable->getConstUnionPointer();
             TType t(variable->getType());
-            node = intermediate.addConstantUnion(constArray, t, line);
+            node = intermediate.addConstantUnion(constArray, t, loc);
         } else
-            node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
+            node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
     }
 
     return node;
@@ -292,18 +660,18 @@ TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString*
 //
 // Same error message for all places assignments don't work.
 //
-void TParseContext::assignError(int line, const char* op, TString left, TString right)
+void TParseContext::assignError(TSourceLoc loc, const char* op, TString left, TString right)
 {
-    error(line, "", op, "cannot convert from '%s' to '%s'",
+    error(loc, "", op, "cannot convert from '%s' to '%s'",
           right.c_str(), left.c_str());
 }
 
 //
 // Same error message for all places unary operations don't work.
 //
-void TParseContext::unaryOpError(int line, const char* op, TString operand)
+void TParseContext::unaryOpError(TSourceLoc loc, const char* op, TString operand)
 {
-   error(line, " wrong operand type", op, 
+   error(loc, " wrong operand type", op, 
           "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
           op, operand.c_str());
 }
@@ -311,9 +679,9 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand)
 //
 // Same error message for all binary operations don't work.
 //
-void TParseContext::binaryOpError(int line, const char* op, TString left, TString right)
+void TParseContext::binaryOpError(TSourceLoc loc, const char* op, TString left, TString right)
 {
-    error(line, " wrong operand types:", op,
+    error(loc, " wrong operand types:", op,
             "no operation '%s' exists that takes a left-hand operand of type '%s' and "
             "a right operand of type '%s' (or there is no acceptable conversion)", 
             op, left.c_str(), right.c_str());
@@ -331,7 +699,7 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr)
         return;
 
     if (symbol->getType().getBasicType() == EbtVoid) {
-        error(symbol->getLine(), "undeclared identifier", symbol->getName().c_str(), "");
+        error(symbol->getLoc(), "undeclared identifier", symbol->getName().c_str(), "");
 
         // Add to symbol table to prevent future error messages on the same name
             
@@ -341,11 +709,11 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr)
         // substitute a symbol node for this new variable
         nodePtr = intermediate.addSymbol(fakeVariable->getUniqueId(), 
                                          fakeVariable->getName(), 
-                                         fakeVariable->getType(), symbol->getLine());
+                                         fakeVariable->getType(), symbol->getLoc());
     } else {
         switch (symbol->getQualifier().storage) {
         case EvqPointCoord:
-            profileRequires(symbol->getLine(), ENoProfile, 120, 0, "gl_PointCoord");
+            profileRequires(symbol->getLoc(), ENoProfile, 120, 0, "gl_PointCoord");
             break;
         default: break; // some compilers want this
         }
@@ -358,7 +726,7 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr)
 //
 // Returns true if the was an error.
 //
-bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node)
+bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node)
 {
     TIntermSymbol* symNode = node->getAsSymbolNode();
     TIntermBinary* binaryNode = node->getAsBinaryNode();
@@ -370,9 +738,9 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
         case EOpIndexDirect:
         case EOpIndexIndirect:
         case EOpIndexDirectStruct:
-            return lValueErrorCheck(line, op, binaryNode->getLeft());
+            return lValueErrorCheck(loc, op, binaryNode->getLeft());
         case EOpVectorSwizzle:
-            errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
+            errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
             if (!errorReturn) {
                 int offset[4] = {0,0,0,0};
 
@@ -384,7 +752,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
                     int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst();
                     offset[value]++;     
                     if (offset[value] > 1) {
-                        error(line, " l-value of swizzle cannot have duplicate components", op, "", "");
+                        error(loc, " l-value of swizzle cannot have duplicate components", op, "", "");
 
                         return true;
                     }
@@ -395,7 +763,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
         default: 
             break;
         }
-        error(line, " l-value required", op, "", "");
+        error(loc, " l-value required", op, "", "");
 
         return true;
     }
@@ -434,7 +802,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
     }
 
     if (message == 0 && binaryNode == 0 && symNode == 0) {
-        error(line, " l-value required", op, "", "");
+        error(loc, " l-value required", op, "", "");
 
         return true;
     }
@@ -450,9 +818,9 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
     // If we get here, we have an error and a message.
     //
     if (symNode)
-        error(line, " l-value required", op, "\"%s\" (%s)", symbol, message);
+        error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
     else
-        error(line, " l-value required", op, "(%s)", message);
+        error(loc, " l-value required", op, "(%s)", message);
 
     return true;
 }
@@ -464,7 +832,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
 void TParseContext::constCheck(TIntermTyped* node, const char* token)
 {
     if (node->getQualifier().storage != EvqConst)
-        error(node->getLine(), "constant expression required", token, "");
+        error(node->getLoc(), "constant expression required", token, "");
 }
 
 //
@@ -476,17 +844,17 @@ void TParseContext::integerCheck(TIntermTyped* node, const char* token)
     if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar() && ! node->isArray())
         return;
 
-    error(node->getLine(), "scalar integer expression required", token, "");
+    error(node->getLoc(), "scalar integer expression required", token, "");
 }
 
 //
 // Both test, and if necessary spit out an error, to see if we are currently
 // globally scoped.
 //
-void TParseContext::globalCheck(int line, bool global, const char* token)
+void TParseContext::globalCheck(TSourceLoc loc, bool global, const char* token)
 {
     if (! global)
-        error(line, "only allowed at global scope", token, "");
+        error(loc, "only allowed at global scope", token, "");
 }
 
 //
@@ -494,16 +862,16 @@ void TParseContext::globalCheck(int line, bool global, const char* token)
 // of scope.  Except, if the symbol table is at the built-in push-level,
 // which is when we are parsing built-ins.
 //
-bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
+bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier)
 {
     if (!symbolTable.atBuiltInLevel()) {
         if (identifier.substr(0, 3) == TString("gl_")) {
-            error(line, "reserved built-in name", "gl_", "");
+            error(loc, "reserved built-in name", "gl_", "");
 
             return true;
         }
         if (identifier.find("__") != TString::npos) {
-            error(line, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", "");
+            error(loc, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", "");
 
             return true;
         }
@@ -519,7 +887,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
 //
 // Returns true if there was an error in construction.
 //
-bool TParseContext::constructorError(int line, TIntermNode* node, TFunction& function, TOperator op, TType& type)
+bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
 {
     type = function.getReturnType();
 
@@ -584,48 +952,48 @@ bool TParseContext::constructorError(int line, TIntermNode* node, TFunction& fun
             // auto adapt the constructor type to the number of arguments
             type.changeArraySize(function.getParamCount());
         } else if (type.getArraySize() != function.getParamCount()) {
-            error(line, "array constructor needs one argument per array element", "constructor", "");
+            error(loc, "array constructor needs one argument per array element", "constructor", "");
             return true;
         }
     }
 
     if (arrayArg && op != EOpConstructStruct) {
-        error(line, "constructing from a non-dereferenced array", "constructor", "");
+        error(loc, "constructing from a non-dereferenced array", "constructor", "");
         return true;
     }
 
     if (matrixInMatrix && ! type.isArray()) {
-        profileRequires(line, ENoProfile, 120, 0, "constructing matrix from matrix");
+        profileRequires(loc, ENoProfile, 120, 0, "constructing matrix from matrix");
         return false;
     }
 
     if (overFull) {
-        error(line, "too many arguments", "constructor", "");
+        error(loc, "too many arguments", "constructor", "");
         return true;
     }
     
     if (op == EOpConstructStruct && ! type.isArray() && type.getStruct()->size() != function.getParamCount()) {
-        error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
+        error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
         return true;
     }
 
     if ((op != EOpConstructStruct && size != 1 && size < type.getObjectSize()) ||
         (op == EOpConstructStruct && size < type.getObjectSize())) {
-        error(line, "not enough data provided for construction", "constructor", "");
+        error(loc, "not enough data provided for construction", "constructor", "");
         return true;
     }
 
     TIntermTyped* typed = node->getAsTyped();
     if (typed == 0) {
-        error(line, "constructor argument does not have a type", "constructor", "");
+        error(loc, "constructor argument does not have a type", "constructor", "");
         return true;
     }
     if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) {
-        error(line, "cannot convert a sampler", "constructor", "");
+        error(loc, "cannot convert a sampler", "constructor", "");
         return true;
     }
     if (typed->getBasicType() == EbtVoid) {
-        error(line, "cannot convert a void", "constructor", "");
+        error(loc, "cannot convert a void", "constructor", "");
         return true;
     }
 
@@ -636,10 +1004,10 @@ bool TParseContext::constructorError(int line, TIntermNode* node, TFunction& fun
 //
 // returns true in case of an error
 //
-bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
+bool TParseContext::voidErrorCheck(TSourceLoc loc, const TString& identifier, const TPublicType& pubType)
 {
     if (pubType.basicType == EbtVoid) {
-        error(line, "illegal use of type 'void'", identifier.c_str(), "");
+        error(loc, "illegal use of type 'void'", identifier.c_str(), "");
         return true;
     } 
 
@@ -647,31 +1015,31 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP
 }
 
 // Checks to see if the node (for the expression) contains a scalar boolean expression or not
-void TParseContext::boolCheck(int line, const TIntermTyped* type)
+void TParseContext::boolCheck(TSourceLoc loc, const TIntermTyped* type)
 {
     if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
-        error(line, "boolean expression expected", "", "");
+        error(loc, "boolean expression expected", "", "");
 }
 
 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
-void TParseContext::boolCheck(int line, const TPublicType& pType)
+void TParseContext::boolCheck(TSourceLoc loc, const TPublicType& pType)
 {
     if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1))
-        error(line, "boolean expression expected", "", "");
+        error(loc, "boolean expression expected", "", "");
 }
 
-bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
+bool TParseContext::samplerErrorCheck(TSourceLoc loc, const TPublicType& pType, const char* reason)
 {
     if (pType.basicType == EbtStruct) {
         if (containsSampler(*pType.userDef)) {
-            error(line, reason, TType::getBasicString(pType.basicType), "(structure cannot contain a sampler or image)");
+            error(loc, reason, TType::getBasicString(pType.basicType), "(structure cannot contain a sampler or image)");
         
             return true;
         }
         
         return false;
     } else if (pType.basicType == EbtSampler) {
-        error(line, reason, TType::getBasicString(pType.basicType), "");
+        error(loc, reason, TType::getBasicString(pType.basicType), "");
 
         return true;
     }
@@ -679,7 +1047,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
     return false;
 }
 
-void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TPublicType& publicType)
+void TParseContext::globalQualifierFix(TSourceLoc loc, TQualifier& qualifier, const TPublicType& publicType)
 {
     if (! symbolTable.atGlobalLevel())
         return;
@@ -688,13 +1056,13 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP
 
     switch (qualifier.storage) {
     case EvqIn:
-        profileRequires(line, ENoProfile, 130, 0, "in for stage inputs");
-        profileRequires(line, EEsProfile, 300, 0, "in for stage inputs");
+        profileRequires(loc, ENoProfile, 130, 0, "in for stage inputs");
+        profileRequires(loc, EEsProfile, 300, 0, "in for stage inputs");
         qualifier.storage = EvqVaryingIn;
         break;
     case EvqOut:
-        profileRequires(line, ENoProfile, 130, 0, "out for stage outputs");
-        profileRequires(line, EEsProfile, 300, 0, "out for stage outputs");
+        profileRequires(loc, ENoProfile, 130, 0, "out for stage outputs");
+        profileRequires(loc, EEsProfile, 300, 0, "out for stage outputs");
         qualifier.storage = EvqVaryingOut;
         break;
     case EvqVaryingIn:
@@ -702,7 +1070,7 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP
         break;
     case EvqInOut:
         qualifier.storage = EvqVaryingIn;
-        error(line, "cannot use 'inout' at global scope", "", "");
+        error(loc, "cannot use 'inout' at global scope", "", "");
 
         return;
     default:
@@ -711,7 +1079,7 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP
 
     // Do non-in/out error checks
 
-    if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform"))
+    if (qualifier.storage != EvqUniform && samplerErrorCheck(loc, publicType, "samplers and images must be uniform"))
         return;
 
     if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
@@ -720,37 +1088,37 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP
     // now, knowing it is a shader in/out, do all the in/out semantic checks
 
     if (publicType.basicType == EbtBool) {
-        error(line, "cannot be bool",  getStorageQualifierString(qualifier.storage), "");
+        error(loc, "cannot be bool",  getStorageQualifierString(qualifier.storage), "");
 
         return;
     }
 
     if (language == EShLangVertex && qualifier.storage == EvqVaryingIn) {
         if (publicType.basicType == EbtStruct) {
-            error(line, "cannot be a structure or array",  getStorageQualifierString(qualifier.storage), "");
+            error(loc, "cannot be a structure or array",  getStorageQualifierString(qualifier.storage), "");
 
             return;
         }
         if (publicType.arraySizes) {
-            requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays");
-            profileRequires(line, ENoProfile, 150, 0, "vertex input arrays");
+            requireProfile(loc, (EProfileMask)~EEsProfileMask, "vertex input arrays");
+            profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays");
         }
     }
 
     if (language == EShLangFragment && qualifier.storage == EvqVaryingOut) {
-        profileRequires(line, EEsProfile, 300, 0, "fragment shader output");
+        profileRequires(loc, EEsProfile, 300, 0, "fragment shader output");
         if (publicType.basicType == EbtStruct) {
-            error(line, "cannot be a structure",  getStorageQualifierString(qualifier.storage), "");
+            error(loc, "cannot be a structure",  getStorageQualifierString(qualifier.storage), "");
 
             return;
         }
     }
 
     if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || publicType.basicType == EbtDouble) {
-        profileRequires(line, EEsProfile, 300, 0, "shader input/output");
+        profileRequires(loc, EEsProfile, 300, 0, "shader input/output");
         if (language != EShLangVertex   && qualifier.storage == EvqVaryingIn  && ! qualifier.flat ||
             language != EShLangFragment && qualifier.storage == EvqVaryingOut && ! qualifier.flat) {
-            error(line, "must be qualified as 'flat'", getStorageQualifierString(qualifier.storage), TType::getBasicString(publicType.basicType));
+            error(loc, "must be qualified as 'flat'", getStorageQualifierString(qualifier.storage), TType::getBasicString(publicType.basicType));
          
             return;
         }
@@ -758,7 +1126,7 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP
 
     if (language == EShLangVertex && qualifier.storage == EvqVaryingIn && 
         (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)) {
-        error(line, "vertex input cannot be further qualified", "", "");
+        error(loc, "vertex input cannot be further qualified", "", "");
 
         return;
     }
@@ -773,31 +1141,31 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP
 // 'dst', for the purpose of error checking order for versions
 // that require specific orderings of qualifiers.
 // 
-void TParseContext::mergeQualifiers(int line, TQualifier& dst, const TQualifier& src, bool force)
+void TParseContext::mergeQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src, bool force)
 {
     // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers')
     if (src.isAuxiliary() && dst.isAuxiliary())
-        error(line, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", "");
+        error(loc, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", "");
 
     // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers')
     if (src.isInterpolation() && dst.isInterpolation())
-        error(line, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", "");
+        error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", "");
 
     // Ordering
     if (! force && version < 420) {
         // non-function parameters
         if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
-            error(line, "invariant qualifier must appear first", "", "");
+            error(loc, "invariant qualifier must appear first", "", "");
         else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
-            error(line, "interpolation qualifiers must appear before storage and precision qualifiers", "", "");
+            error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", "");
         else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone))
-            error(line, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", "");
+            error(loc, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", "");
         else if (src.storage != EvqTemporary && (dst.precision != EpqNone))
-            error(line, "precision qualifier must appear as last qualifier", "", "");
+            error(loc, "precision qualifier must appear as last qualifier", "", "");
 
         // function parameters
         if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut))
-            error(line, "in/out must appear before const", "", "");
+            error(loc, "in/out must appear before const", "", "");
     }
 
     // Storage qualification
@@ -810,16 +1178,16 @@ void TParseContext::mergeQualifiers(int line, TQualifier& dst, const TQualifier&
              dst.storage == EvqConst && src.storage == EvqIn)
         dst.storage = EvqConstReadOnly;
     else if (src.storage != EvqTemporary)
-        error(line, "too many storage qualifiers", getStorageQualifierString(src.storage), "");
+        error(loc, "too many storage qualifiers", getStorageQualifierString(src.storage), "");
 
     // Precision qualifiers
     if (! force && src.precision != EpqNone && dst.precision != EpqNone)
-        error(line, "only one precision qualifier allowed", getPrecisionQualifierString(src.precision), "");
+        error(loc, "only one precision qualifier allowed", getPrecisionQualifierString(src.precision), "");
     if (dst.precision == EpqNone || force && src.precision != EpqNone)
         dst.precision = src.precision;
 
     // Layout qualifiers
-    mergeLayoutQualifiers(line, dst, src);
+    mergeLayoutQualifiers(loc, dst, src);
 
     // individual qualifiers
     bool repeated = false;
@@ -839,10 +1207,10 @@ void TParseContext::mergeQualifiers(int line, TQualifier& dst, const TQualifier&
     MERGE_SINGLETON(writeonly);
 
     if (repeated)
-        error(line, "replicated qualifiers", "", "");
+        error(loc, "replicated qualifiers", "", "");
 }
 
-void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrecisionQualifier qualifier)
+void TParseContext::setDefaultPrecision(TSourceLoc loc, TPublicType& publicType, TPrecisionQualifier qualifier)
 {
     TBasicType basicType = publicType.basicType;
 
@@ -862,7 +1230,7 @@ void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrec
         }
     }
 
-    error(line, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), "");
+    error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), "");
 }
 
 // used to flatten the sampler type space into a single dimension
@@ -883,7 +1251,7 @@ TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType)
         return defaultPrecision[publicType.basicType];
 }
 
-void TParseContext::precisionQualifierCheck(int line, TPublicType& publicType)
+void TParseContext::precisionQualifierCheck(TSourceLoc loc, TPublicType& publicType)
 {
     // Built-in symbols are allowed some ambiguous precisions, to be pinned down
     // later by context.
@@ -892,18 +1260,18 @@ void TParseContext::precisionQualifierCheck(int line, TPublicType& publicType)
 
     if (publicType.basicType == EbtFloat || publicType.basicType == EbtUint || publicType.basicType == EbtInt || publicType.basicType == EbtSampler) {
         if (publicType.qualifier.precision == EpqNone) {
-            error(line, "type requires declaration of default precision qualifier", TType::getBasicString(publicType.basicType), "");
+            error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(publicType.basicType), "");
             publicType.qualifier.precision = EpqMedium;
             defaultPrecision[publicType.basicType] = EpqMedium;
         }
     } else if (publicType.qualifier.precision != EpqNone)
-        error(line, "type cannot have precision qualifier", TType::getBasicString(publicType.basicType), "");
+        error(loc, "type cannot have precision qualifier", TType::getBasicString(publicType.basicType), "");
 }
 
-void TParseContext::parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type)
+void TParseContext::parameterSamplerCheck(TSourceLoc loc, TStorageQualifier qualifier, const TType& type)
 {
     if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && type.getBasicType() == EbtSampler)
-        error(line, "samplers cannot be output parameters", type.getCompleteTypeString().c_str(), "");
+        error(loc, "samplers cannot be output parameters", type.getCompleteTypeString().c_str(), "");
 }
 
 bool TParseContext::containsSampler(const TType& type)
@@ -934,7 +1302,7 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel()
     TVariable* variable = symbol->getAsVariable();
 
     if (! variable) {
-        error(0, "INTERNAL ERROR, variable expected", name->c_str(), "");
+        infoSink.info.message(EPrefixInternalError, "variable expected");
         return true;
     }
 
@@ -942,7 +1310,7 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel()
 
     if (! symbolTable.insert(*newVariable)) {
         delete newVariable;
-        error(0, "INTERNAL ERROR inserting new symbol", name->c_str(), "");
+        infoSink.info.message(EPrefixInternalError, "inserting new symbol");
         return true;
     }
 
@@ -952,11 +1320,11 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel()
 //
 // Do size checking for an array type's size.
 //
-void TParseContext::arraySizeCheck(int line, TIntermTyped* expr, int& size)
+void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size)
 {
     TIntermConstantUnion* constant = expr->getAsConstantUnion();
     if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) {
-        error(line, "array size must be a constant integer expression", "", "");
+        error(loc, "array size must be a constant integer expression", "", "");
         size = 1;
 
         return;
@@ -965,7 +1333,7 @@ void TParseContext::arraySizeCheck(int line, TIntermTyped* expr, int& size)
     size = constant->getUnionArrayPointer()->getIConst();
 
     if (size <= 0) {
-        error(line, "array size must be a positive integer", "", "");
+        error(loc, "array size must be a positive integer", "", "");
         size = 1;
 
         return;
@@ -977,14 +1345,14 @@ void TParseContext::arraySizeCheck(int line, TIntermTyped* expr, int& size)
 //
 // Returns true if there is an error.
 //
-bool TParseContext::arrayQualifierError(int line, const TPublicType& type)
+bool TParseContext::arrayQualifierError(TSourceLoc loc, const TPublicType& type)
 {
     if (type.qualifier.storage == EvqConst)
-        profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array");
+        profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "const array");
 
     if (type.qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
-        requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays");
-        profileRequires(line, ENoProfile, 150, 0, "vertex input arrays");
+        requireProfile(loc, (EProfileMask)~EEsProfileMask, "vertex input arrays");
+        profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays");
     }
 
     return false;
@@ -993,34 +1361,34 @@ bool TParseContext::arrayQualifierError(int line, const TPublicType& type)
 //
 // Require array to have size
 //
-void TParseContext::arraySizeRequiredCheck(int line, int& size)
+void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int& size)
 {
     if (size == 0) {
-        error(line, "array size required", "", "");
+        error(loc, "array size required", "", "");
         size = 1;
     }
 }
 
-void TParseContext::arrayDimError(int line)
+void TParseContext::arrayDimError(TSourceLoc loc)
 {
-    requireProfile(line, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), "arrays of arrays");
-    profileRequires(line, ECoreProfile, 430, 0, "arrays of arrays");
-    profileRequires(line, ECompatibilityProfile, 430, 0, "arrays of arrays");
+    requireProfile(loc, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), "arrays of arrays");
+    profileRequires(loc, ECoreProfile, 430, 0, "arrays of arrays");
+    profileRequires(loc, ECompatibilityProfile, 430, 0, "arrays of arrays");
 }
 
-void TParseContext::arrayDimCheck(int line, TArraySizes sizes1, TArraySizes sizes2)
+void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes sizes1, TArraySizes sizes2)
 {
     if (sizes1 && sizes2 ||
         sizes1 && sizes1->size() > 1 ||
         sizes2 && sizes2->size() > 1)
-        arrayDimError(line);
+        arrayDimError(loc);
 }
 
-void TParseContext::arrayDimCheck(int line, const TType* type, TArraySizes sizes2)
+void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes sizes2)
 {
     if (type && type->isArray() && sizes2 ||
         sizes2 && sizes2->size() > 1)
-        arrayDimError(line);
+        arrayDimError(loc);
 }
 
 //
@@ -1029,7 +1397,7 @@ void TParseContext::arrayDimCheck(int line, const TType* type, TArraySizes sizes
 //
 // size == 0 means no specified size.
 //
-void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType& type, TVariable*& variable)
+void TParseContext::arrayCheck(TSourceLoc loc, TString& identifier, const TPublicType& type, TVariable*& variable)
 {
     //
     // Don't check for reserved word use until after we know it's not in the symbol table,
@@ -1039,14 +1407,14 @@ void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType&
     bool sameScope = false;
     TSymbol* symbol = symbolTable.find(identifier, 0, &sameScope);
     if (symbol == 0 || !sameScope) {
-        if (reservedErrorCheck(line, identifier))
+        if (reservedErrorCheck(loc, identifier))
             return;
         
         variable = new TVariable(&identifier, TType(type));
 
         if (! symbolTable.insert(*variable)) {
             delete variable;
-            error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), "");
+            error(loc, "INTERNAL ERROR inserting new symbol", identifier.c_str(), "");
 
             return;
         }
@@ -1054,28 +1422,28 @@ void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType&
         variable = symbol->getAsVariable();
 
         if (! variable) {
-            error(line, "array variable name expected", identifier.c_str(), "");
+            error(loc, "array variable name expected", identifier.c_str(), "");
             return;
         }
 
         if (! variable->getType().isArray()) {
-            error(line, "redeclaring non-array as array", identifier.c_str(), "");
+            error(loc, "redeclaring non-array as array", identifier.c_str(), "");
             return;
         }
         if (variable->getType().getArraySize() > 0) {
-            error(line, "redeclaration of array with size", identifier.c_str(), "");
+            error(loc, "redeclaration of array with size", identifier.c_str(), "");
             return;
         }
         
         if (! variable->getType().sameElementType(TType(type))) {
-            error(line, "redeclaration of array with a different type", identifier.c_str(), "");
+            error(loc, "redeclaration of array with a different type", identifier.c_str(), "");
             return;
         }
 
         TType* t = variable->getArrayInformationType();
         while (t != 0) {
             if (t->getMaxArraySize() > type.arraySizes->front()) {
-                error(line, "higher index value already used for the array", identifier.c_str(), "");
+                error(loc, "higher index value already used for the array", identifier.c_str(), "");
                 return;
             }
             t->setArraySizes(type.arraySizes);
@@ -1085,20 +1453,20 @@ void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType&
         variable->getType().setArraySizes(type.arraySizes);
     } 
 
-    voidErrorCheck(line, identifier, type);
+    voidErrorCheck(loc, identifier, type);
 }
 
-bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
+bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc loc)
 {
     TSymbol* symbol = symbolTable.find(node->getName());
     if (symbol == 0) {
-        error(line, " undeclared identifier", node->getName().c_str(), "");
+        error(loc, " undeclared identifier", node->getName().c_str(), "");
         return true;
     }
 
     TVariable* variable = symbol->getAsVariable();
     if (! variable) {
-        error(0, "array variable name expected", node->getName().c_str(), "");
+        error(loc, "array variable name expected", node->getName().c_str(), "");
         return true;
     }
 
@@ -1110,13 +1478,13 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
     if (node->getName() == "gl_TexCoord") {
         TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords");
         if (! texCoord || ! texCoord->getAsVariable()) {
-            infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", line);
+            infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", loc);
             return true;
         }
 
         int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst();
         if (texCoordValue <= size) {
-            error(line, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", "");
+            error(loc, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", "");
             return true;
         }
     }
@@ -1142,14 +1510,14 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
 //
 // Enforce non-initializer type/qualifier rules.
 //
-void TParseContext::nonInitConstCheck(int line, TString& identifier, TPublicType& type)
+void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TPublicType& type)
 {
     //
     // Make the qualifier make sense.
     //
     if (type.qualifier.storage  == EvqConst) {
         type.qualifier.storage = EvqTemporary;
-        error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
+        error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
     }
 }
 
@@ -1157,16 +1525,16 @@ void TParseContext::nonInitConstCheck(int line, TString& identifier, TPublicType
 // Do semantic checking for a variable declaration that has no initializer,
 // and update the symbol table.
 //
-void TParseContext::nonInitCheck(int line, TString& identifier, TPublicType& type)
+void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicType& type)
 {
-    reservedErrorCheck(line, identifier);
+    reservedErrorCheck(loc, identifier);
 
     TVariable* variable = new TVariable(&identifier, TType(type));
 
     if (! symbolTable.insert(*variable))
-        error(line, "redefinition", variable->getName().c_str(), "");
+        error(loc, "redefinition", variable->getName().c_str(), "");
     else {
-        voidErrorCheck(line, identifier, type);
+        voidErrorCheck(loc, identifier, type);
 
         // see if it's a linker-level object to track
         if (type.qualifier.isUniform() || type.qualifier.isPipeInput() || type.qualifier.isPipeOutput())
@@ -1174,7 +1542,7 @@ void TParseContext::nonInitCheck(int line, TString& identifier, TPublicType& typ
     }
 }
 
-void TParseContext::paramCheck(int line, TStorageQualifier qualifier, TType* type)
+void TParseContext::paramCheck(TSourceLoc loc, TStorageQualifier qualifier, TType* type)
 {
     switch (qualifier) {
     case EvqConst:
@@ -1191,22 +1559,22 @@ void TParseContext::paramCheck(int line, TStorageQualifier qualifier, TType* typ
         break;
     default:
         type->getQualifier().storage = EvqIn;
-        error(line, "qualifier not allowed on function parameter", getStorageQualifierString(qualifier), "");
+        error(loc, "qualifier not allowed on function parameter", getStorageQualifierString(qualifier), "");
         break;
     }
 }
 
-void TParseContext::nestedBlockCheck(int line)
+void TParseContext::nestedBlockCheck(TSourceLoc loc)
 {
     if (structNestingLevel > 0)
-        error(line, "cannot nest a block definition inside a structure or block", "", "");
+        error(loc, "cannot nest a block definition inside a structure or block", "", "");
     ++structNestingLevel;
 }
 
-void TParseContext::nestedStructCheck(int line)
+void TParseContext::nestedStructCheck(TSourceLoc loc)
 {
     if (structNestingLevel > 0)
-        error(line, "cannot nest a structure definition inside a structure or block", "", "");
+        error(loc, "cannot nest a structure definition inside a structure or block", "", "");
     ++structNestingLevel;
 }
 
@@ -1215,7 +1583,7 @@ void TParseContext::nestedStructCheck(int line)
 //
 
 // Put the id's layout qualification into the public type.
-void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TString& id)
+void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id)
 {
     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
     if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor))
@@ -1231,26 +1599,26 @@ void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TStrin
     else if (id == TQualifier::getLayoutPackingString(ElpStd430))
         publicType.qualifier.layoutPacking = ElpStd430;
     else if (id == "location")
-        error(line, "requires an integer assignment (e.g., location = 4)", "location", "");
+        error(loc, "requires an integer assignment (e.g., location = 4)", "location", "");
     else if (id == "binding")
-        error(line, "requires an integer assignment (e.g., binding = 4)", "binding", "");
+        error(loc, "requires an integer assignment (e.g., binding = 4)", "binding", "");
     else
-        error(line, "unrecognized layout identifier", id.c_str(), "");
+        error(loc, "unrecognized layout identifier", id.c_str(), "");
 }
 
 // Put the id's layout qualifier value into the public type.
-void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TString& id, int value)
+void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, int value)
 {
     std::transform(id.begin(), id.end(), id.begin(), ::tolower);
     if (id == "location") {
         if ((unsigned int)value >= TQualifier::layoutLocationEnd)
-            error(line, "value is too large", id.c_str(), "");
+            error(loc, "value is too large", id.c_str(), "");
         else
             publicType.qualifier.layoutSlotLocation = value;
     } else if (id == "binding")
-        error(line, "not supported", "binding", "");
+        error(loc, "not supported", "binding", "");
     else
-        error(line, "there is no such layout identifier taking an assigned value", id.c_str(), "");
+        error(loc, "there is no such layout identifier taking an assigned value", id.c_str(), "");
 
     // TODO: semantics: error check: make sure locations are non-overlapping across the whole stage
     // TODO: semantics: error check: if more than one fragment output, all must have a location
@@ -1258,7 +1626,7 @@ void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TStrin
 }
 
 // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
-void TParseContext::mergeLayoutQualifiers(int line, TQualifier& dst, const TQualifier& src)
+void TParseContext::mergeLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src)
 {
     if (src.layoutMatrix != ElmNone)
         dst.layoutMatrix = src.layoutMatrix;
@@ -1281,19 +1649,19 @@ void TParseContext::mergeLayoutQualifiers(int line, TQualifier& dst, const TQual
 //
 // Return the function symbol if found, otherwise 0.
 //
-const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
+const TFunction* TParseContext::findFunction(TSourceLoc loc, TFunction* call, bool *builtIn)
 {
     TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
 
     if (symbol == 0) {        
-        error(line, "no matching overloaded function found", call->getName().c_str(), "");
+        error(loc, "no matching overloaded function found", call->getName().c_str(), "");
 
         return 0;
     }
     
     const TFunction* function = symbol->getAsFunction();
     if (! function) {
-        error(line, "function name expected", call->getName().c_str(), "");
+        error(loc, "function name expected", call->getName().c_str(), "");
 
         return 0;
     }
@@ -1305,16 +1673,16 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu
 // Initializers show up in several places in the grammar.  Have one set of
 // code to handle them here.
 //
-bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier, TPublicType& pType, 
+bool TParseContext::executeInitializerError(TSourceLoc loc, TString& identifier, TPublicType& pType, 
                                             TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
 {
     TType type(pType);
 
     if (variable == 0) {
-        if (reservedErrorCheck(line, identifier))
+        if (reservedErrorCheck(loc, identifier))
             return true;
 
-        if (voidErrorCheck(line, identifier, pType))
+        if (voidErrorCheck(loc, identifier, pType))
             return true;
 
         //
@@ -1322,7 +1690,7 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier
         //
         variable = new TVariable(&identifier, type);
         if (! symbolTable.insert(*variable)) {
-            error(line, "redefinition", variable->getName().c_str(), "");
+            error(loc, "redefinition", variable->getName().c_str(), "");
             return true;
             // don't delete variable, it's used by error recovery, and the pool 
             // pop will take care of the memory
@@ -1334,7 +1702,7 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier
     //
     TStorageQualifier qualifier = variable->getType().getQualifier().storage;
     if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
-        error(line, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
+        error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
         return true;
     }
 
@@ -1348,12 +1716,12 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier
     //
     if (qualifier == EvqConst) {
         if (qualifier != initializer->getType().getQualifier().storage) {
-            error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
+            error(loc, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
             variable->getType().getQualifier().storage = EvqTemporary;
             return true;
         }
         if (type != initializer->getType()) {
-            error(line, " non-matching types for const initializer ", 
+            error(loc, " non-matching types for const initializer ", 
                 variable->getType().getStorageQualifierString(), "");
             variable->getType().getQualifier().storage = EvqTemporary;
             return true;
@@ -1372,21 +1740,21 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier
                 constUnion* constArray = tVar->getConstUnionPointer();
                 variable->shareConstPointer(constArray);
             } else {
-                error(line, "expected variable", initializer->getAsSymbolNode()->getName().c_str(), "");
+                error(loc, "expected variable", initializer->getAsSymbolNode()->getName().c_str(), "");
                 return true;
             }
         } else {
-            error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
+            error(loc, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
             variable->getType().getQualifier().storage = EvqTemporary;
             return true;
         }
     }
  
     if (qualifier != EvqConst) {
-        TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
-        intermNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, line);
+        TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
+        intermNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
         if (intermNode == 0) {
-            assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
+            assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
             return true;
         }
     } else 
@@ -1400,7 +1768,7 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier
 //
 // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
 //
-TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type, TOperator op, TFunction* fnCall, TSourceLoc line)
+TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type, TOperator op, TFunction* fnCall, TSourceLoc loc)
 {
     if (node == 0)
         return 0;
@@ -1429,14 +1797,14 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type
         // If structure constructor or array constructor is being called 
         // for only one parameter inside the structure, we need to call constructStruct function once.
         if (type.isArray())
-            newNode = constructStruct(node, elementType, 1, node->getLine());
+            newNode = constructStruct(node, elementType, 1, node->getLoc());
         else if (op == EOpConstructStruct)
-            newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLine());
+            newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc());
         else
-            newNode = constructBuiltIn(type, op, node, node->getLine(), false);
+            newNode = constructBuiltIn(type, op, node, node->getLoc(), false);
 
         if (newNode && (type.isArray() || op == EOpConstructStruct))
-            newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, line);
+            newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
 
         return newNode;
     }
@@ -1457,11 +1825,11 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type
     for (TIntermSequence::iterator p = sequenceVector.begin(); 
                                    p != sequenceVector.end(); p++, paramCount++) {
         if (type.isArray())
-            newNode = constructStruct(*p, elementType, paramCount+1, node->getLine());
+            newNode = constructStruct(*p, elementType, paramCount+1, node->getLoc());
         else if (op == EOpConstructStruct)
-            newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLine());
+            newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
         else
-            newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
+            newNode = constructBuiltIn(type, op, *p, node->getLoc(), true);
         
         if (newNode) {
             p = sequenceVector.erase(p); 
@@ -1469,7 +1837,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type
         }
     }
 
-    TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, line);
+    TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, loc);
 
     return constructor;
 }
@@ -1481,7 +1849,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type
 //
 // Returns 0 for an error or the constructed node.
 //
-TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset)
+TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermNode* node, TSourceLoc loc, bool subset)
 {
     TIntermTyped* newNode;
     TOperator basicOp;
@@ -1544,13 +1912,13 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
         break;
 
     default:
-        error(line, "unsupported construction", "", "");
+        error(loc, "unsupported construction", "", "");
 
         return 0;
     }
-    newNode = intermediate.addUnaryMath(basicOp, node, node->getLine());
+    newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc());
     if (newNode == 0) {
-        error(line, "can't convert", "constructor", "");
+        error(loc, "can't convert", "constructor", "");
         return 0;
     }
 
@@ -1563,7 +1931,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
         return newNode;
 
     // setAggregateOperator will insert a new node for the constructor, as needed.
-    return intermediate.setAggregateOperator(newNode, op, type, line);
+    return intermediate.setAggregateOperator(newNode, op, type, loc);
 }
 
 // This function tests for the type of the parameters to the structures constructors. Raises
@@ -1571,11 +1939,11 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
 //
 // Returns 0 for an error or the input node itself if the expected and the given parameter types match.
 //
-TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, TSourceLoc line)
+TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, TSourceLoc loc)
 {
     TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
     if (! converted || converted->getType() != type) {
-        error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
+        error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
                 node->getAsTyped()->getType().getCompleteTypeString().c_str(), type.getCompleteTypeString().c_str());
         
         return 0;
@@ -1587,41 +1955,41 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
 //
 // Do everything needed to add an interface block.
 //
-void TParseContext::addBlock(int line, TTypeList& typeList, const TString* instanceName, TArraySizes arraySizes)
+void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString* instanceName, TArraySizes arraySizes)
 {
     // First, error checks
 
-    if (reservedErrorCheck(line, *blockName))
+    if (reservedErrorCheck(loc, *blockName))
         return;
 
-    if (instanceName && reservedErrorCheck(line, *instanceName))
+    if (instanceName && reservedErrorCheck(loc, *instanceName))
         return;
 
     if (profile == EEsProfile && arraySizes)
-        arraySizeRequiredCheck(line, arraySizes->front());        
+        arraySizeRequiredCheck(loc, arraySizes->front());        
 
     if (currentBlockDefaults.storage == EvqUniform) {
-        requireProfile(line, (EProfileMask)(~ENoProfileMask), "uniform block");
-        profileRequires(line, EEsProfile, 300, 0, "uniform block");
+        requireProfile(loc, (EProfileMask)(~ENoProfileMask), "uniform block");
+        profileRequires(loc, EEsProfile, 300, 0, "uniform block");
     } else {
-        error(line, "only uniform interface blocks are supported", blockName->c_str(), "");
+        error(loc, "only uniform interface blocks are supported", blockName->c_str(), "");
 
         return;
     }
 
-    arrayDimCheck(line, arraySizes, 0);
+    arrayDimCheck(loc, arraySizes, 0);
 
     // check for qualifiers and types that don't belong within a block
     for (unsigned int member = 0; member < typeList.size(); ++member) {
         TQualifier memberQualifier = typeList[member].type->getQualifier();
         if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockDefaults.storage)
-            error(line, "member storage qualifier cannot contradict block storage qualifier", typeList[member].type->getFieldName().c_str(), "");
+            error(loc, "member storage qualifier cannot contradict block storage qualifier", typeList[member].type->getFieldName().c_str(), "");
         if (currentBlockDefaults.storage == EvqUniform && memberQualifier.isInterpolation() || memberQualifier.isAuxiliary())
-            error(line, "member of uniform block cannot have an auxiliary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), "");
+            error(loc, "member of uniform block cannot have an auxiliary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), "");
 
         TBasicType basicType = typeList[member].type->getBasicType();
         if (basicType == EbtSampler)
-            error(line, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), "");
+            error(loc, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), "");
     }
 
     // Make default block qualification, and adjust the member qualifications
@@ -1634,10 +2002,10 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta
     default:          defaultQualification.clear();                    break;
     }
 
-    mergeLayoutQualifiers(line, defaultQualification, currentBlockDefaults);
+    mergeLayoutQualifiers(loc, defaultQualification, currentBlockDefaults);
     for (unsigned int member = 0; member < typeList.size(); ++member) {
         TQualifier memberQualification = defaultQualification;
-        mergeQualifiers(line, memberQualification, typeList[member].type->getQualifier(), false);
+        mergeQualifiers(loc, memberQualification, typeList[member].type->getQualifier(), false);
         typeList[member].type->getQualifier() = memberQualification;
     }
 
@@ -1649,7 +2017,7 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta
     blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
     TVariable* userTypeDef = new TVariable(blockName, blockType, true);
     if (! symbolTable.insert(*userTypeDef)) {
-        error(line, "redefinition", blockName->c_str(), "block name");
+        error(loc, "redefinition", blockName->c_str(), "block name");
 
         return;
     }
@@ -1663,9 +2031,9 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta
     TVariable* variable = new TVariable(instanceName, blockType);
     if (! symbolTable.insert(*variable)) {
         if (*instanceName == "")
-            error(line, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
+            error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
         else
-            error(line, "block instance name redefinition", variable->getName().c_str(), "");
+            error(loc, "block instance name redefinition", variable->getName().c_str(), "");
 
         return;
     }
@@ -1675,12 +2043,12 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta
 }
 
 // For an identifier that is already declared, add more qualification to it.
-void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, const TString& identifier)
+void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier)
 {
     TSymbol* existing = symbolTable.find(identifier);
     TVariable* variable = existing ? existing->getAsVariable() : 0;
     if (! variable) {
-        error(line, "identifier not previously declared", identifier.c_str(), "");
+        error(loc, "identifier not previously declared", identifier.c_str(), "");
 
         return;
     }
@@ -1690,7 +2058,7 @@ void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, const
         qualifier.isInterpolation() ||
         qualifier.storage != EvqTemporary ||
         qualifier.precision != EpqNone) {
-        error(line, "cannot add storage, auxiliary, memory, interpolation, or precision qualifier to an existing variable", identifier.c_str(), "");
+        error(loc, "cannot add storage, auxiliary, memory, interpolation, or precision qualifier to an existing variable", identifier.c_str(), "");
 
         return;
     }
@@ -1699,10 +2067,10 @@ void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, const
         variable->getType().getQualifier().invariant = true;
 }
 
-void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, TIdentifierList& identifiers)
+void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, TIdentifierList& identifiers)
 {
     for (unsigned int i = 0; i < identifiers.size(); ++i)
-        addQualifierToExisting(line, qualifier, *identifiers[i]);
+        addQualifierToExisting(loc, qualifier, *identifiers[i]);
 }
 
 void TParseContext::updateQualifierDefaults(TQualifier qualifier)
@@ -1728,13 +2096,13 @@ void TParseContext::updateQualifierDefaults(TQualifier qualifier)
     }
 }
 
-void TParseContext::updateQualifierDefaults(int line, TQualifier qualifier)
+void TParseContext::updateQualifierDefaults(TSourceLoc loc, TQualifier qualifier)
 {
     if (qualifier.isAuxiliary() || 
         qualifier.isMemory() ||
         qualifier.isInterpolation() ||
         qualifier.precision != EpqNone)
-        error(line, "cannot use auxiliary, memory, interpolation, or precision qualifier in a standalone qualifier", "", "");
+        error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a standalone qualifier", "", "");
 
     switch (qualifier.storage) {
     case EvqUniform:
@@ -1742,47 +2110,47 @@ void TParseContext::updateQualifierDefaults(int line, TQualifier qualifier)
     case EvqOut:
         break;
     default:
-        error(line, "standalone qualifier requires 'uniform', 'in', or 'out' storage qualification", "", "");
+        error(loc, "standalone qualifier requires 'uniform', 'in', or 'out' storage qualification", "", "");
         return;
     }
 
     updateQualifierDefaults(qualifier);
 }
 
-void TParseContext::updateTypedDefaults(int line, TQualifier qualifier, const TString* id)
+void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, const TString* id)
 {
     bool cantHaveId = false;
 
     if (! id) {
         if (qualifier.hasLayout())
-            warn(line, "cannot set qualifier defaults when using a type and no identifier", "", "");
+            warn(loc, "cannot set qualifier defaults when using a type and no identifier", "", "");
         
         return;
     }
 
     if (qualifier.storage == EvqUniform) {
         if (qualifier.layoutMatrix != ElmNone)
-            error(line, "cannot specify matrix layout on a variable declaration", id->c_str(), "");
+            error(loc, "cannot specify matrix layout on a variable declaration", id->c_str(), "");
         if (qualifier.layoutPacking != ElpNone)
-            error(line, "cannot specify packing on a variable declaration", id->c_str(), "");
+            error(loc, "cannot specify packing on a variable declaration", id->c_str(), "");
     } else if (qualifier.storage == EvqVaryingIn) {
         if (qualifier.hasLayout() && language != EShLangVertex) {
-            error(line, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), "");
+            error(loc, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), "");
         }
     } else if (qualifier.storage == EvqVaryingOut) {
         if (qualifier.hasLayout() && language != EShLangFragment) {
-            error(line, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), "");
+            error(loc, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), "");
         }
     } else {
         if (qualifier.layoutMatrix != ElmNone ||
             qualifier.layoutPacking != ElpNone)
-            error(line, "layout qualifiers for matrix layout and packing only apply to uniform blocks", id->c_str(), "");
+            error(loc, "layout qualifiers for matrix layout and packing only apply to uniform blocks", id->c_str(), "");
         else if (qualifier.hasLocation())
-            error(line, "location qualifiers only appy to uniform, in, or out storage qualifiers", id->c_str(), "");
+            error(loc, "location qualifiers only appy to uniform, in, or out storage qualifiers", id->c_str(), "");
     }
 
     if (cantHaveId)
-        error(line, "cannot set global layout qualifiers on uniform variable, use just 'uniform' or a block", id->c_str(), "");
+        error(loc, "cannot set global layout qualifiers on uniform variable, use just 'uniform' or a block", id->c_str(), "");
 
     updateQualifierDefaults(qualifier);
 }
@@ -1799,7 +2167,7 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter
 
     if (statements) {
         if (switchSequence->size() == 0)
-            error(statements->getLine(), "cannot have statements before first case/default label", "switch", "");
+            error(statements->getLoc(), "cannot have statements before first case/default label", "switch", "");
         statements->setOperator(EOpSequence);
         switchSequence->push_back(statements);
     }
@@ -1811,14 +2179,14 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter
                 TIntermTyped* prevExpression = prevBranch->getExpression();
                 TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression();
                 if (prevExpression == 0 && newExpression == 0)
-                    error(branchNode->getLine(), "duplicate label", "default", "");
+                    error(branchNode->getLoc(), "duplicate label", "default", "");
                 else if (prevExpression != 0 && 
                           newExpression != 0 &&
                          prevExpression->getAsConstantUnion() && 
                           newExpression->getAsConstantUnion() &&
                          prevExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst() == 
                           newExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst())
-                    error(branchNode->getLine(), "duplicated value", "case", "");
+                    error(branchNode->getLoc(), "duplicated value", "case", "");
             }
         }
         switchSequence->push_back(branchNode);
@@ -1829,17 +2197,17 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter
 // Turn the top-level node sequence built up of wrapupSwitchSubsequence9)
 // into a switch node.
 //
-TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TIntermAggregate* lastStatements)
+TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
 {
-    profileRequires(line, EEsProfile, 300, 0, "switch statements");
-    profileRequires(line, ENoProfile, 130, 0, "switch statements");
+    profileRequires(loc, EEsProfile, 300, 0, "switch statements");
+    profileRequires(loc, ENoProfile, 130, 0, "switch statements");
 
     wrapupSwitchSubsequence(lastStatements, 0);
 
     if (expression == 0 || 
         expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint ||
         expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector())
-            error(line, "condition must be a scalar integer expression", "switch", "");
+            error(loc, "condition must be a scalar integer expression", "switch", "");
 
     // If there is nothing to do, drop the switch but still execute the expression
     TIntermSequence* switchSequence = switchSequenceStack.back();
@@ -1847,17 +2215,17 @@ TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TInter
         return expression;
 
     if (lastStatements == 0) {
-        error(line, "last case/default label must be followed by statements", "switch", "");
+        error(loc, "last case/default label must be followed by statements", "switch", "");
 
         return expression;
     }
 
     TIntermAggregate* body = new TIntermAggregate(EOpSequence);
     body->getSequence() = *switchSequenceStack.back();
-    body->setLine(line);
+    body->setLoc(loc);
 
     TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
-    switchNode->setLine(line);
+    switchNode->setLoc(loc);
 
     return switchNode;
 }
@@ -1869,7 +2237,7 @@ TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TInter
 // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
 // a constant matrix.
 //
-TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc loc)
 {
     TIntermTyped* typedNode;
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1879,12 +2247,12 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
         unionArray = tempConstantNode->getUnionArrayPointer();
 
         if (!unionArray) {  // this error message should never be raised
-            infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", line);
+            infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", loc);
 
             return node;
         }
     } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
-        error(line, "Cannot offset into the vector", "Error", "");
+        error(loc, "Cannot offset into the vector", "Error", "");
 
         return 0;
     }
@@ -1893,13 +2261,13 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
 
     for (int i = 0; i < fields.num; i++) {
         if (fields.offsets[i] >= node->getType().getObjectSize()) {
-            error(line, "", "[", "vector index out of range '%d'", fields.offsets[i]);
+            error(loc, "", "[", "vector index out of range '%d'", fields.offsets[i]);
             fields.offsets[i] = 0;
         }
         
         constArray[i] = unionArray[fields.offsets[i]];
     } 
-    typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
+    typedNode = intermediate.addConstantUnion(constArray, node->getType(), loc);
 
     return typedNode;
 }
@@ -1910,13 +2278,13 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
 // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a 
 // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
 //
-TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc loc)
 {
     TIntermTyped* typedNode;
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
 
     if (index >= node->getType().getMatrixCols()) {
-        error(line, "", "[", "matrix field selection out of range '%d'", index);
+        error(loc, "", "[", "matrix field selection out of range '%d'", index);
         index = 0;
     }
 
@@ -1924,9 +2292,9 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
          constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
          int size = tempConstantNode->getType().getMatrixRows();
          // Note: the type is corrected (dereferenced) by the caller
-         typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
+         typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), loc);
     } else {
-        error(line, "Cannot offset into the matrix", "Error", "");
+        error(loc, "Cannot offset into the matrix", "Error", "");
 
         return 0;
     }
@@ -1941,7 +2309,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
 // to the function could either be a symbol node (a[0] where a is a constant array)that represents a 
 // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
 //
-TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc loc)
 {
     TIntermTyped* typedNode;
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
@@ -1950,7 +2318,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
     arrayElementType.dereference();
 
     if (index >= node->getType().getArraySize() || index < 0) {
-        error(line, "", "[", "array index '%d' out of range", index);
+        error(loc, "", "[", "array index '%d' out of range", index);
         index = 0;
     }
 
@@ -1958,9 +2326,9 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
 
     if (tempConstantNode) {
          constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
-         typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
+         typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), loc);
     } else {
-        error(line, "Cannot offset into the array", "Error", "");
+        error(loc, "Cannot offset into the array", "Error", "");
 
         return 0;
     }
@@ -1974,7 +2342,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
 // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
 // function and returns the parse-tree with the values of the embedded/nested struct.
 //
-TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
+TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc loc)
 {
     TTypeList* fields = node->getType().getStruct();
     TIntermTyped *typedNode;
@@ -1993,9 +2361,9 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
     if (tempConstantNode) {
          constUnion* constArray = tempConstantNode->getUnionArrayPointer();
 
-         typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
+         typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), loc); // type will be changed in the calling function
     } else {
-        error(line, "Cannot offset into the structure", "Error", "");
+        error(loc, "Cannot offset into the structure", "Error", "");
 
         return 0;
     }
index 990fd3f..8f72eac 100644 (file)
@@ -55,7 +55,9 @@ struct TPragma {
        TPragmaTable pragmaTable;
 };
 
-
+namespace glslang {
+    class TScanContext;
+};
 
 //
 // The following are extra variables needed during parsing, grouped together so
@@ -64,6 +66,7 @@ struct TPragma {
 struct TParseContext {
     TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&,
                   bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
+    glslang::TScanContext *scanContext;
     TIntermediate& intermediate; // to hold and build a parse tree
     TSymbolTable& symbolTable;   // symbol table that goes with the current language, version, and profile
     TInfoSink& infoSink;
@@ -71,7 +74,6 @@ struct TParseContext {
     TIntermNode* treeRoot;       // root of parse tree being created
     TIntermAggregate *linkage;   // aggregate node of objects the linker may need, if not reference by the rest of the AST
     int numErrors;               // number of compile-time errors encountered
-    bool lexAfterType;           // true if we've recognized a type, so can only be looking for an identifier
     int loopNestingLevel;        // 0 if outside all loops
     int structNestingLevel;      // 0 if outside blocks and structures
     TList<TIntermSequence*> switchSequenceStack;  // case, node, case, case, node, ...; ensure only one node between cases;   stack of them for nesting
@@ -91,7 +93,7 @@ struct TParseContext {
     static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex()
     TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
        TString HashErrMsg;
-    bool AfterEOF;
+    bool afterEOF;
     const TString* blockName;
     TQualifier globalUniformDefaults;
     TQualifier globalInputDefaults;
@@ -100,93 +102,91 @@ struct TParseContext {
 
     void initializeExtensionBehavior();
     const char* getPreamble();
+    bool parseShaderStrings(char* strings[], int strLen[], int numStrings);
     
     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);
+    bool reservedErrorCheck(TSourceLoc, const TString& identifier);
 
-    TIntermTyped* handleVariable(int line, TSymbol* symbol, TString* string);
-    bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
-    void assignError(int line, const char* op, TString left, TString right);
-    void unaryOpError(int line, const char* op, TString operand);
-    void binaryOpError(int line, const char* op, TString left, TString right);
+    TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
+    bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&);
+    void assignError(TSourceLoc, const char* op, TString left, TString right);
+    void unaryOpError(TSourceLoc, const char* op, TString operand);
+    void binaryOpError(TSourceLoc, const char* op, TString left, TString right);
     void variableCheck(TIntermTyped*& nodePtr);
-    bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
+    bool lValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
     void constCheck(TIntermTyped* node, const char* token);
     void integerCheck(TIntermTyped* node, const char* token);
-    void globalCheck(int line, bool global, const char* token);
-    bool constructorError(int line, TIntermNode*, TFunction&, TOperator, TType&);
-    void arraySizeCheck(int line, TIntermTyped* expr, int& size);
-    bool arrayQualifierError(int line, const TPublicType&);
-    void arraySizeRequiredCheck(int line, int& size);
-    void arrayDimError(int line);
-    void arrayDimCheck(int line, TArraySizes sizes1, TArraySizes sizes2);
-    void arrayDimCheck(int line, const TType*, TArraySizes);
-    void arrayCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable);
+    void globalCheck(TSourceLoc, bool global, const char* token);
+    bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&);
+    void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
+    bool arrayQualifierError(TSourceLoc, const TPublicType&);
+    void arraySizeRequiredCheck(TSourceLoc, int& size);
+    void arrayDimError(TSourceLoc);
+    void arrayDimCheck(TSourceLoc, TArraySizes sizes1, TArraySizes sizes2);
+    void arrayDimCheck(TSourceLoc, const TType*, TArraySizes);
+    void arrayCheck(TSourceLoc, TString& identifier, const TPublicType&, TVariable*& variable);
     bool insertBuiltInArrayAtGlobalLevel();
-    bool voidErrorCheck(int, const TString&, const TPublicType&);
-    void boolCheck(int, const TIntermTyped*);
-    void boolCheck(int, const TPublicType&);
-    bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
-    void globalQualifierFix(int line, TQualifier&, const TPublicType&);
-    bool structQualifierErrorCheck(int line, const TPublicType& pType);
-    void mergeQualifiers(int line, TQualifier& dst, const TQualifier& src, bool force);
-    void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier);
+    bool voidErrorCheck(TSourceLoc, const TString&, const TPublicType&);
+    void boolCheck(TSourceLoc, const TIntermTyped*);
+    void boolCheck(TSourceLoc, const TPublicType&);
+    bool samplerErrorCheck(TSourceLoc, const TPublicType& pType, const char* reason);
+    void globalQualifierFix(TSourceLoc, TQualifier&, const TPublicType&);
+    bool structQualifierErrorCheck(TSourceLoc, const TPublicType& pType);
+    void mergeQualifiers(TSourceLoc, TQualifier& dst, const TQualifier& src, bool force);
+    void setDefaultPrecision(TSourceLoc, TPublicType&, TPrecisionQualifier);
     int computeSamplerTypeIndex(TSampler&);
     TPrecisionQualifier getDefaultPrecision(TPublicType&);
-    void precisionQualifierCheck(int line, TPublicType&);
-    void parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type);
+    void precisionQualifierCheck(TSourceLoc, TPublicType&);
+    void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
     bool containsSampler(const TType& type);
-    void nonInitConstCheck(int line, TString& identifier, TPublicType& type);
-    void nonInitCheck(int line, TString& identifier, TPublicType& type);
-    void paramCheck(int line, TStorageQualifier qualifier, TType* type);
-    void nestedBlockCheck(int line);
-    void nestedStructCheck(int line);
-
-    void setLayoutQualifier(int line, TPublicType&, TString&);
-    void setLayoutQualifier(int line, TPublicType&, TString&, int);
-    void mergeLayoutQualifiers(int line, TQualifier& dest, const TQualifier& src);
-
-    const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
-    bool executeInitializerError(TSourceLoc line, TString& identifier, TPublicType& pType,
+    void nonInitConstCheck(TSourceLoc, TString& identifier, TPublicType& type);
+    void nonInitCheck(TSourceLoc, TString& identifier, TPublicType& type);
+    void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type);
+    void nestedBlockCheck(TSourceLoc);
+    void nestedStructCheck(TSourceLoc);
+
+    void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
+    void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
+    void mergeLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
+
+    const TFunction* findFunction(TSourceLoc, TFunction* pfnCall, bool *builtIn = 0);
+    bool executeInitializerError(TSourceLoc, TString& identifier, TPublicType& pType,
                                  TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
     TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc);
     TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
     TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
-    void addBlock(int line, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0);
-    void addQualifierToExisting(int line, TQualifier, const TString& identifier);
-    void addQualifierToExisting(int line, TQualifier, TIdentifierList&);
+    void addBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0);
+    void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
+    void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
     void updateQualifierDefaults(TQualifier);
-    void updateQualifierDefaults(int line, TQualifier);
-    void updateTypedDefaults(int line, TQualifier, const TString* id);
+    void updateQualifierDefaults(TSourceLoc, TQualifier);
+    void updateTypedDefaults(TSourceLoc, TQualifier, const TString* id);
     void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
-    TIntermNode* addSwitch(int line, TIntermTyped* expression, TIntermAggregate* body);
+    TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body);
     TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
     TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
-    TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
+    TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc);
     TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
 
     bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
 
-    void requireProfile(int line, EProfileMask profileMask, const char *featureDesc);
-    void requireStage(int line, EShLanguageMask languageMask, const char *featureDesc);
-    void profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc);
-    void profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc);
-    void checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc);
-    void requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc);
-    void fullIntegerCheck(int line, const char* op);
-    void doubleCheck(int line, const char* op);
+    void requireProfile(TSourceLoc, EProfileMask profileMask, const char *featureDesc);
+    void requireStage(TSourceLoc, EShLanguageMask languageMask, const char *featureDesc);
+    void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc);
+    void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc);
+    void checkDeprecated(TSourceLoc, EProfile callingProfile, int depVersion, const char *featureDesc);
+    void requireNotRemoved(TSourceLoc, EProfile callingProfile, int removedVersion, const char *featureDesc);
+    void fullIntegerCheck(TSourceLoc, const char* op);
+    void doubleCheck(TSourceLoc, const char* op);
 };
 
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&, const char* preamble);
-int PaParseComment(int &lineno, TParseContext&);
-void ResetFlex();
-
 typedef TParseContext* TParseContextPointer;
 TParseContextPointer& ThreadLocalParseContext();
 
+// TODO: threading:
 typedef struct TThreadParseContextRec
 {
        TParseContext *lpGlobalParseContext;
index d7f1119..ca9af6a 100644 (file)
 //POSSIBILITY OF SUCH DAMAGE.
 //
 
+//
+// GLSL scanning, leveraging the scanning done by the preprocessor.
+//
+
 #include <string.h>
 
 #include "Scan.h"
+#include "Include/Types.h"
+#include "SymbolTable.h"
+#include "glslang_tab.cpp.h"
+#include "ParseHelper.h"
+#include "ScanContext.h"
+
+// preprocessor includes
+extern "C" {
+    #include "preprocessor/parser.h"
+    #include "preprocessor/preprocess.h"
+}
 
 namespace glslang {
     
@@ -138,10 +153,14 @@ void ConsumeWhitespaceComment(TInputScanner& input, bool& foundNonSpaceTab)
     } while (true);
 }
 
-// Returns true if there was non-white space (e.g., a comment, newline) before the #version;
-// otherwise, returns true.
+// Returns true if there was non-white space (e.g., a comment, newline) before the #version
+// or no #version was found; otherwise, returns false.  There is no error case, it always
+// succeeds, but will leave version == 0 if no #version was found.
+//
+// N.B. does not attempt to leave input in any particular known state.  The assumption
+// is that scanning will start anew, following the rules for the chosen version/profile,
+// and with a corresponding parsing context.
 //
-// N.B. does not attempt to leave input in any particular known state
 bool ScanVersion(TInputScanner& input, int& version, EProfile& profile)
 {
     // This function doesn't have to get all the semantics correct, 
@@ -214,3 +233,793 @@ bool ScanVersion(TInputScanner& input, int& version, EProfile& profile)
 }
 
 }; // end glslang namespace
+
+namespace glslang {
+
+// This gets filled in by the preprocessor scanner.
+class TPpToken{
+public:
+    yystypepp lexer;
+};
+
+// Fill this in when doing glslang-level scanning, to hand back to the parser.
+class TParserToken {
+public:
+    explicit TParserToken(YYSTYPE& b) : sType(b) { }
+
+    YYSTYPE& sType;
+};
+
+};  // end namespace glslang
+
+// This is the function the glslang parser (i.e., bison) calls to get its next token
+int yylex(YYSTYPE* glslangTokenDesc, TParseContext& parseContext)
+{
+    glslang::TParserToken token(*glslangTokenDesc);
+
+    return parseContext.scanContext->tokenize(token);
+}
+
+namespace {
+
+// A single global usable by all threads, by all versions, by all languages.
+// After a single process-level initialization, this is read only and thread safe
+std::map<std::string, int>* KeywordMap = 0;
+std::set<std::string>* ReservedSet = 0;
+
+};
+
+namespace glslang {
+
+void TScanContext::fillInKeywordMap()
+{
+    if (KeywordMap != 0) {
+        // this is really an error, as this should called only once per process
+        // but, the only risk is if two threads called simultaneously
+        return;
+    }
+    KeywordMap = new std::map<std::string, int>;
+
+    (*KeywordMap)["const"] =                   CONST;
+    (*KeywordMap)["uniform"] =                 UNIFORM;
+    (*KeywordMap)["in"] =                      IN;
+    (*KeywordMap)["out"] =                     OUT;
+    (*KeywordMap)["inout"] =                   INOUT;
+    (*KeywordMap)["struct"] =                  STRUCT;
+    (*KeywordMap)["break"] =                   BREAK;
+    (*KeywordMap)["continue"] =                CONTINUE;
+    (*KeywordMap)["do"] =                      DO;
+    (*KeywordMap)["for"] =                     FOR;
+    (*KeywordMap)["while"] =                   WHILE;
+    (*KeywordMap)["switch"] =                  SWITCH;
+    (*KeywordMap)["case"] =                    CASE;
+    (*KeywordMap)["default"] =                 DEFAULT;
+    (*KeywordMap)["if"] =                      IF;
+    (*KeywordMap)["else"] =                    ELSE;
+    (*KeywordMap)["discard"] =                 DISCARD;
+    (*KeywordMap)["return"] =                  RETURN;
+    (*KeywordMap)["void"] =                    VOID;
+    (*KeywordMap)["bool"] =                    BOOL;
+    (*KeywordMap)["float"] =                   FLOAT;
+    (*KeywordMap)["int"] =                     INT;
+    (*KeywordMap)["bvec2"] =                   BVEC2;
+    (*KeywordMap)["bvec3"] =                   BVEC3;
+    (*KeywordMap)["bvec4"] =                   BVEC4;
+    (*KeywordMap)["vec2"] =                    VEC2;
+    (*KeywordMap)["vec3"] =                    VEC3;
+    (*KeywordMap)["vec4"] =                    VEC4;
+    (*KeywordMap)["ivec2"] =                   IVEC2;
+    (*KeywordMap)["ivec3"] =                   IVEC3;
+    (*KeywordMap)["ivec4"] =                   IVEC4;
+    (*KeywordMap)["mat2"] =                    MAT2;
+    (*KeywordMap)["mat3"] =                    MAT3;
+    (*KeywordMap)["mat4"] =                    MAT4;
+    (*KeywordMap)["sampler2D"] =               SAMPLER2D;
+    (*KeywordMap)["samplerCube"] =             SAMPLERCUBE;
+    (*KeywordMap)["true"] =                    BOOLCONSTANT;
+    (*KeywordMap)["false"] =                   BOOLCONSTANT;
+    (*KeywordMap)["attribute"] =               ATTRIBUTE;
+    (*KeywordMap)["varying"] =                 VARYING;
+    (*KeywordMap)["buffer"] =                  BUFFER;
+    (*KeywordMap)["coherent"] =                COHERENT;
+    (*KeywordMap)["restrict"] =                RESTRICT;
+    (*KeywordMap)["readonly"] =                READONLY;
+    (*KeywordMap)["writeonly"] =               WRITEONLY;
+    (*KeywordMap)["atomic_uint"] =             ATOMIC_UINT;
+    (*KeywordMap)["volatile"] =                VOLATILE;
+    (*KeywordMap)["layout"] =                  LAYOUT;
+    (*KeywordMap)["shared"] =                  SHARED;
+    (*KeywordMap)["patch"] =                   PATCH;
+    (*KeywordMap)["sample"] =                  SAMPLE;
+    (*KeywordMap)["subroutine"] =              SUBROUTINE;
+    (*KeywordMap)["highp"] =                   HIGH_PRECISION;
+    (*KeywordMap)["mediump"] =                 MEDIUM_PRECISION;
+    (*KeywordMap)["lowp"] =                    LOW_PRECISION;
+    (*KeywordMap)["precision"] =               PRECISION;
+    (*KeywordMap)["mat2x2"] =                  MAT2X2;
+    (*KeywordMap)["mat2x3"] =                  MAT2X3;
+    (*KeywordMap)["mat2x4"] =                  MAT2X4;
+    (*KeywordMap)["mat3x2"] =                  MAT3X2;
+    (*KeywordMap)["mat3x3"] =                  MAT3X3;
+    (*KeywordMap)["mat3x4"] =                  MAT3X4;
+    (*KeywordMap)["mat4x2"] =                  MAT4X2;
+    (*KeywordMap)["mat4x3"] =                  MAT4X3;
+    (*KeywordMap)["mat4x4"] =                  MAT4X4;
+    (*KeywordMap)["dmat2"] =                   DMAT2;
+    (*KeywordMap)["dmat3"] =                   DMAT3;
+    (*KeywordMap)["dmat4"] =                   DMAT4;
+    (*KeywordMap)["dmat2x2"] =                 DMAT2X2;
+    (*KeywordMap)["dmat2x3"] =                 DMAT2X3;
+    (*KeywordMap)["dmat2x4"] =                 DMAT2X4;
+    (*KeywordMap)["dmat3x2"] =                 DMAT3X2;
+    (*KeywordMap)["dmat3x3"] =                 DMAT3X3;
+    (*KeywordMap)["dmat3x4"] =                 DMAT3X4;
+    (*KeywordMap)["dmat4x2"] =                 DMAT4X2;
+    (*KeywordMap)["dmat4x3"] =                 DMAT4X3;
+    (*KeywordMap)["dmat4x4"] =                 DMAT4X4;
+    (*KeywordMap)["image1D"] =                 IMAGE1D;
+    (*KeywordMap)["iimage1D"] =                IIMAGE1D;
+    (*KeywordMap)["uimage1D"] =                UIMAGE1D;
+    (*KeywordMap)["image2D"] =                 IMAGE2D;
+    (*KeywordMap)["iimage2D"] =                IIMAGE2D;
+    (*KeywordMap)["uimage2D"] =                UIMAGE2D;
+    (*KeywordMap)["image3D"] =                 IMAGE3D;
+    (*KeywordMap)["iimage3D"] =                IIMAGE3D;
+    (*KeywordMap)["uimage3D"] =                UIMAGE3D;
+    (*KeywordMap)["image2DRect"] =             IMAGE2DRECT;
+    (*KeywordMap)["iimage2DRect"] =            IIMAGE2DRECT;
+    (*KeywordMap)["uimage2DRect"] =            UIMAGE2DRECT;
+    (*KeywordMap)["imageCube"] =               IMAGECUBE;
+    (*KeywordMap)["iimageCube"] =              IIMAGECUBE;
+    (*KeywordMap)["uimageCube"] =              UIMAGECUBE;
+    (*KeywordMap)["imageBuffer"] =             IMAGEBUFFER;
+    (*KeywordMap)["iimageBuffer"] =            IIMAGEBUFFER;
+    (*KeywordMap)["uimageBuffer"] =            UIMAGEBUFFER;
+    (*KeywordMap)["image1DArray"] =            IMAGE1DARRAY;
+    (*KeywordMap)["iimage1DArray"] =           IIMAGE1DARRAY;
+    (*KeywordMap)["uimage1DArray"] =           UIMAGE1DARRAY;
+    (*KeywordMap)["image2DArray"] =            IMAGE2DARRAY;
+    (*KeywordMap)["iimage2DArray"] =           IIMAGE2DARRAY;
+    (*KeywordMap)["uimage2DArray"] =           UIMAGE2DARRAY;
+    (*KeywordMap)["imageCubeArray"] =          IMAGECUBEARRAY;
+    (*KeywordMap)["iimageCubeArray"] =         IIMAGECUBEARRAY;
+    (*KeywordMap)["uimageCubeArray"] =         UIMAGECUBEARRAY;
+    (*KeywordMap)["image2DMS"] =               IMAGE2DMS;
+    (*KeywordMap)["iimage2DMS"] =              IIMAGE2DMS;
+    (*KeywordMap)["uimage2DMS"] =              UIMAGE2DMS;
+    (*KeywordMap)["image2DMSArray"] =          IMAGE2DMSARRAY;
+    (*KeywordMap)["iimage2DMSArray"] =         IIMAGE2DMSARRAY;
+    (*KeywordMap)["uimage2DMSArray"] =         UIMAGE2DMSARRAY;
+    (*KeywordMap)["double"] =                  DOUBLE;
+    (*KeywordMap)["dvec2"] =                   DVEC2;
+    (*KeywordMap)["dvec3"] =                   DVEC3;
+    (*KeywordMap)["dvec4"] =                   DVEC4;
+    (*KeywordMap)["samplerCubeArray"] =        SAMPLERCUBEARRAY;
+    (*KeywordMap)["samplerCubeArrayShadow"] =  SAMPLERCUBEARRAYSHADOW;
+    (*KeywordMap)["isamplerCubeArray"] =       ISAMPLERCUBEARRAY;
+    (*KeywordMap)["usamplerCubeArray"] =       USAMPLERCUBEARRAY;
+    (*KeywordMap)["sampler1DArrayShadow"] =    SAMPLER1DARRAYSHADOW;
+    (*KeywordMap)["isampler1DArray"] =         ISAMPLER1DARRAY;
+    (*KeywordMap)["usampler1D"] =              USAMPLER1D;
+    (*KeywordMap)["isampler1D"] =              ISAMPLER1D;
+    (*KeywordMap)["usampler1DArray"] =         USAMPLER1DARRAY;
+    (*KeywordMap)["samplerBuffer"] =           SAMPLERBUFFER;
+    (*KeywordMap)["uint"] =                    UINT;
+    (*KeywordMap)["uvec2"] =                   UVEC2;
+    (*KeywordMap)["uvec3"] =                   UVEC3;
+    (*KeywordMap)["uvec4"] =                   UVEC4;
+    (*KeywordMap)["samplerCubeShadow"] =       SAMPLERCUBESHADOW;
+    (*KeywordMap)["sampler2DArray"] =          SAMPLER2DARRAY;
+    (*KeywordMap)["sampler2DArrayShadow"] =    SAMPLER2DARRAYSHADOW;
+    (*KeywordMap)["isampler2D"] =              ISAMPLER2D;
+    (*KeywordMap)["isampler3D"] =              ISAMPLER3D;
+    (*KeywordMap)["isamplerCube"] =            ISAMPLERCUBE;
+    (*KeywordMap)["isampler2DArray"] =         ISAMPLER2DARRAY;
+    (*KeywordMap)["usampler2D"] =              USAMPLER2D;
+    (*KeywordMap)["usampler3D"] =              USAMPLER3D;
+    (*KeywordMap)["usamplerCube"] =            USAMPLERCUBE;
+    (*KeywordMap)["usampler2DArray"] =         USAMPLER2DARRAY;
+    (*KeywordMap)["isampler2DRect"] =          ISAMPLER2DRECT;
+    (*KeywordMap)["usampler2DRect"] =          USAMPLER2DRECT;
+    (*KeywordMap)["isamplerBuffer"] =          ISAMPLERBUFFER;
+    (*KeywordMap)["usamplerBuffer"] =          USAMPLERBUFFER;
+    (*KeywordMap)["sampler2DMS"] =             SAMPLER2DMS;
+    (*KeywordMap)["isampler2DMS"] =            ISAMPLER2DMS;
+    (*KeywordMap)["usampler2DMS"] =            USAMPLER2DMS;
+    (*KeywordMap)["sampler2DMSArray"] =        SAMPLER2DMSARRAY;
+    (*KeywordMap)["isampler2DMSArray"] =       ISAMPLER2DMSARRAY;
+    (*KeywordMap)["usampler2DMSArray"] =       USAMPLER2DMSARRAY;
+    (*KeywordMap)["sampler1D"] =               SAMPLER1D;
+    (*KeywordMap)["sampler1DShadow"] =         SAMPLER1DSHADOW;
+    (*KeywordMap)["sampler3D"] =               SAMPLER3D;
+    (*KeywordMap)["sampler2DShadow"] =         SAMPLER2DSHADOW;
+    (*KeywordMap)["sampler2DRect"] =           SAMPLER2DRECT;
+    (*KeywordMap)["sampler2DRectShadow"] =     SAMPLER2DRECTSHADOW;
+    (*KeywordMap)["sampler1DArray"] =          SAMPLER1DARRAY;
+    (*KeywordMap)["noperspective"] =           NOPERSPECTIVE;
+    (*KeywordMap)["smooth"] =                  SMOOTH;
+    (*KeywordMap)["flat"] =                    FLAT;
+    (*KeywordMap)["centroid"] =                CENTROID;
+    (*KeywordMap)["precise"] =                 PRECISE;
+    (*KeywordMap)["invariant"] =               INVARIANT;
+    (*KeywordMap)["packed"] =                  PACKED;
+    (*KeywordMap)["resource"] =                RESOURCE;
+    (*KeywordMap)["superp"] =                  SUPERP;
+
+    ReservedSet = new std::set<std::string>;
+    
+    ReservedSet->insert("common");
+    ReservedSet->insert("partition");
+    ReservedSet->insert("active");
+    ReservedSet->insert("asm");
+    ReservedSet->insert("class");
+    ReservedSet->insert("union");
+    ReservedSet->insert("enum");
+    ReservedSet->insert("typedef");
+    ReservedSet->insert("template");
+    ReservedSet->insert("this");
+    ReservedSet->insert("goto");
+    ReservedSet->insert("inline");
+    ReservedSet->insert("noinline");
+    ReservedSet->insert("public");
+    ReservedSet->insert("static");
+    ReservedSet->insert("extern");
+    ReservedSet->insert("external");
+    ReservedSet->insert("interface");
+    ReservedSet->insert("long");
+    ReservedSet->insert("short");
+    ReservedSet->insert("half");
+    ReservedSet->insert("fixed");
+    ReservedSet->insert("unsigned");
+    ReservedSet->insert("input");
+    ReservedSet->insert("output");
+    ReservedSet->insert("hvec2");
+    ReservedSet->insert("hvec3");
+    ReservedSet->insert("hvec4");
+    ReservedSet->insert("fvec2");
+    ReservedSet->insert("fvec3");
+    ReservedSet->insert("fvec4");
+    ReservedSet->insert("sampler3DRect");
+    ReservedSet->insert("filter");
+    ReservedSet->insert("sizeof");
+    ReservedSet->insert("cast");
+    ReservedSet->insert("namespace");
+    ReservedSet->insert("using");
+}
+
+int TScanContext::tokenize(TParserToken& token)
+{
+    parserToken = &token;
+    TPpToken ppTokenStorage;
+    ppToken = &ppTokenStorage;
+    tokenText = PpTokenize(&ppToken->lexer);
+
+    loc.string = cpp->tokenLoc->file;
+    loc.line = cpp->tokenLoc->line;
+    parserToken->sType.lex.loc = loc;
+    switch (ppToken->lexer.ppToken) {
+    case ';':  afterType = false;   return SEMICOLON;
+    case ',':  afterType = false;   return COMMA;
+    case ':':                       return COLON;
+    case '=':  afterType = false;   return EQUAL;
+    case '(':  afterType = false;   return LEFT_PAREN;
+    case ')':  afterType = false;   return RIGHT_PAREN;
+    case '.':  field = true;        return DOT;
+    case '!':                       return BANG;
+    case '-':                       return DASH;
+    case '~':                       return TILDE;
+    case '+':                       return PLUS;
+    case '*':                       return STAR;
+    case '/':                       return SLASH;
+    case '%':                       return PERCENT;
+    case '<':                       return LEFT_ANGLE;
+    case '>':                       return RIGHT_ANGLE;
+    case '|':                       return VERTICAL_BAR;
+    case '^':                       return CARET;
+    case '&':                       return AMPERSAND;
+    case '?':                       return QUESTION;
+    case '[':                       return LEFT_BRACKET;
+    case ']':                       return RIGHT_BRACKET;
+    case '{':                       return LEFT_BRACE;
+    case '}':                       return RIGHT_BRACE;
+
+    case CPP_AND_OP:                return AND_OP;
+    case CPP_SUB_ASSIGN:            return SUB_ASSIGN;
+    case CPP_MOD_ASSIGN:            return MOD_ASSIGN;
+    case CPP_ADD_ASSIGN:            return ADD_ASSIGN;
+    case CPP_DIV_ASSIGN:            return DIV_ASSIGN;
+    case CPP_MUL_ASSIGN:            return MUL_ASSIGN;
+    case CPP_EQ_OP:                 return EQ_OP;
+    case CPP_XOR_OP:                return XOR_OP;
+    case CPP_GE_OP:                 return GE_OP;
+    case CPP_RIGHT_OP:              return RIGHT_OP;
+    case CPP_LE_OP:                 return LE_OP;
+    case CPP_LEFT_OP:               return LEFT_OP;
+    case CPP_DEC_OP:                return DEC_OP;
+    case CPP_NE_OP:                 return NE_OP;
+    case CPP_OR_OP:                 return OR_OP;
+    case CPP_INC_OP:                return INC_OP;
+    case CPP_RIGHT_ASSIGN:          return RIGHT_ASSIGN;
+    case CPP_LEFT_ASSIGN:           return LEFT_ASSIGN;
+    case CPP_AND_ASSIGN:            return AND_ASSIGN;
+    case CPP_OR_ASSIGN:             return OR_ASSIGN;
+    case CPP_XOR_ASSIGN:            return XOR_ASSIGN;
+                                   
+    case CPP_INTCONSTANT:           parserToken->sType.lex.i = ppToken->lexer.sc_int;        return INTCONSTANT;
+    case CPP_UINTCONSTANT:          parserToken->sType.lex.i = ppToken->lexer.sc_int;        return UINTCONSTANT;
+    case CPP_FLOATCONSTANT:         parserToken->sType.lex.d = ppToken->lexer.sc_dval;       return FLOATCONSTANT;
+    case CPP_DOUBLECONSTANT:        parserToken->sType.lex.d = ppToken->lexer.sc_dval;       return DOUBLECONSTANT;
+    case CPP_IDENTIFIER:            return tokenizeIdentifier();
+
+    case EOF:                       return 0;
+                                   
+    default:
+        parseContext.infoSink.info.message(EPrefixInternalError, "Unknown PP token", loc);
+        return 0;
+    }
+}
+
+int TScanContext::tokenizeIdentifier()
+{
+    if (ReservedSet->find(tokenText) != ReservedSet->end())
+        return reservedWord();
+
+    keyword = (*KeywordMap)[tokenText];
+    if (keyword == 0) {
+        // Should have an identifier of some sort
+        return identifierOrType();
+    }
+    field = false;
+
+    switch (keyword) {
+    case CONST:
+    case UNIFORM:
+    case IN:
+    case OUT:
+    case INOUT:
+    case STRUCT:
+    case BREAK:
+    case CONTINUE:
+    case DO:
+    case FOR:
+    case WHILE:
+    case IF:
+    case ELSE:
+    case DISCARD:
+    case RETURN:
+    case CASE:
+        return keyword;
+
+    case SWITCH:
+    case DEFAULT:
+        if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
+            parseContext.profile != EEsProfile && parseContext.version < 130)
+            reservedWord();
+        return keyword;
+
+    case VOID:
+    case BOOL:
+    case FLOAT:
+    case INT:
+    case BVEC2:
+    case BVEC3:
+    case BVEC4:
+    case VEC2:
+    case VEC3:
+    case VEC4:
+    case IVEC2:
+    case IVEC3:
+    case IVEC4:
+    case MAT2:
+    case MAT3:
+    case MAT4:
+    case SAMPLER2D:
+    case SAMPLERCUBE:
+        afterType = true;
+        return keyword;
+
+    case BOOLCONSTANT:
+        if (strcmp("true", tokenText) == 0)
+            parserToken->sType.lex.b = true;
+        else
+            parserToken->sType.lex.b = false;
+        return keyword;
+
+    case ATTRIBUTE:
+    case VARYING:
+        if (parseContext.profile == EEsProfile && parseContext.version >= 300)
+            reservedWord();
+        return keyword;
+
+    case BUFFER:
+        if (parseContext.version < 430)
+            return identifierOrType();
+        return keyword;
+
+    case COHERENT:
+    case RESTRICT:
+    case READONLY:
+    case WRITEONLY:
+    case ATOMIC_UINT:
+        return es30ReservedFromGLSL(420);
+
+    case VOLATILE:
+        if (parseContext.profile == EEsProfile || parseContext.version < 420)
+            reservedWord();
+        return keyword;
+
+    case LAYOUT:
+    case SHARED:
+        if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
+            parseContext.profile != EEsProfile && parseContext.version < 140)
+            return identifierOrType();
+        return keyword;
+
+    case PATCH:
+    case SAMPLE:
+    case SUBROUTINE:
+        return es30ReservedFromGLSL(400);
+
+    case HIGH_PRECISION:
+    case MEDIUM_PRECISION:
+    case LOW_PRECISION:
+    case PRECISION:
+        return precisionKeyword();
+
+    case MAT2X2:
+    case MAT2X3:
+    case MAT2X4:
+    case MAT3X2:
+    case MAT3X3:
+    case MAT3X4:
+    case MAT4X2:
+    case MAT4X3:
+    case MAT4X4:        
+        return matNxM();
+
+    case DMAT2:
+    case DMAT3:
+    case DMAT4:
+    case DMAT2X2:
+    case DMAT2X3:
+    case DMAT2X4:
+    case DMAT3X2:
+    case DMAT3X3:
+    case DMAT3X4:
+    case DMAT4X2:
+    case DMAT4X3:
+    case DMAT4X4:
+        return dMat();
+
+    case IMAGE1D:
+    case IIMAGE1D:
+    case UIMAGE1D:
+    case IMAGE2D:
+    case IIMAGE2D:
+    case UIMAGE2D:
+    case IMAGE3D:
+    case IIMAGE3D:
+    case UIMAGE3D:
+    case IMAGE2DRECT:
+    case IIMAGE2DRECT:
+    case UIMAGE2DRECT:
+    case IMAGECUBE:
+    case IIMAGECUBE:
+    case UIMAGECUBE:
+    case IMAGEBUFFER:
+    case IIMAGEBUFFER:
+    case UIMAGEBUFFER:
+    case IMAGE1DARRAY:
+    case IIMAGE1DARRAY:
+    case UIMAGE1DARRAY:
+    case IMAGE2DARRAY:
+    case IIMAGE2DARRAY:
+    case UIMAGE2DARRAY:
+        return firstGenerationImage();
+
+    case IMAGECUBEARRAY:
+    case IIMAGECUBEARRAY:
+    case UIMAGECUBEARRAY:
+    case IMAGE2DMS:
+    case IIMAGE2DMS:
+    case UIMAGE2DMS:
+    case IMAGE2DMSARRAY:
+    case IIMAGE2DMSARRAY:
+    case UIMAGE2DMSARRAY:
+        return secondGenerationImage();
+
+    case DOUBLE:
+    case DVEC2:
+    case DVEC3:
+    case DVEC4:
+    case SAMPLERCUBEARRAY:
+    case SAMPLERCUBEARRAYSHADOW:
+    case ISAMPLERCUBEARRAY:
+    case USAMPLERCUBEARRAY:
+        afterType = true;
+        if (parseContext.profile == EEsProfile || parseContext.version < 400)
+            reservedWord();
+        return keyword;
+
+    case ISAMPLER1D:
+    case ISAMPLER1DARRAY:
+    case SAMPLER1DARRAYSHADOW:
+    case USAMPLER1D:
+    case USAMPLER1DARRAY:
+    case SAMPLERBUFFER:
+        afterType = true;
+        return es30ReservedFromGLSL(130);
+
+    case UINT:
+    case UVEC2:
+    case UVEC3:
+    case UVEC4:
+    case SAMPLERCUBESHADOW:
+    case SAMPLER2DARRAY:
+    case SAMPLER2DARRAYSHADOW:
+    case ISAMPLER2D:
+    case ISAMPLER3D:
+    case ISAMPLERCUBE:
+    case ISAMPLER2DARRAY:
+    case USAMPLER2D:
+    case USAMPLER3D:
+    case USAMPLERCUBE:
+    case USAMPLER2DARRAY:
+        afterType = true;
+        return nonreservedKeyword(300, 130);
+        
+    case ISAMPLER2DRECT:
+    case USAMPLER2DRECT:
+    case ISAMPLERBUFFER:
+    case USAMPLERBUFFER:
+        afterType = true;
+        return es30ReservedFromGLSL(140);
+        
+    case SAMPLER2DMS:
+    case ISAMPLER2DMS:
+    case USAMPLER2DMS:
+    case SAMPLER2DMSARRAY:
+    case ISAMPLER2DMSARRAY:
+    case USAMPLER2DMSARRAY:
+        afterType = true;
+        return es30ReservedFromGLSL(150);
+
+    case SAMPLER1D:
+    case SAMPLER1DSHADOW:
+        afterType = true;
+        if (parseContext.profile == EEsProfile)
+            reservedWord();
+        return keyword;
+
+    case SAMPLER3D:
+    case SAMPLER2DSHADOW:
+        afterType = true;
+        if (parseContext.profile == EEsProfile && parseContext.version < 300)
+            reservedWord();
+        return keyword;
+
+    case SAMPLER2DRECT:
+    case SAMPLER2DRECTSHADOW:
+        afterType = true;
+        if (parseContext.profile == EEsProfile ||
+            parseContext.profile != EEsProfile && parseContext.version < 140)
+            reservedWord();
+        return keyword;
+
+    case SAMPLER1DARRAY:
+        afterType = true;
+        if (parseContext.profile == EEsProfile && parseContext.version == 300)
+            reservedWord();
+        else if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
+                 parseContext.profile != EEsProfile && parseContext.version < 130)
+            return identifierOrType();
+        return keyword;
+
+    case NOPERSPECTIVE:
+        return es30ReservedFromGLSL(130);
+        
+    case SMOOTH:
+        if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
+            parseContext.profile != EEsProfile && parseContext.version < 130)
+            return identifierOrType();
+        return keyword;
+
+    case FLAT:
+        if (parseContext.profile == EEsProfile && parseContext.version < 300)
+            reservedWord();
+        else if (parseContext.profile != EEsProfile && parseContext.version < 130)
+            return identifierOrType();
+        return keyword;
+
+    case CENTROID:
+        if (parseContext.version < 120)
+            return identifierOrType();
+        return keyword;
+
+    case PRECISE:
+        if (parseContext.profile == EEsProfile ||
+            parseContext.profile != EEsProfile && parseContext.version < 400)
+            return identifierOrType();
+        return keyword;
+
+    case INVARIANT:
+        if (parseContext.profile != EEsProfile && parseContext.version < 120)
+            return identifierOrType();
+        return keyword;
+
+    case PACKED:
+        if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
+            parseContext.profile != EEsProfile && parseContext.version < 330)
+            return reservedWord();
+        return identifierOrType();
+
+    case RESOURCE:
+    {
+        bool reserved = parseContext.profile == EEsProfile && parseContext.version >= 300 ||
+                        parseContext.profile != EEsProfile && parseContext.version >= 420;
+        return identifierOrReserved(reserved);
+    }
+    case SUPERP:
+    {
+        bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130;
+        return identifierOrReserved(reserved);
+    }
+    
+    default:        
+        parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
+        return 0;
+    }
+}
+
+int TScanContext::identifierOrType()
+{
+    parserToken->sType.lex.string = NewPoolTString(tokenText);
+    if (field) {
+        field = false;
+        return FIELD_SELECTION;
+    }
+
+    parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
+    if (afterType == false && parserToken->sType.lex.symbol) {
+        if (TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
+            if (variable->isUserType()) {
+                afterType = true;
+
+                return TYPE_NAME;
+            }
+        }
+    }
+
+    return IDENTIFIER;
+}
+
+int TScanContext::reservedWord()
+{
+    ThreadLocalParseContext()->error(loc, "Reserved word.", tokenText, "", "");
+
+    return 0;
+}
+
+int TScanContext::identifierOrReserved(bool reserved)
+{
+    if (reserved) {
+        reservedWord();
+
+        return 0;
+    }
+
+    if (parseContext.forwardCompatible)
+        parseContext.warn(loc, "using future reserved keyword", tokenText, "");
+
+    return identifierOrType();
+}
+
+// For keywords that suddenly showed up on non-ES (not previously reserved)
+// but then got reserved by ES 3.0.
+int TScanContext::es30ReservedFromGLSL(int version)
+{
+    if (parseContext.profile == EEsProfile && parseContext.version < 300 ||
+        parseContext.profile != EEsProfile && parseContext.version < version) {
+            if (parseContext.forwardCompatible)
+                parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, "");
+
+            return identifierOrType();
+    } else if (parseContext.profile == EEsProfile && parseContext.version >= 300)
+        reservedWord();
+
+    return keyword;
+}
+
+// For a keyword that was never reserved, until it suddenly
+// showed up, both in an es version and a non-ES version.
+int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion)
+{
+    if (parseContext.profile == EEsProfile && parseContext.version < esVersion ||
+        parseContext.profile != EEsProfile && parseContext.version < nonEsVersion) {
+        if (parseContext.forwardCompatible)
+            parseContext.warn(loc, "using future keyword", tokenText, "");
+
+        return identifierOrType();
+    }
+
+    return keyword;
+}
+
+int TScanContext::precisionKeyword()
+{
+    if (parseContext.profile == EEsProfile || parseContext.version >= 130)
+        return keyword;
+
+    if (parseContext.forwardCompatible)
+        parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, "");
+
+    return identifierOrType();
+}
+
+int TScanContext::matNxM()
+{
+    afterType = true;
+
+    if (parseContext.version > 110)
+        return keyword;
+
+    if (parseContext.forwardCompatible)
+        parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, "");
+
+    return identifierOrType();
+}
+
+int TScanContext::dMat()
+{
+    afterType = true;
+
+    if (parseContext.profile == EEsProfile && parseContext.version >= 300) {
+        reservedWord();
+
+        return keyword;
+    }
+
+    if (parseContext.profile != EEsProfile && parseContext.version >= 400)
+        return keyword;
+
+    if (parseContext.forwardCompatible)
+        parseContext.warn(loc, "using future type keyword", tokenText, "");
+
+    return identifierOrType();
+}
+
+int TScanContext::firstGenerationImage()
+{
+    afterType = true;
+
+    if (parseContext.profile != EEsProfile && parseContext.version >= 420)
+        return keyword;
+
+    if (parseContext.profile == EEsProfile && parseContext.version >= 300 ||
+        parseContext.profile != EEsProfile && parseContext.version >= 130) {
+        reservedWord();
+
+        return keyword;
+    }
+
+    if (parseContext.forwardCompatible)
+        parseContext.warn(loc, "using future type keyword", tokenText, "");
+
+    return identifierOrType();
+}
+
+int TScanContext::secondGenerationImage()
+{
+    afterType = true;
+
+    if (parseContext.profile != EEsProfile && parseContext.version >= 420)
+        return keyword;
+
+    if (parseContext.forwardCompatible)
+        parseContext.warn(loc, "using future type keyword", tokenText, "");
+
+    return identifierOrType();
+}
+
+};
index 1ea57ee..81a6fb3 100644 (file)
@@ -105,7 +105,7 @@ protected:
     int currentChar;
 };
 
-// The location of these is still pending a grand design for going to a singular
+// TODO: The location of these is still pending a grand design for going to a singular
 // scanner for version finding, preprocessing, and tokenizing:
 void ConsumeWhiteSpace(TInputScanner& input, bool& foundNonSpaceTab);
 bool ConsumeComment(TInputScanner& input);
diff --git a/glslang/MachineIndependent/ScanContext.h b/glslang/MachineIndependent/ScanContext.h
new file mode 100644 (file)
index 0000000..116a36b
--- /dev/null
@@ -0,0 +1,80 @@
+//
+//Copyright (C) 2013 LunarG, Inc.
+//
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//    Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+//    Redistributions in binary form must reproduce the above
+//    copyright notice, this list of conditions and the following
+//    disclaimer in the documentation and/or other materials provided
+//    with the distribution.
+//
+//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+
+//
+// This holds context specific to the GLSL scanner, which
+// sits between the preprocessor scanner and parser.
+//
+
+#include "ParseHelper.h"
+
+namespace glslang {
+
+class TParserToken;
+class TPpToken;
+
+class TScanContext {
+public:
+    explicit TScanContext(TParseContext& pc) : parseContext(pc), afterType(false), field(false) { }
+    virtual ~TScanContext() { }
+
+    static void fillInKeywordMap();
+    int tokenize(TParserToken&);
+
+protected:
+    int tokenizeIdentifier();
+    int identifierOrType();
+    int reservedWord();
+    int identifierOrReserved(bool reserved);
+    int es30ReservedFromGLSL(int version);
+    int nonreservedKeyword(int esVersion, int nonEsVersion);
+    int precisionKeyword();
+    int matNxM();
+    int dMat();
+    int firstGenerationImage();
+    int secondGenerationImage();
+
+    TParseContext& parseContext;
+    bool afterType;           // true if we've recognized a type, so can only be looking for an identifier
+    bool field;               // true if we're on a field, right after a '.'
+    TSourceLoc loc;
+    TParserToken* parserToken;
+    TPpToken* ppToken;
+
+    const char* tokenText;
+    int keyword;
+};
+
+};
index 6c84330..0a1a12a 100644 (file)
 #include "SymbolTable.h"
 #include "ParseHelper.h"
 #include "Scan.h"
+#include "ScanContext.h"
 
 #include "../Include/ShHandle.h"
 #include "InitializeDll.h"
 
+extern "C" {
+#include "preprocessor/preprocess.h"
+}
+
 #define SH_EXPORTING
 #include "../Public/ShaderLang.h"
 #include "Initialize.h"
@@ -99,8 +104,9 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
                symbolTable = &symbolTables[language];
 
     TParseContext parseContext(*symbolTable, intermediate, true, version, profile, language, infoSink);
-
     ThreadLocalParseContext() = &parseContext;
+    glslang::TScanContext scanContext(parseContext);
+    parseContext.scanContext = &scanContext;
     
     assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
        
@@ -123,8 +129,6 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
         return false;
     }
 
-    ResetFlex();
-    
     for (TBuiltInStrings::iterator i  = BuiltInStrings[parseContext.language].begin();
                                    i != BuiltInStrings[parseContext.language].end();    ++i) {
         const char* builtInShaders[1];
@@ -132,7 +136,7 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
 
         builtInShaders[0] = (*i).c_str();
         builtInLengths[0] = (int) (*i).size();
-        if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext, 0) != 0) {
+        if (! parseContext.parseShaderStrings(const_cast<char**>(builtInShaders), builtInLengths, 1) != 0) {
             infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
             printf("Unable to parse built-ins\n");
 
@@ -271,6 +275,8 @@ int ShInitialize()
         PerProcessGPA = new TPoolAllocator(true);
     }
     
+    glslang::TScanContext::fillInKeywordMap();
+
     return true;
 }
 
@@ -411,19 +417,24 @@ int ShCompile(
     AddContextSpecificSymbols(resources, compiler->infoSink, &symbolTable, version, profile, compiler->getLanguage());
 
     TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
+    glslang::TScanContext scanContext(parseContext);
+    parseContext.scanContext = &scanContext;
+
+    TSourceLoc beginning;
+    beginning.line = 1;
+    beginning.string = 0;
     
     if (! goodProfile)
-        parseContext.error(1, "incorrect", "#version", "");
+        parseContext.error(beginning, "incorrect", "#version", "");
 
     parseContext.initializeExtensionBehavior();
     if (versionStatementMissing)
-        parseContext.warn(1, "statement missing: use #version on first line of shader", "#version", "");
+        parseContext.warn(beginning, "statement missing: use #version on first line of shader", "#version", "");
     else if (profile == EEsProfile && version >= 300 && versionNotFirst)
-        parseContext.error(1, "statement must appear first in ESSL shader; before comments or newlines", "#version", "");
+        parseContext.error(beginning, "statement must appear first in ESSL shader; before comments or newlines", "#version", "");
 
     ThreadLocalParseContext() = &parseContext;
     
-    ResetFlex();
     InitPreprocessor();
 
     //
@@ -440,8 +451,8 @@ int ShCompile(
     if (parseContext.insertBuiltInArrayAtGlobalLevel())
         success = false;
 
-    int ret = PaParseStrings(const_cast<char**>(shaderStrings), lengths, numStrings, parseContext, parseContext.getPreamble());
-    if (ret)
+    bool ret = parseContext.parseShaderStrings(const_cast<char**>(shaderStrings), lengths, numStrings);
+    if (ret)
         success = false;
     intermediate.addSymbolLinkageNodes(parseContext.treeRoot, parseContext.linkage, parseContext.language, symbolTable);
 
index 9bb38b4..cfcc931 100644 (file)
@@ -64,10 +64,10 @@ const char* ProfileName[EProfileCount] = {
 // which subset allows the feature.  If the current profile is not present,
 // give an error message.
 //
-void TParseContext::requireProfile(int line, EProfileMask profileMask, const char *featureDesc)
+void TParseContext::requireProfile(TSourceLoc loc, EProfileMask profileMask, const char *featureDesc)
 {
     if (((1 << profile) & profileMask) == 0)
-        error(line, "not supported with this profile:", featureDesc, ProfileName[profile]);
+        error(loc, "not supported with this profile:", featureDesc, ProfileName[profile]);
 }
 
 //
@@ -75,10 +75,10 @@ void TParseContext::requireProfile(int line, EProfileMask profileMask, const cha
 // which subset allows the feature.  If the current stage is not present,
 // give an error message.
 //
-void TParseContext::requireStage(int line, EShLanguageMask languageMask, const char *featureDesc)
+void TParseContext::requireStage(TSourceLoc loc, EShLanguageMask languageMask, const char *featureDesc)
 {
     if (((1 << language) & languageMask) == 0)
-        error(line, "not supported in this stage:", featureDesc, StageName[language]);
+        error(loc, "not supported in this stage:", featureDesc, StageName[language]);
 }
 
 //
@@ -88,7 +88,7 @@ void TParseContext::requireStage(int line, EShLanguageMask languageMask, const c
 //
 
 // one that takes multiple extensions
-void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc)
+void TParseContext::profileRequires(TSourceLoc loc, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc)
 {
     if (profile == callingProfile) {
         bool okay = false;
@@ -98,7 +98,7 @@ void TParseContext::profileRequires(int line, EProfile callingProfile, int minVe
             TBehavior behavior = extensionBehavior[extensions[i]];
             switch (behavior) {
             case EBhWarn:
-                infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), line);
+                infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
                 // fall through
             case EBhRequire:
             case EBhEnable:
@@ -109,29 +109,29 @@ void TParseContext::profileRequires(int line, EProfile callingProfile, int minVe
         }
 
         if (! okay)
-            error(line, "not supported for this version or the enabled extensions", featureDesc, "");
+            error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
     }
 }
 
 // one that takes a single extension
-void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc)
+void TParseContext::profileRequires(TSourceLoc loc, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc)
 {
-    profileRequires(line, callingProfile, minVersion, extension ? 1 : 0, &extension, featureDesc);
+    profileRequires(loc, callingProfile, minVersion, extension ? 1 : 0, &extension, featureDesc);
 }
 
 //
 // Within a profile, see if a feature is deprecated and error or warn based on whether
 // a future compatibility context is being use.
 //
-void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc)
+void TParseContext::checkDeprecated(TSourceLoc loc, EProfile callingProfile, int depVersion, const char *featureDesc)
 {
     if (profile == callingProfile) {
         if (version >= depVersion) {
             if (forwardCompatible)
-                error(line, "deprecated, may be removed in future release", featureDesc, "");
+                error(loc, "deprecated, may be removed in future release", featureDesc, "");
             else if (! (messages & EShMsgSuppressWarnings))
                 infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " +
-                                                       String(depVersion) + "; may be removed in future release").c_str(), line);
+                                                       String(depVersion) + "; may be removed in future release").c_str(), loc);
         }
     }
 }
@@ -140,27 +140,27 @@ void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVe
 // Within a profile, see if a feature has now been removed and if so, give an error.
 // The version argument is the first version no longer having the feature.
 //
-void TParseContext::requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc)
+void TParseContext::requireNotRemoved(TSourceLoc loc, EProfile callingProfile, int removedVersion, const char *featureDesc)
 {
     if (profile == callingProfile) {
         if (version >= removedVersion) {
             const int maxSize = 60;
             char buf[maxSize];
             snprintf(buf, maxSize, "%s profile; removed in version %d", ProfileName[profile], removedVersion);
-            error(line, "no longer supported in", featureDesc, buf);
+            error(loc, "no longer supported in", featureDesc, buf);
         }
     }
 }
 
-void TParseContext::fullIntegerCheck(int line, const char* op)
+void TParseContext::fullIntegerCheck(TSourceLoc loc, const char* op)
 {   
-    profileRequires(line, ENoProfile, 130, 0, op); 
-    profileRequires(line, EEsProfile, 300, 0, op);
+    profileRequires(loc, ENoProfile, 130, 0, op); 
+    profileRequires(loc, EEsProfile, 300, 0, op);
 }
 
-void TParseContext::doubleCheck(int line, const char* op)
+void TParseContext::doubleCheck(TSourceLoc loc, const char* op)
 {   
-    requireProfile(line, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), op);
-    profileRequires(line, ECoreProfile, 400, 0, op);
-    profileRequires(line, ECompatibilityProfile, 400, 0, op);
+    requireProfile(loc, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), op);
+    profileRequires(loc, ECoreProfile, 400, 0, op);
+    profileRequires(loc, ECompatibilityProfile, 400, 0, op);
 }
diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l
deleted file mode 100644 (file)
index 1ca307d..0000000
+++ /dev/null
@@ -1,1155 +0,0 @@
-/*\r
-//\r
-//Copyright (C) 2002-2005  3Dlabs Inc. Ltd.\r
-//Copyright (C) 2012-2013 LunarG, Inc.\r
-//\r
-//All rights reserved.\r
-//\r
-//Redistribution and use in source and binary forms, with or without\r
-//modification, are permitted provided that the following conditions\r
-//are met:\r
-//\r
-//    Redistributions of source code must retain the above copyright\r
-//    notice, this list of conditions and the following disclaimer.\r
-//\r
-//    Redistributions in binary form must reproduce the above\r
-//    copyright notice, this list of conditions and the following\r
-//    disclaimer in the documentation and/or other materials provided\r
-//    with the distribution.\r
-//\r
-//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its\r
-//    contributors may be used to endorse or promote products derived\r
-//    from this software without specific prior written permission.\r
-//\r
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
-//POSSIBILITY OF SUCH DAMAGE.\r
-//\r
-*/\r
-/* Based on\r
-ANSI C grammar, Lex specification\r
-\r
-In 1985, Jeff Lee published this Lex specification together with a Yacc\r
-grammar for the April 30, 1985 ANSI C draft.  Tom Stockfisch reposted\r
-both to net.sources in 1987; that original, as mentioned in the answer\r
-to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net,\r
-file usenet/net.sources/ansi.c.grammar.Z.\r
-\r
-I intend to keep this version as close to the current C Standard grammar\r
-as possible; please let me know if you discover discrepancies.\r
-\r
-Jutta Degener, 1995\r
-*/\r
-\r
-D           [0-9]\r
-L           [a-zA-Z_]\r
-H           [a-fA-F0-9]\r
-E           [Ee][+-]?{D}+\r
-O           [0-7]\r
-U           [uU]\r
-F           [fF]\r
-LF          [lL][fF]\r
-\r
-%option nounput\r
-%{\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include "ParseHelper.h"\r
-#include "glslang_tab.cpp.h"\r
-\r
-void PaReservedWord();\r
-int PaIdentOrType(const char* yytext, TParseContext&, YYSTYPE* pyylval);\r
-int PaIdentOrReserved(bool reserved, TParseContext&, int line, const char* text, YYSTYPE* pyylval);\r
-int PaES30ReservedFromGLSL(int version, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword);\r
-int PaNonreservedKeyword(int esVersion, int nonEsVersion, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword);\r
-int PaPrecisionKeyword(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword);\r
-int PaMatNxM(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword);\r
-int PaDMat(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword);\r
-int Pa1stGenerationImage(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword);\r
-int Pa2ndGenerationImage(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword);\r
-\r
-/* windows only pragma */\r
-#ifdef _MSC_VER\r
-#pragma warning(disable : 4102)\r
-#endif\r
-\r
-int yy_input(char* buf, int max_size);\r
-\r
-#ifdef _WIN32\r
-    TSourceLoc yylineno;\r
-    extern int yyparse(TParseContext&);\r
-    #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)\r
-#else\r
-    extern int yyparse(void*);\r
-    #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)\r
-    #define parseContext (*((TParseContext*)(parseContextLocal)))              \r
-#endif\r
-\r
-#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size))\r
-\r
-%}\r
-\r
-%option noyywrap\r
-%option never-interactive\r
-%option outfile="gen_glslang.cpp"\r
-%x FIELDS\r
-\r
-%%\r
-<*>"//"[^\n]*"\n"     { /* CPP should have taken care of this */ };\r
-\r
-"attribute"     {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile && parseContext.version >= 300)\r
-                        PaReservedWord();\r
-                    return ATTRIBUTE;\r
-                }\r
-"const"         {   pyylval->lex.line = yylineno;\r
-                    return CONST;\r
-                }\r
-"uniform"       {   pyylval->lex.line = yylineno;\r
-                    return UNIFORM;\r
-                }\r
-"varying"       {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile && parseContext.version >= 300)\r
-                        PaReservedWord();\r
-                    return VARYING;\r
-                }\r
-"buffer"        {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.version < 430)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return BUFFER;\r
-                }\r
-"shared"        {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile && parseContext.version < 300 ||\r
-                        parseContext.profile != EEsProfile && parseContext.version < 140)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return SHARED;\r
-                }\r
-"coherent"      {   return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, COHERENT); }\r
-"volatile"      {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile || parseContext.version < 420)\r
-                        PaReservedWord();\r
-                    return VOLATILE;\r
-                }\r
-"restrict"      {   return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, RESTRICT); }\r
-"readonly"      {   return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, READONLY); }\r
-"writeonly"     {   return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, WRITEONLY); }\r
-\r
-"layout"        {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile && parseContext.version < 300 ||\r
-                        parseContext.profile != EEsProfile && parseContext.version < 140)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return LAYOUT;\r
-                }\r
-"centroid"      {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.version < 120)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return CENTROID;\r
-                }\r
-"flat"          {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile && parseContext.version < 300)\r
-                        PaReservedWord();\r
-                    else if (parseContext.profile != EEsProfile && parseContext.version < 130)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return FLAT;\r
-                }\r
-"smooth"        {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile && parseContext.version < 300 ||\r
-                        parseContext.profile != EEsProfile && parseContext.version < 130)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return SMOOTH;\r
-                }\r
-"noperspective" {   return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, NOPERSPECTIVE); }\r
-"patch"         {   return PaES30ReservedFromGLSL(400, parseContext, yylineno, yytext, pyylval, PATCH); }\r
-"sample"        {   return PaES30ReservedFromGLSL(400, parseContext, yylineno, yytext, pyylval, SAMPLE); }\r
-\r
-"break"         {   pyylval->lex.line = yylineno; return BREAK; }\r
-"continue"      {   pyylval->lex.line = yylineno; return CONTINUE; }\r
-"do"            {   pyylval->lex.line = yylineno; return DO; }\r
-"for"           {   pyylval->lex.line = yylineno; return FOR; }\r
-"while"         {   pyylval->lex.line = yylineno; return WHILE; }\r
-"switch"        {   pyylval->lex.line = yylineno; return SWITCH; }\r
-"case"          {   pyylval->lex.line = yylineno; return CASE; }\r
-"default"       {   pyylval->lex.line = yylineno; return DEFAULT; }\r
-\r
-"if"            {   pyylval->lex.line = yylineno; return IF; }\r
-"else"          {   pyylval->lex.line = yylineno; return ELSE; }\r
-\r
-"subroutine"    {   return PaES30ReservedFromGLSL(400, parseContext, yylineno, yytext, pyylval, SUBROUTINE); }\r
-\r
-"in"            {   pyylval->lex.line = yylineno; return IN; }\r
-"out"           {   pyylval->lex.line = yylineno; return OUT; }\r
-"inout"         {   pyylval->lex.line = yylineno; return INOUT; }\r
-\r
-"precise"       {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile ||\r
-                        parseContext.profile != EEsProfile && parseContext.version < 400)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return PRECISE;\r
-                }\r
-"invariant"     {   pyylval->lex.line = yylineno;;\r
-                    if (parseContext.profile != EEsProfile && parseContext.version < 120)\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                    return INVARIANT;\r
-                }\r
-\r
-"highp"         {   return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, HIGH_PRECISION); }\r
-"mediump"       {   return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, MEDIUM_PRECISION); }\r
-"lowp"          {   return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, LOW_PRECISION); }\r
-"precision"     {   return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, PRECISION); }\r
-\r
-"float"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return FLOAT; }\r
-"double"        {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                    if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                        PaReservedWord();\r
-                    return DOUBLE;\r
-                }\r
-"int"           {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return INT; }\r
-"uint"          {   parseContext.lexAfterType = true;\r
-                    return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UINT);\r
-                }\r
-"void"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VOID; }\r
-"bool"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BOOL; }\r
-"true"          {   pyylval->lex.line = yylineno; pyylval->lex.b = true;  return BOOLCONSTANT; }\r
-"false"         {   pyylval->lex.line = yylineno; pyylval->lex.b = false; return BOOLCONSTANT; }\r
-\r
-"discard"       {   pyylval->lex.line = yylineno; return DISCARD; }\r
-"return"        {   pyylval->lex.line = yylineno; return RETURN; }\r
-\r
-"atomic_uint"   {   return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, ATOMIC_UINT); }\r
-\r
-"mat2"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return MAT2; }\r
-"mat3"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return MAT3; }\r
-"mat4"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return MAT4; }\r
-\r
-"mat2x2"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT2X2); }\r
-"mat2x3"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT2X3); }\r
-"mat2x4"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT2X4); }\r
-"mat3x2"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT3X2); }\r
-"mat3x3"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT3X3); }\r
-"mat3x4"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT3X4); }\r
-"mat4x2"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT4X2); }\r
-"mat4x3"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT4X3); }\r
-"mat4x4"        {   return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT4X4); }\r
-"dmat2"         {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2); }\r
-"dmat3"         {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3); }\r
-"dmat4"         {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4); }\r
-"dmat2x2"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2X2); }\r
-"dmat2x3"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2X3); }\r
-"dmat2x4"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2X4); }\r
-"dmat3x2"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3X2); }\r
-"dmat3x3"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3X3); }\r
-"dmat3x4"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3X4); }\r
-"dmat4x2"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4X2); }\r
-"dmat4x3"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4X3); }\r
-"dmat4x4"       {   return   PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4X4); }\r
-\r
-"vec2"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VEC2; }\r
-"vec3"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VEC3; }\r
-"vec4"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VEC4; }\r
-"dvec2"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                    if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                        PaReservedWord();\r
-                    return DVEC2;\r
-                }\r
-"dvec3"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                    if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                        PaReservedWord();\r
-                    return DVEC3;\r
-                }\r
-"dvec4"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                    if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                        PaReservedWord();\r
-                    return DVEC4;\r
-                }\r
-"ivec2"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return IVEC2; }\r
-"ivec3"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return IVEC3; }\r
-"ivec4"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return IVEC4; }\r
-"uvec2"         {   parseContext.lexAfterType = true;\r
-                    return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UVEC2);\r
-                }\r
-"uvec3"         {   parseContext.lexAfterType = true;\r
-                    return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UVEC3);\r
-                }\r
-"uvec4"         {   parseContext.lexAfterType = true;\r
-                    return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UVEC4);\r
-                }\r
-"bvec2"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BVEC2; }\r
-"bvec3"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BVEC3; }\r
-"bvec4"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BVEC4; }\r
-\r
-"sampler2D"             {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }\r
-"samplerCube"           {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }\r
-\r
-"sampler1D"             {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile)\r
-                                PaReservedWord();\r
-                            return SAMPLER1D;\r
-                        }\r
-"sampler3D"             {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile && parseContext.version < 300)\r
-                                PaReservedWord();\r
-                            return SAMPLER3D;\r
-                        }\r
-"sampler1DShadow"       {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile)\r
-                                PaReservedWord();\r
-                            return SAMPLER1DSHADOW;\r
-                        }\r
-"sampler2DShadow"       {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile && parseContext.version < 300)\r
-                                PaReservedWord();\r
-                            return SAMPLER2DSHADOW;\r
-                        }\r
-"sampler2DRect"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile ||\r
-                                parseContext.profile != EEsProfile && parseContext.version < 140)\r
-                                PaReservedWord();\r
-                            return SAMPLER2DRECT;\r
-                        }\r
-"sampler2DRectShadow"   {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile ||\r
-                                parseContext.profile != EEsProfile && parseContext.version < 140)\r
-                                PaReservedWord();\r
-                            return SAMPLER2DRECTSHADOW;\r
-                        }\r
-"samplerCubeShadow"     {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, SAMPLERCUBESHADOW);\r
-                        }\r
-"sampler1DArray"        {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile && parseContext.version == 300)\r
-                                PaReservedWord();\r
-                            else if (parseContext.profile == EEsProfile && parseContext.version < 300 ||\r
-                                     parseContext.profile != EEsProfile && parseContext.version < 130)\r
-                                return PaIdentOrType(yytext, parseContext, pyylval);\r
-                            return SAMPLER1DARRAY;\r
-                        }\r
-"sampler2DArray"        {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, SAMPLER2DARRAY);\r
-                        }\r
-"sampler2DArrayShadow"  {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, SAMPLER2DARRAYSHADOW);\r
-                        }\r
-"samplerCubeArray"      {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                                return PaIdentOrType(yytext, parseContext, pyylval);\r
-                            return SAMPLERCUBEARRAY;\r
-                        }\r
-"sampler1DArrayShadow"  {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, SAMPLER1DARRAYSHADOW);\r
-                        }\r
-"samplerCubeArrayShadow" {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                                return PaIdentOrType(yytext, parseContext, pyylval);\r
-                            return SAMPLERCUBEARRAYSHADOW;\r
-                        }\r
-"isampler1D"            {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, ISAMPLER1D);\r
-                        }\r
-"isampler2D"            {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLER2D);\r
-                        }\r
-"isampler3D"            {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLER3D);\r
-                        }\r
-"isamplerCube"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLERCUBE);\r
-                        }\r
-"isampler1DArray"       {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, ISAMPLER1DARRAY);\r
-                        }\r
-"isampler2DArray"       {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLER2DARRAY);\r
-                        }\r
-"usampler1D"            {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval,  USAMPLER1D);\r
-                        }\r
-"usampler2D"            {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLER2D);\r
-                        }\r
-"usampler3D"            {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLER3D);\r
-                        }\r
-"usamplerCube"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLERCUBE);\r
-                        }\r
-"usampler1DArray"       {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval,  USAMPLER1DARRAY);\r
-                        }\r
-"usampler2DArray"       {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLER2DARRAY);\r
-                        }\r
-"isampler2DRect"        {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, ISAMPLER2DRECT);\r
-                        }\r
-"usampler2DRect"        {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, USAMPLER2DRECT);\r
-                        }\r
-"isamplerCubeArray"     {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                                return PaIdentOrType(yytext, parseContext, pyylval);\r
-                            return ISAMPLERCUBEARRAY;\r
-                        }\r
-"usamplerCubeArray"     {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            if (parseContext.profile == EEsProfile || parseContext.version < 400)\r
-                                return PaIdentOrType(yytext, parseContext, pyylval);\r
-                            return USAMPLERCUBEARRAY;\r
-                        }\r
-"samplerBuffer"         {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, SAMPLERBUFFER);\r
-                        }\r
-"isamplerBuffer"        {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, ISAMPLERBUFFER);\r
-                        }\r
-"usamplerBuffer"        {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, USAMPLERBUFFER);\r
-                        }\r
-"sampler2DMS"           {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, SAMPLER2DMS);\r
-                        }\r
-"isampler2DMS"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, ISAMPLER2DMS);\r
-                        }\r
-"usampler2DMS"          {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, USAMPLER2DMS);\r
-                        }\r
-"sampler2DMSArray"      {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, SAMPLER2DMSARRAY);\r
-                        }\r
-"isampler2DMSArray"     {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, ISAMPLER2DMSARRAY);\r
-                        }\r
-"usampler2DMSArray"     {   pyylval->lex.line = yylineno; parseContext.lexAfterType = true;\r
-                            return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, USAMPLER2DMSARRAY);\r
-                        }\r
-"image1D"               {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE1D); }\r
-"iimage1D"              {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE1D); }\r
-"uimage1D"              {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE1D); }\r
-"image2D"               {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2D); }\r
-"iimage2D"              {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2D); }\r
-"uimage2D"              {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2D); }\r
-"image3D"               {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE3D); }\r
-"iimage3D"              {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE3D); }\r
-"uimage3D"              {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE3D); }\r
-"image2DRect"           {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DRECT); }\r
-"iimage2DRect"          {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DRECT); }\r
-"uimage2DRect"          {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DRECT); }\r
-"imageCube"             {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGECUBE); }\r
-"iimageCube"            {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGECUBE); }\r
-"uimageCube"            {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGECUBE); }\r
-"imageBuffer"           {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGEBUFFER); }\r
-"iimageBuffer"          {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGEBUFFER); }\r
-"uimageBuffer"          {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGEBUFFER); }\r
-"image1DArray"          {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE1DARRAY); }\r
-"iimage1DArray"         {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE1DARRAY); }\r
-"uimage1DArray"         {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE1DARRAY); }\r
-"image2DArray"          {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DARRAY); }\r
-"iimage2DArray"         {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DARRAY); }\r
-"uimage2DArray"         {   return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DARRAY); }\r
-\r
-"imageCubeArray"        {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGECUBEARRAY); }\r
-"iimageCubeArray"       {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGECUBEARRAY); }\r
-"uimageCubeArray"       {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGECUBEARRAY); }\r
-"image2DMS"             {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DMS); }\r
-"iimage2DMS"            {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DMS); }\r
-"uimage2DMS"            {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DMS); }\r
-"image2DMSArray"        {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DMSARRAY); }\r
-"iimage2DMSArray"       {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DMSARRAY); }\r
-"uimage2DMSArray"       {   return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DMSARRAY); }\r
-\r
-"struct"        {   pyylval->lex.line = yylineno; return STRUCT; }\r
-\r
-"common"        {   PaReservedWord(); return 0; }\r
-"partition"     {   PaReservedWord(); return 0; }\r
-"active"        {   PaReservedWord(); return 0; }\r
-"asm"           {   PaReservedWord(); return 0; }\r
-"class"         {   PaReservedWord(); return 0; }\r
-"union"         {   PaReservedWord(); return 0; }\r
-"enum"          {   PaReservedWord(); return 0; }\r
-"typedef"       {   PaReservedWord(); return 0; }\r
-"template"      {   PaReservedWord(); return 0; }\r
-"this"          {   PaReservedWord(); return 0; }\r
-\r
-"packed"        {   pyylval->lex.line = yylineno;\r
-                    if (parseContext.profile == EEsProfile && parseContext.version < 300 ||\r
-                        parseContext.profile != EEsProfile && parseContext.version < 330) {\r
-                        PaReservedWord();\r
-                        return 0;\r
-                    } else\r
-                        return PaIdentOrType(yytext, parseContext, pyylval);\r
-                }\r
-"resource"      {   bool reserved = parseContext.profile == EEsProfile && parseContext.version >= 300 ||\r
-                                    parseContext.profile != EEsProfile && parseContext.version >= 420;\r
-                    return PaIdentOrReserved(reserved, parseContext, yylineno, yytext, pyylval);\r
-                }\r
-"goto"          {   PaReservedWord(); return 0; }\r
-\r
-"inline"        {   PaReservedWord(); return 0; }\r
-"noinline"      {   PaReservedWord(); return 0; }\r
-"public"        {   PaReservedWord(); return 0; }\r
-"static"        {   PaReservedWord(); return 0; }\r
-"extern"        {   PaReservedWord(); return 0; }\r
-"external"      {   PaReservedWord(); return 0; }\r
-"interface"     {   PaReservedWord(); return 0; }\r
-\r
-"long"          {   PaReservedWord(); return 0; }\r
-"short"         {   PaReservedWord(); return 0; }\r
-"half"          {   PaReservedWord(); return 0; }\r
-"fixed"         {   PaReservedWord(); return 0; }\r
-"unsigned"      {   PaReservedWord(); return 0; }\r
-\r
-"superp"        {   bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130;\r
-                    return PaIdentOrReserved(reserved, parseContext, yylineno, yytext, pyylval);\r
-                }\r
-"input"         {   PaReservedWord(); return 0; }\r
-"output"        {   PaReservedWord(); return 0; }\r
-\r
-"hvec2"         {   PaReservedWord(); return 0; }\r
-"hvec3"         {   PaReservedWord(); return 0; }\r
-"hvec4"         {   PaReservedWord(); return 0; }\r
-"fvec2"         {   PaReservedWord(); return 0; }\r
-"fvec3"         {   PaReservedWord(); return 0; }\r
-"fvec4"         {   PaReservedWord(); return 0; }\r
-\r
-"sampler3DRect" {   PaReservedWord(); return 0; }\r
-\r
-"filter"        {   PaReservedWord(); return 0; }\r
-\r
-"sizeof"        {   PaReservedWord(); return 0; }\r
-"cast"          {   PaReservedWord(); return 0; }\r
-\r
-"namespace"     {   PaReservedWord(); return 0; }\r
-"using"         {   PaReservedWord(); return 0; }\r
-\r
-{L}({L}|{D})*       {\r
-   pyylval->lex.line = yylineno;\r
-   return PaIdentOrType(yytext, parseContext, pyylval);\r
-}\r
-\r
-0[xX]{H}+         { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; }\r
-0{O}+             { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; }\r
-0{D}+             { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); return 0;}\r
-{D}+              { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; }\r
-\r
-0[xX]{H}+{U}      { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; }\r
-0{O}+{U}          { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; }\r
-0{D}+{U}          { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); return 0;}\r
-{D}+{U}           { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; }\r
-\r
-{D}+{F}               { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; }\r
-{D}+{E}{F}?           { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; }\r
-{D}+"."{D}*({E})?{F}? { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; }\r
-"."{D}+({E})?{F}?     { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; }\r
-\r
-{D}+{LF}              { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }\r
-{D}+{E}{LF}           { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }\r
-{D}+"."{D}*({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }\r
-"."{D}+({E})?{LF}     { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }\r
-\r
-"+="            {  pyylval->lex.line = yylineno; return ADD_ASSIGN; }\r
-"-="            {  pyylval->lex.line = yylineno; return SUB_ASSIGN; }\r
-"*="            {  pyylval->lex.line = yylineno; return MUL_ASSIGN; }\r
-"/="            {  pyylval->lex.line = yylineno; return DIV_ASSIGN; }\r
-"%="            {  pyylval->lex.line = yylineno; return MOD_ASSIGN; }\r
-"<<="           {  pyylval->lex.line = yylineno; return LEFT_ASSIGN; }\r
-">>="           {  pyylval->lex.line = yylineno; return RIGHT_ASSIGN; }\r
-"&="            {  pyylval->lex.line = yylineno; return AND_ASSIGN; }\r
-"^="            {  pyylval->lex.line = yylineno; return XOR_ASSIGN; }\r
-"|="            {  pyylval->lex.line = yylineno; return OR_ASSIGN; }\r
-\r
-"++"            {  pyylval->lex.line = yylineno; return INC_OP; }\r
-"--"            {  pyylval->lex.line = yylineno; return DEC_OP; }\r
-"&&"            {  pyylval->lex.line = yylineno; return AND_OP; }\r
-"||"            {  pyylval->lex.line = yylineno; return OR_OP; }\r
-"^^"            {  pyylval->lex.line = yylineno; return XOR_OP; }\r
-"<="            {  pyylval->lex.line = yylineno; return LE_OP; }\r
-">="            {  pyylval->lex.line = yylineno; return GE_OP; }\r
-"=="            {  pyylval->lex.line = yylineno; return EQ_OP; }\r
-"!="            {  pyylval->lex.line = yylineno; return NE_OP; }\r
-"<<"            {  pyylval->lex.line = yylineno; return LEFT_OP; }\r
-">>"            {  pyylval->lex.line = yylineno; return RIGHT_OP; }\r
-";"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return SEMICOLON; }\r
-("{"|"<%")      {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return LEFT_BRACE; }\r
-("}"|"%>")      {  pyylval->lex.line = yylineno; return RIGHT_BRACE; }\r
-","         {  pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return COMMA; }\r
-":"         {  pyylval->lex.line = yylineno; return COLON; }\r
-"="         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return EQUAL; }\r
-"("         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return LEFT_PAREN; }\r
-")"         {  pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return RIGHT_PAREN; }\r
-("["|"<:")      {  pyylval->lex.line = yylineno; return LEFT_BRACKET; }\r
-("]"|":>")      {  pyylval->lex.line = yylineno; return RIGHT_BRACKET; }\r
-"."         { BEGIN(FIELDS);  return DOT; }\r
-"!"         {  pyylval->lex.line = yylineno; return BANG; }\r
-"-"         {  pyylval->lex.line = yylineno; return DASH; }\r
-"~"         {  pyylval->lex.line = yylineno; return TILDE; }\r
-"+"         {  pyylval->lex.line = yylineno; return PLUS; }\r
-"*"         {  pyylval->lex.line = yylineno; return STAR; }\r
-"/"         {  pyylval->lex.line = yylineno; return SLASH; }\r
-"%"         {  pyylval->lex.line = yylineno; return PERCENT; }\r
-"<"         {  pyylval->lex.line = yylineno; return LEFT_ANGLE; }\r
-">"         {  pyylval->lex.line = yylineno; return RIGHT_ANGLE; }\r
-"|"         {  pyylval->lex.line = yylineno; return VERTICAL_BAR; }\r
-"^"         {  pyylval->lex.line = yylineno; return CARET; }\r
-"&"         {  pyylval->lex.line = yylineno; return AMPERSAND; }\r
-"?"         {  pyylval->lex.line = yylineno; return QUESTION; }\r
-\r
-<FIELDS>{L}({L}|{D})* {\r
-BEGIN(INITIAL);\r
-    pyylval->lex.line = yylineno;\r
-    pyylval->lex.string = NewPoolTString(yytext);\r
-    return FIELD_SELECTION; }\r
-<FIELDS>[ \t\v\f\r] {}\r
-\r
-[ \t\v\n\f\r]   {  }\r
-<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}\r
-<*>.    { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";\r
-          return 0; }\r
-\r
-%%\r
-\r
-\r
-//Including Pre-processor.\r
-extern "C" {\r
-  #include "./preprocessor/preprocess.h"\r
-}\r
-\r
-//\r
-// The YY_INPUT macro just calls this.  Maybe this could be just put into\r
-// the macro directly.\r
-//\r
-\r
-int yy_input(char* buf, int max_size)\r
-{\r
-     char *char_token =NULL;\r
-     int len;\r
-\r
-    if ((len = yylex_CPP(buf, max_size)) == 0)\r
-        return 0;\r
-    if (len >= max_size)\r
-        YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );\r
-\r
-    buf[len] = ' ';\r
-    return len+1;\r
-}\r
-\r
-\r
-//\r
-// Parse an array of strings using yyparse.  We set up globals used by\r
-// yywrap.\r
-//\r
-// Returns 0 for success, as per yyparse().\r
-//\r
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal, const char* preamble)\r
-{\r
-    if (!argv || argc == 0)\r
-        return 1;\r
-\r
-    for (int i = 0; i < argc; ++i) {\r
-        if (! argv[i]) {\r
-            parseContextLocal.error(0, "Null shader source string", "", "");\r
-\r
-            return 1;\r
-        }\r
-    }\r
-\r
-    // set up all the cpp fields...\r
-    cpp->pC = (void*)&parseContextLocal;\r
-    char *writeablePreamble = 0;\r
-    if (preamble) {\r
-        // preAmble could be a hard-coded string; make writable copy\r
-        // TODO: efficiency PP: make it not need writable strings\r
-        int size = strlen(preamble) + 1;\r
-        writeablePreamble = new char[size];\r
-        memcpy(writeablePreamble, preamble, size);\r
-        ScanFromString(writeablePreamble);\r
-        cpp->PaWhichStr = -1;\r
-    } else {\r
-        ScanFromString(argv[0]);\r
-        cpp->PaWhichStr = 0;\r
-    }\r
-    if (! strLen) {\r
-        int argv0len = (int) strlen(argv[0]);\r
-        strLen   = &argv0len;\r
-    }\r
-    yyrestart(0);\r
-    (&parseContextLocal)->AfterEOF = false;\r
-    cpp->PaArgv     = argv;\r
-    cpp->PaArgc     = argc;\r
-    cpp->PaStrLen   = strLen;\r
-    cpp->notAVersionToken = 0;\r
-    yylineno   = 1;\r
-\r
-    // TODO: desktop PP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens\r
-    int len = 0;\r
-    while (argv[0][len] == ' '  ||\r
-           argv[0][len] == '\t' ||\r
-           argv[0][len] == '\n' ||\r
-           argv[0][len] == '\r') {\r
-        if (++len >= strLen[0]) {\r
-            delete writeablePreamble;\r
-            return 0;\r
-        }\r
-    }\r
-\r
-    if (*cpp->PaStrLen > 0) {\r
-        int ret;\r
-        #ifdef _WIN32\r
-            ret = yyparse(parseContextLocal);\r
-        #else\r
-            ret = yyparse((void*)(&parseContextLocal));\r
-        #endif\r
-        delete writeablePreamble;\r
-        if (cpp->CompileError == 1 || parseContextLocal.numErrors > 0)\r
-             return 1;\r
-        else\r
-             return 0;\r
-    }\r
-\r
-    delete writeablePreamble;\r
-\r
-    return 0;\r
-}\r
-\r
-void yyerror(const char *s)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    if (pc.AfterEOF) {\r
-        if (cpp->tokensBeforeEOF == 1)\r
-            ThreadLocalParseContext()->error(yylineno, "", "pre-mature EOF", s, "");\r
-    } else\r
-        ThreadLocalParseContext()->error(yylineno, "", yytext, s, "");\r
-}\r
-\r
-void PaReservedWord()\r
-{\r
-    ThreadLocalParseContext()->error(yylineno, "Reserved word.", yytext, "", "");\r
-}\r
-\r
-int PaIdentOrType(const char* yytext, TParseContext& parseContextLocal, YYSTYPE* pyylval)\r
-{\r
-    pyylval->lex.string = NewPoolTString(yytext);\r
-    pyylval->lex.symbol = parseContextLocal.symbolTable.find(*pyylval->lex.string);\r
-    if (parseContextLocal.lexAfterType == false && pyylval->lex.symbol) {\r
-        if (TVariable* variable = pyylval->lex.symbol->getAsVariable()) {\r
-            if (variable->isUserType()) {\r
-                parseContextLocal.lexAfterType = true;\r
-\r
-                return TYPE_NAME;\r
-            }\r
-        }\r
-    }\r
-\r
-    return IDENTIFIER;\r
-}\r
-\r
-int PaIdentOrReserved(bool reserved, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval)\r
-{\r
-    pyylval->lex.line = line;\r
-\r
-    if (reserved) {\r
-        PaReservedWord();\r
-\r
-        return 0;\r
-    }\r
-\r
-    if (pc.forwardCompatible)\r
-        pc.warn(yylineno, "using future reserved keyword", text, "");\r
-\r
-    return PaIdentOrType(text, pc, pyylval);\r
-}\r
-\r
-// For keywords that suddenly showed up on non-ES (not previously reserved)\r
-// but then got reserved by ES 3.0.\r
-int PaES30ReservedFromGLSL(int version, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword)\r
-{\r
-    pyylval->lex.line = line;\r
-\r
-    if (pc.profile == EEsProfile && pc.version < 300 ||\r
-        pc.profile != EEsProfile && pc.version < version) {\r
-            if (pc.forwardCompatible)\r
-                pc.warn(yylineno, "future reserved word in ES 300 and keyword in GLSL", text, "");\r
-\r
-            return PaIdentOrType(text, pc, pyylval);\r
-    } else if (pc.profile == EEsProfile && pc.version >= 300)\r
-        PaReservedWord();\r
-\r
-    return keyword;\r
-}\r
-\r
-// For a keyword that was never reserved, until it suddenly\r
-// showed up, both in an es version and a non-ES version.\r
-int PaNonreservedKeyword(int esVersion, int nonEsVersion, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword)\r
-{\r
-    pyylval->lex.line = line;\r
-\r
-    if (pc.profile == EEsProfile && pc.version < esVersion ||\r
-        pc.profile != EEsProfile && pc.version < nonEsVersion) {\r
-        if (pc.forwardCompatible)\r
-            pc.warn(yylineno, "using future keyword", text, "");\r
-\r
-        return PaIdentOrType(text, pc, pyylval);\r
-    }\r
-\r
-    return keyword;\r
-}\r
-\r
-int PaPrecisionKeyword(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword)\r
-{\r
-    pyylval->lex.line = line;\r
-\r
-    if (pc.profile == EEsProfile || pc.version >= 130)\r
-        return keyword;\r
-\r
-    if (pc.forwardCompatible)\r
-        pc.warn(yylineno, "using ES precision qualifier keyword", text, "");\r
-\r
-    return PaIdentOrType(text, pc, pyylval);\r
-}\r
-\r
-int PaMatNxM(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword)\r
-{\r
-    pyylval->lex.line = line;\r
-    pc.lexAfterType = true;\r
-\r
-    if (pc.version > 110)\r
-        return keyword;\r
-\r
-    if (pc.forwardCompatible)\r
-        pc.warn(yylineno, "using future non-square matrix type keyword", text, "");\r
-\r
-    return PaIdentOrType(text, pc, pyylval);\r
-}\r
-\r
-int PaDMat(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword)\r
-{\r
-    pyylval->lex.line = line;\r
-    pc.lexAfterType = true;\r
-\r
-    if (pc.profile == EEsProfile && pc.version >= 300) {\r
-        PaReservedWord();\r
-\r
-        return keyword;\r
-    }\r
-\r
-    if (pc.profile != EEsProfile && pc.version >= 400)\r
-        return keyword;\r
-\r
-    if (pc.forwardCompatible)\r
-        pc.warn(yylineno, "using future type keyword", text, "");\r
-\r
-    return PaIdentOrType(text, pc, pyylval);\r
-}\r
-\r
-int Pa1stGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword)\r
-{\r
-    pyylval->lex.line = line;\r
-    pc.lexAfterType = true;\r
-\r
-    if (pc.profile != EEsProfile && pc.version >= 420)\r
-        return keyword;\r
-\r
-    if (pc.profile == EEsProfile && pc.version >= 300 ||\r
-        pc.profile != EEsProfile && pc.version >= 130) {\r
-        PaReservedWord();\r
-\r
-        return keyword;\r
-    }\r
-\r
-    if (pc.forwardCompatible)\r
-        pc.warn(yylineno, "using future type keyword", text, "");\r
-\r
-    return PaIdentOrType(text, pc, pyylval);\r
-}\r
-\r
-int Pa2ndGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword)\r
-{\r
-    pyylval->lex.line = line;\r
-    pc.lexAfterType = true;\r
-\r
-    if (pc.profile != EEsProfile && pc.version >= 420)\r
-        return keyword;\r
-\r
-    if (pc.forwardCompatible)\r
-        pc.warn(yylineno, "using future type keyword", text, "");\r
-\r
-    return PaIdentOrType(text, pc, pyylval);\r
-}\r
-\r
-extern "C" {\r
-\r
-void ShPpDebugLogMsg(const char *msg)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    pc.infoSink.debug.message(EPrefixNone, msg);\r
-}\r
-\r
-void ShPpWarningToInfoLog(const char *msg)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    pc.warn(yylineno, msg, "Preprocessor", "");\r
-}\r
-\r
-void ShPpErrorToInfoLog(const char *msg)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    pc.error(yylineno, msg, "Preprocessor", "");\r
-}\r
-\r
-// return 1 if error\r
-// return 0 if no error\r
-int ShPpMacrosMustBeDefinedError()\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    if (pc.profile == EEsProfile) {\r
-        if (pc.messages & EShMsgRelaxedErrors)\r
-            ShPpWarningToInfoLog("undefined macro in expression not allowed in es profile");\r
-        else {\r
-            ShPpErrorToInfoLog("undefined macro in expression");\r
-            \r
-            return 1;\r
-        }\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-void SetLineNumber(int line)\r
-{\r
-    yylineno &= ~SourceLocLineMask;\r
-    yylineno |= line;\r
-}\r
-\r
-void SetStringNumber(int string)\r
-{\r
-    yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask);\r
-}\r
-\r
-int GetStringNumber(void)\r
-{\r
-    return yylineno >> 16;\r
-}\r
-\r
-int GetLineNumber(void)\r
-{\r
-    return yylineno & SourceLocLineMask;\r
-}\r
-\r
-void IncLineNumber(void)\r
-{\r
-    if ((yylineno & SourceLocLineMask) <= SourceLocLineMask)\r
-        ++yylineno;\r
-}\r
-\r
-void DecLineNumber(void)\r
-{\r
-    if ((yylineno & SourceLocLineMask) > 0)\r
-        --yylineno;\r
-}\r
-\r
-void HandlePragma(const char **tokens, int numTokens)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    if (!strcmp(tokens[0], "optimize")) {\r
-        if (numTokens != 4) {\r
-            ShPpErrorToInfoLog("optimize pragma syntax is incorrect");\r
-            return;\r
-        }\r
-\r
-        if (strcmp(tokens[1], "(")) {\r
-            ShPpErrorToInfoLog("\"(\" expected after 'optimize' keyword");\r
-            return;\r
-        }\r
-\r
-        if (!strcmp(tokens[2], "on"))\r
-            pc.contextPragma.optimize = true;\r
-        else if (!strcmp(tokens[2], "off"))\r
-            pc.contextPragma.optimize = false;\r
-        else {\r
-            ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'optimize' pragma");\r
-            return;\r
-        }\r
-\r
-        if (strcmp(tokens[3], ")")) {\r
-            ShPpErrorToInfoLog("\")\" expected to end 'optimize' pragma");\r
-            return;\r
-        }\r
-    } else if (!strcmp(tokens[0], "debug")) {\r
-        if (numTokens != 4) {\r
-            ShPpErrorToInfoLog("debug pragma syntax is incorrect");\r
-            return;\r
-        }\r
-\r
-        if (strcmp(tokens[1], "(")) {\r
-            ShPpErrorToInfoLog("\"(\" expected after 'debug' keyword");\r
-            return;\r
-        }\r
-\r
-        if (!strcmp(tokens[2], "on"))\r
-            pc.contextPragma.debug = true;\r
-        else if (!strcmp(tokens[2], "off"))\r
-            pc.contextPragma.debug = false;\r
-        else {\r
-            ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'debug' pragma");\r
-            return;\r
-        }\r
-\r
-        if (strcmp(tokens[3], ")")) {\r
-            ShPpErrorToInfoLog("\")\" expected to end 'debug' pragma");\r
-            return;\r
-        }\r
-    } else {\r
-\r
-#ifdef PRAGMA_TABLE\r
-        //\r
-        // implementation specific pragma\r
-        // use parseContext.contextPragma.pragmaTable to store the information about pragma\r
-        // For now, just ignore the pragma that the implementation cannot recognize\r
-        // An Example of one such implementation for a pragma that has a syntax like\r
-        // #pragma pragmaname(pragmavalue)\r
-        // This implementation stores the current pragmavalue against the pragma name in pragmaTable.\r
-        //\r
-        if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {\r
-            TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable;\r
-            TPragmaTable::iterator iter;\r
-            iter = pragmaTable.find(TString(tokens[0]));\r
-            if (iter != pragmaTable.end()) {\r
-                iter->second = tokens[2];\r
-            } else {\r
-                pragmaTable[tokens[0]] = tokens[2];\r
-            }\r
-        } else if (numTokens >= 2) {\r
-            TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable;\r
-            TPragmaTable::iterator iter;\r
-            iter = pragmaTable.find(TString(tokens[0]));\r
-            if (iter != pragmaTable.end()) {\r
-                iter->second = tokens[1];\r
-            } else {\r
-                pragmaTable[tokens[0]] = tokens[1];\r
-            }\r
-        }\r
-#endif // PRAGMA_TABLE\r
-    }\r
-}\r
-\r
-void StoreStr(const char *string)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    TString strSrc;\r
-    strSrc = TString(string);\r
-\r
-    pc.HashErrMsg = pc.HashErrMsg + " " + strSrc;\r
-}\r
-\r
-const char* GetStrfromTStr(void)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    cpp->ErrMsg = pc.HashErrMsg.c_str();\r
-    return cpp->ErrMsg;\r
-}\r
-\r
-void ResetTString(void)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-\r
-    pc.HashErrMsg = "";\r
-}\r
-\r
-void SetVersion(int version)\r
-{\r
-    // called by the CPP, but this functionality is currently\r
-    // taken over by ScanVersion() before parsing starts\r
-\r
-    // CPP should still report errors in semantics\r
-}\r
-\r
-int GetVersion(void* cppPc)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cppPc);\r
-\r
-    return pc.version;\r
-}\r
-\r
-void SetProfile(EProfile profile)\r
-{\r
-    // called by the CPP, but this functionality is currently\r
-    // taken over by ScanVersion() before parsing starts\r
-\r
-    // CPP should still report errors in semantics\r
-}\r
-\r
-TBehavior GetBehavior(const char* behavior)\r
-{\r
-    if (!strcmp("require", behavior))\r
-        return EBhRequire;\r
-    else if (!strcmp("enable", behavior))\r
-        return EBhEnable;\r
-    else if (!strcmp("disable", behavior))\r
-        return EBhDisable;\r
-    else if (!strcmp("warn", behavior))\r
-        return EBhWarn;\r
-    else {\r
-        ShPpErrorToInfoLog((TString("behavior '") + behavior + "' is not supported").c_str());\r
-        return EBhDisable;\r
-    }\r
-}\r
-\r
-void updateExtensionBehavior(const char* extName, const char* behavior)\r
-{\r
-    TParseContext& pc = *((TParseContext *)cpp->pC);\r
-    TBehavior behaviorVal = GetBehavior(behavior);\r
-    TMap<TString, TBehavior>:: iterator iter;\r
-    TString msg;\r
-\r
-    // special cased for all extension\r
-    if (!strcmp(extName, "all")) {\r
-        if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {\r
-            ShPpErrorToInfoLog("extension 'all' cannot have 'require' or 'enable' behavior");\r
-            return;\r
-        } else {\r
-            for (iter = pc.extensionBehavior.begin(); iter != pc.extensionBehavior.end(); ++iter)\r
-                iter->second = behaviorVal;\r
-        }\r
-    } else {\r
-        iter = pc.extensionBehavior.find(TString(extName));\r
-        if (iter == pc.extensionBehavior.end()) {\r
-            switch (behaviorVal) {\r
-            case EBhRequire:\r
-                ShPpErrorToInfoLog((TString("extension '") + extName + "' is not supported").c_str());\r
-                break;\r
-            case EBhEnable:\r
-            case EBhWarn:\r
-            case EBhDisable:\r
-                pc.warn(yylineno, "extension not supported", extName, "");\r
-                break;\r
-            default:\r
-                assert(0 && "unexpected behaviorVal");\r
-            }\r
-\r
-            return;\r
-        } else\r
-            iter->second = behaviorVal;\r
-    }\r
-}\r
-\r
-}  // extern "C"\r
-\r
-void ResetFlex()\r
-{\r
-    yy_start = 1;\r
-}\r
index a342956..f824400 100644 (file)
@@ -77,7 +77,7 @@ extern void yyerror(const char*);
 \r
 %union {\r
     struct {\r
-        TSourceLoc line;\r
+        TSourceLoc loc;\r
         union {\r
             TString *string;\r
             int i;\r
@@ -88,7 +88,7 @@ extern void yyerror(const char*);
         TSymbol* symbol;\r
     } lex;\r
     struct {\r
-        TSourceLoc line;\r
+        TSourceLoc loc;\r
         TOperator op;\r
         union {\r
             TIntermNode* intermNode;\r
@@ -100,7 +100,7 @@ extern void yyerror(const char*);
             TPublicType type;\r
             TFunction* function;\r
             TParameter param;\r
-            TTypeLine typeLine;\r
+            TTypeLoc typeLine;\r
             TTypeList* typeList;\r
             TArraySizes arraySizes;\r
             TIdentifierList* identifierList;\r
@@ -176,6 +176,8 @@ extern void yyerror(const char*);
 %token <lex> INVARIANT PRECISE\r
 %token <lex> HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION\r
 \r
+%token <lex> PACKED RESOURCE SUPERP\r
+\r
 %type <interm> assignment_operator unary_operator\r
 %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression\r
 %type <interm.intermTypedNode> expression integer_expression assignment_expression\r
@@ -222,7 +224,7 @@ extern void yyerror(const char*);
 \r
 variable_identifier\r
     : IDENTIFIER {\r
-        $$ = parseContext.handleVariable($1.line, $1.symbol, $1.string);\r
+        $$ = parseContext.handleVariable($1.loc, $1.symbol, $1.string);\r
     }\r
     ;\r
 \r
@@ -233,29 +235,29 @@ primary_expression
     | INTCONSTANT {\r
         constUnion *unionArray = new constUnion[1];\r
         unionArray->setIConst($1.i);\r
-        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);\r
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc);\r
     }\r
     | UINTCONSTANT {        \r
-        parseContext.fullIntegerCheck($1.line, "unsigned literal");\r
+        parseContext.fullIntegerCheck($1.loc, "unsigned literal");\r
         constUnion *unionArray = new constUnion[1];\r
         unionArray->setUConst($1.u);\r
-        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.line);\r
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.loc);\r
     }\r
     | FLOATCONSTANT {\r
         constUnion *unionArray = new constUnion[1];\r
         unionArray->setDConst($1.d);\r
-        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);\r
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc);\r
     }\r
     | DOUBLECONSTANT {\r
-        parseContext.doubleCheck($1.line, "double literal");\r
+        parseContext.doubleCheck($1.loc, "double literal");\r
         constUnion *unionArray = new constUnion[1];\r
         unionArray->setDConst($1.d);\r
-        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.line);\r
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.loc);\r
     }\r
     | BOOLCONSTANT {\r
         constUnion *unionArray = new constUnion[1];\r
         unionArray->setBConst($1.b);\r
-        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.line);\r
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.loc);\r
     }\r
     | LEFT_PAREN expression RIGHT_PAREN {\r
         $$ = $2;\r
@@ -270,58 +272,58 @@ postfix_expression
         parseContext.variableCheck($1);\r
         if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {\r
             if ($1->getAsSymbolNode())\r
-                parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getName().c_str(), "");\r
+                parseContext.error($2.loc, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getName().c_str(), "");\r
             else\r
-                parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");\r
+                parseContext.error($2.loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");\r
         }\r
         if ($1->getType().getQualifier().storage == EvqConst && $3->getQualifier().storage == EvqConst) {\r
             if ($1->isArray()) { // constant folding for arrays\r
-                $$ = parseContext.addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);\r
+                $$ = parseContext.addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.loc);\r
             } else if ($1->isVector()) {  // constant folding for vectors\r
                 TVectorFields fields;\r
                 fields.num = 1;\r
                 fields.offsets[0] = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array\r
-                $$ = parseContext.addConstVectorNode(fields, $1, $2.line);\r
+                $$ = parseContext.addConstVectorNode(fields, $1, $2.loc);\r
             } else if ($1->isMatrix()) { // constant folding for matrices\r
-                $$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);\r
+                $$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.loc);\r
             }\r
         } else {\r
             if ($3->getQualifier().storage == EvqConst) {\r
                 int index = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst();\r
                 if (! $1->isArray() && ($1->isVector() && $1->getType().getVectorSize() <= index ||\r
                                         $1->isMatrix() && $1->getType().getMatrixCols() <= index))\r
-                    parseContext.error($2.line, "", "[", "index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());\r
+                    parseContext.error($2.loc, "", "[", "index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());\r
                 else {\r
                     if ($1->isArray()) {\r
                         if ($1->getType().getArraySize() == 0) {\r
                             if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst())\r
-                                parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line);\r
+                                parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.loc);\r
                             else\r
-                                parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line);\r
+                                parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.loc);\r
                         } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize() ||\r
                                     $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0)\r
-                            parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());\r
+                            parseContext.error($2.loc, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());\r
                     }\r
-                    $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);\r
+                    $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, $3, $2.loc);\r
                 }\r
             } else {\r
                 if ($1->isArray() && $1->getType().getArraySize() == 0)\r
-                    parseContext.error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");\r
+                    parseContext.error($2.loc, "", "[", "array must be redeclared with a size before being indexed with a variable");\r
                 if ($1->getBasicType() == EbtBlock)\r
-                    parseContext.requireProfile($1->getLine(), static_cast<EProfileMask>(~EEsProfileMask), "variable indexing block array");\r
+                    parseContext.requireProfile($1->getLoc(), static_cast<EProfileMask>(~EEsProfileMask), "variable indexing block array");\r
                 if ($1->getBasicType() == EbtSampler) {\r
-                    parseContext.requireProfile($1->getLine(), static_cast<EProfileMask>(ECoreProfileMask | ECompatibilityProfileMask), "variable indexing sampler array");\r
-                    parseContext.profileRequires($1->getLine(), ECoreProfile, 400, 0, "variable indexing sampler array");\r
+                    parseContext.requireProfile($1->getLoc(), static_cast<EProfileMask>(ECoreProfileMask | ECompatibilityProfileMask), "variable indexing sampler array");\r
+                    parseContext.profileRequires($1->getLoc(), ECoreProfile, 400, 0, "variable indexing sampler array");\r
                 }\r
 \r
-                $$ = parseContext.intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);\r
+                $$ = parseContext.intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.loc);\r
             }\r
         }\r
 \r
         if ($$ == 0) {\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setDConst(0.0);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $2.loc);\r
         } else {\r
             TType newType($1->getType());\r
             newType.dereference();\r
@@ -340,21 +342,21 @@ postfix_expression
             //\r
 \r
             if (*$3.string == "length") {\r
-                parseContext.profileRequires($3.line, ENoProfile, 120, "GL_3DL_array_objects", ".length");\r
-                $$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line);\r
+                parseContext.profileRequires($3.loc, ENoProfile, 120, "GL_3DL_array_objects", ".length");\r
+                $$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.loc);\r
             } else {\r
-                parseContext.error($3.line, "only the length method is supported for array", $3.string->c_str(), "");\r
+                parseContext.error($3.loc, "only the length method is supported for array", $3.string->c_str(), "");\r
                 $$ = $1;\r
             }\r
         } else if ($1->isVector()) {\r
             TVectorFields fields;\r
-            if (! parseContext.parseVectorFields(*$3.string, $1->getVectorSize(), fields, $3.line)) {\r
+            if (! parseContext.parseVectorFields($3.loc, *$3.string, $1->getVectorSize(), fields)) {\r
                 fields.num = 1;\r
                 fields.offsets[0] = 0;\r
             }\r
 \r
             if ($1->getType().getQualifier().storage == EvqConst) { // constant folding for vector fields\r
-                $$ = parseContext.addConstVectorNode(fields, $1, $3.line);\r
+                $$ = parseContext.addConstVectorNode(fields, $1, $3.loc);\r
                 if ($$ == 0)\r
                     $$ = $1;\r
                 else\r
@@ -363,23 +365,23 @@ postfix_expression
                 if (fields.num == 1) {\r
                     constUnion *unionArray = new constUnion[1];\r
                     unionArray->setIConst(fields.offsets[0]);\r
-                    TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);\r
-                    $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);\r
+                    TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.loc);\r
+                    $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.loc);\r
                     $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getType().getQualifier().precision));\r
                 } else {\r
                     TString vectorString = *$3.string;\r
-                    TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, $3.line);\r
-                    $$ = parseContext.intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);\r
+                    TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, $3.loc);\r
+                    $$ = parseContext.intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.loc);\r
                     $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getType().getQualifier().precision, (int) vectorString.size()));\r
                 }\r
             }\r
         } else if ($1->isMatrix())\r
-            parseContext.error($2.line, "field selection not allowed on matrix", ".", "");\r
+            parseContext.error($2.loc, "field selection not allowed on matrix", ".", "");\r
         else if ($1->getBasicType() == EbtStruct || $1->getBasicType() == EbtBlock) {\r
             bool fieldFound = false;\r
             TTypeList* fields = $1->getType().getStruct();\r
             if (fields == 0) {\r
-                parseContext.error($2.line, "structure has no fields", "Internal Error", "");\r
+                parseContext.error($2.loc, "structure has no fields", "Internal Error", "");\r
                 $$ = $1;\r
             } else {\r
                 unsigned int i;\r
@@ -391,7 +393,7 @@ postfix_expression
                 }\r
                 if (fieldFound) {\r
                     if ($1->getType().getQualifier().storage == EvqConst) {\r
-                        $$ = parseContext.addConstStruct(*$3.string, $1, $2.line);\r
+                        $$ = parseContext.addConstStruct(*$3.string, $1, $2.loc);\r
                         if ($$ == 0)\r
                             $$ = $1;\r
                         else {\r
@@ -403,36 +405,36 @@ postfix_expression
                     } else {\r
                         constUnion *unionArray = new constUnion[1];\r
                         unionArray->setIConst(i);\r
-                        TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);\r
-                        $$ = parseContext.intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);\r
+                        TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.loc);\r
+                        $$ = parseContext.intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.loc);\r
                         $$->setType(*(*fields)[i].type);\r
                     }\r
                 } else {\r
-                    parseContext.error($2.line, " no such field in structure", $3.string->c_str(), "");\r
+                    parseContext.error($2.loc, " no such field in structure", $3.string->c_str(), "");\r
                     $$ = $1;\r
                 }\r
             }\r
         } else {\r
-            parseContext.error($2.line, " dot operator requires structure, array, vector, or matrix on left hand side", $3.string->c_str(), "");\r
+            parseContext.error($2.loc, " dot operator requires structure, array, vector, or matrix on left hand side", $3.string->c_str(), "");\r
             $$ = $1;\r
         }\r
         // don't delete $3.string, it's from the pool\r
     }\r
     | postfix_expression INC_OP {\r
         parseContext.variableCheck($1);\r
-        parseContext.lValueErrorCheck($2.line, "++", $1);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line);\r
+        parseContext.lValueErrorCheck($2.loc, "++", $1);\r
+        $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.unaryOpError($2.line, "++", $1->getCompleteString());\r
+            parseContext.unaryOpError($2.loc, "++", $1->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
     | postfix_expression DEC_OP {\r
         parseContext.variableCheck($1);\r
-        parseContext.lValueErrorCheck($2.line, "--", $1);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line);\r
+        parseContext.lValueErrorCheck($2.loc, "--", $1);\r
+        $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.unaryOpError($2.line, "--", $1->getCompleteString());\r
+            parseContext.unaryOpError($2.loc, "--", $1->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
@@ -451,17 +453,17 @@ function_call
         TOperator op = fnCall->getBuiltInOp();\r
         if (op == EOpArrayLength) {\r
             if (fnCall->getParamCount() > 0)\r
-                parseContext.error($1.line, "method does not accept any arguments", fnCall->getName().c_str(), "");\r
+                parseContext.error($1.loc, "method does not accept any arguments", fnCall->getName().c_str(), "");\r
             int length;\r
             if ($1.intermNode->getAsTyped() == 0 || ! $1.intermNode->getAsTyped()->getType().isArray() || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {\r
-                parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");\r
+                parseContext.error($1.loc, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");\r
                 length = 1;\r
             } else\r
                 length = $1.intermNode->getAsTyped()->getType().getArraySize();\r
 \r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setIConst(length);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc);\r
         } else if (op != EOpNull) {\r
             //\r
             // Then this should be a constructor.\r
@@ -469,26 +471,26 @@ function_call
             // Their parameters will be verified algorithmically.\r
             //\r
             TType type(EbtVoid);  // use this to get the type back\r
-            if (parseContext.constructorError($1.line, $1.intermNode, *fnCall, op, type)) {\r
+            if (parseContext.constructorError($1.loc, $1.intermNode, *fnCall, op, type)) {\r
                 $$ = 0;\r
             } else {\r
                 //\r
                 // It's a constructor, of type 'type'.\r
                 //\r
-                $$ = parseContext.addConstructor($1.intermNode, type, op, fnCall, $1.line);\r
+                $$ = parseContext.addConstructor($1.intermNode, type, op, fnCall, $1.loc);\r
                 if ($$ == 0)\r
-                    parseContext.error($1.line, "cannot construct with these arguments", type.getCompleteString().c_str(), "");\r
+                    parseContext.error($1.loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");\r
             }\r
 \r
             if ($$ == 0)\r
-                $$ = parseContext.intermediate.setAggregateOperator(0, op, type, $1.line);\r
+                $$ = parseContext.intermediate.setAggregateOperator(0, op, type, $1.loc);\r
         } else {\r
             //\r
             // Not a constructor.  Find it in the symbol table.\r
             //\r
             const TFunction* fnCandidate;\r
             bool builtIn;\r
-            fnCandidate = parseContext.findFunction($1.line, fnCall, &builtIn);\r
+            fnCandidate = parseContext.findFunction($1.loc, fnCall, &builtIn);\r
             if (fnCandidate) {\r
                 //\r
                 // A declared function.  But, it might still map to a built-in\r
@@ -499,14 +501,14 @@ function_call
                     // A function call mapped to a built-in operation.\r
                     $$ = parseContext.intermediate.addBuiltInFunctionCall(op, fnCandidate->getParamCount() == 1, $1.intermNode, fnCandidate->getReturnType());\r
                     if ($$ == 0)  {\r
-                        parseContext.error($1.intermNode->getLine(), " wrong operand type", "Internal Error",\r
+                        parseContext.error($1.intermNode->getLoc(), " wrong operand type", "Internal Error",\r
                                            "built in unary operator function.  Type: %s",\r
                                            static_cast<TIntermTyped*>($1.intermNode)->getCompleteString().c_str());\r
                         YYERROR;\r
                     }\r
                 } else {\r
                     // This is a real function call\r
-                    $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, fnCandidate->getReturnType(), $1.line);\r
+                    $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, fnCandidate->getReturnType(), $1.loc);\r
 \r
                     // this is how we know whether the given function is a builtIn function or a user defined function\r
                     // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also\r
@@ -520,8 +522,8 @@ function_call
                     for (int i = 0; i < fnCandidate->getParamCount(); ++i) {\r
                         qual = (*fnCandidate)[i].type->getQualifier().storage;\r
                         if (qual == EvqOut || qual == EvqInOut) {\r
-                            if (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped()))\r
-                                parseContext.error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");\r
+                            if (parseContext.lValueErrorCheck($$->getLoc(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped()))\r
+                                parseContext.error($1.intermNode->getLoc(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");\r
                         }\r
                         qualifierList.push_back(qual);\r
                     }\r
@@ -536,7 +538,7 @@ function_call
                 // Put on a dummy node for error recovery\r
                 constUnion *unionArray = new constUnion[1];\r
                 unionArray->setDConst(0.0);\r
-                $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);\r
+                $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc);\r
             }\r
         }\r
         delete fnCall;\r
@@ -552,11 +554,11 @@ function_call_or_method
 function_call_generic\r
     : function_call_header_with_parameters RIGHT_PAREN {\r
         $$ = $1;\r
-        $$.line = $2.line;\r
+        $$.loc = $2.loc;\r
     }\r
     | function_call_header_no_parameters RIGHT_PAREN {\r
         $$ = $1;\r
-        $$.line = $2.line;\r
+        $$.loc = $2.loc;\r
     }\r
     ;\r
 \r
@@ -580,7 +582,7 @@ function_call_header_with_parameters
         TParameter param = { 0, new TType($3->getType()) };\r
         $1.function->addParameter(param);\r
         $$.function = $1.function;\r
-        $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.line);\r
+        $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);\r
     }\r
     ;\r
 \r
@@ -601,8 +603,8 @@ function_identifier
         $$.intermNode = 0;\r
 \r
         if ($1.arraySizes) {\r
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor");\r
-            parseContext.profileRequires($1.line, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor");\r
+            parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor");\r
+            parseContext.profileRequires($1.loc, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor");\r
         }\r
 \r
         $1.qualifier.precision = EpqNone;\r
@@ -721,7 +723,7 @@ function_identifier
             default: break; // some compilers want this\r
             }\r
             if (op == EOpNull) {\r
-                parseContext.error($1.line, "cannot construct this type", TType::getBasicString($1.basicType), "");\r
+                parseContext.error($1.loc, "cannot construct this type", TType::getBasicString($1.basicType), "");\r
                 $1.basicType = EbtFloat;\r
                 op = EOpConstructFloat;\r
             }\r
@@ -744,15 +746,15 @@ function_identifier
                 $$.function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength);\r
                 $$.intermNode = method->getObject();\r
             } else\r
-                parseContext.error(method->getLine(), "only arrays have methods", "", "");\r
+                parseContext.error(method->getLoc(), "only arrays have methods", "", "");\r
         } else {\r
             TIntermSymbol* symbol = $1->getAsSymbolNode();\r
             if (symbol) {\r
-                parseContext.reservedErrorCheck(symbol->getLine(), symbol->getName());\r
+                parseContext.reservedErrorCheck(symbol->getLoc(), symbol->getName());\r
                 TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid));\r
                 $$.function = function;\r
             } else\r
-                parseContext.error($1->getLine(), "function call, method, or subroutine call expected", "", "");\r
+                parseContext.error($1->getLoc(), "function call, method, or subroutine call expected", "", "");\r
         }\r
 \r
         if ($$.function == 0) {\r
@@ -768,27 +770,27 @@ unary_expression
         parseContext.variableCheck($1);\r
         $$ = $1;\r
         if (TIntermMethod* method = $1->getAsMethodNode())\r
-            parseContext.error($1->getLine(), "incomplete method syntax", method->getMethodName().c_str(), "");\r
+            parseContext.error($1->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), "");\r
     }\r
     | INC_OP unary_expression {\r
-        parseContext.lValueErrorCheck($1.line, "++", $2);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line);\r
+        parseContext.lValueErrorCheck($1.loc, "++", $2);\r
+        $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.loc);\r
         if ($$ == 0) {\r
-            parseContext.unaryOpError($1.line, "++", $2->getCompleteString());\r
+            parseContext.unaryOpError($1.loc, "++", $2->getCompleteString());\r
             $$ = $2;\r
         }\r
     }\r
     | DEC_OP unary_expression {\r
-        parseContext.lValueErrorCheck($1.line, "--", $2);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line);\r
+        parseContext.lValueErrorCheck($1.loc, "--", $2);\r
+        $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.loc);\r
         if ($$ == 0) {\r
-            parseContext.unaryOpError($1.line, "--", $2->getCompleteString());\r
+            parseContext.unaryOpError($1.loc, "--", $2->getCompleteString());\r
             $$ = $2;\r
         }\r
     }\r
     | unary_operator unary_expression {\r
         if ($1.op != EOpNull) {\r
-            $$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.line);\r
+            $$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.loc);\r
             if ($$ == 0) {\r
                 char errorOp[2] = {0, 0};\r
                 switch($1.op) {\r
@@ -797,7 +799,7 @@ unary_expression
                 case EOpBitwiseNot: errorOp[0] = '~'; break;\r
                 default: break; // some compilers want this\r
                 }\r
-                parseContext.unaryOpError($1.line, errorOp, $2->getCompleteString());\r
+                parseContext.unaryOpError($1.loc, errorOp, $2->getCompleteString());\r
                 $$ = $2;\r
             }\r
         } else\r
@@ -807,33 +809,33 @@ unary_expression
 // Grammar Note:  No traditional style type casts.\r
 \r
 unary_operator\r
-    : PLUS  { $$.line = $1.line; $$.op = EOpNull; }\r
-    | DASH  { $$.line = $1.line; $$.op = EOpNegative; }\r
-    | BANG  { $$.line = $1.line; $$.op = EOpLogicalNot; }\r
-    | TILDE { $$.line = $1.line; $$.op = EOpBitwiseNot; }\r
+    : PLUS  { $$.loc = $1.loc; $$.op = EOpNull; }\r
+    | DASH  { $$.loc = $1.loc; $$.op = EOpNegative; }\r
+    | BANG  { $$.loc = $1.loc; $$.op = EOpLogicalNot; }\r
+    | TILDE { $$.loc = $1.loc; $$.op = EOpBitwiseNot; }\r
     ;\r
 // Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.\r
 \r
 multiplicative_expression\r
     : unary_expression { $$ = $1; }\r
     | multiplicative_expression STAR unary_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "*", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
     | multiplicative_expression SLASH unary_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "/", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
     | multiplicative_expression PERCENT unary_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "%", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
@@ -842,16 +844,16 @@ multiplicative_expression
 additive_expression\r
     : multiplicative_expression { $$ = $1; }\r
     | additive_expression PLUS multiplicative_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "+", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
     | additive_expression DASH multiplicative_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "-", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
@@ -860,18 +862,18 @@ additive_expression
 shift_expression\r
     : additive_expression { $$ = $1; }\r
     | shift_expression LEFT_OP additive_expression {\r
-        parseContext.fullIntegerCheck($2.line, "bit shift left");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line);\r
+        parseContext.fullIntegerCheck($2.loc, "bit shift left");\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "<<", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
     | shift_expression RIGHT_OP additive_expression {\r
-        parseContext.fullIntegerCheck($2.line, "bit shift right");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line);\r
+        parseContext.fullIntegerCheck($2.loc, "bit shift right");\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, ">>", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
@@ -880,39 +882,39 @@ shift_expression
 relational_expression\r
     : shift_expression { $$ = $1; }\r
     | relational_expression LEFT_ANGLE shift_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "<", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         }\r
     }\r
     | relational_expression RIGHT_ANGLE shift_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, ">", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         }\r
     }\r
     | relational_expression LE_OP shift_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "<=", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         }\r
     }\r
     | relational_expression GE_OP shift_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, ">=", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         }\r
     }\r
     ;\r
@@ -920,34 +922,34 @@ relational_expression
 equality_expression\r
     : relational_expression { $$ = $1; }\r
     | equality_expression EQ_OP relational_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "==", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         } else if (($1->isArray() || $3->isArray()))\r
-            parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "==");\r
+            parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "==");\r
     }\r
     | equality_expression NE_OP relational_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "!=", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         } else if (($1->isArray() || $3->isArray()))\r
-            parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "!=");\r
+            parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "!=");\r
     }\r
     ;\r
 \r
 and_expression\r
     : equality_expression { $$ = $1; }\r
     | and_expression AMPERSAND equality_expression {\r
-        parseContext.fullIntegerCheck($2.line, "bitwise and");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line);\r
+        parseContext.fullIntegerCheck($2.loc, "bitwise and");\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "&", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
@@ -956,10 +958,10 @@ and_expression
 exclusive_or_expression\r
     : and_expression { $$ = $1; }\r
     | exclusive_or_expression CARET and_expression {\r
-        parseContext.fullIntegerCheck($2.line, "bitwise exclusive or");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line);\r
+        parseContext.fullIntegerCheck($2.loc, "bitwise exclusive or");\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "^", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
@@ -968,10 +970,10 @@ exclusive_or_expression
 inclusive_or_expression\r
     : exclusive_or_expression { $$ = $1; }\r
     | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {\r
-        parseContext.fullIntegerCheck($2.line, "bitwise inclusive or");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line);\r
+        parseContext.fullIntegerCheck($2.loc, "bitwise inclusive or");\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "|", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         }\r
     }\r
@@ -980,12 +982,12 @@ inclusive_or_expression
 logical_and_expression\r
     : inclusive_or_expression { $$ = $1; }\r
     | logical_and_expression AND_OP inclusive_or_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "&&", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         }\r
     }\r
     ;\r
@@ -993,12 +995,12 @@ logical_and_expression
 logical_xor_expression\r
     : logical_and_expression { $$ = $1; }\r
     | logical_xor_expression XOR_OP logical_and_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "^^", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         }\r
     }\r
     ;\r
@@ -1006,12 +1008,12 @@ logical_xor_expression
 logical_or_expression\r
     : logical_xor_expression { $$ = $1; }\r
     | logical_or_expression OR_OP logical_xor_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, "||", $1->getCompleteString(), $3->getCompleteString());\r
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setBConst(false);\r
-            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);\r
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
         }\r
     }\r
     ;\r
@@ -1019,11 +1021,11 @@ logical_or_expression
 conditional_expression\r
     : logical_or_expression { $$ = $1; }\r
     | logical_or_expression QUESTION expression COLON assignment_expression {\r
-        parseContext.boolCheck($2.line, $1);\r
+        parseContext.boolCheck($2.loc, $1);\r
 \r
-        $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.line);\r
+        $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, ":", $3->getCompleteString(), $5->getCompleteString());\r
             $$ = $5;\r
         }\r
     }\r
@@ -1032,42 +1034,42 @@ conditional_expression
 assignment_expression\r
     : conditional_expression { $$ = $1; }\r
     | unary_expression assignment_operator assignment_expression {\r
-        parseContext.lValueErrorCheck($2.line, "assign", $1);\r
-        $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.line);\r
+        parseContext.lValueErrorCheck($2.loc, "assign", $1);\r
+        $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $1;\r
         } else if (($1->isArray() || $3->isArray()))\r
-            parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "=");\r
+            parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "=");\r
     }\r
     ;\r
 \r
 assignment_operator\r
-    : EQUAL        { $$.line = $1.line; $$.op = EOpAssign; }\r
-    | MUL_ASSIGN   { $$.line = $1.line; $$.op = EOpMulAssign; }\r
-    | DIV_ASSIGN   { $$.line = $1.line; $$.op = EOpDivAssign; }\r
-    | MOD_ASSIGN   { $$.line = $1.line; $$.op = EOpModAssign; }\r
-    | ADD_ASSIGN   { $$.line = $1.line; $$.op = EOpAddAssign; }\r
-    | SUB_ASSIGN   { $$.line = $1.line; $$.op = EOpSubAssign; }\r
+    : EQUAL        { $$.loc = $1.loc; $$.op = EOpAssign; }\r
+    | MUL_ASSIGN   { $$.loc = $1.loc; $$.op = EOpMulAssign; }\r
+    | DIV_ASSIGN   { $$.loc = $1.loc; $$.op = EOpDivAssign; }\r
+    | MOD_ASSIGN   { $$.loc = $1.loc; $$.op = EOpModAssign; }\r
+    | ADD_ASSIGN   { $$.loc = $1.loc; $$.op = EOpAddAssign; }\r
+    | SUB_ASSIGN   { $$.loc = $1.loc; $$.op = EOpSubAssign; }\r
     | LEFT_ASSIGN  {\r
-        parseContext.fullIntegerCheck($1.line, "bit-shift left assign");\r
-        $$.line = $1.line; $$.op = EOpLeftShiftAssign;\r
+        parseContext.fullIntegerCheck($1.loc, "bit-shift left assign");\r
+        $$.loc = $1.loc; $$.op = EOpLeftShiftAssign;\r
     }\r
     | RIGHT_ASSIGN {\r
-        parseContext.fullIntegerCheck($1.line, "bit-shift right assign");\r
-        $$.line = $1.line; $$.op = EOpRightShiftAssign;\r
+        parseContext.fullIntegerCheck($1.loc, "bit-shift right assign");\r
+        $$.loc = $1.loc; $$.op = EOpRightShiftAssign;\r
     }\r
     | AND_ASSIGN   {\r
-        parseContext.fullIntegerCheck($1.line, "bitwise-and assign");\r
-        $$.line = $1.line; $$.op = EOpAndAssign;\r
+        parseContext.fullIntegerCheck($1.loc, "bitwise-and assign");\r
+        $$.loc = $1.loc; $$.op = EOpAndAssign;\r
     }\r
     | XOR_ASSIGN   {\r
-        parseContext.fullIntegerCheck($1.line, "bitwise-xor assign");\r
-        $$.line = $1.line; $$.op = EOpExclusiveOrAssign;\r
+        parseContext.fullIntegerCheck($1.loc, "bitwise-xor assign");\r
+        $$.loc = $1.loc; $$.op = EOpExclusiveOrAssign;\r
     }\r
     | OR_ASSIGN    {\r
-        parseContext.fullIntegerCheck($1.line, "bitwise-or assign");\r
-        $$.line = $1.line; $$.op = EOpInclusiveOrAssign;\r
+        parseContext.fullIntegerCheck($1.loc, "bitwise-or assign");\r
+        $$.loc = $1.loc; $$.op = EOpInclusiveOrAssign;\r
     }\r
     ;\r
 \r
@@ -1076,9 +1078,9 @@ expression
         $$ = $1;\r
     }\r
     | expression COMMA assignment_expression {\r
-        $$ = parseContext.intermediate.addComma($1, $3, $2.line);\r
+        $$ = parseContext.intermediate.addComma($1, $3, $2.loc);\r
         if ($$ == 0) {\r
-            parseContext.binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());\r
+            parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString());\r
             $$ = $3;\r
         }\r
     }\r
@@ -1102,47 +1104,47 @@ declaration
         $$ = $1.intermAggregate;\r
     }\r
     | PRECISION precision_qualifier type_specifier SEMICOLON {\r
-        parseContext.profileRequires($1.line, ENoProfile, 130, 0, "precision statement");\r
+        parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "precision statement");\r
 \r
         // lazy setting of the previous scope's defaults, only takes on first one in a particular scope\r
         parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]);\r
 \r
-               parseContext.setDefaultPrecision($1.line, $3, $2.qualifier.precision);\r
+               parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision);\r
         $$ = 0;\r
     }\r
     | block_structure SEMICOLON {\r
-        parseContext.addBlock($1.line, *$1.typeList);\r
+        parseContext.addBlock($1.loc, *$1.typeList);\r
         $$ = 0;\r
     }\r
     | block_structure IDENTIFIER SEMICOLON {\r
-        parseContext.addBlock($1.line, *$1.typeList, $2.string);\r
+        parseContext.addBlock($1.loc, *$1.typeList, $2.string);\r
         $$ = 0;\r
     }\r
     | block_structure IDENTIFIER array_specifier SEMICOLON {\r
-        parseContext.addBlock($1.line, *$1.typeList, $2.string, $3.arraySizes);\r
+        parseContext.addBlock($1.loc, *$1.typeList, $2.string, $3.arraySizes);\r
         $$ = 0;\r
     }\r
     | type_qualifier SEMICOLON {\r
-        parseContext.updateQualifierDefaults($1.line, $1.qualifier);\r
+        parseContext.updateQualifierDefaults($1.loc, $1.qualifier);\r
         $$ = 0;\r
     }\r
     | type_qualifier IDENTIFIER SEMICOLON {\r
-        parseContext.addQualifierToExisting($1.line, $1.qualifier, *$2.string);\r
+        parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string);\r
         $$ = 0;\r
     }\r
     | type_qualifier IDENTIFIER identifier_list SEMICOLON {\r
         $3->push_back($2.string);\r
-        parseContext.addQualifierToExisting($1.line, $1.qualifier, *$3);\r
+        parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3);\r
         $$ = 0;\r
     }\r
     ;\r
 \r
 block_structure\r
-    : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.line); } struct_declaration_list RIGHT_BRACE {\r
+    : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_list RIGHT_BRACE {\r
         --parseContext.structNestingLevel;\r
         parseContext.blockName = $2.string;\r
         parseContext.currentBlockDefaults = $1.qualifier;\r
-        $$.line = $1.line;\r
+        $$.loc = $1.loc;\r
         $$.typeList = $5;\r
     }\r
 \r
@@ -1161,7 +1163,7 @@ function_prototype
     : function_declarator RIGHT_PAREN  {\r
         // ES can't declare prototypes inside functions\r
         if (! parseContext.symbolTable.atGlobalLevel())\r
-            parseContext.requireProfile($2.line, static_cast<EProfileMask>(~EEsProfileMask), "local function declaration");\r
+            parseContext.requireProfile($2.loc, static_cast<EProfileMask>(~EEsProfileMask), "local function declaration");\r
 \r
         //\r
         // Multiple declarations of the same function are allowed.\r
@@ -1176,15 +1178,15 @@ function_prototype
         bool builtIn;\r
         TSymbol* symbol = parseContext.symbolTable.find($1->getMangledName(), &builtIn);\r
         if (symbol && symbol->getAsFunction() && builtIn)\r
-            parseContext.requireProfile($2.line, static_cast<EProfileMask>(~EEsProfileMask), "redeclaration of built-in function");\r
+            parseContext.requireProfile($2.loc, static_cast<EProfileMask>(~EEsProfileMask), "redeclaration of built-in function");\r
         TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;\r
         if (prevDec) {\r
             if (prevDec->getReturnType() != $1->getReturnType()) {\r
-                parseContext.error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getCompleteTypeString().c_str(), "");\r
+                parseContext.error($2.loc, "overloaded functions must have the same return type", $1->getReturnType().getCompleteTypeString().c_str(), "");\r
             }\r
             for (int i = 0; i < prevDec->getParamCount(); ++i) {\r
                 if ((*prevDec)[i].type->getQualifier().storage != (*$1)[i].type->getQualifier().storage)\r
-                    parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getStorageQualifierString(), "");\r
+                    parseContext.error($2.loc, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getStorageQualifierString(), "");\r
             }\r
         }\r
 \r
@@ -1194,10 +1196,10 @@ function_prototype
         // being redeclared.  So, pass back up this declaration, not the one in the symbol table.\r
         //\r
         $$.function = $1;\r
-        $$.line = $2.line;\r
+        $$.loc = $2.loc;\r
 \r
         if (! parseContext.symbolTable.insert(*$$.function))\r
-            parseContext.error($2.line, "illegal redeclaration", $$.function->getName().c_str(), "");\r
+            parseContext.error($2.loc, "illegal redeclaration", $$.function->getName().c_str(), "");\r
     }\r
     ;\r
 \r
@@ -1229,7 +1231,7 @@ function_header_with_parameters
             //\r
             // This parameter > first is void\r
             //\r
-            parseContext.error($2.line, "cannot be an argument type except for '(void)'", "void", "");\r
+            parseContext.error($2.loc, "cannot be an argument type except for '(void)'", "void", "");\r
             delete $3.param.type;\r
         } else {\r
             // Add the parameter\r
@@ -1242,7 +1244,7 @@ function_header_with_parameters
 function_header\r
     : fully_specified_type IDENTIFIER LEFT_PAREN {\r
         if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) {\r
-            parseContext.error($2.line, "no qualifiers allowed for function return",\r
+            parseContext.error($2.loc, "no qualifiers allowed for function return",\r
                                getStorageQualifierString($1.qualifier.storage), "");\r
         }\r
 \r
@@ -1258,34 +1260,34 @@ parameter_declarator
     // Type + name\r
     : type_specifier IDENTIFIER {\r
         if ($1.arraySizes) {\r
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
-            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");\r
-            parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front());\r
+            parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+            parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
+            parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front());\r
         }\r
         if ($1.basicType == EbtVoid) {\r
-            parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");\r
+            parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), "");\r
         }\r
-        parseContext.reservedErrorCheck($2.line, *$2.string);\r
+        parseContext.reservedErrorCheck($2.loc, *$2.string);\r
 \r
         TParameter param = {$2.string, new TType($1)};\r
-        $$.line = $2.line;\r
+        $$.loc = $2.loc;\r
         $$.param = param;\r
     }\r
     | type_specifier IDENTIFIER array_specifier {\r
         if ($1.arraySizes) {\r
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
-            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");\r
-            parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front());\r
+            parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+            parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
+            parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front());\r
         }\r
-        parseContext.arrayDimCheck($2.line, $1.arraySizes, $3.arraySizes);\r
+        parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes);\r
 \r
-        parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front());\r
-        parseContext.reservedErrorCheck($2.line, *$2.string);\r
+        parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->front());\r
+        parseContext.reservedErrorCheck($2.loc, *$2.string);\r
 \r
         $1.arraySizes = $3.arraySizes;\r
 \r
         TParameter param = { $2.string, new TType($1)};\r
-        $$.line = $2.line;\r
+        $$.loc = $2.loc;\r
         $$.param = param;\r
     }\r
     ;\r
@@ -1299,14 +1301,14 @@ parameter_declaration
         if ($1.qualifier.precision != EpqNone)\r
             $$.param.type->getQualifier().precision = $1.qualifier.precision;\r
 \r
-        parseContext.parameterSamplerCheck($2.line, $1.qualifier.storage, *$$.param.type);\r
-        parseContext.paramCheck($1.line, $1.qualifier.storage, $$.param.type);\r
+        parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);\r
+        parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);\r
     }\r
     | parameter_declarator {\r
         $$ = $1;\r
 \r
-        parseContext.parameterSamplerCheck($1.line, EvqIn, *$1.param.type);\r
-        parseContext.paramCheck($1.line, EvqTemporary, $$.param.type);\r
+        parseContext.parameterSamplerCheck($1.loc, EvqIn, *$1.param.type);\r
+        parseContext.paramCheck($1.loc, EvqTemporary, $$.param.type);\r
     }\r
     //\r
     // Without name\r
@@ -1316,14 +1318,14 @@ parameter_declaration
         if ($1.qualifier.precision != EpqNone)\r
             $$.param.type->getQualifier().precision = $1.qualifier.precision;\r
 \r
-        parseContext.parameterSamplerCheck($2.line, $1.qualifier.storage, *$$.param.type);\r
-        parseContext.paramCheck($1.line, $1.qualifier.storage, $$.param.type);\r
+        parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);\r
+        parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);\r
     }\r
     | parameter_type_specifier {\r
         $$ = $1;\r
 \r
-        parseContext.parameterSamplerCheck($1.line, EvqIn, *$1.param.type);\r
-        parseContext.paramCheck($1.line, EvqTemporary, $$.param.type);\r
+        parseContext.parameterSamplerCheck($1.loc, EvqIn, *$1.param.type);\r
+        parseContext.paramCheck($1.loc, EvqTemporary, $$.param.type);\r
     }\r
     ;\r
 \r
@@ -1340,42 +1342,42 @@ init_declarator_list
     }\r
     | init_declarator_list COMMA IDENTIFIER {\r
         $$ = $1;\r
-        parseContext.nonInitConstCheck($3.line, *$3.string, $$.type);\r
-        parseContext.nonInitCheck($3.line, *$3.string, $$.type);\r
+        parseContext.nonInitConstCheck($3.loc, *$3.string, $$.type);\r
+        parseContext.nonInitCheck($3.loc, *$3.string, $$.type);\r
     }\r
     | init_declarator_list COMMA IDENTIFIER array_specifier {\r
-        parseContext.nonInitConstCheck($3.line, *$3.string, $1.type);\r
+        parseContext.nonInitConstCheck($3.loc, *$3.string, $1.type);\r
         if (parseContext.profile == EEsProfile)\r
-            parseContext.arraySizeRequiredCheck($4.line, $4.arraySizes->front());\r
-        parseContext.arrayDimCheck($3.line, $1.type.arraySizes, $4.arraySizes);\r
+            parseContext.arraySizeRequiredCheck($4.loc, $4.arraySizes->front());\r
+        parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes);\r
 \r
         $$ = $1;\r
 \r
-        if (! parseContext.arrayQualifierError($4.line, $1.type)) {\r
+        if (! parseContext.arrayQualifierError($4.loc, $1.type)) {\r
             $1.type.arraySizes = $4.arraySizes;\r
             TVariable* variable;\r
-            parseContext.arrayCheck($4.line, *$3.string, $1.type, variable);\r
+            parseContext.arrayCheck($4.loc, *$3.string, $1.type, variable);\r
         }\r
     }\r
     | init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer {\r
         $$ = $1;\r
 \r
         TVariable* variable = 0;\r
-        if (! parseContext.arrayQualifierError($4.line, $1.type)) {\r
+        if (! parseContext.arrayQualifierError($4.loc, $1.type)) {\r
             $1.type.arraySizes = $4.arraySizes;\r
-            parseContext.arrayCheck($4.line, *$3.string, $1.type, variable);\r
+            parseContext.arrayCheck($4.loc, *$3.string, $1.type, variable);\r
         }\r
-        parseContext.arrayDimCheck($3.line, $1.type.arraySizes, $4.arraySizes);\r
+        parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes);\r
 \r
-        parseContext.profileRequires($5.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer");\r
+        parseContext.profileRequires($5.loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer");\r
 \r
         TIntermNode* intermNode;\r
-        if (! parseContext.executeInitializerError($3.line, *$3.string, $1.type, $6, intermNode, variable)) {\r
+        if (! parseContext.executeInitializerError($3.loc, *$3.string, $1.type, $6, intermNode, variable)) {\r
             //\r
             // build the intermediate representation\r
             //\r
             if (intermNode)\r
-                $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.line);\r
+                $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.loc);\r
             else\r
                 $$.intermAggregate = $1.intermAggregate;\r
         } else\r
@@ -1385,12 +1387,12 @@ init_declarator_list
         $$ = $1;\r
 \r
         TIntermNode* intermNode;\r
-        if (!parseContext.executeInitializerError($3.line, *$3.string, $1.type, $5, intermNode)) {\r
+        if (!parseContext.executeInitializerError($3.loc, *$3.string, $1.type, $5, intermNode)) {\r
             //\r
             // build the intermediate representation\r
             //\r
             if (intermNode)\r
-                $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.line);\r
+                $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.loc);\r
             else\r
                 $$.intermAggregate = $1.intermAggregate;\r
         } else\r
@@ -1402,54 +1404,54 @@ single_declaration
     : fully_specified_type {\r
         $$.type = $1;\r
         $$.intermAggregate = 0;\r
-        parseContext.updateTypedDefaults($1.line, $$.type.qualifier, 0);\r
+        parseContext.updateTypedDefaults($1.loc, $$.type.qualifier, 0);\r
     }\r
     | fully_specified_type IDENTIFIER {\r
         $$.intermAggregate = 0;\r
         $$.type = $1;\r
 \r
-        parseContext.nonInitConstCheck($2.line, *$2.string, $$.type);\r
-        parseContext.nonInitCheck($2.line, *$2.string, $$.type);\r
+        parseContext.nonInitConstCheck($2.loc, *$2.string, $$.type);\r
+        parseContext.nonInitCheck($2.loc, *$2.string, $$.type);\r
         \r
-        parseContext.updateTypedDefaults($2.line, $$.type.qualifier, $2.string);\r
+        parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string);\r
     }\r
     | fully_specified_type IDENTIFIER array_specifier {\r
         $$.intermAggregate = 0;\r
-        parseContext.nonInitConstCheck($2.line, *$2.string, $1);        \r
+        parseContext.nonInitConstCheck($2.loc, *$2.string, $1);        \r
         if (parseContext.profile == EEsProfile)\r
-            parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front());        \r
-        parseContext.arrayDimCheck($2.line, $1.arraySizes, $3.arraySizes);\r
+            parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->front());        \r
+        parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes);\r
 \r
         $$.type = $1;\r
 \r
-        if (! parseContext.arrayQualifierError($3.line, $1)) {\r
+        if (! parseContext.arrayQualifierError($3.loc, $1)) {\r
             $1.arraySizes = $3.arraySizes;\r
             TVariable* variable;\r
-            parseContext.arrayCheck($3.line, *$2.string, $1, variable);\r
+            parseContext.arrayCheck($3.loc, *$2.string, $1, variable);\r
         }\r
-        parseContext.updateTypedDefaults($2.line, $$.type.qualifier, $2.string);\r
+        parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string);\r
     }\r
     | fully_specified_type IDENTIFIER array_specifier EQUAL initializer {        \r
-        parseContext.arrayDimCheck($3.line, $1.arraySizes, $3.arraySizes);\r
+        parseContext.arrayDimCheck($3.loc, $1.arraySizes, $3.arraySizes);\r
 \r
         $$.intermAggregate = 0;\r
         $$.type = $1;\r
 \r
         TVariable* variable = 0;\r
-        if (! parseContext.arrayQualifierError($3.line, $1)) {\r
+        if (! parseContext.arrayQualifierError($3.loc, $1)) {\r
             $1.arraySizes = $3.arraySizes;\r
-            parseContext.arrayCheck($3.line, *$2.string, $1, variable);\r
+            parseContext.arrayCheck($3.loc, *$2.string, $1, variable);\r
         }\r
 \r
-        parseContext.profileRequires($4.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer");\r
+        parseContext.profileRequires($4.loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer");\r
 \r
         TIntermNode* intermNode;\r
-        if (!parseContext.executeInitializerError($2.line, *$2.string, $1, $5, intermNode, variable)) {\r
+        if (!parseContext.executeInitializerError($2.loc, *$2.string, $1, $5, intermNode, variable)) {\r
             //\r
             // Build intermediate representation\r
             //\r
             if (intermNode)\r
-                $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.line);\r
+                $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.loc);\r
             else\r
                 $$.intermAggregate = 0;\r
         } else\r
@@ -1459,12 +1461,12 @@ single_declaration
         $$.type = $1;\r
 \r
         TIntermNode* intermNode;\r
-        if (!parseContext.executeInitializerError($2.line, *$2.string, $1, $4, intermNode)) {\r
+        if (!parseContext.executeInitializerError($2.loc, *$2.string, $1, $4, intermNode)) {\r
             //\r
             // Build intermediate representation\r
             //\r
             if (intermNode)\r
-                $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.line);\r
+                $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.loc);\r
             else\r
                 $$.intermAggregate = 0;\r
         } else\r
@@ -1478,29 +1480,29 @@ fully_specified_type
         $$ = $1;\r
 \r
         if ($1.arraySizes) {\r
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
-            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");\r
+            parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+            parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
             if (parseContext.profile == EEsProfile)\r
-                parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front());\r
+                parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front());\r
         }\r
 \r
-        parseContext.precisionQualifierCheck($$.line, $$);\r
+        parseContext.precisionQualifierCheck($$.loc, $$);\r
     }\r
     | type_qualifier type_specifier  {\r
-        parseContext.globalQualifierFix($1.line, $1.qualifier, $2);\r
+        parseContext.globalQualifierFix($1.loc, $1.qualifier, $2);\r
 \r
         if ($2.arraySizes) {\r
-            parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
-            parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type");\r
+            parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+            parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");\r
             if (parseContext.profile == EEsProfile)\r
-                parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front());\r
+                parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front());\r
         }\r
 \r
-        if ($2.arraySizes && parseContext.arrayQualifierError($2.line, $1))\r
+        if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1))\r
             $2.arraySizes = 0;\r
         \r
-        parseContext.mergeQualifiers($2.line, $2.qualifier, $1.qualifier, true);\r
-        parseContext.precisionQualifierCheck($2.line, $2);\r
+        parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);\r
+        parseContext.precisionQualifierCheck($2.loc, $2);\r
 \r
         $$ = $2;\r
 \r
@@ -1513,32 +1515,32 @@ fully_specified_type
 \r
 invariant_qualifier\r
     : INVARIANT {\r
-        parseContext.profileRequires($$.line, ENoProfile, 120, 0, "invariant");\r
-        $$.init($1.line);\r
+        parseContext.profileRequires($$.loc, ENoProfile, 120, 0, "invariant");\r
+        $$.init($1.loc);\r
         $$.qualifier.invariant = true;\r
     }\r
     ;\r
 \r
 interpolation_qualifier\r
     : SMOOTH {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "smooth");\r
-        parseContext.profileRequires($1.line, ENoProfile, 130, 0, "smooth");\r
-        parseContext.profileRequires($1.line, EEsProfile, 300, 0, "smooth");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "smooth");\r
+        parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "smooth");\r
+        parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "smooth");\r
+        $$.init($1.loc);\r
         $$.qualifier.smooth = true;\r
     }\r
     | FLAT {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "flat");\r
-        parseContext.profileRequires($1.line, ENoProfile, 130, 0, "flat");\r
-        parseContext.profileRequires($1.line, EEsProfile, 300, 0, "flat");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "flat");\r
+        parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "flat");\r
+        parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "flat");\r
+        $$.init($1.loc);\r
         $$.qualifier.flat = true;\r
     }\r
     | NOPERSPECTIVE {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "noperspective");\r
-        parseContext.requireProfile($1.line, static_cast<EProfileMask>(~EEsProfileMask), "noperspective");\r
-        parseContext.profileRequires($1.line, ENoProfile, 130, 0, "noperspective");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "noperspective");\r
+        parseContext.requireProfile($1.loc, static_cast<EProfileMask>(~EEsProfileMask), "noperspective");\r
+        parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective");\r
+        $$.init($1.loc);\r
         $$.qualifier.nopersp = true;\r
     }\r
     ;\r
@@ -1555,28 +1557,28 @@ layout_qualifier_id_list
     }\r
     | layout_qualifier_id_list COMMA layout_qualifier_id {\r
         $$ = $1;\r
-        parseContext.mergeLayoutQualifiers($2.line, $$.qualifier, $3.qualifier);\r
+        parseContext.mergeLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier);\r
     }\r
 \r
 layout_qualifier_id\r
     : IDENTIFIER {\r
-        $$.init($1.line);\r
-        parseContext.setLayoutQualifier($1.line, $$, *$1.string);\r
+        $$.init($1.loc);\r
+        parseContext.setLayoutQualifier($1.loc, $$, *$1.string);\r
     }\r
     | IDENTIFIER EQUAL INTCONSTANT {\r
-        $$.init($1.line);\r
-        parseContext.setLayoutQualifier($1.line, $$, *$1.string, $3.i);\r
+        $$.init($1.loc);\r
+        parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3.i);\r
     }\r
     | SHARED { // because "shared" is both an identifier and a keyword\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         TString strShared("shared");\r
-        parseContext.setLayoutQualifier($1.line, $$, strShared);\r
+        parseContext.setLayoutQualifier($1.loc, $$, strShared);\r
     }\r
     ;\r
 \r
 precise_qualifier\r
     : PRECISE {\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
     }\r
     ;\r
 \r
@@ -1589,7 +1591,7 @@ type_qualifier
         if ($$.basicType == EbtVoid)\r
             $$.basicType = $2.basicType;\r
 \r
-        parseContext.mergeQualifiers($$.line, $$.qualifier, $2.qualifier, false);\r
+        parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false);\r
     }\r
     ;\r
 \r
@@ -1619,112 +1621,112 @@ single_type_qualifier
 \r
 storage_qualifier\r
     : CONST {\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqConst;\r
     }\r
     | ATTRIBUTE {\r
-        parseContext.requireStage($1.line, EShLangVertexMask, "attribute");\r
-        parseContext.checkDeprecated($1.line, ECoreProfile, 130, "attribute");\r
-        parseContext.checkDeprecated($1.line, ENoProfile, 130, "attribute");\r
-        parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "attribute");\r
-        parseContext.requireNotRemoved($1.line, EEsProfile, 300, "attribute");\r
+        parseContext.requireStage($1.loc, EShLangVertexMask, "attribute");\r
+        parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute");\r
+        parseContext.checkDeprecated($1.loc, ENoProfile, 130, "attribute");\r
+        parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "attribute");\r
+        parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "attribute");\r
 \r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute");\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "attribute");\r
 \r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqVaryingIn;\r
     }\r
     | VARYING {\r
-        parseContext.checkDeprecated($1.line, ENoProfile, 130, "varying");\r
-        parseContext.checkDeprecated($1.line, ECoreProfile, 130, "varying");\r
-        parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "varying");\r
-        parseContext.requireNotRemoved($1.line, EEsProfile, 300, "varying");\r
+        parseContext.checkDeprecated($1.loc, ENoProfile, 130, "varying");\r
+        parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "varying");\r
+        parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "varying");\r
+        parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "varying");\r
 \r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying");\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "varying");\r
 \r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         if (parseContext.language == EShLangVertex)\r
             $$.qualifier.storage = EvqVaryingOut;\r
         else\r
             $$.qualifier.storage = EvqVaryingIn;\r
     }\r
     | INOUT {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "out");\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqInOut;\r
     }\r
     | IN {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "in");\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqIn;\r
     }\r
     | OUT {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "out");\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqOut;\r
     }\r
     | CENTROID {\r
-        parseContext.profileRequires($1.line, ENoProfile, 120, 0, "centroid");\r
-        parseContext.profileRequires($1.line, EEsProfile, 300, 0, "centroid");\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid");\r
-        $$.init($1.line);\r
+        parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid");\r
+        parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid");\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "centroid");\r
+        $$.init($1.loc);\r
         $$.qualifier.centroid = true;\r
     }\r
     | PATCH {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "patch");\r
+        $$.init($1.loc);\r
         $$.qualifier.patch = true;\r
     }\r
     | SAMPLE {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "sample");\r
+        $$.init($1.loc);\r
         $$.qualifier.sample = true;\r
     }\r
     | UNIFORM {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "uniform");\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqUniform;\r
     }\r
     | BUFFER {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "buffer");\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqUniform; // TODO: 4.0 functionality: implement BUFFER\r
     }\r
     | SHARED {\r
-        parseContext.requireProfile($1.line, static_cast<EProfileMask>(~EEsProfileMask), "shared");\r
-        parseContext.profileRequires($1.line, ECoreProfile, 430, 0, "shared");\r
-        parseContext.requireStage($1.line, EShLangComputeMask, "shared");\r
-        $$.init($1.line);\r
+        parseContext.requireProfile($1.loc, static_cast<EProfileMask>(~EEsProfileMask), "shared");\r
+        parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared");\r
+        parseContext.requireStage($1.loc, EShLangComputeMask, "shared");\r
+        $$.init($1.loc);\r
         $$.qualifier.shared = true;\r
     }\r
     | COHERENT {\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.qualifier.coherent = true;\r
     }\r
     | VOLATILE {\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.qualifier.volatil = true;\r
     }\r
     | RESTRICT {\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.qualifier.restrict = true;\r
     }\r
     | READONLY {\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.qualifier.readonly = true;\r
     }\r
     | WRITEONLY {\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.qualifier.writeonly = true;\r
     }\r
     | SUBROUTINE {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "subroutine");\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqUniform;\r
     }\r
     | SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN {\r
-        parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine");\r
-        $$.init($1.line);\r
+        parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "subroutine");\r
+        $$.init($1.loc);\r
         $$.qualifier.storage = EvqUniform;\r
         // TODO: 4.0 semantics: subroutines\r
         // 1) make sure each identifier is a type declared earlier with SUBROUTINE\r
@@ -1746,7 +1748,7 @@ type_specifier
         $$.qualifier.precision = parseContext.getDefaultPrecision($$);\r
     }\r
     | type_specifier_nonarray array_specifier {        \r
-        parseContext.arrayDimCheck($2.line, $2.arraySizes, 0);\r
+        parseContext.arrayDimCheck($2.loc, $2.arraySizes, 0);\r
         $$ = $1;\r
         $$.qualifier.precision = parseContext.getDefaultPrecision($$);\r
         $$.arraySizes = $2.arraySizes;\r
@@ -1755,16 +1757,16 @@ type_specifier
 \r
 array_specifier\r
     : LEFT_BRACKET RIGHT_BRACKET {\r
-        $$.line = $1.line;\r
+        $$.loc = $1.loc;\r
         $$.arraySizes = NewPoolTArraySizes();\r
         $$.arraySizes->push_back(0);\r
     }\r
     | LEFT_BRACKET constant_expression RIGHT_BRACKET {\r
-        $$.line = $1.line;\r
+        $$.loc = $1.loc;\r
         $$.arraySizes = NewPoolTArraySizes();\r
 \r
         int size;\r
-        parseContext.arraySizeCheck($2->getLine(), $2, size);\r
+        parseContext.arraySizeCheck($2->getLoc(), $2, size);\r
         $$.arraySizes->push_back(size);\r
     }\r
     | array_specifier LEFT_BRACKET RIGHT_BRACKET {\r
@@ -1775,626 +1777,626 @@ array_specifier
         $$ = $1;\r
 \r
         int size;\r
-        parseContext.arraySizeCheck($3->getLine(), $3, size);\r
+        parseContext.arraySizeCheck($3->getLoc(), $3, size);\r
         $$.arraySizes->push_back(size);\r
     }\r
     ;\r
 \r
 type_specifier_nonarray\r
     : VOID {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtVoid;\r
     }\r
     | FLOAT {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
     }\r
     | DOUBLE {\r
-        parseContext.doubleCheck($1.line, "double");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
     }\r
     | INT {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtInt;\r
     }\r
     | UINT {\r
-        parseContext.fullIntegerCheck($1.line, "unsigned integer");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.fullIntegerCheck($1.loc, "unsigned integer");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtUint;\r
     }\r
     | BOOL {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtBool;\r
     }\r
     | VEC2 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setVector(2);\r
     }\r
     | VEC3 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setVector(3);\r
     }\r
     | VEC4 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setVector(4);\r
     }\r
     | DVEC2 {\r
-        parseContext.doubleCheck($1.line, "double vector");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double vector");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setVector(2);\r
     }\r
     | DVEC3 {\r
-        parseContext.doubleCheck($1.line, "double vector");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double vector");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setVector(3);\r
     }\r
     | DVEC4 {\r
-        parseContext.doubleCheck($1.line, "double vector");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double vector");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setVector(4);\r
     }\r
     | BVEC2 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtBool;\r
         $$.setVector(2);\r
     }\r
     | BVEC3 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtBool;\r
         $$.setVector(3);\r
     }\r
     | BVEC4 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtBool;\r
         $$.setVector(4);\r
     }\r
     | IVEC2 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtInt;\r
         $$.setVector(2);\r
     }\r
     | IVEC3 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtInt;\r
         $$.setVector(3);\r
     }\r
     | IVEC4 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtInt;\r
         $$.setVector(4);\r
     }\r
     | UVEC2 {\r
-        parseContext.fullIntegerCheck($1.line, "unsigned integer vector");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.fullIntegerCheck($1.loc, "unsigned integer vector");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtUint;\r
         $$.setVector(2);\r
     }\r
     | UVEC3 {\r
-        parseContext.fullIntegerCheck($1.line, "unsigned integer vector");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.fullIntegerCheck($1.loc, "unsigned integer vector");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtUint;\r
         $$.setVector(3);\r
     }\r
     | UVEC4 {\r
-        parseContext.fullIntegerCheck($1.line, "unsigned integer vector");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.fullIntegerCheck($1.loc, "unsigned integer vector");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtUint;\r
         $$.setVector(4);\r
     }\r
     | MAT2 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(2, 2);\r
     }\r
     | MAT3 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(3, 3);\r
     }\r
     | MAT4 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(4, 4);\r
     }\r
     | MAT2X2 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(2, 2);\r
     }\r
     | MAT2X3 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(2, 3);\r
     }\r
     | MAT2X4 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(2, 4);\r
     }\r
     | MAT3X2 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(3, 2);\r
     }\r
     | MAT3X3 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(3, 3);\r
     }\r
     | MAT3X4 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(3, 4);\r
     }\r
     | MAT4X2 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(4, 2);\r
     }\r
     | MAT4X3 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(4, 3);\r
     }\r
     | MAT4X4 {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtFloat;\r
         $$.setMatrix(4, 4);\r
     }\r
     | DMAT2 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(2, 2);\r
     }\r
     | DMAT3 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(3, 3);\r
     }\r
     | DMAT4 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(4, 4);\r
     }\r
     | DMAT2X2 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(2, 2);\r
     }\r
     | DMAT2X3 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(2, 3);\r
     }\r
     | DMAT2X4 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(2, 4);\r
     }\r
     | DMAT3X2 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(3, 2);\r
     }\r
     | DMAT3X3 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(3, 3);\r
     }\r
     | DMAT3X4 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(3, 4);\r
     }\r
     | DMAT4X2 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(4, 2);\r
     }\r
     | DMAT4X3 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(4, 3);\r
     }\r
     | DMAT4X4 {\r
-        parseContext.doubleCheck($1.line, "double matrix");\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        parseContext.doubleCheck($1.loc, "double matrix");\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtDouble;\r
         $$.setMatrix(4, 4);\r
     }\r
     | ATOMIC_UINT {\r
         // TODO: 4.2 functionality: add type\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtInt;\r
     }\r
     | SAMPLER1D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd1D);\r
     }\r
     | SAMPLER2D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd2D);\r
     }\r
     | SAMPLER3D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd3D);\r
     }\r
     | SAMPLERCUBE {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, EsdCube);\r
     }\r
     | SAMPLER1DSHADOW {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd1D, false, true);\r
     }\r
     | SAMPLER2DSHADOW {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd2D, false, true);\r
     }\r
     | SAMPLERCUBESHADOW {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, EsdCube, false, true);\r
     }\r
     | SAMPLER1DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd1D, true);\r
     }\r
     | SAMPLER2DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd2D, true);\r
     }\r
     | SAMPLER1DARRAYSHADOW {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd1D, true, true);\r
     }\r
     | SAMPLER2DARRAYSHADOW {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd2D, true, true);\r
     }\r
     | SAMPLERCUBEARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, EsdCube, true);\r
     }\r
     | SAMPLERCUBEARRAYSHADOW {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, EsdCube, true, true);\r
     }\r
     | ISAMPLER1D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd1D);\r
     }\r
     | ISAMPLER2D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd2D);\r
     }\r
     | ISAMPLER3D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd3D);\r
     }\r
     | ISAMPLERCUBE {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, EsdCube);\r
     }\r
     | ISAMPLER1DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd1D, true);\r
     }\r
     | ISAMPLER2DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd2D, true);\r
     }\r
     | ISAMPLERCUBEARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd3D, true);\r
     }\r
     | USAMPLER1D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, Esd1D);\r
     }\r
     | USAMPLER2D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, Esd2D);\r
     }\r
     | USAMPLER3D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, Esd3D);\r
     }\r
     | USAMPLERCUBE {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, EsdCube);\r
     }\r
     | USAMPLER1DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, Esd1D, true);\r
     }\r
     | USAMPLER2DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, Esd2D, true);\r
     }\r
     | USAMPLERCUBEARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, EsdCube, true);\r
     }\r
     | SAMPLER2DRECT {\r
-        parseContext.profileRequires($1.line, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+        parseContext.profileRequires($1.loc, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
 \r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, EsdRect);\r
     }\r
     | SAMPLER2DRECTSHADOW {\r
-        parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+        parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
 \r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, EsdRect, false, true);\r
     }\r
     | ISAMPLER2DRECT {\r
-        parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+        parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
 \r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, EsdRect);\r
     }\r
     | USAMPLER2DRECT {\r
-        parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+        parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
 \r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, EsdRect);\r
     }\r
     | SAMPLERBUFFER {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, EsdBuffer);\r
     }\r
     | ISAMPLERBUFFER {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, EsdBuffer);\r
     }\r
     | USAMPLERBUFFER {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, EsdBuffer);\r
     }\r
     | SAMPLER2DMS {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd2D, false, false, true);\r
     }\r
     | ISAMPLER2DMS {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd2D, false, false, true);\r
     }\r
     | USAMPLER2DMS {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, Esd2D, false, false, true);\r
     }\r
     | SAMPLER2DMSARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtFloat, Esd2D, true, false, true);\r
     }\r
     | ISAMPLER2DMSARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtInt, Esd2D, true, false, true);\r
     }\r
     | USAMPLER2DMSARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.set(EbtUint, Esd2D, true, false, true);\r
     }\r
     | IMAGE1D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, Esd1D);\r
     }\r
     | IIMAGE1D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, Esd1D);\r
     }\r
     | UIMAGE1D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, Esd1D);\r
     }\r
     | IMAGE2D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, Esd2D);\r
     }\r
     | IIMAGE2D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, Esd2D);\r
     }\r
     | UIMAGE2D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, Esd2D);\r
     }\r
     | IMAGE3D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, Esd3D);\r
     }\r
     | IIMAGE3D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, Esd3D);\r
     }\r
     | UIMAGE3D {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, Esd3D);\r
     }\r
     | IMAGE2DRECT {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, EsdRect);\r
     }\r
     | IIMAGE2DRECT {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, EsdRect);\r
     }\r
     | UIMAGE2DRECT {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, EsdRect);\r
     }\r
     | IMAGECUBE {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, EsdCube);\r
     }\r
     | IIMAGECUBE {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, EsdCube);\r
     }\r
     | UIMAGECUBE {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, EsdCube);\r
     }\r
     | IMAGEBUFFER {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, EsdBuffer);\r
     }\r
     | IIMAGEBUFFER {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, EsdBuffer);\r
     }\r
     | UIMAGEBUFFER {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, EsdBuffer);\r
     }\r
     | IMAGE1DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, Esd1D, true);\r
     }\r
     | IIMAGE1DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, Esd1D, true);\r
     }\r
     | UIMAGE1DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, Esd1D, true);\r
     }\r
     | IMAGE2DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, Esd2D, true);\r
     }\r
     | IIMAGE2DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, Esd2D, true);\r
     }\r
     | UIMAGE2DARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, Esd2D, true);\r
     }\r
     | IMAGECUBEARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, EsdCube, true);\r
     }\r
     | IIMAGECUBEARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, EsdCube, true);\r
     }\r
     | UIMAGECUBEARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, EsdCube, true);\r
     }\r
     | IMAGE2DMS {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, Esd2D, false, false, true);\r
     }\r
     | IIMAGE2DMS {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, Esd2D, false, false, true);\r
     }\r
     | UIMAGE2DMS {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, Esd2D, false, false, true);\r
     }\r
     | IMAGE2DMSARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtFloat, Esd2D, true, false, true);\r
     }\r
     | IIMAGE2DMSARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtInt, Esd2D, true, false, true);\r
     }\r
     | UIMAGE2DMSARRAY {\r
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
         $$.basicType = EbtSampler;\r
         $$.sampler.setImage(EbtUint, Esd2D, true, false, true);\r
     }\r
@@ -2409,49 +2411,49 @@ type_specifier_nonarray
         //\r
         if (TVariable* variable = ($1.symbol)->getAsVariable()) {\r
             const TType& structure = variable->getType();\r
-            $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
+            $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
             $$.basicType = EbtStruct;\r
             $$.userDef = &structure;\r
         } else\r
-            parseContext.error($1.line, "expected type name", $1.string->c_str(), "");\r
+            parseContext.error($1.loc, "expected type name", $1.string->c_str(), "");\r
     }\r
     ;\r
 \r
 precision_qualifier\r
     : HIGH_PRECISION {\r
-        parseContext.profileRequires($1.line, ENoProfile, 130, 0, "highp precision qualifier");\r
-        $$.init($1.line);\r
+        parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "highp precision qualifier");\r
+        $$.init($1.loc);\r
         if (parseContext.profile == EEsProfile)\r
                    $$.qualifier.precision = EpqHigh;\r
     }\r
     | MEDIUM_PRECISION {\r
-        parseContext.profileRequires($1.line, ENoProfile, 130, 0, "mediump precision qualifier");\r
-        $$.init($1.line);\r
+        parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "mediump precision qualifier");\r
+        $$.init($1.loc);\r
         if (parseContext.profile == EEsProfile)\r
                $$.qualifier.precision = EpqMedium;\r
     }\r
     | LOW_PRECISION {\r
-        parseContext.profileRequires($1.line, ENoProfile, 130, 0, "lowp precision qualifier");\r
-        $$.init($1.line);\r
+        parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "lowp precision qualifier");\r
+        $$.init($1.loc);\r
         if (parseContext.profile == EEsProfile)\r
                $$.qualifier.precision = EpqLow;\r
     }\r
     ;\r
 \r
 struct_specifier\r
-    : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.line); } struct_declaration_list RIGHT_BRACE {\r
+    : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE {\r
         TType* structure = new TType($5, *$2.string);\r
         TVariable* userTypeDef = new TVariable($2.string, *structure, true);\r
         if (! parseContext.symbolTable.insert(*userTypeDef))\r
-            parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct");\r
-        $$.init($1.line);\r
+            parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct");\r
+        $$.init($1.loc);\r
         $$.basicType = EbtStruct;\r
         $$.userDef = structure;\r
         --parseContext.structNestingLevel;\r
     }\r
-    | STRUCT LEFT_BRACE { parseContext.nestedStructCheck($1.line); } struct_declaration_list RIGHT_BRACE {\r
+    | STRUCT LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE {\r
         TType* structure = new TType($4, TString(""));\r
-        $$.init($1.line);\r
+        $$.init($1.loc);\r
         $$.basicType = EbtStruct;\r
         $$.userDef = structure;\r
         --parseContext.structNestingLevel;\r
@@ -2467,7 +2469,7 @@ struct_declaration_list
         for (unsigned int i = 0; i < $2->size(); ++i) {\r
             for (unsigned int j = 0; j < $$->size(); ++j) {\r
                 if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName())\r
-                    parseContext.error((*$2)[i].line, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str());\r
+                    parseContext.error((*$2)[i].loc, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str());\r
             }\r
             $$->push_back((*$2)[i]);\r
         }\r
@@ -2477,38 +2479,38 @@ struct_declaration_list
 struct_declaration\r
     : type_specifier struct_declarator_list SEMICOLON {\r
         if ($1.arraySizes) {\r
-            parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
-            parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");\r
+            parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+            parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
             if (parseContext.profile == EEsProfile)\r
-                parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front());\r
+                parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front());\r
         }\r
 \r
         $$ = $2;\r
 \r
-        parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1);\r
-        parseContext.precisionQualifierCheck($1.line, $1);\r
+        parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1);\r
+        parseContext.precisionQualifierCheck($1.loc, $1);\r
 \r
         for (unsigned int i = 0; i < $$->size(); ++i) {\r
-            parseContext.arrayDimCheck($1.line, (*$$)[i].type, $1.arraySizes);\r
+            parseContext.arrayDimCheck($1.loc, (*$$)[i].type, $1.arraySizes);\r
             (*$$)[i].type->mergeType($1);\r
         }\r
     }\r
     | type_qualifier type_specifier struct_declarator_list SEMICOLON {\r
         if ($2.arraySizes) {\r
-            parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
-            parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type");\r
+            parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+            parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");\r
             if (parseContext.profile == EEsProfile)\r
-                parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front());\r
+                parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front());\r
         }\r
 \r
         $$ = $3;\r
 \r
-        parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2);\r
-        parseContext.mergeQualifiers($2.line, $2.qualifier, $1.qualifier, true);\r
-        parseContext.precisionQualifierCheck($2.line, $2);\r
+        parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2);\r
+        parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);\r
+        parseContext.precisionQualifierCheck($2.loc, $2);\r
 \r
         for (unsigned int i = 0; i < $$->size(); ++i) {\r
-            parseContext.arrayDimCheck($1.line, (*$$)[i].type, $2.arraySizes);\r
+            parseContext.arrayDimCheck($1.loc, (*$$)[i].type, $2.arraySizes);\r
             (*$$)[i].type->mergeType($2);\r
         }\r
     }\r
@@ -2527,16 +2529,16 @@ struct_declarator_list
 struct_declarator\r
     : IDENTIFIER {\r
         $$.type = new TType(EbtVoid);\r
-        $$.line = $1.line;\r
+        $$.loc = $1.loc;\r
         $$.type->setFieldName(*$1.string);\r
     }\r
     | IDENTIFIER array_specifier {        \r
         if (parseContext.profile == EEsProfile)\r
-            parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front());\r
-        parseContext.arrayDimCheck($1.line, $2.arraySizes, 0);\r
+            parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front());\r
+        parseContext.arrayDimCheck($1.loc, $2.arraySizes, 0);\r
 \r
         $$.type = new TType(EbtVoid);\r
-        $$.line = $1.line;\r
+        $$.loc = $1.loc;\r
         $$.type->setFieldName(*$1.string);\r
         $$.type->setArraySizes($2.arraySizes);\r
     }\r
@@ -2615,7 +2617,7 @@ compound_statement_no_new_scope
 \r
 statement_list\r
     : statement {\r
-        $$ = parseContext.intermediate.makeAggregate($1, 0);\r
+        $$ = parseContext.intermediate.makeAggregate($1);\r
         if ($1 && $1->getAsBranchNode() && ($1->getAsBranchNode()->getFlowOp() == EOpCase ||\r
                                             $1->getAsBranchNode()->getFlowOp() == EOpDefault)) {\r
             parseContext.wrapupSwitchSubsequence(0, $1);\r
@@ -2628,7 +2630,7 @@ statement_list
             parseContext.wrapupSwitchSubsequence($1, $2);\r
             $$ = 0;  // start a fresh subsequence for what's after this case\r
         } else\r
-            $$ = parseContext.intermediate.growAggregate($1, $2, 0);\r
+            $$ = parseContext.intermediate.growAggregate($1, $2);\r
     }\r
     ;\r
 \r
@@ -2639,8 +2641,8 @@ expression_statement
 \r
 selection_statement\r
     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {\r
-        parseContext.boolCheck($1.line, $3);\r
-        $$ = parseContext.intermediate.addSelection($3, $5, $1.line);\r
+        parseContext.boolCheck($1.loc, $3);\r
+        $$ = parseContext.intermediate.addSelection($3, $5, $1.loc);\r
     }\r
     ;\r
 \r
@@ -2659,13 +2661,13 @@ condition
     // In 1996 c++ draft, conditions can include single declarations\r
     : expression {\r
         $$ = $1;\r
-        parseContext.boolCheck($1->getLine(), $1);\r
+        parseContext.boolCheck($1->getLoc(), $1);\r
     }\r
     | fully_specified_type IDENTIFIER EQUAL initializer {\r
         TIntermNode* intermNode;\r
-        parseContext.boolCheck($2.line, $1);\r
+        parseContext.boolCheck($2.loc, $1);\r
 \r
-        if (parseContext.executeInitializerError($2.line, *$2.string, $1, $4, intermNode))\r
+        if (parseContext.executeInitializerError($2.loc, *$2.string, $1, $4, intermNode))\r
             $$ = 0;\r
         else\r
             $$ = $4;\r
@@ -2678,7 +2680,7 @@ switch_statement
         parseContext.switchSequenceStack.push_back(new TIntermSequence);\r
     } \r
     LEFT_BRACE switch_statement_list RIGHT_BRACE {\r
-        $$ = parseContext.addSwitch($1.line, $3, $7);\r
+        $$ = parseContext.addSwitch($1.loc, $3, $7);\r
         delete parseContext.switchSequenceStack.back();\r
         parseContext.switchSequenceStack.pop_back();\r
     }\r
@@ -2697,10 +2699,10 @@ case_label
     : CASE expression COLON {\r
         parseContext.constCheck($2, "case");\r
         parseContext.integerCheck($2, "case");\r
-        $$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.line);\r
+        $$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.loc);\r
     }\r
     | DEFAULT COLON {\r
-        $$ = parseContext.intermediate.addBranch(EOpDefault, $1.line);\r
+        $$ = parseContext.intermediate.addBranch(EOpDefault, $1.loc);\r
     }\r
     ;\r
 \r
@@ -2711,13 +2713,13 @@ iteration_statement
     }\r
       condition RIGHT_PAREN statement_no_new_scope {\r
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);\r
-        $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.line);\r
+        $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.loc);\r
         --parseContext.loopNestingLevel;\r
     }\r
     | DO { ++parseContext.loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {\r
-        parseContext.boolCheck($8.line, $6);\r
+        parseContext.boolCheck($8.loc, $6);\r
 \r
-        $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line);\r
+        $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);\r
         --parseContext.loopNestingLevel;\r
     }\r
     | FOR LEFT_PAREN {\r
@@ -2726,11 +2728,11 @@ iteration_statement
     }\r
       for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {\r
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);\r
-        $$ = parseContext.intermediate.makeAggregate($4, $2.line);\r
+        $$ = parseContext.intermediate.makeAggregate($4, $2.loc);\r
         $$ = parseContext.intermediate.growAggregate(\r
                 $$,\r
-                parseContext.intermediate.addLoop($7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.line),\r
-                $1.line);\r
+                parseContext.intermediate.addLoop($7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.loc),\r
+                $1.loc);\r
         $$->getAsAggregate()->setOperator(EOpSequence);\r
         --parseContext.loopNestingLevel;\r
     }\r
@@ -2768,30 +2770,30 @@ for_rest_statement
 jump_statement\r
     : CONTINUE SEMICOLON {\r
         if (parseContext.loopNestingLevel <= 0)\r
-            parseContext.error($1.line, "continue statement only allowed in loops", "", "");\r
-        $$ = parseContext.intermediate.addBranch(EOpContinue, $1.line);\r
+            parseContext.error($1.loc, "continue statement only allowed in loops", "", "");\r
+        $$ = parseContext.intermediate.addBranch(EOpContinue, $1.loc);\r
     }\r
     | BREAK SEMICOLON {\r
         if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0)\r
-            parseContext.error($1.line, "break statement only allowed in switch and loops", "", "");\r
-        $$ = parseContext.intermediate.addBranch(EOpBreak, $1.line);\r
+            parseContext.error($1.loc, "break statement only allowed in switch and loops", "", "");\r
+        $$ = parseContext.intermediate.addBranch(EOpBreak, $1.loc);\r
     }\r
     | RETURN SEMICOLON {\r
-        $$ = parseContext.intermediate.addBranch(EOpReturn, $1.line);\r
+        $$ = parseContext.intermediate.addBranch(EOpReturn, $1.loc);\r
         if (parseContext.currentFunctionType->getBasicType() != EbtVoid)\r
-            parseContext.error($1.line, "non-void function must return a value", "return", "");\r
+            parseContext.error($1.loc, "non-void function must return a value", "return", "");\r
     }\r
     | RETURN expression SEMICOLON {\r
-        $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.line);\r
+        $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc);\r
         parseContext.functionReturnsValue = true;\r
         if (parseContext.currentFunctionType->getBasicType() == EbtVoid)\r
-            parseContext.error($1.line, "void function cannot return a value", "return", "");\r
+            parseContext.error($1.loc, "void function cannot return a value", "return", "");\r
         else if (*(parseContext.currentFunctionType) != $2->getType())\r
-            parseContext.error($1.line, "function return is not matching type:", "return", "");\r
+            parseContext.error($1.loc, "function return is not matching type:", "return", "");\r
     }\r
     | DISCARD SEMICOLON {\r
-        parseContext.requireStage($1.line, EShLangFragmentMask, "discard");\r
-        $$ = parseContext.intermediate.addBranch(EOpKill, $1.line);\r
+        parseContext.requireStage($1.loc, EShLangFragmentMask, "discard");\r
+        $$ = parseContext.intermediate.addBranch(EOpKill, $1.loc);\r
     }\r
     ;\r
 \r
@@ -2803,7 +2805,7 @@ translation_unit
         parseContext.treeRoot = $$;\r
     }\r
     | translation_unit external_declaration {\r
-        $$ = parseContext.intermediate.growAggregate($1, $2, 0);\r
+        $$ = parseContext.intermediate.growAggregate($1, $2);\r
         parseContext.treeRoot = $$;\r
     }\r
     ;\r
@@ -2824,7 +2826,7 @@ function_definition
         TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;\r
 \r
         if (! prevDec)\r
-            parseContext.error($1.line, "can't find function name", function.getName().c_str(), "");\r
+            parseContext.error($1.loc, "can't find function name", function.getName().c_str(), "");\r
 \r
         //\r
         // Note:  'prevDec' could be 'function' if this is the first time we've seen function\r
@@ -2835,7 +2837,7 @@ function_definition
             //\r
             // Then this function already has a body.\r
             //\r
-            parseContext.error($1.line, "function already has a body", function.getName().c_str(), "");\r
+            parseContext.error($1.loc, "function already has a body", function.getName().c_str(), "");\r
         }\r
         if (prevDec) {\r
             prevDec->setDefined();\r
@@ -2852,9 +2854,9 @@ function_definition
         //\r
         if (function.getName() == "main") {\r
             if (function.getParamCount() > 0)\r
-                parseContext.error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), "");\r
+                parseContext.error($1.loc, "function cannot take any parameter(s)", function.getName().c_str(), "");\r
             if (function.getReturnType().getBasicType() != EbtVoid)\r
-                parseContext.error($1.line, "", function.getReturnType().getCompleteTypeString().c_str(), "main function cannot return a value");\r
+                parseContext.error($1.loc, "", function.getReturnType().getCompleteTypeString().c_str(), "main function cannot return a value");\r
         }\r
 \r
         //\r
@@ -2879,7 +2881,7 @@ function_definition
                 // Insert the parameters with name in the symbol table.\r
                 //\r
                 if (! parseContext.symbolTable.insert(*variable)) {\r
-                    parseContext.error($1.line, "redefinition", variable->getName().c_str(), "");\r
+                    parseContext.error($1.loc, "redefinition", variable->getName().c_str(), "");\r
                     delete variable;\r
                 }\r
                 //\r
@@ -2894,23 +2896,23 @@ function_definition
                                                paramNodes,\r
                                                parseContext.intermediate.addSymbol(variable->getUniqueId(),\r
                                                                        variable->getName(),\r
-                                                                       variable->getType(), $1.line),\r
-                                               $1.line);\r
+                                                                       variable->getType(), $1.loc),\r
+                                               $1.loc);\r
             } else {\r
-                paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);\r
+                paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, $1.loc), $1.loc);\r
             }\r
         }\r
-        parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), $1.line);\r
+        parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), $1.loc);\r
         $1.intermAggregate = paramNodes;\r
         parseContext.loopNestingLevel = 0;\r
     }\r
     compound_statement_no_new_scope {\r
         //   May be best done as post process phase on intermediate code\r
         if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue)\r
-            parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str());\r
+            parseContext.error($1.loc, "function does not return a value:", "", $1.function->getName().c_str());\r
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);\r
-        $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0);\r
-        parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getReturnType(), $1.line);\r
+        $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3);\r
+        parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getReturnType(), $1.loc);\r
         $$->getAsAggregate()->setName($1.function->getMangledName().c_str());\r
 \r
         // store the pragma information for debug and optimize and other vendor specific\r
index bbab55b..e538f6a 100644 (file)
@@ -63,7 +63,11 @@ void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
 {
     int i;
 
-    infoSink.debug << FormatSourceLoc(node->getLine());
+    infoSink.debug << node->getLoc().string << ":";
+    if (node->getLoc().line)
+        infoSink.debug << node->getLoc().line;
+    else
+        infoSink.debug << "? ";
 
     for (i = 0; i < depth; ++i)
         infoSink.debug << "  ";
@@ -445,7 +449,7 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
             }
             break;
         default:
-            out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
+            out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
             break;
         }
     }
index 4332d82..fb7602d 100644 (file)
@@ -62,7 +62,9 @@ public:
     TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc);
     TIntermTyped* addBuiltInFunctionCall(TOperator, bool unary, TIntermNode*, const TType& returnType);
     bool canImplicitlyPromote(TBasicType from, TBasicType to);
+    TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
     TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
+    TIntermAggregate* makeAggregate(TIntermNode* node);
     TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc);
     TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
     bool areAllChildConst(TIntermAggregate* aggrNode);
index 5ddb177..84b5bb0 100644 (file)
@@ -69,7 +69,7 @@ public:
 void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
 {
     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
+    oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLoc());
 
     return;
 }
@@ -84,13 +84,13 @@ bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
         const int maxSize = GlslangMaxTypeLength + 50;
         char buf[maxSize];
         snprintf(buf, maxSize, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
-        oit->infoSink.info.message(EPrefixError, buf, node->getLine());
+        oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
         oit->error = true;
 
         return false;  
     }
 
-   oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
+   oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLoc());
     
     return false;
 }
@@ -102,7 +102,7 @@ bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
     const int maxSize = GlslangMaxTypeLength + 50;
     char buf[maxSize];
     snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
-    oit->infoSink.info.message(EPrefixError, buf, node->getLine());
+    oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
     oit->error = true;
 
     return false;  
@@ -116,7 +116,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
         const int maxSize = GlslangMaxTypeLength + 50;
         char buf[maxSize];
         snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
-        oit->infoSink.info.message(EPrefixError, buf, node->getLine());
+        oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
         oit->error = true;
 
         return false;  
@@ -165,7 +165,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
 bool ParseSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
 {
     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
+    oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLoc());
     oit->error = true;
     return false;
 }
@@ -235,7 +235,7 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
 bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
 {
     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
+    oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLoc());
     oit->error = true;
     
     return false;
@@ -244,7 +244,7 @@ bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
 bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
 {
     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
+    oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLoc());
     oit->error = true;
     
     return false;
index 2f43c48..e473e78 100644 (file)
@@ -107,29 +107,20 @@ static const struct {
     { CPP_ADD_ASSIGN,     "+=" },
     { CPP_DIV_ASSIGN,     "/=" },
     { CPP_MUL_ASSIGN,     "*=" },
-    { CPP_RIGHT_BRACKET,  ":>" },
     { CPP_EQ_OP,          "==" },
     { CPP_XOR_OP,         "^^" }, 
     { CPP_XOR_ASSIGN,     "^=" }, 
-    { CPP_FLOATCONSTANT,  "<float-const>" },
     { CPP_GE_OP,          ">=" },
     { CPP_RIGHT_OP,       ">>" },
-    { CPP_RIGHT_ASSIGN,   ">>=" }, 
-    { CPP_IDENTIFIER,     "<ident>" },
-    { CPP_INTCONSTANT,    "<int-const>" },
+    { CPP_RIGHT_ASSIGN,   ">>="}, 
     { CPP_LE_OP,          "<=" },
     { CPP_LEFT_OP,        "<<" },
-    { CPP_LEFT_ASSIGN,    "<<=" },
-    { CPP_LEFT_BRACKET,   "<:" },
-    { CPP_LEFT_BRACE,     "<%" }, 
+    { CPP_LEFT_ASSIGN,    "<<="},
     { CPP_DEC_OP,         "--" },
-    { CPP_RIGHT_BRACE,    "%>" }, 
     { CPP_NE_OP,          "!=" },
     { CPP_OR_OP,          "||" },
     { CPP_OR_ASSIGN,      "|=" }, 
     { CPP_INC_OP,         "++" },
-    { CPP_STRCONSTANT,    "<string-const>" },
-    { CPP_TYPEIDENTIFIER, "<type-ident>" },
 };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -672,7 +663,7 @@ int InitAtomTable(AtomTable *atable, int htsize)
     // Initialize lower part of atom table to "<undefined>" atom:
 
     AddAtomFixed(atable, "<undefined>", 0);
-    for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++)
+    for (ii = 0; ii < CPP_FIRST_USER_TOKEN_SY; ii++)
         atable->amap[ii] = atable->amap[0];
 
     // Add single character tokens to the atom table:
@@ -697,7 +688,7 @@ int InitAtomTable(AtomTable *atable, int htsize)
     // Add error symbol if running in error mode:
 
     if (cpp->options.ErrorMode)
-        AddAtomFixed(atable, "error", ERROR_SY);
+        AddAtomFixed(atable, "error", CPP_ERROR_SY);
 
     AddAtom(atable, "<*** end fixed atoms ***>");
 
diff --git a/glslang/MachineIndependent/preprocessor/compile.h b/glslang/MachineIndependent/preprocessor/compile.h
deleted file mode 100644 (file)
index 08a9280..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-//
-//Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-//    Redistributions of source code must retain the above copyright
-//    notice, this list of conditions and the following disclaimer.
-//
-//    Redistributions in binary form must reproduce the above
-//    copyright notice, this list of conditions and the following
-//    disclaimer in the documentation and/or other materials provided
-//    with the distribution.
-//
-//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-//    contributors may be used to endorse or promote products derived
-//    from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms.  If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder. 
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// compile.h
-//
-
-#if !defined(__COMPILE_H)
-#define __COMPILE_H 1
-
-int InitCPPStruct(void);
-
-typedef struct Options_Rec{
-    const char *profileString;
-    int ErrorMode;
-    int Quiet;
-       
-    // Debug The Compiler options:
-    int DumpAtomTable;
-} Options;
-
-struct CPPStruct_Rec {
-    // Public members
-    SourceLoc *pLastSourceLoc;  // Set at the start of each statement by the tree walkers
-    Options options;            // Compile options and parameters
-
-    // Private members
-    SourceLoc lastSourceLoc;
-
-    // Scanner data:
-
-    SourceLoc *tokenLoc;        // Source location of most recent token seen by the scanner
-    int mostRecentToken;        // Most recent token seen by the scanner
-    InputSrc *currentInput;
-    int previous_token;
-    int notAVersionToken;      // used to make sure that #version is the first token seen in the file, if present
-    
-       void *pC;                   // storing the parseContext of the compile object in cpp.  
-     
-    // Private members:
-    SourceLoc ltokenLoc;
-       int ifdepth;                //current #if-#else-#endif nesting in the cpp.c file (pre-processor)    
-    int elsedepth[64];          //Keep a track of #if depth..Max allowed is 64.   
-    int elsetracker;            //#if-#else and #endif constructs...Counter.
-    const char *ErrMsg;
-    int CompileError;           //Indicate compile error when #error, #else,#elif mismatch.
-
-    //
-    // Globals used to communicate between PaParseStrings() and yy_input()and 
-    // also across the files.(gen_glslang.cpp and scanner.c)
-    //
-    int    PaWhichStr;            // which string we're parsing
-    int*   PaStrLen;              // array of lengths of the PaArgv strings
-    int    PaArgc;                // count of strings in the array
-    char** PaArgv;                // our array of strings to parse    
-    unsigned int tokensBeforeEOF : 1;
-};
-
-#endif // !defined(__COMPILE_H)
index 82da285..d001da7 100644 (file)
@@ -630,7 +630,8 @@ static int CPPerror(yystypepp * yylvalpp)
     const char *message;
        
     while (token != '\n') {
-               if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
+               if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
+            token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT) {
             StoreStr(yylvalpp->symbol_name);
                }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
                        StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident));
@@ -681,11 +682,9 @@ static int CPPpragma(yystypepp * yylvalpp)
                        strcpy(allTokens[tokenCount++], SrcStr);
                        break;
                case CPP_INTCONSTANT:
-                       SrcStr = yylvalpp->symbol_name;
-                       allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
-                       strcpy(allTokens[tokenCount++], SrcStr);
-                       break;
+        case CPP_UINTCONSTANT:
                case CPP_FLOATCONSTANT:
+        case CPP_DOUBLECONSTANT:
                        SrcStr = yylvalpp->symbol_name;
                        allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
                        strcpy(allTokens[tokenCount++], SrcStr);
@@ -715,41 +714,35 @@ static int CPPpragma(yystypepp * yylvalpp)
        return token;    
 } // CPPpragma
 
+// This is just for error checking: the version and profile are decided before preprocessing starts
 static int CPPversion(yystypepp * yylvalpp)
 {
-
     int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
 
     if (cpp->notAVersionToken == 1)
         ShPpErrorToInfoLog("#version must occur before any other statement in the program");
 
-    if(token=='\n'){
+    if (token == '\n'){
                DecLineNumber();
         ShPpErrorToInfoLog("#version");
         IncLineNumber();
+
                return token;
        }
+
     if (token != CPP_INTCONSTANT)
         ShPpErrorToInfoLog("#version");
        
-    yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
-
-    SetVersion(yylvalpp->sc_int);
+    yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
 
     token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
     
-       if (token == '\n') {
-        SetProfile(ENoProfile);
+       if (token == '\n')
                return token;
-       }
        else {
-        if (yylvalpp->sc_ident == coreAtom)
-            SetProfile(ECoreProfile);
-        else if (yylvalpp->sc_ident == compatibilityAtom)
-            SetProfile(ECompatibilityProfile);
-        else if (yylvalpp->sc_ident == esAtom)
-            SetProfile(EEsProfile);
-        else 
+        if (yylvalpp->sc_ident != coreAtom &&
+            yylvalpp->sc_ident != compatibilityAtom &&
+            yylvalpp->sc_ident != esAtom)
             ShPpErrorToInfoLog("#version profile name");
 
         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
@@ -1025,7 +1018,7 @@ int MacroExpand(int atom, yystypepp* yylvalpp, int expandUndef)
     }
 
        if (atom == __VERSION__Atom) {
-        yylvalpp->sc_int = GetVersion(cpp->pC);
+        yylvalpp->sc_int = GetShaderVersion(cpp->pC);
         sprintf(yylvalpp->symbol_name, "%d", yylvalpp->sc_int);
         UngetToken(CPP_INTCONSTANT, yylvalpp);
 
index cdedb62..7fcab55 100644 (file)
@@ -116,8 +116,7 @@ int   GetLineNumber(void);                  // Get the current String Number.
 int   GetStringNumber(void);                // Get the current String Number. 
 const char* GetStrfromTStr(void);           // Convert TString to String.  
 void  SetVersion(int);
-void  SetProfile(EProfile);
-int   GetVersion(void*);
+int   GetShaderVersion(void*);
 void  updateExtensionBehavior(const char* extName, const char* behavior);
 int   FreeCPP(void);
 
index b1b15fa..b7b6533 100644 (file)
@@ -86,10 +86,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 CPPStruct  *cpp      = NULL;
 static int  refCount = 0;
 
-int InitPreprocessor(void);
 int ResetPreprocessor(void);
 int FreeCPPStruct(void);
-int FinalizePreprocessor(void);
 
 /*
  * InitCPPStruct() - Initilaize the CPP structure.
index 98a9afb..5cd32b8 100644 (file)
@@ -75,20 +75,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \****************************************************************************/
 
-#ifndef BISON_PARSER_H
-# define BISON_PARSER_H
+#ifndef PARSER_H
+# define PARSER_H
 
-#ifndef yystypepp
-typedef struct {
-    int    sc_int;
-    float  sc_fval;
-    double sc_dval;
-    int    sc_ident;
-       char   symbol_name[MAX_SYMBOL_NAME_LEN+1];
-} yystypepp;
-
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
 # define       CPP_AND_OP              257
 # define       CPP_SUB_ASSIGN      259
 # define       CPP_MOD_ASSIGN      260
@@ -97,7 +86,7 @@ typedef struct {
 # define       CPP_MUL_ASSIGN  263
 # define       CPP_EQ_OP               264
 # define    CPP_XOR_OP         265 
-# define       ERROR_SY            266
+# define       CPP_ERROR_SY        266
 # define       CPP_FLOATCONSTANT       267
 # define       CPP_GE_OP               268
 # define       CPP_RIGHT_OP        269
@@ -111,9 +100,6 @@ typedef struct {
 # define       CPP_INC_OP          277
 # define       CPP_STRCONSTANT     278
 # define       CPP_TYPEIDENTIFIER      279
-
-# define       FIRST_USER_TOKEN_SY     289
-
 # define       CPP_RIGHT_ASSIGN            280
 # define       CPP_LEFT_ASSIGN     281
 # define       CPP_AND_ASSIGN  282
@@ -123,5 +109,8 @@ typedef struct {
 # define       CPP_RIGHT_BRACKET       286
 # define       CPP_LEFT_BRACE  287
 # define       CPP_RIGHT_BRACE 288
+# define    CPP_UINTCONSTANT 289
+# define    CPP_DOUBLECONSTANT 290
+# define       CPP_FIRST_USER_TOKEN_SY 291     
 
-#endif /* not BISON_PARSER_H */
+#endif /* not PARSER_H */
index 0af2759..22c8a28 100644 (file)
@@ -75,10 +75,84 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 \****************************************************************************/
 
-#include "slglobals.h"
+#ifndef PREPROCESS_H
+#define PREPROCESS_H
+
+typedef struct SourceLoc_Rec {
+    int file;
+    int line;
+} SourceLoc;
+
+typedef struct Options_Rec {
+    const char *profileString;
+    int ErrorMode;
+    int Quiet;
+       
+    // Debug The Compiler options:
+    int DumpAtomTable;
+} Options;
+
+#define MAX_TOKEN_LENGTH 1024
+
+typedef struct {
+    int    ppToken;
+    int    sc_int;
+    double sc_dval;
+    int    sc_ident;
+       char   symbol_name[MAX_TOKEN_LENGTH+1];
+} yystypepp;
+
+typedef struct InputSrc {
+    struct InputSrc    *prev;
+    int                        (*scan)(struct InputSrc *, yystypepp *);
+    int                        (*getch)(struct InputSrc *, yystypepp *);
+    void               (*ungetch)(struct InputSrc *, int, yystypepp *);
+    int                        name;  /* atom */
+    int                        line;
+} InputSrc;
+
+typedef struct CPPStruct {
+    // Public members
+    SourceLoc *pLastSourceLoc;  // Set at the start of each statement by the tree walkers
+    Options options;            // Compile options and parameters
+
+    // Private members
+    SourceLoc lastSourceLoc;
+
+    // Scanner data:
+
+    SourceLoc *tokenLoc;        // Source location of most recent token seen by the scanner
+    int mostRecentToken;        // Most recent token seen by the scanner
+    InputSrc *currentInput;
+    int previous_token;
+    int notAVersionToken;       // used to make sure that #version is the first token seen in the file, if present
+    
+       void *pC;                   // storing the parseContext of the compile object in cpp.  
+     
+    // Private members:
+    SourceLoc ltokenLoc;
+       int ifdepth;                //current #if-#else-#endif nesting in the cpp.c file (pre-processor)    
+    int elsedepth[64];          //Keep a track of #if depth..Max allowed is 64.   
+    int elsetracker;            //#if-#else and #endif constructs...Counter.
+    const char *ErrMsg;
+    int CompileError;           //Indicate compile error when #error, #else,#elif mismatch.
+
+    //
+    // Globals used to communicate between parseStrings() and yy_input()and 
+    // also across the files.(gen_glslang.cpp and scanner.c)
+    //
+    int    PaWhichStr;            // which string we're parsing
+    int*   PaStrLen;              // array of lengths of the PaArgv strings
+    int    PaArgc;                // count of strings in the array
+    char** PaArgv;                // our array of strings to parse    
+    unsigned int tokensBeforeEOF : 1;
+} CPPStruct;
+
 extern CPPStruct *cpp;
-int InitCPPStruct(void);
-int InitScanner(CPPStruct *cpp);
-int InitAtomTable(AtomTable *atable, int htsize);
+
+int InitPreprocessor(void);
+int FinalizePreprocessor(void);
 int ScanFromString(char *s);
-char* GetStringOfAtom(AtomTable *atable, int atom);
+const char* PpTokenize(yystypepp*);
+
+#endif
index 06cba8d..f117625 100644 (file)
@@ -222,7 +222,7 @@ int ScanFromString(char *s)
     cpp->currentInput = &in->base;
 
     return 1;
-} // ScanFromString;
+}
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -239,6 +239,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
 {
     int HasDecimal, declen, exp, ExpSign;
     int str_len;
+    int isDouble = 0;
     
     HasDecimal = 0;
     declen = 0;
@@ -250,7 +251,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
         HasDecimal = 1;
         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
         while (ch >= '0' && ch <= '9') {
-            if (len < MAX_SYMBOL_NAME_LEN) {
+            if (len < MAX_TOKEN_LENGTH) {
                 declen++;
                 if (len > 0 || ch != '0') {
                     str[len] = ch;
@@ -267,7 +268,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
     // Exponent:
 
     if (ch == 'e' || ch == 'E') {
-        if (len >= MAX_SYMBOL_NAME_LEN) {
+        if (len >= MAX_TOKEN_LENGTH) {
             ShPpErrorToInfoLog("floating-point literal too long");
             len = 1,str_len=1;
         } else {
@@ -284,7 +285,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
             }
             if (ch >= '0' && ch <= '9') {
                 while (ch >= '0' && ch <= '9') {
-                    if (len < MAX_SYMBOL_NAME_LEN) {
+                    if (len < MAX_TOKEN_LENGTH) {
                         exp = exp*10 + ch - '0';
                                        str[len++]=ch;
                         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
@@ -301,7 +302,6 @@ 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");
     } else {
@@ -311,16 +311,17 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
                 cpp->currentInput->ungetch(cpp->currentInput, ch2, yylvalpp);
                 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
             } else {
-                if (len < MAX_SYMBOL_NAME_LEN) {
+                if (len < MAX_TOKEN_LENGTH) {
                     str[len++] = ch;
                     str[len++] = ch2;
+                    isDouble = 1;
                 } else {
                     ShPpErrorToInfoLog("floating-point literal too long");
                     len = 1,str_len=1;
                 }
             }
         } else if (ch == 'f' || ch == 'F') {
-            if (len < MAX_SYMBOL_NAME_LEN)
+            if (len < MAX_TOKEN_LENGTH)
                 str[len++] = ch;
             else {
                 ShPpErrorToInfoLog("floating-point literal too long");
@@ -332,12 +333,14 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
         str[len]='\0';      
         
         yylvalpp->sc_dval = strtod(str, 0);
-        yylvalpp->sc_fval = (float)yylvalpp->sc_dval;
     }
     // Suffix:
     strcpy(yylvalpp->symbol_name, str);
 
-    return CPP_FLOATCONSTANT;
+    if (isDouble)
+        return CPP_DOUBLECONSTANT;
+    else
+        return CPP_FLOATCONSTANT;
 } // lFloatConst
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -346,8 +349,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
     
 static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
 {
-    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
-    char string_val[MAX_STRING_LEN + 1];
+    char tokenText[MAX_TOKEN_LENGTH + 1];
     int AlreadyComplained = 0;
     int len, ch, ii;
     unsigned ival = 0;
@@ -368,7 +370,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
         default:
                        return ch; // Single character token
         case EOF:
-            return -1;
+            return EOF;
                case 'A': case 'B': case 'C': case 'D': case 'E':
         case 'F': case 'G': case 'H': case 'I': case 'J':
         case 'K': case 'L': case 'M': case 'N': case 'O':
@@ -393,30 +395,32 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
                             ch = nextch;
                     } else
                         ShPpErrorToInfoLog("can only escape newlines");
-                } else if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
-                    len++;
+                } else if (len < MAX_TOKEN_LENGTH) {
+                    tokenText[len++] = ch;
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);                                        
                 } else {
-                    ShPpErrorToInfoLog("name too long");
-                    break;
+                    if (! AlreadyComplained) {
+                        ShPpErrorToInfoLog("name too long");
+                        AlreadyComplained = 1;
+                    }
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);                                        
                 }
             } while ((ch >= 'a' && ch <= 'z') ||
                      (ch >= 'A' && ch <= 'Z') ||
                      (ch >= '0' && ch <= '9') ||
                      ch == '_' ||
                      ch == '\\');
-            if (len > MAX_SYMBOL_NAME_LEN)
-                len = MAX_SYMBOL_NAME_LEN;
-            symbol_name[len] = '\0';
+
+            tokenText[len] = '\0';
             cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+            yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
+
             return CPP_IDENTIFIER;
-            break;
         case '0':
             yylvalpp->symbol_name[len++] = ch;
             ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             if (ch == 'x' || ch == 'X') {
+                int uint = 0;
                                yylvalpp->symbol_name[len++] = ch;
                 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 if ((ch >= '0' && ch <= '9') ||
@@ -425,10 +429,8 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
                 {
                     ival = 0;
                     do {
-                        if (len >= MAX_SYMBOL_NAME_LEN)
-                            break;
-                                               yylvalpp->symbol_name[len++] = ch;
                         if (ival <= 0x0fffffff) {
+                                                   yylvalpp->symbol_name[len++] = ch;
                             if (ch >= '0' && ch <= '9') {
                                 ii = ch - '0';
                             } else if (ch >= 'A' && ch <= 'F') {
@@ -440,9 +442,10 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
                             ival = (ival << 4) | ii;
                         } else {
                             if (! AlreadyComplained) {
-                                ShPpErrorToInfoLog("hexidecimal literal too long");
+                                ShPpErrorToInfoLog("hexidecimal literal too big");
                                 AlreadyComplained = 1;
                             }
+                            ival = 0xffffffff;
                         }
                         ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                     } while ((ch >= '0' && ch <= '9') ||
@@ -451,38 +454,51 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
                 } else {
                     ShPpErrorToInfoLog("bad digit in hexidecimal literal");
                 }
-                if (ch == 'u' || ch == 'U')
-                    yylvalpp->symbol_name[len++] = ch;
-                else
+                if (ch == 'u' || ch == 'U') {
+                    if (len < MAX_TOKEN_LENGTH)
+                        yylvalpp->symbol_name[len++] = ch;
+                    uint = 1;
+                } else
                                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                 yylvalpp->symbol_name[len] = '\0';
                                yylvalpp->sc_int = (int)ival;
 
-                return CPP_INTCONSTANT;
+                if (uint)
+                    return CPP_UINTCONSTANT;
+                else
+                    return CPP_INTCONSTANT;
             } else if (ch >= '0' && ch <= '7') { // octal integer constants
+                int uint = 0;
                 ival = 0;
                 do {
-                    if (len >= MAX_SYMBOL_NAME_LEN)
-                        break;
-                    yylvalpp->symbol_name[len++] = ch;
                     if (ival <= 0x1fffffff) {
+                        yylvalpp->symbol_name[len++] = ch;
                         ii = ch - '0';
                         ival = (ival << 3) | ii;
                     } else {
                         if (!AlreadyComplained) {
-                            ShPpErrorToInfoLog("octal literal too long");
+                            ShPpErrorToInfoLog("octal literal too big");
                             AlreadyComplained = 1;
                         }
+                        ival = 0xffffffff;
                     }
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 } while (ch >= '0' && ch <= '7');
                 if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') 
                      return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+                else  if (ch == 'u' || ch == 'U') {
+                    if (len < MAX_TOKEN_LENGTH)
+                        yylvalpp->symbol_name[len++] = ch;
+                    uint = 1;
+                } else
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                 yylvalpp->symbol_name[len] = '\0';
-                               cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                                yylvalpp->sc_int = (int)ival;
 
-                return CPP_INTCONSTANT;
+                if (uint)
+                    return CPP_UINTCONSTANT;
+                else
+                    return CPP_INTCONSTANT;
             } else {
                                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
                                ch = '0';
@@ -491,25 +507,30 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
         case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
             do {
-                if (len < MAX_SYMBOL_NAME_LEN) {
+                if (len < MAX_TOKEN_LENGTH) {
                     if (len > 0 || ch != '0') {
                         yylvalpp->symbol_name[len] = ch;
                         len++;
                     }
-                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 } else {
-                    ShPpErrorToInfoLog("token too long");
-                    break;
+                    if (! AlreadyComplained) {
+                        ShPpErrorToInfoLog("integer literal too long");
+                        AlreadyComplained = 1;
+                    }
                 }
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
             } while (ch >= '0' && ch <= '9');
             if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') {
                 return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
             } else {
                 // Finish handling signed and unsigned integers
                 int numericLen = len;
-                if (ch == 'u' || ch == 'U')
-                    yylvalpp->symbol_name[len++] = ch;
-                else
+                int uint = 0;
+                if (ch == 'u' || ch == 'U') {
+                    if (len < MAX_TOKEN_LENGTH)
+                        yylvalpp->symbol_name[len++] = ch;
+                    uint = 1;
+                } else
                     cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
 
                 yylvalpp->symbol_name[len] = '\0';                             
@@ -517,16 +538,18 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
                 for (ii = 0; ii < numericLen; ii++) {
                     ch = yylvalpp->symbol_name[ii] - '0';
                     if ((ival > 429496729) || (ival == 429496729 && ch >= 6)) {
-                        if (! AlreadyComplained) {
-                            ShPpErrorToInfoLog("integral literal too long");
-                            AlreadyComplained = 1;
-                        }
-                    }
-                    ival = ival * 10 + ch;
+                        ShPpErrorToInfoLog("integral literal too big");
+                        ival = -1;
+                        break;
+                    } else
+                        ival = ival * 10 + ch;
                 }
                 yylvalpp->sc_int = (int)ival;
 
-                return CPP_INTCONSTANT;
+                if (uint)
+                    return CPP_UINTCONSTANT;
+                else
+                    return CPP_INTCONSTANT;
             }
             break;
         case '-':
@@ -737,39 +760,39 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
                         break;
                     }
                 }
-                if (len < MAX_STRING_LEN) {
-                    string_val[len] = ch;
+                if (len < MAX_TOKEN_LENGTH) {
+                    tokenText[len] = ch;
                     len++;
                     ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
                 } else
                     break;
             };
-            string_val[len] = '\0';
+            tokenText[len] = '\0';
             if (ch == '"') {
-                yylvalpp->sc_ident = LookUpAddString(atable, string_val);
+                yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
                 return CPP_STRCONSTANT;
             } else {
                 ShPpErrorToInfoLog("end of line in string");
-                return ERROR_SY;
+                return CPP_ERROR_SY;
             }
         }
     }
 } // byte_scan
 
-int yylex_CPP(char* buf, int maxSize)
+const char* PpTokenize(yystypepp* yylvalpp)
 {    
-    yystypepp yylvalpp;
     int token = '\n';   
 
     for(;;) {
 
         char* tokenString = 0;
-        token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
-        if(check_EOF(token))
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        yylvalpp->ppToken = token;
+        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;
@@ -779,42 +802,34 @@ int yylex_CPP(char* buf, int maxSize)
             }
         }
         cpp->previous_token = token;
-        // expand macros
-        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp, 0) == 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 {            
-            cpp->notAVersionToken = 1;            
-            tokenString = GetStringOfAtom(atable,token);
-        }
+        cpp->notAVersionToken = 1;
+
+        // expand macros
+        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp, 0) == 1)
+            continue;
+
+        if (token == CPP_IDENTIFIER)
+            tokenString = GetStringOfAtom(atable, yylvalpp->sc_ident);
+        else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
+                 token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
+            tokenString = yylvalpp->symbol_name;
+        else
+            tokenString = GetStringOfAtom(atable, token);
 
         if (tokenString) {
-            if ((signed)strlen(tokenString) >= maxSize) {
+            if (tokenString[0] != 0)
                 cpp->tokensBeforeEOF = 1;
-                return maxSize;               
-            } else  if (strlen(tokenString) > 0) {
-                strcpy(buf, tokenString);
-                cpp->tokensBeforeEOF = 1;
-                return (int)strlen(tokenString);
-            }  
 
-            return 0;
+            return tokenString;
         }
     }
 
     return 0;
-} // yylex
+} // PpTokenize
 
 //Checks if the token just read is EOF or not.
 int check_EOF(int token)
index 0c90b44..86d3008 100644 (file)
@@ -81,9 +81,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #if !defined(__SCANNER_H)
 #define __SCANNER_H 1
 
-#define MAX_SYMBOL_NAME_LEN 1025
-#define MAX_STRING_LEN 1025
-
+#include "preprocess.h"
 #include "parser.h"
 
 // Not really atom table stuff but needed first...
@@ -91,23 +89,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 extern "C" {
 #endif
 
-typedef struct SourceLoc_Rec {
-    unsigned short file, line;
-} SourceLoc;
-
 int yyparse (void);
 
-int yylex_CPP(char* buf, int maxSize);
-
-typedef struct InputSrc {
-    struct InputSrc    *prev;
-    int                        (*scan)(struct InputSrc *, yystypepp *);
-    int                        (*getch)(struct InputSrc *, yystypepp *);
-    void               (*ungetch)(struct InputSrc *, int, yystypepp *);
-    int                        name;  /* atom */
-    int                        line;
-} 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 
index 3af2386..9027f0a 100644 (file)
@@ -81,7 +81,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #if !defined(__SLGLOBALS_H)
 #define __SLGLOBALS_H 1
 
-typedef struct CPPStruct_Rec CPPStruct;
+#include "preprocess.h"
 
 // TODO: threading: Multi-threading note: The existence of this global makes
 // this preprocessing single-threaded only.
@@ -101,7 +101,6 @@ extern CPPStruct *cpp;
 #include "cpp.h"
 #include "tokens.h"
 #include "symbols.h"
-#include "compile.h"
 #if !defined(NO_PARSER)
 #include "parser.h"
 #endif
index 8677713..a5e7669 100644 (file)
@@ -257,8 +257,10 @@ void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
             lAddByte(pTok, (unsigned char) *s++);
         lAddByte(pTok, 0);
         break;
-    case CPP_FLOATCONSTANT:
     case CPP_INTCONSTANT:
+    case CPP_UINTCONSTANT:
+    case CPP_FLOATCONSTANT:
+    case CPP_DOUBLECONSTANT:
          str = yylvalpp->symbol_name;
          while (*str){
             lAddByte(pTok, (unsigned char) *str);
@@ -293,8 +295,9 @@ void RewindTokenStream(TokenStream *pTok)
 
 int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
 {
-    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
-    char string_val[MAX_STRING_LEN + 1];
+    //TODO: PP: why is this different than byte_scan
+
+    char tokenText[MAX_TOKEN_LENGTH + 1];
     int ltoken, len;
     char ch;
 
@@ -312,8 +315,8 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
                      (ch >= '0' && ch <= '9') ||
                      ch == '_')
             {
-                if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
+                if (len < MAX_TOKEN_LENGTH) {
+                    tokenText[len] = ch;
                     len++;
                     ch = lReadByte(pTok);
                 } else {
@@ -321,30 +324,31 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
                     break;
                 }
             }
-            symbol_name[len] = '\0';
+            tokenText[len] = '\0';
             assert(ch == '\0');
-            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+            yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
             return CPP_IDENTIFIER;
             break;
         case CPP_STRCONSTANT:
             len = 0;
             while ((ch = lReadByte(pTok)) != 0) {
-                if (len < MAX_STRING_LEN)
-                    string_val[len++] = ch;
+                if (len < MAX_TOKEN_LENGTH)
+                    tokenText[len++] = ch;
                 else
                     break;
             }
 
-            string_val[len] = 0;
-            yylvalpp->sc_ident = LookUpAddString(atable, string_val);
+            tokenText[len] = 0;
+            yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
             break;
         case CPP_FLOATCONSTANT:
+        case CPP_DOUBLECONSTANT:
             len = 0;
             ch = lReadByte(pTok);
-            while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
+            while ((ch >= '0' && ch <= '9') || ch=='e' || ch=='E' || ch=='.' || ch=='+' || ch=='-' || ch=='l' || ch=='L' || ch=='f'|| ch=='F')
             {
-                if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
+                if (len < MAX_TOKEN_LENGTH) {
+                    tokenText[len] = ch;
                     len++;
                     ch = lReadByte(pTok);
                 } else {
@@ -352,18 +356,19 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
                     break;
                 }
             }
-            symbol_name[len] = '\0';
+            tokenText[len] = '\0';
             assert(ch == '\0');
-            strcpy(yylvalpp->symbol_name,symbol_name);
-            yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
+            strcpy(yylvalpp->symbol_name, tokenText);
+            yylvalpp->sc_dval = atof(yylvalpp->symbol_name);
             break;
         case CPP_INTCONSTANT:
+        case CPP_UINTCONSTANT:
             len = 0;
             ch = lReadByte(pTok);
-            while ((ch >= '0' && ch <= '9'))
+            while ((ch >= '0' && ch <= '9') || ch == 'u' || ch == 'U')
             {
-                if (len < MAX_SYMBOL_NAME_LEN) {
-                    symbol_name[len] = ch;
+                if (len < MAX_TOKEN_LENGTH) {
+                    tokenText[len] = ch;
                     len++;
                     ch = lReadByte(pTok);
                 } else {
@@ -371,10 +376,10 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
                     break;
                 }
             }
-            symbol_name[len] = '\0';
+            tokenText[len] = '\0';
             assert(ch == '\0');
-            strcpy(yylvalpp->symbol_name,symbol_name);
-            yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+            strcpy(yylvalpp->symbol_name,tokenText);
+            yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
             break;
         case '(':
             yylvalpp->sc_int = lReadByte(pTok);
@@ -456,7 +461,7 @@ void UngetToken(int token, yystypepp * yylvalpp) {
 
 void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
     int token;
-    const int maxSize = MAX_SYMBOL_NAME_LEN + 5;
+    const int maxSize = MAX_TOKEN_LENGTH + 5;
     char str[100];
 
     if (fp == 0) fp = stdout;
@@ -471,10 +476,12 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
             snprintf(str, maxSize, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
             break;
         case CPP_FLOATCONSTANT:
-            //printf("%g9.6 ", yylvalpp->sc_fval);
+        case CPP_DOUBLECONSTANT:
+            printf("%g9.6 ", yylvalpp->sc_dval);
             break;
         case CPP_INTCONSTANT:
-            //printf("%d ", yylvalpp->sc_int);
+        case CPP_UINTCONSTANT:
+            printf("%d ", yylvalpp->sc_int);
             break;
         default:
             if (token >= 127)