Create a base GLSL front-end from the 3Dlabs glslang front-end from 20-Sep-2005.
authorJohn Kessenich <cepheus@frii.com>
Wed, 12 Dec 2012 21:15:54 +0000 (21:15 +0000)
committerJohn Kessenich <cepheus@frii.com>
Wed, 12 Dec 2012 21:15:54 +0000 (21:15 +0000)
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@19944 e7fa87d3-cd2b-0410-9028-fcbf551c1848

80 files changed:
BuildLinux.sh [new file with mode: 0755]
OGLCompilersDLL/InitializeDll.cpp [new file with mode: 0644]
OGLCompilersDLL/InitializeDll.h [new file with mode: 0644]
OGLCompilersDLL/Makefile [new file with mode: 0644]
README.txt [new file with mode: 0644]
StandAlone.sln [new file with mode: 0644]
StandAlone.vcproj [new file with mode: 0644]
StandAlone/Makefile [new file with mode: 0644]
StandAlone/StandAlone.cpp [new file with mode: 0644]
StandAlone/sample.frag [new file with mode: 0644]
StandAlone/sample.frag.out [new file with mode: 0644]
StandAlone/sample.vert [new file with mode: 0644]
StandAlone/sample.vert.out [new file with mode: 0644]
glslang.vcproj [new file with mode: 0644]
glslang/GenericCodeGen/CodeGen.cpp [new file with mode: 0644]
glslang/GenericCodeGen/Link.cpp [new file with mode: 0644]
glslang/GenericCodeGen/Makefile [new file with mode: 0644]
glslang/Include/BaseTypes.h [new file with mode: 0644]
glslang/Include/Common.h [new file with mode: 0644]
glslang/Include/ConstantUnion.h [new file with mode: 0644]
glslang/Include/InfoSink.h [new file with mode: 0644]
glslang/Include/InitializeGlobals.h [new file with mode: 0644]
glslang/Include/InitializeParseContext.h [new file with mode: 0644]
glslang/Include/PoolAlloc.h [new file with mode: 0644]
glslang/Include/ResourceLimits.h [new file with mode: 0644]
glslang/Include/ShHandle.h [new file with mode: 0644]
glslang/Include/Types.h [new file with mode: 0644]
glslang/Include/intermediate.h [new file with mode: 0644]
glslang/MachineIndependent/InfoSink.cpp [new file with mode: 0644]
glslang/MachineIndependent/Initialize.cpp [new file with mode: 0644]
glslang/MachineIndependent/Initialize.h [new file with mode: 0644]
glslang/MachineIndependent/IntermTraverse.cpp [new file with mode: 0644]
glslang/MachineIndependent/Intermediate.cpp [new file with mode: 0644]
glslang/MachineIndependent/MMap.h [new file with mode: 0644]
glslang/MachineIndependent/Makefile [new file with mode: 0644]
glslang/MachineIndependent/ParseHelper.cpp [new file with mode: 0644]
glslang/MachineIndependent/ParseHelper.h [new file with mode: 0644]
glslang/MachineIndependent/PoolAlloc.cpp [new file with mode: 0644]
glslang/MachineIndependent/QualifierAlive.cpp [new file with mode: 0644]
glslang/MachineIndependent/QualifierAlive.h [new file with mode: 0644]
glslang/MachineIndependent/RemoveTree.cpp [new file with mode: 0644]
glslang/MachineIndependent/RemoveTree.h [new file with mode: 0644]
glslang/MachineIndependent/ShaderLang.cpp [new file with mode: 0644]
glslang/MachineIndependent/SymbolTable.cpp [new file with mode: 0644]
glslang/MachineIndependent/SymbolTable.h [new file with mode: 0644]
glslang/MachineIndependent/glslang.l [new file with mode: 0644]
glslang/MachineIndependent/glslang.y [new file with mode: 0644]
glslang/MachineIndependent/intermOut.cpp [new file with mode: 0644]
glslang/MachineIndependent/localintermediate.h [new file with mode: 0644]
glslang/MachineIndependent/parseConst.cpp [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/Makefile [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/atom.c [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/atom.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/compile.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/cpp.c [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/cpp.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/cppstruct.c [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/memory.c [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/memory.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/parser.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/preprocess.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/scanner.c [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/scanner.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/slglobals.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/symbols.c [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/symbols.h [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/tokens.c [new file with mode: 0644]
glslang/MachineIndependent/preprocessor/tokens.h [new file with mode: 0644]
glslang/MachineIndependent/unistd.h [new file with mode: 0644]
glslang/OSDependent/Linux/Makefile [new file with mode: 0644]
glslang/OSDependent/Linux/osinclude.h [new file with mode: 0644]
glslang/OSDependent/Linux/ossource.cpp [new file with mode: 0644]
glslang/OSDependent/Windows/main.cpp [new file with mode: 0644]
glslang/OSDependent/Windows/osinclude.h [new file with mode: 0644]
glslang/OSDependent/Windows/ossource.cpp [new file with mode: 0644]
glslang/Public/ShaderLang.h [new file with mode: 0644]
tools/bison.exe [new file with mode: 0644]
tools/bison.hairy [new file with mode: 0644]
tools/bison.simple [new file with mode: 0644]
tools/flex.exe [new file with mode: 0644]

diff --git a/BuildLinux.sh b/BuildLinux.sh
new file mode 100755 (executable)
index 0000000..1abd9c5
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/bash
+
+# build the StandAlone app and all it's dependencies
+make -C StandAlone
+
+# so we can find the shared library
+LD_LIBRARY_PATH=`pwd`/glslang/MachineIndependent/lib:${LD_LIBRARY_PATH}
+export LD_LIBRARY_PATH
+
+# run using test data
+cd StandAlone
+./StandAlone -i sample.vert sample.frag
+
diff --git a/OGLCompilersDLL/InitializeDll.cpp b/OGLCompilersDLL/InitializeDll.cpp
new file mode 100644 (file)
index 0000000..8804ae8
--- /dev/null
@@ -0,0 +1,149 @@
+//
+//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.
+//
+
+#define SH_EXPORTING
+
+#include "InitializeDll.h"
+#include "Include/InitializeGlobals.h"
+#include "Include/InitializeParseContext.h"
+
+#include "Public/ShaderLang.h"
+
+OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
+
+bool InitProcess()
+{
+    if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
+               //
+               // Function is re-entrant.
+               //
+        return true;
+       }
+
+    ThreadInitializeIndex = OS_AllocTLSIndex();
+
+    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
+        return false;
+       }
+
+
+    if (!InitializePoolIndex()) {
+        assert(0 && "InitProcess(): Failed to initalize global pool");
+        return false;
+       }
+
+    if (!InitializeParseContextIndex()) {
+        assert(0 && "InitProcess(): Failed to initalize parse context");
+        return false;
+       }
+
+       InitThread();
+    return true;
+}
+
+
+bool InitThread()
+{
+       //
+    // This function is re-entrant
+       //
+    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
+               assert(0 && "InitThread(): Process hasn't been initalised.");
+        return false;
+       }
+
+    if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
+        return true;
+
+       InitializeGlobalPools();
+
+       if (!InitializeGlobalParseContext())
+        return false;
+
+    if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
+               assert(0 && "InitThread(): Unable to set init flag.");
+        return false;
+       }
+
+    return true;
+}
+
+
+bool DetachThread()
+{
+    bool success = true;
+
+    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
+        return true;
+
+       //
+       // Function is re-entrant and this thread may not have been initalised.
+       //
+    if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
+        if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
+                       assert(0 && "DetachThread(): Unable to clear init flag.");
+            success = false;
+               }
+
+               FreeGlobalPools();
+
+               if (!FreeParseContext())
+            success = false;
+       }
+
+    return success;
+}
+
+bool DetachProcess()
+{
+    bool success = true;
+
+    if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
+        return true;
+
+    ShFinalize();
+
+    success = DetachThread();
+
+       FreePoolIndex();
+
+       if (!FreeParseContextIndex())
+        success = false;
+
+    OS_FreeTLSIndex(ThreadInitializeIndex);
+    ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
+
+    return success;
+}
diff --git a/OGLCompilersDLL/InitializeDll.h b/OGLCompilersDLL/InitializeDll.h
new file mode 100644 (file)
index 0000000..f1ea567
--- /dev/null
@@ -0,0 +1,47 @@
+//
+//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.
+//
+#ifndef __INITIALIZEDLL_H
+#define __INITIALIZEDLL_H
+
+
+#include "osinclude.h"
+
+
+bool InitProcess();
+bool InitThread();
+bool DetachThread();
+bool DetachProcess();
+
+#endif // __INITIALIZEDLL_H
+
diff --git a/OGLCompilersDLL/Makefile b/OGLCompilersDLL/Makefile
new file mode 100644 (file)
index 0000000..f45495b
--- /dev/null
@@ -0,0 +1,53 @@
+INCLUDE = -I. -I../glslang -I../glslang/Include -I../glslang/OSDependent/Linux -I../glslang/MachineIndependent
+WARNINGS = -Wall -Wwrite-strings -Wpointer-arith -Wcast-align -Wstrict-prototypes \
+       -Wnested-externs
+DEFINE = -Dlinux -D__i386__
+  
+CPP = g++
+CPPOPTIONS = -O3 -Wno-deprecated -D_ALT_NS=1
+CPPOPTIONS = -g -Wno-deprecated -D_ALT_NS=1 
+CPPFLAGS = $(CPPOPTIONS) $(DEFINE) $(INCLUDE)
+
+#
+# Linking related
+#
+AR = ar
+STATIC_OPTION = rcs
+
+#
+# Misc
+#
+export PERL = perl
+export RM = rm -f
+export MV = mv -f
+export DEPEND = g++ -M
+
+#
+# Object file variables are defined here.
+#
+OSSRCS = InitializeDll.cpp
+OSOBJS = InitializeDll.o
+
+LIBNAME = libInitializeDll.a
+
+all : $(LIBNAME)
+
+$(LIBNAME) : $(OSOBJS)
+        $(AR) $(STATIC_OPTION) $(LIBNAME) $(OSOBJS) 
+
+%.o : %.cpp
+       $(CPP) $(CPPFLAGS) -c $<
+
+#
+# Dependency
+#
+depend : $(OSSRCS)
+       $(DEPEND) $(CPPFLAGS) $(OSSRCS) > depend
+include depend
+
+#
+# Cleanup
+#
+.PHONY : clean
+clean :
+       $(RM) *.o *.a
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..b7ab72f
--- /dev/null
@@ -0,0 +1,337 @@
+OpenGL Shading Language source readme for Window and Linux
+
+Version: Sept 20, 2005
+
+
+Source Copyright
+----------------
+
+
+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.
+
+Changes since June 2005 Release
+-------------------------------
+- Some infrastructure is simplified, improved, and cleaned up.  Details follow.
+
+- TPublicType is easier to setup and extend.
+
+- Constant values know their own types. Methods are added to set the 
+constant values as the data members are now protected instead of public.
+Lots of code was cleaned up because of that. 
+
+- Added support for an array object extension. Array constructors are 
+allowed. Constant arrays can be declared and parse time constant folding 
+and propagation is done through array objects. Extension GL_3DL_array_objects 
+must be enabled to use the array objects.
+
+- Arrays and structures are handled more uniformly. Sizing is simplified and improved.
+
+- Changed the implementation of the way constants values were stored in 
+the parse tree. Constants are now always flattened out. Constructors with 
+constant values are represented with constant values directly. Example mat2(1) 
+is stored as a constant node with values 1.0, 0.0, 0.0, 1.0. Earlier this
+was stored as an aggregate node with correct operator and a single constant 
+value 1.0. This change caused a lot of code to be cleaned up and simplified.
+
+- Renamed ARB texture rectangle functions to match the final version of the specification.
+
+
+Changes since Feb 2005 Release
+------------------------------
+- Source now compiles on gcc 3.4.4.
+- Fixed constant folding for ternary operator.
+- Non-dereferenced arrays not allowed in constructors. Other semantic 
+error checking on arrays such as ++array, array1 = array2.
+- Max allowed index for gl_TexCoord is gl_MaxTextureCoords - 1.
+- Raise an error when one of the string passed to the parser is a NULL 
+pointer.
+- Parser code tested to be portable on STLport stl.
+- Detect error when preprocessor directives does not begin at the start 
+of the line.
+
+Please feel free to submit any fixes to the parser code.
+
+
+Changes since Jan 2005 Release
+------------------------------
+- Relaxed grammar rules for ?: (ternary operator) to allow assignment 
+expressions after the ':'.
+- Fixed the correct parsing of empty shader source string.
+- No longer raise an error when gl_Position is not written in a vertex 
+shader. This is link time functionality.
+- Added some basic support for MSVC++6.0 to the extent that C++ standards 
+are not violated.
+
+
+Changes since Sept 2004 Release
+-------------------------------
+- Memory usage by builtIn symbol table level is reduced to 1/4th of what 
+was used earlier.
+- Built In symbol table level is split into two, the first level contains 
+symbols that do not change and the second level is constructed per compile, 
+based on the resource values specified by the driver. This required ShCompile
+method to take in a pointer to the resource values.
+- Correct handling of pragmas.
+- Fixed defects such as comma operator folding, swizzling allowed only with 
+offsets from same set, texture look up functions appropriately split between 
+vertex and fragment shaders, ternary operator type checking, preprocessor 
+directives etc.
+- Linux build now use flex version 2.5.4 that comes with Redhat 9.0
+
+
+Changes since July 2004 Release
+-------------------------------
+- Structures when initialized both as a constant and a non constant were broken.
+
+
+Changes Since Apr 2004 Release
+-------------------------------
+- Added support for #extension and #version preprocessor directives.
+- Removed printf statements and instead dump messages on InfoSink.
+- Most of the source code is now thread safe except for some of the 
+preprocessor code. Also For Linux, the per thread data clean up is yet to be
+implemented as it is not exactly known when the thread exits.
+- Fixed comma operator when used with constant initializer.
+- Added folding when constructors are called with constant values.
+- Correctly updated builtIn names for texture functions from 
+texture{1|2}DShadow[Proj][Lod] to shadow{1|2}D[Proj][Lod].
+- Updated the built-in constant names as per latest GL2 specs.
+- Portable across more platforms.
+
+
+Changes Since Oct 2003 Release
+-------------------------------
+- Added new reserved keywords.  Also reserved %=.
+- Fixed some bugs and memory leaks in the preprocessor.
+- Fixed name mangling for function names.  Names also now include array sizes.
+- Fixed implementation of unsized arrays.
+- Constructors: Disallow matrices constructed from matrices, and unused 
+arguments.
+   Also fixed some cases like float(vec2) that were not working right.
+- TILDA -> TILDE.
+- Fixed structure qualifier semantics:  they apply to variables declared, 
+not the structure definition.
+
+
+Changes since May 2003 Release
+-------------------------------
+
+- Corrected some bugs in preprocessor.
+- Keeping track of maximum size of the array used in the source code.
+- Parameter passing during function call and keeping track of inout and out 
+parameters.
+- Added some more built in functions.
+- Portability to Linux
+
+
+Changes Since April 2002 Release
+--------------------------------
+
+* Semantic changes to bring the implementation and spec closer together,
+  and support issue resolution.
+
+* Some minor functionality completeness.  
+
+  - User function calls are more complete, 
+  - added the ^^ operator (logical exclusive or)
+  - fixed variable scoping in if-else
+  - no declarations in if-conditions
+  - improved typing of field selectors
+  - removed suffixes from literal constants
+  - many smaller semantic changes to be in line with the current spec
+  - added preprocessor
+  - added non-scalar constants
+  - added structures
+
+
+Changes since July 2002 Release
+-------------------------------
+
+Brought up to date with version 1.051 of the OpenGL Shading Language 
+Specification.  It is now almost complete.  The list of detailed 
+changes would be long, as the specification has changed extensively, 
+and all missing functionality has been added.
+
+
+Procedure to Build on Windows
+-----------------------------
+
+Put this project in a path name without spaces.
+
+procedure To build using MS visual studio .Net.  
+
+It has two projects.
+The glslang project must be compiled first, followed by the
+StandAlone project.
+
+1.  The solution is StandAlone.sln.  The two necessary
+projects are glslang.vcproj and StandAlone.vcproj,
+which devstudio will automatically open.
+
+2.  You may have a missing header file, unistd.h.  Create an empty one in
+some standard devstudio or SDK system include directory.  (Bison/flex
+generate a #include <unistd.h>, this makes them happy.)
+
+3.  Build the glslang project (in devstudio, right click the glslang project
+and build).  This creates the glslang.dll and glslang.lib files needed to
+make the StandAlone compiler run.  It leaves them in the StandAlone
+directory.
+
+4.  Build the StandAlone project if you want to run the tests or run the
+compiler stand-alone.
+
+
+Running Stand Alone on Windows
+------------------------------
+
+The build process should create glslang.dll and StandAlone.exe.  glslang.dll
+has an interface suitable for integration with an ICD.  StandAlone.exe uses
+this interface to create a version of the compiler that can run outside
+the ICD environment.
+
+The stand-alone compiler is a Win32 console application, best executed 
+from a command prompt.  
+
+\93cd\94 into the StandAlone directory, or a directory you've installed
+StandAlone.exe, the OglBuiltIns subdirectory, and glslang.dll into.
+
+The normal case will be to compile and link a pair of shaders like this:
+
+    StandAlone -i <vertex-file>.vert  <fragment-file>.frag
+
+    where the following command line options are possible for StandAlone:
+    i - dump parse tree
+    m - dump linker output (nothing dumped in the source code provided)
+    a - dump assembly code (nothing dumped in the source code provided)
+
+The applied compilation-language is based on the file extension.  
+Give the full name of the files containing the shader source code.  
+The output from running this will contain compile and link errors, as
+well as a textual version of the intermediate representation.
+
+
+Procedure to build and run on Linux
+-----------------------------------
+
+A simple bash script "BuildLinux.sh" is provided to do the build and run the test
+cases, or you may run the steps manually as described below:
+
+"cd" into StandAlone directory and run make. It will build all the dependency 
+directories also. You can also go to the specific directories and do a make for each 
+directory individually. Make sure that there exists a lib directory at the given 
+path: glslang/MachineIndependent/lib where libglslang.so is stored.
+
+To compile glslang.l, flex version 2.5.31 is required. An executable of flex is 
+provided in tools directory. To compile glslang.y, bison version 1.35 or higher is 
+required. Most versions of Red Hat comes with bison 1.35.
+
+Once the executable is generated, it needs to be dynamically linked with the 
+shared object created in lib directory. To achieve that, we need to "cd" to 
+StandAlone directory to update the LD_LIBRARY_PATH as follows
+
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./../glslang/MachineIndependent/lib
+
+You can also update LD_LIBRARY_PATH in the .cshrc or .bashrc file, depending on 
+the shell you are using. You will need to give the complete path of "lib" directory
+in .cshrc or .bashrc files.
+
+The normal case will be to compile and link a pair of shaders like this:
+
+    ./StandAlone -i <vertex-file>.vert  <fragment-file>.frag
+
+    where the following command line options are possible for StandAlone:
+    i - dump parse tree
+    m - dump linker output (nothing dumped in the source code provided)
+    a - dump assembly code (nothing dumped in the source code provided)
+
+The applied compilation-language is based on the file extension.  
+Give the full name of the files containing the shader source code.  
+The output from running this will contain compile and link errors, as
+well as a textual version of the intermediate representation.
+
+To generate the dependencies, you can run "make depend".
+This step has already been done and need not be done again by the user.
+
+To clean the ".o"s, ".a"s and ".so" generated by make, you can use "make clean".
+
+
+Notes for Understanding/Modifying the Code
+------------------------------------------
+
+* This is completely machine independent code.  We have a working
+  back-end card-specific compiler that is not present.  Instead, a trivial
+  back-end compiler is in the directory GenericCodeGen.
+
+* The main directory for parsing and intermediate representation is 
+  MachineIndependent.
+
+* Header files shared between machine independent parsing and the
+  machine dependent compiling and linking are in include.
+
+* Header files shared between the compiler and an ICD are in public.
+
+* Merging with future updates will be easiest if initially you confine
+  your changes to the GenericCodeGen directory.
+
+* To write a back-end compiler, see the next section on Basic Design.
+
+
+Basic Design
+------------
+
+1.  Code is parsed by flex/bison, with the aid of a symbol table and an 
+    intermediate representation.  The symbol table is not passed on to
+    the back-end; the intermediate representation stands on its own.
+
+2.  The intermediate representation is very high-level, and represented
+    as an in-memory tree.   This serves to lose no information from the
+    original program, and to have efficient transfer of the result from
+    parsing to the back-end.  In the intermediate representation,
+    constants are propogated and folded, and some dead code is eliminated.
+
+3.  The primary algorithm of the back-end compiler is to traverse the 
+    tree (high-level intermediate representation), and create an internal
+    object code representation.  There is a query in the compiler interface
+    to the ICD for retrieval of this object code.
+
+4.  Reduction of the tree to a linear byte-code style low-level intermediate
+    representation is likely a good way to generate fully optimized code.
+    There is some possibility of standardizing such a byte code.
+
+See these files to get started:
+
+* IntermOut.cpp:  this shows traversing the tree to generate output.
+* CodeGen.cpp:    this shows the basic interface to the back-end compiler.
+* Link.cpp:       this shows the basic interface to the linker.
+* Intermediate.h: to see the data structures backing the tree.
+
diff --git a/StandAlone.sln b/StandAlone.sln
new file mode 100644 (file)
index 0000000..b2f325a
--- /dev/null
@@ -0,0 +1,28 @@
+Microsoft Visual Studio Solution File, Format Version 7.00\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tests - StandAlone", "StandAlone.vcproj", "{660D0A05-69A9-4F09-9664-02FBEB08FAE2}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Targets - glslang (generic)", "glslang.vcproj", "{3B146CC5-B2B8-4573-9D46-6139E2EDFEA3}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfiguration) = preSolution\r
+               ConfigName.0 = UserM_Debug\r
+               ConfigName.1 = UserM_Release\r
+       EndGlobalSection\r
+       GlobalSection(ProjectDependencies) = postSolution\r
+               {660D0A05-69A9-4F09-9664-02FBEB08FAE2}.0 = {3B146CC5-B2B8-4573-9D46-6139E2EDFEA3}\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfiguration) = postSolution\r
+               {660D0A05-69A9-4F09-9664-02FBEB08FAE2}.UserM_Debug.ActiveCfg = UserM_Debug|Win32\r
+               {660D0A05-69A9-4F09-9664-02FBEB08FAE2}.UserM_Debug.Build.0 = UserM_Debug|Win32\r
+               {660D0A05-69A9-4F09-9664-02FBEB08FAE2}.UserM_Release.ActiveCfg = UserM_Release|Win32\r
+               {660D0A05-69A9-4F09-9664-02FBEB08FAE2}.UserM_Release.Build.0 = UserM_Release|Win32\r
+               {3B146CC5-B2B8-4573-9D46-6139E2EDFEA3}.UserM_Debug.ActiveCfg = UserM_Debug|Win32\r
+               {3B146CC5-B2B8-4573-9D46-6139E2EDFEA3}.UserM_Debug.Build.0 = UserM_Debug|Win32\r
+               {3B146CC5-B2B8-4573-9D46-6139E2EDFEA3}.UserM_Release.ActiveCfg = UserM_Release|Win32\r
+               {3B146CC5-B2B8-4573-9D46-6139E2EDFEA3}.UserM_Release.Build.0 = UserM_Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityGlobals) = postSolution\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityAddIns) = postSolution\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/StandAlone.vcproj b/StandAlone.vcproj
new file mode 100644 (file)
index 0000000..411a83c
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="Tests - StandAlone"\r
+       ProjectGUID="{660D0A05-69A9-4F09-9664-02FBEB08FAE2}">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="UserM_Debug|Win32"\r
+                       OutputDirectory="UserM_Debug"\r
+                       IntermediateDirectory="UserM_Debug"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="glslang"\r
+                               PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE,GENERIC_COMPILER"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="5"\r
+                               UsePrecompiledHeader="0"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="UserM_Debug/"\r
+                               ObjectFile="UserM_Debug/"\r
+                               ProgramDataBaseFileName="UserM_Debug/Standalone"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="1"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib psapi.lib Standalone\glslang.lib"\r
+                               OutputFile="UserM_Debug/StandAlone.exe"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="TRUE"\r
+                               IgnoreDefaultLibraryNames=""\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile="UserM_Debug/StandAlone.pdb"\r
+                               SubSystem="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName="UserM_Debug/StandAlone.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               Description="move exe"\r
+                               CommandLine="xcopy /y UserM_Debug\StandAlone.exe Standalone"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="UserM_Release|Win32"\r
+                       OutputDirectory="UserM_Release"\r
+                       IntermediateDirectory="UserM_Release"\r
+                       ConfigurationType="1"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="TRUE"\r
+                               AdditionalIncludeDirectories="glslang"\r
+                               PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE,GENERIC_COMPILER"\r
+                               StringPooling="TRUE"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="4"\r
+                               BufferSecurityCheck="TRUE"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               UsePrecompiledHeader="0"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="UserM_Release/"\r
+                               ObjectFile="UserM_Release/"\r
+                               ProgramDataBaseFileName="UserM_Release/Standalone"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="1"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib psapi.lib Standalone\glslang.lib"\r
+                               OutputFile="UserM_Release/StandAlone.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               IgnoreDefaultLibraryNames=""\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile="UserM_Release/StandAlone.pdb"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName="UserM_Release/StandAlone.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               Description="move exe"\r
+                               CommandLine="xcopy /y UserM_Release\StandAlone.exe Standalone"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="Standalone\StandAlone.cpp">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/StandAlone/Makefile b/StandAlone/Makefile
new file mode 100644 (file)
index 0000000..80023b1
--- /dev/null
@@ -0,0 +1,40 @@
+CC=g++
+OBJECTPATH=./../glslang/MachineIndependent
+LIBPATH=./../glslang/MachineIndependent/lib
+SRCS=StandAlone.cpp
+
+TARGETOBJECT=StandAlone.o
+
+default: all
+
+all: StandAlone
+
+StandAlone: $(TARGETOBJECT) SHAREDOBJECT
+       $(CC) -g -o $@ $(TARGETOBJECT) -L $(LIBPATH) -lglslang -lpthread \
+       -lm -lstdc++
+
+SHAREDOBJECT:
+       cd $(OBJECTPATH); make all
+
+%.o : %.cpp
+       $(CC) -c $<
+
+#
+# Cleanup
+#
+.PHONY : clean
+clean :
+       $(RM) *.o StandAlone
+       cd $(OBJECTPATH); make clean
+
+depend:
+       cd $(OBJECTPATH); make depend
+       makedepend -Y -- $(SRCS)
+# DO NOT DELETE
+
+StandAlone.o: ./../glslang/Include/ShHandle.h
+StandAlone.o: ./../glslang/Public/ShaderLang.h
+StandAlone.o: ./../glslang/Include/InfoSink.h ./../glslang/Include/Common.h
+StandAlone.o: ./../glslang/Include/PoolAlloc.h
+StandAlone.o: ./../glslang/Public/ShaderLang.h
+
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
new file mode 100644 (file)
index 0000000..e970185
--- /dev/null
@@ -0,0 +1,366 @@
+//
+//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.
+//
+#include "./../glslang/Include/ShHandle.h"
+#include "./../glslang/Public/ShaderLang.h"
+#include <string.h>
+#include <math.h>
+
+#ifdef _WIN32
+    #include <windows.h>
+    #include <psapi.h>
+#endif
+
+extern "C" {
+    SH_IMPORT_EXPORT void ShOutputHtml();
+}
+
+//#define MEASURE_MEMORY
+
+//
+// Return codes from main.
+//
+enum TFailCode {
+    ESuccess = 0,
+    EFailUsage,
+    EFailCompile,
+    EFailLink,
+    EFailCompilerCreate,
+    EFailLinkerCreate
+};
+
+//
+// Just placeholders for testing purposes.  The stand-alone environment
+// can't actually do a full link without something specifying real
+// attribute bindings.
+//
+ShBinding FixedAttributeBindings[] = { 
+    { "gl_Vertex", 15 },
+    { "gl_Color", 10 },
+    { "gl_Normal", 7 },
+};
+
+ShBindingTable FixedAttributeTable = { 3, FixedAttributeBindings };
+
+static EShLanguage FindLanguage(char *lang);
+bool CompileFile(char *fileName, ShHandle, int, const TBuiltInResource*);
+void usage();
+void FreeFileData(char **data);
+char** ReadFileData(char *fileName);
+void InfoLogMsg(char* msg, const char* name, const int num);
+int ShOutputMultipleStrings(char ** );
+//Added to accomodate the multiple strings.
+int OutputMultipleStrings = 1;
+
+//
+// Set up the per compile resources
+//
+void GenerateResources(TBuiltInResource& resources)
+{    
+    resources.maxLights = 32;
+    resources.maxClipPlanes = 6;
+    resources.maxTextureUnits = 32;
+    resources.maxTextureCoords = 32;
+    resources.maxVertexAttribs = 64;
+    resources.maxVertexUniformComponents = 4096;
+    resources.maxVaryingFloats = 64;
+    resources.maxVertexTextureImageUnits = 32;
+    resources.maxCombinedTextureImageUnits = 32;
+    resources.maxTextureImageUnits = 32;
+    resources.maxFragmentUniformComponents = 4096;
+    resources.maxDrawBuffers = 32;
+}
+
+int C_DECL main(int argc, char* argv[])
+{
+    bool delay = false;
+    int numCompilers = 0;
+    bool compileFailed = false;
+    bool linkFailed = false;
+    int debugOptions = 0;
+    int i;
+    
+    ShHandle    linker = 0;
+    ShHandle    uniformMap = 0;
+    ShHandle    compilers[EShLangCount];
+
+    ShInitialize();
+
+#ifdef _WIN32
+    __try {
+#endif
+        argc--;
+        argv++;    
+        for (; argc >= 1; argc--, argv++) {
+            if (argv[0][0] == '-' || argv[0][0] == '/') {
+                switch (argv[0][1]) {
+                case 'd': delay    = true;                           break;
+
+#ifdef MEASURE_MEMORY
+                case 'i': break;
+                case 'a': break;
+                case 'h': break;
+#else
+                case 'i': debugOptions |= EDebugOpIntermediate;       break;
+                case 'a': debugOptions |= EDebugOpAssembly;           break;
+#endif
+                case 'c': if(!ShOutputMultipleStrings(++argv))
+                                                         return EFailUsage; 
+                          --argc;                                    break;
+                case 'm': debugOptions |= EDebugOpLinkMaps;           break;
+                default:  usage();                       return EFailUsage;
+                }
+            } else {
+                compilers[numCompilers] = ShConstructCompiler(FindLanguage(argv[0]), debugOptions);
+                if (compilers[numCompilers] == 0)
+                    return EFailCompilerCreate;
+                ++numCompilers;
+
+                TBuiltInResource resources;
+                GenerateResources(resources);
+                if (! CompileFile(argv[0], compilers[numCompilers-1], debugOptions, &resources))
+                    compileFailed = true;                
+            }
+        }
+
+        if (!numCompilers) {
+            usage();
+            return EFailUsage;
+        }
+
+        linker = ShConstructLinker(EShExVertexFragment, debugOptions);
+        if (linker == 0)
+            return EFailLinkerCreate;
+
+        uniformMap = ShConstructUniformMap();
+        if (uniformMap == 0)
+            return EFailLinkerCreate;
+
+        if (numCompilers > 0) {
+            ShSetFixedAttributeBindings(linker, &FixedAttributeTable);
+            if (! ShLink(linker, compilers, numCompilers, uniformMap, 0, 0))
+                linkFailed = true;
+        }
+
+        for (i = 0; i < numCompilers; ++i) {
+            InfoLogMsg("BEGIN", "COMPILER", i);
+            puts(ShGetInfoLog(compilers[i]));
+            InfoLogMsg("END", "COMPILER", i);
+        }
+
+        InfoLogMsg("BEGIN", "LINKER", -1);
+        puts(ShGetInfoLog(linker));
+        InfoLogMsg("END", "LINKER", -1);
+    
+#ifdef _WIN32
+    } __finally {    
+#endif    
+        for (i = 0; i < numCompilers; ++i)
+            ShDestruct(compilers[i]);
+
+        ShDestruct(linker);
+        ShDestruct(uniformMap);
+
+#ifdef _WIN32
+        if (delay)
+            Sleep(1000000);
+
+    }
+#endif
+
+    if (compileFailed)
+        return EFailCompile;
+    if (linkFailed)
+        return EFailLink;
+
+    return 0;
+}
+
+//
+//   Deduce the language from the filename.  Files must end in one of the
+//   following extensions:
+//
+//   .frag*    = fragment programs
+//   .vert*    = vertex programs
+//   .pack*    = pack programs
+//   .unpa*    = unpack pragrams
+//
+static EShLanguage FindLanguage(char *name)
+{
+    if (!name)
+        return EShLangFragment;
+
+    char *ext = strrchr(name, '.');
+
+    if (ext && strcmp(ext, ".sl") == 0)
+        for (; ext > name && ext[0] != '.'; ext--);
+    
+    if (ext = strrchr(name, '.')) {
+        if (strncmp(ext, ".frag", 4) == 0) return EShLangFragment;
+        if (strncmp(ext, ".vert", 4) == 0) return EShLangVertex;
+        if (strncmp(ext, ".pack", 4) == 0) return EShLangPack;
+        if (strncmp(ext, ".unpa", 4) == 0) return EShLangUnpack;
+    }
+
+    return EShLangFragment;
+}
+
+
+//
+//   Read a file's data into a string, and compile it using ShCompile
+//
+bool CompileFile(char *fileName, ShHandle compiler, int debugOptions, const TBuiltInResource *resources)
+{
+    int ret;
+    char **data = ReadFileData(fileName);
+
+#ifdef MEASURE_MEMORY
+    PROCESS_MEMORY_COUNTERS counters;
+#endif
+
+    if (!data)
+        return false;
+
+#ifdef MEASURE_MEMORY
+    for (int i = 0; i < 1000; ++i) {
+        for (int j = 0; j < 100; ++j)
+#endif
+            ret = ShCompile(compiler, data, OutputMultipleStrings, EShOptNone, resources, debugOptions);
+#ifdef MEASURE_MEMORY
+
+        GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters));
+    }
+#endif
+
+    FreeFileData(data);
+
+    return ret ? true : false;
+}
+
+
+//
+//   print usage to stdout
+//
+void usage()
+{
+    printf("Usage: standalone [-i -a -c -m -d -h] file1 file2 ...\n"
+           "Where: filename = filename ending in .frag* or .vert*\n");
+}
+
+
+//
+//   Malloc a string of sufficient size and read a string into it.
+//
+# define MAX_SOURCE_STRINGS 5
+char** ReadFileData(char *fileName) 
+{
+    FILE *in    = fopen(fileName, "r");
+    char *fdata;
+    int count = 0;
+    char**return_data=(char**)malloc(MAX_SOURCE_STRINGS+1);
+
+    //return_data[MAX_SOURCE_STRINGS]=NULL;
+       if (!in) {
+        printf("Error: unable to open input file: %s\n", fileName);
+        return 0;
+    }
+    
+    while (fgetc(in) != EOF)
+        count++;
+
+       fseek(in, 0, SEEK_SET);
+       
+       
+       if (!(fdata = (char *)malloc(count+2))) {
+            printf("Error allocating memory\n");
+            return 0;
+    }
+       if (fread(fdata,1,count, in)!=count) {
+            printf("Error reading input file: %s\n", fileName);
+            return 0;
+    }
+    fdata[count] = '\0';
+    fclose(in);
+    if(count==0){
+        return_data[0]=(char*)malloc(count+2);
+        return_data[0][0]='\0';
+        OutputMultipleStrings=0;
+        return return_data;       
+    }
+
+       int len = (int)(ceil)((float)count/(float)OutputMultipleStrings);
+    int ptr_len=0,i=0;
+       while(count>0){
+               return_data[i]=(char*)malloc(len+2);
+               memcpy(return_data[i],fdata+ptr_len,len);
+               return_data[i][len]='\0';
+               count-=(len);
+               ptr_len+=(len);
+               if(count<len){
+            if(count==0){
+               OutputMultipleStrings=(i+1);
+               break;
+            }
+           len = count;
+               }  
+               ++i;
+       }
+    return return_data;
+}
+
+
+
+void FreeFileData(char **data)
+{
+    for(int i=0;i<OutputMultipleStrings;i++)
+        free(data[i]);
+}
+
+
+
+void InfoLogMsg(char* msg, const char* name, const int num)
+{
+    printf(num >= 0 ? "#### %s %s %d INFO LOG ####\n" :
+           "#### %s %s INFO LOG ####\n", msg, name, num);
+}
+
+int ShOutputMultipleStrings(char **argv)
+{
+       if(!(abs(OutputMultipleStrings = atoi(*argv)))||((OutputMultipleStrings >5 || OutputMultipleStrings < 1)? 1:0)){
+          printf("Invalid Command Line Argument after -c option.\n"
+              "Usage: -c <integer> where integer =[1,5]\n"
+              "This option must be specified before the input file path\n");
+       return 0;
+       }
+    return 1;
+}
diff --git a/StandAlone/sample.frag b/StandAlone/sample.frag
new file mode 100644 (file)
index 0000000..0d11cb2
--- /dev/null
@@ -0,0 +1,40 @@
+//\r
+//Copyright (C) 2002-2004  3Dlabs Inc. Ltd.\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
+varying vec3 color;\r
+\r
+void main()\r
+{\r
+    gl_FragColor = vec4(color, 1.0);\r
+}\r
diff --git a/StandAlone/sample.frag.out b/StandAlone/sample.frag.out
new file mode 100644 (file)
index 0000000..5af223e
--- /dev/null
@@ -0,0 +1,15 @@
+#### BEGIN COMPILER 0 INFO LOG ####\r
+0:? Sequence\r
+0:37  Function Definition: main( (void)\r
+0:37    Function Parameters: \r
+0:39    Sequence\r
+0:39      move second child to first child (4-component vector of float)\r
+0:39        'gl_FragColor' (FragColor 4-component vector of float)\r
+0:39        Construct vec4 (4-component vector of float)\r
+0:39          'color' (varying 3-component vector of float)\r
+0:39          1.000000 (const float)\r
+\r
+#### END COMPILER 0 INFO LOG ####\r
+#### BEGIN LINKER INFO LOG ####\r
+\r
+#### END LINKER INFO LOG ####\r
diff --git a/StandAlone/sample.vert b/StandAlone/sample.vert
new file mode 100644 (file)
index 0000000..0ecaf2c
--- /dev/null
@@ -0,0 +1,42 @@
+//\r
+//Copyright (C) 2002-2004  3Dlabs Inc. Ltd.\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
+varying vec3 color;\r
+\r
+void main()\r
+{\r
+    color = vec3(1.0, 1.0, 1.0);\r
+\r
+    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\r
+}\r
diff --git a/StandAlone/sample.vert.out b/StandAlone/sample.vert.out
new file mode 100644 (file)
index 0000000..2d50a82
--- /dev/null
@@ -0,0 +1,20 @@
+#### BEGIN COMPILER 0 INFO LOG ####\r
+0:? Sequence\r
+0:37  Function Definition: main( (void)\r
+0:37    Function Parameters: \r
+0:39    Sequence\r
+0:39      move second child to first child (3-component vector of float)\r
+0:39        'color' (varying 3-component vector of float)\r
+0:39        1.000000 (const float)\r
+0:39        1.000000 (const float)\r
+0:39        1.000000 (const float)\r
+0:41      move second child to first child (4-component vector of float)\r
+0:41        'gl_Position' (Position 4-component vector of float)\r
+0:41        matrix-times-vector (4-component vector of float)\r
+0:41          'gl_ModelViewProjectionMatrix' (uniform 4X4 matrix of float)\r
+0:41          'gl_Vertex' (attribute 4-component vector of float)\r
+\r
+#### END COMPILER 0 INFO LOG ####\r
+#### BEGIN LINKER INFO LOG ####\r
+\r
+#### END LINKER INFO LOG ####\r
diff --git a/glslang.vcproj b/glslang.vcproj
new file mode 100644 (file)
index 0000000..a1fdc9a
--- /dev/null
@@ -0,0 +1,436 @@
+<?xml version="1.0" encoding = "Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.00"\r
+       Name="Targets - glslang (generic)"\r
+       ProjectGUID="{3B146CC5-B2B8-4573-9D46-6139E2EDFEA3}">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="UserM_Debug|Win32"\r
+                       OutputDirectory="UserM_Debug"\r
+                       IntermediateDirectory="UserM_Debug"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="glslang;glslang\MachineIndependent;glslang\OSDependent\Windows;OGLCompilersDLL"\r
+                               PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE,_USRDLL,TEST_EXPORTS,GENERIC_COMPILER"\r
+                               MinimalRebuild="FALSE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="UserM_Debug/"\r
+                               ObjectFile="UserM_Debug/"\r
+                               ProgramDataBaseFileName="UserM_Debug/glslang"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="1"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="UserM_Debug/generic/glslang.dll"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="TRUE"\r
+                               IgnoreDefaultLibraryNames="libcmtd.lib;libcd.lib;libcmt.lib;libcmt.lib"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile="UserM_Debug/glslang.pdb"\r
+                               SubSystem="1"\r
+                               ImportLibrary="UserM_Debug/generic/glslang.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName="UserM_Debug/generic/glslang.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               Description="copy dll"\r
+                               CommandLine="xcopy /y UserM_Debug\generic\glslang.* standalone"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="2057"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="UserM_Release|Win32"\r
+                       OutputDirectory="UserM_Release"\r
+                       IntermediateDirectory="UserM_Release"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               OmitFramePointers="TRUE"\r
+                               AdditionalIncludeDirectories="glslang;glslang\MachineIndependent;glslang\OSDependent\Windows;OGLCompilersDLL"\r
+                               PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE,_USRDLL,TEST_EXPORTS,GENERIC_COMPILER"\r
+                               StringPooling="TRUE"\r
+                               MinimalRebuild="FALSE"\r
+                               BasicRuntimeChecks="0"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="TRUE"\r
+                               EnableFunctionLevelLinking="TRUE"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="UserM_Release/"\r
+                               ObjectFile="UserM_Release/"\r
+                               ProgramDataBaseFileName="UserM_Release/glslang"\r
+                               BrowseInformation="0"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="1"\r
+                               CompileAs="0"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalOptions="/MACHINE:I386"\r
+                               AdditionalDependencies="odbc32.lib odbccp32.lib"\r
+                               OutputFile="UserM_Release/generic/glslang.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               IgnoreDefaultLibraryNames="libcmtd.lib;libcd.lib;libcmt.lib;"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile="UserM_Release/generic/glslang.pdb"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               ImportLibrary="UserM_Release/generic/glslang.lib"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName="UserM_Release/generic/glslang.tlb"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                               Description="copy dll"\r
+                               CommandLine="xcopy /y UserM_Release\generic\glslang.* standalone"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="2057"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <Files>\r
+               <Filter\r
+                       Name="Machine Independent"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;y;l">\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\InfoSink.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\Initialize.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\Initialize.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="OGLCompilersDLL\InitializeDll.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\IntermTraverse.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\Intermediate.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\MMap.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\ParseHelper.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\ParseHelper.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\PoolAlloc.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\QualifierAlive.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\QualifierAlive.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\RemoveTree.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\RemoveTree.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\ShaderLang.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\SymbolTable.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\glslang.l">\r
+                               <FileConfiguration\r
+                                       Name="UserM_Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               Description="Executing flex on $(InputPath)"\r
+                                               CommandLine="$(InputDir)..\..\tools\flex.exe $(InputPath)\r
+if EXIST $(InputDir)gen_glslang.cpp del $(InputDir)gen_glslang.cpp\r
+move gen_glslang.cpp $(InputDir)gen_glslang.cpp\r
+cd $(InputDir)\r
+rename gen_glslang.cpp Gen_glslang.cpp\r
+"\r
+                                               AdditionalDependencies="glslang_tab.h"\r
+                                               Outputs="$(InputDir)Gen_glslang.cpp"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="UserM_Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               Description="Executing flex on $(InputPath)"\r
+                                               CommandLine="$(InputDir)..\..\tools\flex.exe $(InputPath)\r
+if EXIST $(InputDir)gen_glslang.cpp del $(InputDir)gen_glslang.cpp\r
+move gen_glslang.cpp $(InputDir)gen_glslang.cpp\r
+"\r
+                                               AdditionalDependencies="glslang_tab.h"\r
+                                               Outputs="$(InputDir)Gen_glslang.cpp"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\glslang.y">\r
+                               <FileConfiguration\r
+                                       Name="UserM_Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               Description="Executing Bison on $(InputPath)"\r
+                                               CommandLine="SET BISON_SIMPLE=$(InputDir)..\..\tools\bison.simple\r
+SET BISON_HAIRY=$(InputDir)..\..\tools\bison.simple\r
+cd $(InputDir)\r
+$(InputDir)..\..\tools\bison.exe -d -t -v $(InputName).y\r
+if EXIST $(InputDir)Gen_$(InputName)_tab.cpp del $(InputDir)Gen_$(InputName)_tab.cpp\r
+rename $(InputDir)$(InputName)_tab.c Gen_$(InputName)_tab.cpp\r
+"\r
+                                               Outputs="$(InputDir)Gen_$(InputName)_tab.cpp"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="UserM_Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               Description="Executing Bison on $(InputPath)"\r
+                                               CommandLine="SET BISON_SIMPLE=$(InputDir)..\..\tools\bison.simple\r
+SET BISON_HAIRY=$(InputDir)..\..\tools\bison.simple\r
+cd $(InputDir)\r
+$(InputDir)..\..\tools\bison.exe -d -t -v $(InputName).y\r
+if EXIST $(InputDir)Gen_$(InputName)_tab.cpp del $(InputDir)Gen_$(InputName)_tab.cpp\r
+rename $(InputDir)$(InputName)_tab.c Gen_$(InputName)_tab.cpp\r
+"\r
+                                               Outputs="$(InputDir)Gen_$(InputName)_tab.cpp"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\intermOut.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\localintermediate.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\parseConst.cpp">\r
+                       </File>\r
+                       <Filter\r
+                               Name="Generated Source"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\Gen_glslang.cpp">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\Gen_glslang_tab.cpp">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\glslang_tab.h">\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="CPP"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\atom.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\atom.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\compile.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\cpp.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\cpp.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\cppstruct.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\memory.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\memory.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\parser.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\preprocess.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\scanner.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\scanner.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\slglobals.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\symbols.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\symbols.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\tokens.c">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\MachineIndependent\preprocessor\tokens.h">\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files">\r
+                       <File\r
+                               RelativePath="glslang\Include\BaseTypes.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\Common.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\ConstantUnion.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\InfoSink.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="OGLCompilersDLL\InitializeDll.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\InitializeGlobals.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\InitializeParseContext.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\PoolAlloc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\ResourceLimits.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\ShHandle.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\SymbolTable.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\Types.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\Include\intermediate.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\MachineIndependent\unistd.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Public"\r
+                       Filter="">\r
+                       <File\r
+                               RelativePath="glslang\Public\ShaderLang.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Generic Code Gen"\r
+                       Filter="">\r
+                       <File\r
+                               RelativePath="glslang\GenericCodeGen\CodeGen.cpp">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="glslang\GenericCodeGen\Link.cpp">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="OSDependent"\r
+                       Filter="">\r
+                       <Filter\r
+                               Name="Windows"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath="glslang\OSDependent\Windows\main.cpp">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\OSDependent\Windows\osinclude.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\OSDependent\Windows\ossource.cpp">\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="Linux"\r
+                               Filter="">\r
+                               <File\r
+                                       RelativePath="glslang\OSDependent\Linux\osinclude.h">\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="glslang\OSDependent\Linux\ossource.cpp">\r
+                                       <FileConfiguration\r
+                                               Name="UserM_Debug|Win32"\r
+                                               ExcludedFromBuild="TRUE">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       ObjectFile="$(IntDir)/$(InputName)1.obj"/>\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="UserM_Release|Win32"\r
+                                               ExcludedFromBuild="TRUE">\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                                       ObjectFile="$(IntDir)/$(InputName)1.obj"/>\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/glslang/GenericCodeGen/CodeGen.cpp b/glslang/GenericCodeGen/CodeGen.cpp
new file mode 100644 (file)
index 0000000..89394ba
--- /dev/null
@@ -0,0 +1,75 @@
+//
+//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.
+//
+
+#include "../Include/Common.h"
+#include "../Include/ShHandle.h"
+
+//
+// Here is where real machine specific high-level data would be defined.
+//
+class TGenericCompiler : public TCompiler {
+public:
+    TGenericCompiler(EShLanguage l, int dOptions) : TCompiler(l, infoSink), debugOptions(dOptions) { }
+    virtual bool compile(TIntermNode* root);
+    TInfoSink infoSink;
+    int debugOptions;
+};
+
+//
+// This function must be provided to create the actual
+// compile object used by higher level code.  It returns
+// a subclass of TCompiler.
+//
+TCompiler* ConstructCompiler(EShLanguage language, int debugOptions)
+{
+    return new TGenericCompiler(language, debugOptions);
+}
+
+//
+// Delete the compiler made by ConstructCompiler
+//
+void DeleteCompiler(TCompiler* compiler)
+{
+    delete compiler;
+}
+
+//
+//  Generate code from the given parse tree
+//
+bool TGenericCompiler::compile(TIntermNode *root)
+{
+    haveValidObjectCode = true;
+
+    return haveValidObjectCode;
+}
diff --git a/glslang/GenericCodeGen/Link.cpp b/glslang/GenericCodeGen/Link.cpp
new file mode 100644 (file)
index 0000000..60762d8
--- /dev/null
@@ -0,0 +1,91 @@
+//
+//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.
+//
+
+//
+// The top level algorithms for linking multiple
+// shaders together.
+//
+#include "../Include/Common.h"
+#include "../Include/ShHandle.h"
+
+//
+// Actual link object, derived from the shader handle base classes.
+//
+class TGenericLinker : public TLinker {
+public:
+    TGenericLinker(EShExecutable e, int dOptions) : TLinker(e, infoSink), debugOptions(dOptions) { }
+    bool link(TCompilerList&, TUniformMap*) { return true; }
+       void getAttributeBindings(ShBindingTable const **t) const { }
+    TInfoSink infoSink;
+    int debugOptions;
+};
+
+//
+// The internal view of a uniform/float object exchanged with the driver.
+//
+class TUniformLinkedMap : public TUniformMap {
+public:
+    TUniformLinkedMap() { }
+    virtual int getLocation(const char* name) { return 0; }
+};
+
+TShHandleBase* ConstructLinker(EShExecutable executable, int debugOptions)
+{
+    return new TGenericLinker(executable, debugOptions);
+}
+
+void DeleteLinker(TShHandleBase* linker)
+{
+    delete linker;
+}
+
+TUniformMap* ConstructUniformMap()
+{
+    return new TUniformLinkedMap();
+}
+
+void DeleteUniformMap(TUniformMap* map)
+{
+    delete map;
+}
+
+TShHandleBase* ConstructBindings()
+{
+    return 0;
+}
+
+void DeleteBindingList(TShHandleBase* bindingList)
+{
+    delete bindingList;
+}
diff --git a/glslang/GenericCodeGen/Makefile b/glslang/GenericCodeGen/Makefile
new file mode 100644 (file)
index 0000000..2a2f62a
--- /dev/null
@@ -0,0 +1,34 @@
+CC = g++
+
+OBJECTS = CodeGen.o Link.o
+AR=ar
+
+SRCS=CodeGen.cpp Link.cpp
+
+default : all
+all : libCodeGen.a
+
+libCodeGen.a : $(OBJECTS)
+       $(AR) rvu $@ $(OBJECTS)
+       ranlib $@
+
+%.o : %.cpp
+       $(CC) -c $<
+
+#
+# Cleanup
+#
+.PHONY : clean
+clean :
+       $(RM) *.o *.a
+
+depend:
+       makedepend -- $(CFLAGS) -- $(SRCS)
+# DO NOT DELETE
+
+CodeGen.o: ../Include/Common.h ../Include/PoolAlloc.h ../Include/ShHandle.h
+CodeGen.o: ../Public/ShaderLang.h
+CodeGen.o: ../Include/InfoSink.h
+Link.o: ../Include/Common.h ../Include/PoolAlloc.h ../Include/ShHandle.h
+Link.o: ../Public/ShaderLang.h
+Link.o: ../Include/InfoSink.h
diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h
new file mode 100644 (file)
index 0000000..1249cde
--- /dev/null
@@ -0,0 +1,137 @@
+//
+//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.
+//
+
+#ifndef _BASICTYPES_INCLUDED_
+#define _BASICTYPES_INCLUDED_
+
+//
+// Basic type.  Arrays, vectors, etc., are orthogonal to this.
+//
+enum TBasicType {
+    EbtVoid,
+    EbtFloat,
+    EbtInt,
+    EbtBool,
+    EbtGuardSamplerBegin,  // non type:  see implementation of IsSampler()
+    EbtSampler1D,
+    EbtSampler2D,
+    EbtSampler3D,
+    EbtSamplerCube,
+    EbtSampler1DShadow,
+    EbtSampler2DShadow,
+    EbtSamplerRect,        // ARB_texture_rectangle
+    EbtSamplerRectShadow,  // ARB_texture_rectangle
+    EbtGuardSamplerEnd,    // non type:  see implementation of IsSampler()
+    EbtStruct,
+    EbtAddress,            // should be deprecated??
+};
+
+__inline bool IsSampler(TBasicType type)
+{   
+    return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
+}
+
+//
+// Qualifiers and built-ins.  These are mainly used to see what can be read
+// or written, and by the machine dependent translator to know which registers
+// to allocate variables in.  Since built-ins tend to go to different registers
+// than varying or uniform, it makes sense they are peers, not sub-classes.
+//
+enum TQualifier {
+    EvqTemporary,     // For temporaries (within a function), read/write
+    EvqGlobal,        // For globals read/write
+    EvqConst,         // User defined constants and non-output parameters in functions
+    EvqAttribute,     // Readonly 
+    EvqVaryingIn,     // readonly, fragment shaders only
+    EvqVaryingOut,    // vertex shaders only  read/write
+    EvqUniform,       // Readonly, vertex and fragment
+
+    // pack/unpack input and output
+    EvqInput,
+    EvqOutput,
+
+    // parameters
+    EvqIn,
+    EvqOut,
+    EvqInOut,
+    EvqConstReadOnly,
+
+    // built-ins written by vertex shader
+    EvqPosition,
+    EvqPointSize,
+    EvqClipVertex,
+
+    // built-ins read by fragment shader
+    EvqFace,
+    EvqFragCoord,
+
+    // built-ins written by fragment shader
+    EvqFragColor,
+    EvqFragDepth,
+
+    // end of list
+    EvqLast,
+};
+
+//
+// This is just for debug print out, carried along with the definitions above.
+//
+__inline const char* getQualifierString(TQualifier q) 
+{
+    switch (q) {
+    case EvqTemporary:      return "Temporary";      break;
+    case EvqGlobal:         return "Global";         break;
+    case EvqConst:          return "const";          break;
+    case EvqConstReadOnly:  return "const";          break;
+    case EvqAttribute:      return "attribute";      break;
+    case EvqVaryingIn:      return "varying";        break;
+    case EvqVaryingOut:     return "varying";        break;
+    case EvqUniform:        return "uniform";        break;
+    case EvqIn:             return "in";             break;
+    case EvqOut:            return "out";            break;
+    case EvqInOut:          return "inout";          break;
+    case EvqInput:          return "input";          break;
+    case EvqOutput:         return "output";         break;
+    case EvqPosition:       return "Position";       break;
+    case EvqPointSize:      return "PointSize";      break;
+    case EvqClipVertex:     return "ClipVertex";     break;
+    case EvqFace:           return "Face";           break;
+    case EvqFragCoord:      return "FragCoord";      break;
+    case EvqFragColor:      return "FragColor";      break;
+    case EvqFragDepth:      return "FragDepth";      break;
+    default:                return "unknown qualifier";
+    }
+}
+
+#endif // _BASICTYPES_INCLUDED_
diff --git a/glslang/Include/Common.h b/glslang/Include/Common.h
new file mode 100644 (file)
index 0000000..9f20ed2
--- /dev/null
@@ -0,0 +1,192 @@
+//
+//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.
+//
+
+#ifndef _COMMON_INCLUDED_
+#define _COMMON_INCLUDED_
+
+#ifdef _WIN32
+    #include <basetsd.h>
+#elif defined (solaris)
+    #include <sys/int_types.h>
+    #define UINT_PTR uintptr_t
+#else
+    #include <stdint.h>
+    #define UINT_PTR uintptr_t
+#endif
+
+/* windows only pragma */
+#ifdef _MSC_VER
+    #pragma warning(disable : 4786) // Don't warn about too long identifiers
+    #pragma warning(disable : 4514) // unused inline method
+    #pragma warning(disable : 4201) // nameless union
+#endif
+
+//
+// Doing the push and pop below for warnings does not leave the warning state
+// the way it was.  This seems like a defect in the compiler.  We would like
+// to do this, but since it does not work correctly right now, it is turned
+// off.
+//
+//??#pragma warning(push, 3)
+
+       #include <set>
+    #include <vector>
+    #include <map>
+    #include <list>
+    #include <string>
+    #include <stdio.h>
+
+//??#pragma warning(pop)
+
+typedef int TSourceLoc;
+
+       #include <assert.h>
+
+#include "PoolAlloc.h"
+
+//
+// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
+//
+#define POOL_ALLOCATOR_NEW_DELETE(A)                                  \
+    void* operator new(size_t s) { return (A).allocate(s); }          \
+    void* operator new(size_t, void *_Where) { return (_Where);        }     \
+    void operator delete(void*) { }                                   \
+    void operator delete(void *, void *) { }                          \
+    void* operator new[](size_t s) { return (A).allocate(s); }        \
+    void* operator new[](size_t, void *_Where) { return (_Where);      } \
+    void operator delete[](void*) { }                                 \
+    void operator delete[](void *, void *) { }
+
+#define TBaseMap std::map
+#define TBaseList std::list
+#define TBaseSet std::set
+
+//
+// Pool version of string.
+//
+typedef pool_allocator<char> TStringAllocator;
+typedef std::basic_string <char, std::char_traits<char>, TStringAllocator > TString;
+inline TString* NewPoolTString(const char* s)
+{
+       void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
+       return new(memory) TString(s);
+}
+
+//
+// Pool allocator versions of vectors, lists, and maps
+//
+template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
+public:
+    typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
+    TVector() : std::vector<T, pool_allocator<T> >() {}
+    TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
+    TVector(size_type i): std::vector<T, pool_allocator<T> >(i) {}
+};
+
+template <class T> class TList   : public TBaseList  <T, pool_allocator<T> > {
+public:
+    typedef typename TBaseList<T, pool_allocator<T> >::size_type size_type;
+    TList() : TBaseList<T, pool_allocator<T> >() {}
+    TList(const pool_allocator<T>& a) : TBaseList<T, pool_allocator<T> >(a) {}
+    TList(size_type i): TBaseList<T, pool_allocator<T> >(i) {}
+};
+
+// This is called TStlSet, because TSet is taken by an existing compiler class.
+template <class T, class CMP> class TStlSet : public std::set<T, CMP, pool_allocator<T> > {
+    // No pool allocator versions of constructors in std::set.
+};
+
+
+template <class K, class D, class CMP = std::less<K> > 
+class TMap : public TBaseMap<K, D, CMP, pool_allocator<std::pair<K, D> > > {
+public:
+    typedef pool_allocator<std::pair <K, D> > tAllocator;
+
+    TMap() : TBaseMap<K, D, CMP, tAllocator >() {}
+    // use correct two-stage name lookup supported in gcc 3.4 and above
+    TMap(const tAllocator& a) : TBaseMap<K, D, CMP, tAllocator>(TBaseMap<K, D, CMP, tAllocator >::key_compare(), a) {}
+};
+
+//
+// Persistent string memory.  Should only be used for strings that survive
+// across compiles/links.
+//
+typedef std::basic_string<char> TPersistString;
+
+//
+// templatized min and max functions.
+//
+template <class T> T Min(const T a, const T b) { return a < b ? a : b; }
+template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
+
+//
+// Create a TString object from an integer.
+//
+inline const TString String(const int i, const int base = 10)
+{
+    char text[16];     // 32 bit ints are at most 10 digits in base 10
+    
+    #ifdef _WIN32
+        itoa(i, text, base);
+    #else
+        // we assume base 10 for all cases
+        sprintf(text, "%d", i);
+    #endif
+
+    return text;
+}
+
+const unsigned int SourceLocLineMask = 0xffff;
+const unsigned int SourceLocStringShift = 16;
+
+__inline TPersistString FormatSourceLoc(const TSourceLoc loc)
+{
+    char locText[64];
+
+    int string = loc >> SourceLocStringShift;
+    int line = loc & SourceLocLineMask;
+
+    if (line)
+        sprintf(locText, "%d:%d", string, line);
+    else
+        sprintf(locText, "%d:? ", string);
+
+    return TPersistString(locText);
+}
+
+
+typedef TMap<TString, TString> TPragmaTable;
+typedef TMap<TString, TString>::tAllocator TPragmaTableAllocator;
+
+#endif // _COMMON_INCLUDED_
diff --git a/glslang/Include/ConstantUnion.h b/glslang/Include/ConstantUnion.h
new file mode 100644 (file)
index 0000000..3116796
--- /dev/null
@@ -0,0 +1,315 @@
+//
+//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.
+//
+
+#ifndef _CONSTANT_UNION_INCLUDED_
+#define _CONSTANT_UNION_INCLUDED_
+
+
+class constUnion {
+public:
+
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)        
+    void setIConst(int i) {iConst = i; type = EbtInt; }
+    void setFConst(float f) {fConst = f; type = EbtFloat; }
+    void setBConst(bool b) {bConst = b; type = EbtBool; }
+
+    int getIConst() { return iConst; }
+    float getFConst() { return fConst; }
+    bool getBConst() { return bConst; }
+    int getIConst() const { return iConst; }
+    float getFConst() const { return fConst; }
+    bool getBConst() const { return bConst; }
+
+    bool operator==(const int i) const
+    {
+        if (i == iConst)
+            return true;
+
+        return false;
+    }
+
+    bool operator==(const float f) const
+    {
+        if (f == fConst)
+            return true;
+
+        return false;
+    }
+
+    bool operator==(const bool b) const
+    {
+        if (b == bConst)
+            return true;
+
+        return false;
+    }
+
+    bool operator==(const constUnion& constant) const
+    {
+        if (constant.type != type)
+            return false;
+
+        switch (type) {
+        case EbtInt:
+            if (constant.iConst == iConst)
+                return true;
+
+            break;
+        case EbtFloat:
+            if (constant.fConst == fConst)
+                return true;
+
+            break;
+        case EbtBool:
+            if (constant.bConst == bConst)
+                return true;
+
+            break;
+        }
+
+        return false;
+    }
+
+    bool operator!=(const int i) const
+    {
+        return !operator==(i);
+    }
+
+    bool operator!=(const float f) const
+    {
+        return !operator==(f);
+    }
+
+    bool operator!=(const bool b) const
+    {
+        return !operator==(b);
+    }
+
+    bool operator!=(const constUnion& constant) const
+    {
+        return !operator==(constant);
+    }
+
+    bool operator>(const constUnion& constant) const
+    { 
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:
+            if (iConst > constant.iConst)
+                return true;
+
+            return false;
+        case EbtFloat:
+            if (fConst > constant.fConst)
+                return true;
+
+            return false;
+        default:
+            assert(false && "Default missing");
+            return false;
+        }
+
+        return false;
+    }
+
+    bool operator<(const constUnion& constant) const
+    { 
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:
+            if (iConst < constant.iConst)
+                return true;
+
+            return false;
+        case EbtFloat:
+            if (fConst < constant.fConst)
+                return true;
+
+            return false;
+        default:
+            assert(false && "Default missing");
+            return false;
+        }
+
+        return false;
+    }
+
+    constUnion operator+(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
+        case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
+        default: assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator-(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
+        case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
+        default: assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator*(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
+        case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; 
+        default: assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator%(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator>>(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator<<(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator&(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:  returnValue.setIConst(iConst & constant.iConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator|(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator^(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator&&(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    constUnion operator||(const constUnion& constant) const
+    { 
+        constUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
+        default:     assert(false && "Default missing");
+        }
+
+        return returnValue;
+    }
+
+    TBasicType getType() { return type; }
+private:
+
+    union  {
+        int iConst;  // used for ivec, scalar ints
+        bool bConst; // used for bvec, scalar bools
+        float fConst;   // used for vec, mat, scalar floats
+    } ;
+
+    TBasicType type;
+};
+
+#endif // _CONSTANT_UNION_INCLUDED_
diff --git a/glslang/Include/InfoSink.h b/glslang/Include/InfoSink.h
new file mode 100644 (file)
index 0000000..debe9bb
--- /dev/null
@@ -0,0 +1,137 @@
+//
+//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.
+//
+
+#ifndef _INFOSINK_INCLUDED_
+#define _INFOSINK_INCLUDED_
+
+#include "../Include/Common.h"
+#include <math.h>
+
+//
+// TPrefixType is used to centralize how info log messages start.
+// See below.
+//
+enum TPrefixType {
+    EPrefixNone,
+    EPrefixWarning,
+    EPrefixError,
+    EPrefixInternalError,
+    EPrefixUnimplemented,
+    EPrefixNote
+};
+
+enum TOutputStream {
+    ENull = 0,
+    EDebugger = 0x01,
+    EStdOut = 0x02,
+    EString = 0x04,
+};
+//
+// Encapsulate info logs for all objects that have them.
+//
+// The methods are a general set of tools for getting a variety of
+// messages and types inserted into the log.
+//
+class TInfoSinkBase {
+public:
+    TInfoSinkBase() : outputStream(4) {}
+    void erase() { sink.erase(); }
+    TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; }
+    TInfoSinkBase& operator<<(char c)                  { append(1, c); return *this; }
+    TInfoSinkBase& operator<<(const char* s)           { append(s); return *this; }
+    TInfoSinkBase& operator<<(int n)                   { append(String(n)); return *this; }
+    TInfoSinkBase& operator<<(const unsigned int n)    { append(String(n)); return *this; }
+    TInfoSinkBase& operator<<(float n)                 { char buf[40]; 
+                                                     sprintf(buf, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ?
+                                                             "%f" : "%g", n);
+                                                     append(buf); 
+                                                     return *this; }
+    TInfoSinkBase& operator+(const TPersistString& t)  { append(t); return *this; }
+    TInfoSinkBase& operator+(const TString& t)         { append(t); return *this; }
+    TInfoSinkBase& operator<<(const TString& t)        { append(t); return *this; }
+    TInfoSinkBase& operator+(const char* s)            { append(s); return *this; }
+    const char* c_str() const { return sink.c_str(); }
+    void prefix(TPrefixType message) {
+        switch(message) {
+        case EPrefixNone:                                      break;
+        case EPrefixWarning:       append("WARNING: ");        break;
+        case EPrefixError:         append("ERROR: ");          break;
+        case EPrefixInternalError: append("INTERNAL ERROR: "); break;
+        case EPrefixUnimplemented: append("UNIMPLEMENTED: ");  break;
+        case EPrefixNote:          append("NOTE: ");           break;
+        default:                   append("UNKOWN ERROR: ");   break;
+        }
+    }
+    void location(TSourceLoc loc) {
+        append(FormatSourceLoc(loc).c_str());
+        append(": ");
+    }
+    void message(TPrefixType message, const char* s) {
+        prefix(message);
+        append(s);
+        append("\n");
+    }
+    void message(TPrefixType message, const char* s, TSourceLoc loc) {
+        prefix(message);
+        location(loc);
+        append(s);
+        append("\n");
+    }
+    
+    void setOutputStream(int output = 4)
+    {
+        outputStream = output;
+    }
+
+protected:
+    void append(const char *s); 
+
+    void append(int count, char c);
+    void append(const TPersistString& t);
+    void append(const TString& t);
+
+    void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)  
+                                       sink.reserve(sink.capacity() +  sink.capacity() / 2); }
+    void appendToStream(const char* s);
+    TPersistString sink;
+    int outputStream;
+};
+
+class TInfoSink {
+public:
+    TInfoSinkBase info;
+    TInfoSinkBase debug;
+};
+
+#endif // _INFOSINK_INCLUDED_
diff --git a/glslang/Include/InitializeGlobals.h b/glslang/Include/InitializeGlobals.h
new file mode 100644 (file)
index 0000000..dc1ef91
--- /dev/null
@@ -0,0 +1,43 @@
+//
+//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.
+//
+
+#ifndef __INITIALIZE_GLOBALS_INCLUDED_
+#define __INITIALIZE_GLOBALS_INCLUDED_
+
+void InitializeGlobalPools();
+void FreeGlobalPools();
+bool InitializePoolIndex();
+void FreePoolIndex();
+
+#endif // __INITIALIZE_GLOBALS_INCLUDED_
diff --git a/glslang/Include/InitializeParseContext.h b/glslang/Include/InitializeParseContext.h
new file mode 100644 (file)
index 0000000..4d369e8
--- /dev/null
@@ -0,0 +1,45 @@
+//
+//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.
+//
+
+#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
+#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
+#include "osinclude.h"
+
+bool InitializeParseContextIndex();
+bool InitializeGlobalParseContext();
+bool FreeParseContext();
+bool FreeParseContextIndex();
+
+
+#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/glslang/Include/PoolAlloc.h b/glslang/Include/PoolAlloc.h
new file mode 100644 (file)
index 0000000..14c5985
--- /dev/null
@@ -0,0 +1,349 @@
+//
+//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.
+//
+
+#ifndef _POOLALLOC_INCLUDED_
+#define _POOLALLOC_INCLUDED_
+
+#ifdef _DEBUG
+#  define GUARD_BLOCKS  // define to enable guard block sanity checking
+#endif
+
+//
+// This header defines an allocator that can be used to efficiently
+// allocate a large number of small requests for heap memory, with the 
+// intention that they are not individually deallocated, but rather 
+// collectively deallocated at one time.
+//
+// This simultaneously
+//
+// * Makes each individual allocation much more efficient; the
+//     typical allocation is trivial.
+// * Completely avoids the cost of doing individual deallocation.
+// * Saves the trouble of tracking down and plugging a large class of leaks.
+//
+// Individual classes can use this allocator by supplying their own
+// new and delete methods.
+//
+// STL containers can use this allocator by using the pool_allocator
+// class as the allocator (second) template argument.
+//
+
+#include <stddef.h>
+#include <vector>
+
+// If we are using guard blocks, we must track each indivual
+// allocation.  If we aren't using guard blocks, these
+// never get instantiated, so won't have any impact.
+// 
+
+class TAllocation {
+public:
+    TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) :
+        size(size), mem(mem), prevAlloc(prev) {
+        // Allocations are bracketed:
+        //    [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
+        // This would be cleaner with if (guardBlockSize)..., but that
+        // makes the compiler print warnings about 0 length memsets,
+        // even with the if() protecting them.
+#       ifdef GUARD_BLOCKS
+            memset(preGuard(),  guardBlockBeginVal, guardBlockSize);
+            memset(data(),      userDataFill,       size);
+            memset(postGuard(), guardBlockEndVal,   guardBlockSize);
+#       endif
+    }
+    
+    void check() const {
+        checkGuardBlock(preGuard(),  guardBlockBeginVal, "before");
+        checkGuardBlock(postGuard(), guardBlockEndVal,   "after");
+    }
+
+    void checkAllocList() const;
+
+    // Return total size needed to accomodate user buffer of 'size',
+    // plus our tracking data.
+    inline static size_t allocationSize(size_t size) {
+        return size + 2 * guardBlockSize + headerSize();
+    }
+    
+    // Offset from surrounding buffer to get to user data buffer.
+    inline static unsigned char* offsetAllocation(unsigned char* m) {
+        return m + guardBlockSize + headerSize();
+    }
+
+private:
+    void checkGuardBlock(unsigned char* blockMem, unsigned char val, char* locText) const;
+
+    // Find offsets to pre and post guard blocks, and user data buffer
+    unsigned char* preGuard()  const { return mem + headerSize(); }
+    unsigned char* data()      const { return preGuard() + guardBlockSize; }
+    unsigned char* postGuard() const { return data() + size; }
+
+    size_t size;                  // size of the user data area
+    unsigned char* mem;           // beginning of our allocation (pts to header)
+    TAllocation* prevAlloc;       // prior allocation in the chain
+
+    // Support MSVC++ 6.0
+    const static unsigned char guardBlockBeginVal;
+    const static unsigned char guardBlockEndVal;
+    const static unsigned char userDataFill;
+
+    const static size_t guardBlockSize;
+#   ifdef GUARD_BLOCKS    
+    inline static size_t headerSize() { return sizeof(TAllocation); }
+#   else
+    inline static size_t headerSize() { return 0; }
+#   endif
+};
+    
+//
+// There are several stacks.  One is to track the pushing and popping
+// of the user, and not yet implemented.  The others are simply a 
+// repositories of free pages or used pages.
+//
+// Page stacks are linked together with a simple header at the beginning
+// of each allocation obtained from the underlying OS.  Multi-page allocations
+// are returned to the OS.  Individual page allocations are kept for future
+// re-use.
+//
+// The "page size" used is not, nor must it match, the underlying OS
+// page size.  But, having it be about that size or equal to a set of 
+// pages is likely most optimal.
+//
+class TPoolAllocator {
+public:
+    TPoolAllocator(bool global = false, int growthIncrement = 8*1024, int allocationAlignment = 16);
+
+    //
+    // Don't call the destructor just to free up the memory, call pop()
+    //
+    ~TPoolAllocator();
+
+    //
+    // Call push() to establish a new place to pop memory too.  Does not
+    // have to be called to get things started.
+    //
+    void push();
+
+    //
+    // Call pop() to free all memory allocated since the last call to push(),
+    // or if no last call to push, frees all memory since first allocation.
+    //
+    void pop();
+
+    //
+    // Call popAll() to free all memory allocated.
+    //
+    void popAll();
+
+    //
+    // Call allocate() to actually acquire memory.  Returns 0 if no memory
+    // available, otherwise a properly aligned pointer to 'numBytes' of memory.
+    //
+    void* allocate(size_t numBytes);
+
+    //
+    // There is no deallocate.  The point of this class is that
+    // deallocation can be skipped by the user of it, as the model
+    // of use is to simultaneously deallocate everything at once
+    // by calling pop(), and to not have to solve memory leak problems.
+    //
+
+protected:
+    friend struct tHeader;
+    
+    struct tHeader {
+        tHeader(tHeader* nextPage, size_t pageCount) :
+#ifdef GUARD_BLOCKS
+        lastAllocation(0),
+#endif
+        nextPage(nextPage), pageCount(pageCount) { }
+
+        ~tHeader() {
+#ifdef GUARD_BLOCKS
+            if (lastAllocation)
+                lastAllocation->checkAllocList();
+#endif
+        }
+
+        tHeader* nextPage;
+        size_t pageCount;
+#ifdef GUARD_BLOCKS
+        TAllocation* lastAllocation;
+#endif
+    };
+
+    struct tAllocState {
+        size_t offset;
+        tHeader* page;
+    };
+    typedef std::vector<tAllocState> tAllocStack;
+
+    // Track allocations if and only if we're using guard blocks
+    void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) {
+#       ifdef GUARD_BLOCKS
+        new(memory) TAllocation(numBytes, memory, block->lastAllocation);
+        block->lastAllocation = reinterpret_cast<TAllocation*>(memory);
+#       endif
+
+        // This is optimized entirely away if GUARD_BLOCKS is not defined.
+        return TAllocation::offsetAllocation(memory);
+    }
+
+    bool global;            // should be true if this object is globally scoped
+    size_t pageSize;        // granularity of allocation from the OS
+    size_t alignment;       // all returned allocations will be aligned at 
+                            //      this granularity, which will be a power of 2
+    size_t alignmentMask;
+    size_t headerSkip;      // amount of memory to skip to make room for the
+                            //      header (basically, size of header, rounded
+                            //      up to make it aligned
+    size_t currentPageOffset;  // next offset in top of inUseList to allocate from
+    tHeader* freeList;      // list of popped memory
+    tHeader* inUseList;     // list of all memory currently being used
+    tAllocStack stack;      // stack of where to allocate from, to partition pool
+
+    int numCalls;           // just an interesting statistic
+    size_t totalBytes;      // just an interesting statistic
+private:
+    TPoolAllocator& operator=(const TPoolAllocator&);  // dont allow assignment operator
+    TPoolAllocator(const TPoolAllocator&);  // dont allow default copy constructor
+};
+
+
+//
+// There could potentially be many pools with pops happening at
+// different times.  But a simple use is to have a global pop
+// with everyone using the same global allocator.
+//
+typedef TPoolAllocator* PoolAllocatorPointer;
+extern TPoolAllocator& GetGlobalPoolAllocator();
+#define GlobalPoolAllocator GetGlobalPoolAllocator()
+
+
+struct TThreadGlobalPools
+{
+        TPoolAllocator* globalPoolAllocator;
+};
+
+void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator);
+
+//
+// This STL compatible allocator is intended to be used as the allocator
+// parameter to templatized STL containers, like vector and map.
+//
+// It will use the pools for allocation, and not
+// do any deallocation, but will still do destruction.
+//
+template<class T>
+class pool_allocator {
+public:
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+    typedef T *pointer;
+    typedef const T *const_pointer;
+    typedef T& reference;
+    typedef const T& const_reference;
+    typedef T value_type;
+    template<class Other> 
+        struct rebind {
+            typedef pool_allocator<Other> other;
+        };
+    pointer address(reference x) const { return &x; }
+    const_pointer address(const_reference x) const { return &x; }
+
+#ifdef USING_SGI_STL
+       pool_allocator()  { }
+#else
+    pool_allocator() : allocator(GlobalPoolAllocator) { }
+    pool_allocator(TPoolAllocator& a) : allocator(a) { }
+    pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+    template<class Other>
+#ifdef USING_SGI_STL
+        pool_allocator(const pool_allocator<Other>& p) /*: allocator(p.getAllocator())*/ { }
+#else
+        pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
+#endif
+#endif
+
+#ifndef _WIN32
+        template<class Other>
+            pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
+#endif
+
+#ifdef USING_SGI_STL
+    static pointer allocate(size_type n) { 
+        return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
+    pointer allocate(size_type n, const void*) { 
+        return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
+
+       static void deallocate(void*, size_type) { }
+    static void deallocate(pointer, size_type) { }
+#else
+    pointer allocate(size_type n) { 
+        return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
+    pointer allocate(size_type n, const void*) { 
+        return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
+
+       void deallocate(void*, size_type) { }
+    void deallocate(pointer, size_type) { }
+#endif
+
+       pointer _Charalloc(size_t n) {
+        return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
+
+    void construct(pointer p, const T& val) { new ((void *)p) T(val); }
+    void destroy(pointer p) { p->T::~T(); }
+
+    bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); }
+    bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); }
+
+    size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
+    size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
+
+#ifdef USING_SGI_STL
+    //void setAllocator(TPoolAllocator* a) { allocator = a; }
+    static  TPoolAllocator& getAllocator() { return GlobalPoolAllocator; }
+#else
+    void setAllocator(TPoolAllocator* a) { allocator = *a; }
+    TPoolAllocator& getAllocator() const { return allocator; }
+
+protected:
+    TPoolAllocator& allocator;
+#endif
+};
+
+#endif // _POOLALLOC_INCLUDED_
diff --git a/glslang/Include/ResourceLimits.h b/glslang/Include/ResourceLimits.h
new file mode 100644 (file)
index 0000000..f3d1a53
--- /dev/null
@@ -0,0 +1,52 @@
+//
+//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.
+//
+
+#ifndef _RESOURCE_LIMITS_INCLUDED_
+#define _RESOURCE_LIMITS_INCLUDED_
+
+struct TBuiltInResource {
+    int maxLights;
+    int maxClipPlanes;
+    int maxTextureUnits;
+    int maxTextureCoords;
+    int maxVertexAttribs;
+    int maxVertexUniformComponents;
+    int maxVaryingFloats;
+    int maxVertexTextureImageUnits;
+    int maxCombinedTextureImageUnits;
+    int maxTextureImageUnits;
+    int maxFragmentUniformComponents;
+    int maxDrawBuffers;
+};
+#endif // _RESOURCE_LIMITS_INCLUDED_
diff --git a/glslang/Include/ShHandle.h b/glslang/Include/ShHandle.h
new file mode 100644 (file)
index 0000000..0bde67b
--- /dev/null
@@ -0,0 +1,169 @@
+//
+//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.
+//
+
+#ifndef _SHHANDLE_INCLUDED_
+#define _SHHANDLE_INCLUDED_
+
+//
+// Machine independent part of the compiler private objects
+// sent as ShHandle to the driver.
+//
+// This should not be included by driver code.
+//
+
+
+#define SH_EXPORTING   
+#include "../Public/ShaderLang.h"
+
+#include "InfoSink.h"
+
+class TCompiler;
+class TLinker;
+class TUniformMap;
+
+
+//
+// The base class used to back handles returned to the driver.
+//
+class TShHandleBase {
+public:
+    TShHandleBase() { }
+    virtual ~TShHandleBase() { }
+    virtual TCompiler* getAsCompiler() { return 0; }
+    virtual TLinker* getAsLinker() { return 0; }
+    virtual TUniformMap* getAsUniformMap() { return 0; }
+};
+
+//
+// The base class for the machine dependent linker to derive from
+// for managing where uniforms live.
+//
+class TUniformMap : public TShHandleBase {
+public:
+    TUniformMap() { }
+    virtual ~TUniformMap() { }
+    virtual TUniformMap* getAsUniformMap() { return this; }
+    virtual int getLocation(const char* name) = 0;    
+    virtual TInfoSink& getInfoSink() { return infoSink; }
+    TInfoSink infoSink;
+};
+class TIntermNode;
+
+//
+// The base class for the machine dependent compiler to derive from
+// for managing object code from the compile.
+//
+class TCompiler : public TShHandleBase {
+public:
+    TCompiler(EShLanguage l, TInfoSink& sink) : infoSink(sink) , language(l), haveValidObjectCode(false) { }
+    virtual ~TCompiler() { }
+    EShLanguage getLanguage() { return language; }
+    virtual TInfoSink& getInfoSink() { return infoSink; }
+
+    virtual bool compile(TIntermNode* root) = 0;
+
+    virtual TCompiler* getAsCompiler() { return this; }
+    virtual bool linkable() { return haveValidObjectCode; }
+    
+    TInfoSink& infoSink;
+protected:
+    EShLanguage language;
+    bool haveValidObjectCode;
+};
+
+//
+// Link operations are base on a list of compile results...
+//
+typedef TVector<TCompiler*> TCompilerList;
+typedef TVector<TShHandleBase*> THandleList;
+
+//
+// The base class for the machine dependent linker to derive from
+// to manage the resulting executable.
+//
+
+class TLinker : public TShHandleBase {
+public:
+    TLinker(EShExecutable e, TInfoSink& iSink) : 
+        infoSink(iSink),
+        executable(e), 
+        haveReturnableObjectCode(false),
+        appAttributeBindings(0),
+        fixedAttributeBindings(0),
+               excludedAttributes(0),
+               excludedCount(0),
+        uniformBindings(0) { }
+    virtual TLinker* getAsLinker() { return this; }
+    virtual ~TLinker() { }
+    virtual bool link(TCompilerList&, TUniformMap*) = 0;
+    virtual bool link(THandleList&) { return false; }
+    virtual void setAppAttributeBindings(const ShBindingTable* t)   { appAttributeBindings = t; }
+    virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; }
+       virtual void getAttributeBindings(ShBindingTable const **t) const = 0;
+       virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; }
+    virtual ShBindingTable* getUniformBindings() const  { return uniformBindings; }
+    virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here
+    virtual TInfoSink& getInfoSink() { return infoSink; }
+    TInfoSink& infoSink;
+protected:
+    EShExecutable executable;
+    bool haveReturnableObjectCode;  // true when objectCode is acceptable to send to driver
+
+    const ShBindingTable* appAttributeBindings;
+    const ShBindingTable* fixedAttributeBindings;
+       const int* excludedAttributes;
+       int excludedCount;
+    ShBindingTable* uniformBindings;                // created by the linker    
+};
+
+//
+// This is the interface between the machine independent code
+// and the machine dependent code.
+//
+// The machine dependent code should derive from the classes
+// above. Then Construct*() and Delete*() will create and 
+// destroy the machine dependent objects, which contain the
+// above machine independent information.
+//
+TCompiler* ConstructCompiler(EShLanguage, int);
+
+TShHandleBase* ConstructLinker(EShExecutable, int);
+void DeleteLinker(TShHandleBase*);
+    
+TUniformMap* ConstructUniformMap();
+void DeleteCompiler(TCompiler*);
+
+void DeleteUniformMap(TUniformMap*);
+
+#endif // _SHHANDLE_INCLUDED_
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
new file mode 100644 (file)
index 0000000..3db8d3a
--- /dev/null
@@ -0,0 +1,322 @@
+//
+//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.
+//
+
+#ifndef _TYPES_INCLUDED
+#define _TYPES_INCLUDED
+
+#include "../Include/Common.h"
+#include "../Include/BaseTypes.h"
+
+//
+// Need to have association of line numbers to types in a list for building structs.
+//
+class TType;
+struct TTypeLine {
+    TType* type;
+    int line;
+};
+typedef TVector<TTypeLine> TTypeList;
+
+inline TTypeList* NewPoolTTypeList()
+{
+       void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList));
+       return new(memory) TTypeList;
+}
+
+//
+// This is a workaround for a problem with the yacc stack,  It can't have
+// types that it thinks have non-trivial constructors.  It should 
+// just be used while recognizing the grammar, not anything else.  Pointers
+// could be used, but also trying to avoid lots of memory management overhead.
+//
+// Not as bad as it looks, there is no actual assumption that the fields
+// match up or are name the same or anything like that.
+//
+class TPublicType {
+public:
+    TBasicType type;
+    TQualifier qualifier;
+    int size;          // size of vector or matrix, not size of array
+    bool matrix;
+    bool array;
+    int arraySize;
+    TType* userDef;
+    int line;
+
+    void setBasic(TBasicType bt, TQualifier q, int ln = 0) 
+    { 
+        type = bt;
+        qualifier = q;
+        size = 1;
+        matrix = false;
+        array = false;
+        arraySize = 0;
+        userDef = 0;
+        line = ln;
+    }
+
+    void setAggregate(int s, bool m = false)
+    {
+        size = s;
+        matrix = m;
+    }
+
+    void setArray(bool a, int s = 0)
+    {
+        array = a;
+        arraySize = s;
+    }
+};
+
+typedef std::map<TTypeList*, TTypeList*> TStructureMap;
+typedef std::map<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
+//
+// Base class for things that have a type.
+//
+class TType {
+public:
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    explicit TType(TBasicType t, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
+                            type(t), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
+                            structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+                            { }
+    explicit TType(const TPublicType &p) :
+                            type(p.type), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), 
+                            structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+                            {
+                              if (p.userDef) {
+                                  structure = p.userDef->getStruct();
+                                  typeName = NewPoolTString(p.userDef->getTypeName().c_str());
+                              }
+                            }
+    explicit TType(TTypeList* userDef, const TString& n) :
+                            type(EbtStruct), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
+                            structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) {
+                                                               typeName = NewPoolTString(n.c_str());
+                            }
+       explicit TType() {}
+    virtual ~TType() {}
+
+       TType(const TType& type) { *this = type; }
+
+       void copyType(const TType& copyOf, TStructureMap& remapper)
+       {
+               type = copyOf.type;
+               qualifier = copyOf.qualifier;
+               size = copyOf.size;
+               matrix = copyOf.matrix;
+               array = copyOf.array;
+               arraySize = copyOf.arraySize;
+               
+               TStructureMapIterator iter;
+               if (copyOf.structure) {
+               if ((iter = remapper.find(structure)) == remapper.end()) {
+                               // 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);
+                               }
+                       } else {
+                               structure = iter->second;
+                       }
+               } else
+                       structure = 0;
+
+               fieldName = 0;
+               if (copyOf.fieldName)
+                       fieldName = NewPoolTString(copyOf.fieldName->c_str());
+               typeName = 0;
+               if (copyOf.typeName)
+                       typeName = NewPoolTString(copyOf.typeName->c_str());
+               
+               mangled = 0;
+               if (copyOf.mangled)
+                       mangled = NewPoolTString(copyOf.mangled->c_str());
+
+               structureSize = copyOf.structureSize;
+               maxArraySize = copyOf.maxArraySize;
+               assert(copyOf.arrayInformationType == 0);
+               arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
+       }
+
+       TType* clone(TStructureMap& remapper)
+       {
+               TType *newType = new TType();
+               newType->copyType(*this, remapper);
+
+               return newType;
+       }
+    
+    virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
+                            { type = t; size = s; matrix = m; array = a; arraySize = aS; }
+    virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
+                            { type = t; 
+                              size = s; 
+                              matrix = m; 
+                              if (userDef)
+                                  structure = userDef->getStruct(); 
+                              // leave array information intact.
+                            }
+    virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
+    virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
+    virtual const TString& getTypeName() const
+    { 
+               assert(typeName);               
+       return *typeName; 
+    }
+
+    virtual const TString& getFieldName() const
+    { 
+       assert(fieldName);
+               return *fieldName; 
+    }
+    
+    virtual TBasicType getBasicType() const { return type; }
+    virtual TQualifier getQualifier() const { return qualifier; }
+    virtual void changeQualifier(TQualifier q) { qualifier = q; }
+
+    // One-dimensional size of single instance type
+    virtual int getNominalSize() const { return size; }  
+    
+    // Full-dimensional size of single instance of type
+    virtual int getInstanceSize() const  
+    {
+        if (matrix)
+            return size * size;
+        else
+            return size;
+    }
+    
+       virtual bool isMatrix() const { return matrix ? true : false; }
+    virtual bool isArray() const  { return array ? true : false; }
+    int getArraySize() const { return arraySize; }
+    void setArraySize(int s) { array = true; arraySize = s; }
+    void setMaxArraySize (int s) { maxArraySize = s; }
+    int getMaxArraySize () const { return maxArraySize; }
+    void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
+    void setArrayInformationType(TType* t) { arrayInformationType = t; }
+    TType* getArrayInformationType() { return arrayInformationType; }
+    virtual bool isVector() const { return size > 1 && !matrix; }
+    static char* getBasicString(TBasicType t) {
+        switch (t) {
+        case EbtVoid:              return "void";              break;
+        case EbtFloat:             return "float";             break;
+        case EbtInt:               return "int";               break;
+        case EbtBool:              return "bool";              break;
+        case EbtSampler1D:         return "sampler1D";         break;
+        case EbtSampler2D:         return "sampler2D";         break;
+        case EbtSampler3D:         return "sampler3D";         break;
+        case EbtSamplerCube:       return "samplerCube";       break;
+        case EbtSampler1DShadow:   return "sampler1DShadow";   break;
+        case EbtSampler2DShadow:   return "sampler2DShadow";   break;
+        case EbtSamplerRect:       return "samplerRect";       break; // ARB_texture_rectangle
+        case EbtSamplerRectShadow: return "samplerRectShadow"; break; // ARB_texture_rectangle
+        case EbtStruct:            return "structure";         break;
+        default:                   return "unknown type";
+        }
+    }
+    const char* getBasicString() const { return TType::getBasicString(type); }
+    const char* getQualifierString() const { return ::getQualifierString(qualifier); }
+    TTypeList* getStruct() { return structure; }
+
+    int getObjectSize() const
+    {
+        int totalSize;
+        
+        if (getBasicType() == EbtStruct)
+            totalSize = getStructSize();
+        else if (matrix)
+            totalSize = size * size;            
+        else 
+            totalSize = size;
+
+        if (isArray())
+            totalSize *= Max(getArraySize(), getMaxArraySize());
+
+        return totalSize;
+    }
+
+    TTypeList* getStruct() const { return structure; }
+    TString& getMangledName() {
+        if (!mangled) {
+                       mangled = NewPoolTString("");
+            buildMangledName(*mangled);            
+            *mangled += ';' ;
+        }
+    
+        return *mangled;
+    }
+    bool sameElementType(const TType& right) const {
+        return      type == right.type   &&
+                    size == right.size   &&
+                  matrix == right.matrix &&
+               structure == right.structure;
+    }
+    bool operator==(const TType& right) const {
+        return      type == right.type   &&
+                    size == right.size   &&
+                  matrix == right.matrix &&
+                   array == right.array  && (!array || arraySize == right.arraySize) &&
+               structure == right.structure;
+        // don't check the qualifier, it's not ever what's being sought after
+    }
+    bool operator!=(const TType& right) const {
+        return !operator==(right);
+    }
+    TString getCompleteString() const;
+        
+protected:
+    void buildMangledName(TString&);
+    int getStructSize() const;
+
+       TBasicType type      : 6;
+       TQualifier qualifier : 7;
+       int size             : 8; // size of vector or matrix, not size of array
+       unsigned int matrix  : 1;
+       unsigned int array   : 1;
+    int arraySize;
+
+    TTypeList* structure;      // 0 unless this is a struct
+    mutable int structureSize;
+    int maxArraySize;
+    TType* arrayInformationType;
+       TString *fieldName;         // for structure field names
+    TString *mangled;
+       TString *typeName;          // for structure field type name
+};
+
+#endif // _TYPES_INCLUDED_
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
new file mode 100644 (file)
index 0000000..336e43c
--- /dev/null
@@ -0,0 +1,522 @@
+//
+//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.
+//
+
+//
+// Definition of the in-memory high-level intermediate representation
+// of shaders.  This is a tree that parser creates.
+//
+// Nodes in the tree are defined as a hierarchy of classes derived from 
+// TIntermNode. Each is a node in a tree.  There is no preset branching factor;
+// each node can have it's own type of list of children.
+//
+
+#ifndef __INTERMEDIATE_H
+#define __INTERMEDIATE_H
+
+#include "../Include/Common.h"
+#include "../Include/Types.h"
+#include "../Include/ConstantUnion.h"
+
+//
+// Operators used by the high-level (parse tree) representation.
+//
+enum TOperator {
+    EOpNull,            // if in a node, should only mean a node is still being built
+    EOpSequence,        // denotes a list of statements, or parameters, etc.
+    EOpFunctionCall,    
+    EOpFunction,        // For function definition
+    EOpParameters,      // an aggregate listing the parameters to a function
+
+    //
+    // Unary operators
+    //
+    
+    EOpNegative,
+    EOpLogicalNot,
+    EOpVectorLogicalNot,
+    EOpBitwiseNot,
+
+    EOpPostIncrement,
+    EOpPostDecrement,
+    EOpPreIncrement,
+    EOpPreDecrement,
+
+    EOpConvIntToBool,
+    EOpConvFloatToBool,
+    EOpConvBoolToFloat,
+    EOpConvIntToFloat,
+    EOpConvFloatToInt,
+    EOpConvBoolToInt,
+
+    //
+    // binary operations
+    //
+
+    EOpAdd,
+    EOpSub,
+    EOpMul,
+    EOpDiv,
+    EOpMod,
+    EOpRightShift,
+    EOpLeftShift,
+    EOpAnd,
+    EOpInclusiveOr,
+    EOpExclusiveOr,
+    EOpEqual,
+    EOpNotEqual,
+    EOpVectorEqual,
+    EOpVectorNotEqual,
+    EOpLessThan,
+    EOpGreaterThan,
+    EOpLessThanEqual,
+    EOpGreaterThanEqual,
+    EOpComma,
+
+    EOpVectorTimesScalar,
+    EOpVectorTimesMatrix,
+    EOpMatrixTimesVector,
+    EOpMatrixTimesScalar,
+
+    EOpLogicalOr,
+    EOpLogicalXor,
+    EOpLogicalAnd,
+
+    EOpIndexDirect,
+    EOpIndexIndirect,
+    EOpIndexDirectStruct,
+
+    EOpVectorSwizzle,
+
+    //
+    // Built-in functions potentially mapped to operators
+    //
+
+    EOpRadians,
+    EOpDegrees,
+    EOpSin,
+    EOpCos,
+    EOpTan,
+    EOpAsin,
+    EOpAcos,
+    EOpAtan,
+
+    EOpPow,
+    EOpExp,
+    EOpLog,
+    EOpExp2,
+    EOpLog2,
+    EOpSqrt,
+    EOpInverseSqrt,
+
+    EOpAbs,
+    EOpSign,
+    EOpFloor,
+    EOpCeil,
+    EOpFract,
+    EOpMin,
+    EOpMax,
+    EOpClamp,
+    EOpMix,
+    EOpStep,
+    EOpSmoothStep,
+
+    EOpLength,
+    EOpDistance,
+    EOpDot,
+    EOpCross,
+    EOpNormalize,
+    EOpFaceForward,
+    EOpReflect,
+    EOpRefract,
+
+    EOpDPdx,            // Fragment only
+    EOpDPdy,            // Fragment only
+    EOpFwidth,          // Fragment only
+
+    EOpMatrixTimesMatrix,
+
+    EOpAny,
+    EOpAll,
+    
+    EOpItof,         // pack/unpack only
+    EOpFtoi,         // pack/unpack only    
+    EOpSkipPixels,   // pack/unpack only
+    EOpReadInput,    // unpack only
+    EOpWritePixel,   // unpack only
+    EOpBitmapLsb,    // unpack only
+    EOpBitmapMsb,    // unpack only
+    EOpWriteOutput,  // pack only
+    EOpReadPixel,    // pack only
+    
+    //
+    // Branch
+    //
+
+    EOpKill,            // Fragment only
+    EOpReturn,
+    EOpBreak,
+    EOpContinue,
+
+    //
+    // Constructors
+    //
+
+    EOpConstructInt,
+    EOpConstructBool,
+    EOpConstructFloat,
+    EOpConstructVec2,
+    EOpConstructVec3,
+    EOpConstructVec4,
+    EOpConstructBVec2,
+    EOpConstructBVec3,
+    EOpConstructBVec4,
+    EOpConstructIVec2,
+    EOpConstructIVec3,
+    EOpConstructIVec4,
+    EOpConstructMat2,
+    EOpConstructMat3,
+    EOpConstructMat4,
+    EOpConstructStruct,
+
+    //
+    // moves
+    //
+    
+    EOpAssign,
+    EOpAddAssign,
+    EOpSubAssign,
+    EOpMulAssign,
+    EOpVectorTimesMatrixAssign,
+    EOpVectorTimesScalarAssign,
+    EOpMatrixTimesScalarAssign,
+    EOpMatrixTimesMatrixAssign,
+    EOpDivAssign,
+    EOpModAssign,
+    EOpAndAssign,
+    EOpInclusiveOrAssign,
+    EOpExclusiveOrAssign,
+    EOpLeftShiftAssign,
+    EOpRightShiftAssign,
+
+    //
+    // Array operators
+    //
+
+    EOpArrayLength,
+};
+
+class TIntermTraverser;
+class TIntermAggregate;
+class TIntermBinary;
+class TIntermConstantUnion;
+class TIntermSelection;
+class TIntermTyped;
+class TIntermSymbol;
+class TInfoSink;
+
+//
+// Base class for the tree nodes
+//
+class TIntermNode {
+public:
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+
+    TIntermNode() : line(0) {}
+    virtual TSourceLoc getLine() const { return line; }
+    virtual void setLine(TSourceLoc l) { line = l; }
+    virtual void traverse(TIntermTraverser*) = 0;
+    virtual TIntermTyped*     getAsTyped()         { return 0; }
+    virtual TIntermConstantUnion*     getAsConstantUnion()         { return 0; }
+    virtual TIntermAggregate* getAsAggregate()     { return 0; }
+    virtual TIntermBinary*    getAsBinaryNode()    { return 0; }
+    virtual TIntermSelection* getAsSelectionNode() { return 0; }
+    virtual TIntermSymbol*    getAsSymbolNode()    { return 0; }
+    virtual ~TIntermNode() { }
+protected:
+    TSourceLoc line;
+};
+
+//
+// This is just to help yacc.
+//
+struct TIntermNodePair {
+    TIntermNode* node1;
+    TIntermNode* node2;
+};
+
+class TIntermSymbol;
+class TIntermBinary;
+
+//
+// Intermediate class for nodes that have a type.
+//
+class TIntermTyped : public TIntermNode {
+public:
+       TIntermTyped(const TType& t) : type(t)  { }
+    virtual TIntermTyped* getAsTyped()         { return this; }
+    virtual void setType(const TType& t) { type = t; }
+    virtual TType getType() const { return type; }
+    virtual TType* getTypePointer() { return &type; }
+    
+    virtual TBasicType getBasicType() const { return type.getBasicType(); }
+    virtual TQualifier getQualifier() const { return type.getQualifier(); }
+    virtual int getNominalSize() const { return type.getNominalSize(); }
+    virtual int getSize() const { return type.getInstanceSize(); }
+    virtual bool isMatrix() const { return type.isMatrix(); }
+    virtual bool isArray()  const { return type.isArray(); }
+    virtual bool isVector() const { return type.isVector(); }
+    const char* getBasicString()      const { return type.getBasicString(); }
+    const char* getQualifierString()  const { return type.getQualifierString(); }
+    TString getCompleteString() const { return type.getCompleteString(); }
+
+protected:
+    TType type;
+};
+
+//
+// Handle for, do-while, and while loops.
+//
+class TIntermLoop : public TIntermNode {
+public:
+    TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) : 
+        body(aBody),
+        test(aTest),
+        terminal(aTerminal),
+        first(testFirst) { }
+    virtual void traverse(TIntermTraverser*);
+    TIntermNode*  getBody() { return body; }
+    TIntermTyped* getTest() { return test; }
+    TIntermTyped* getTerminal() { return terminal; }
+    bool testFirst() { return first; }
+protected:
+    TIntermNode* body;       // code to loop over
+    TIntermTyped* test;      // exit condition associated with loop, could be 0 for 'for' loops
+    TIntermTyped* terminal;  // exists for for-loops
+    bool first;              // true for while and for, not for do-while
+};
+
+//
+// Handle break, continue, return, and kill.
+//
+class TIntermBranch : public TIntermNode {
+public:
+    TIntermBranch(TOperator op, TIntermTyped* e) :
+        flowOp(op),
+        expression(e) { }
+    virtual void traverse(TIntermTraverser*);
+    TOperator getFlowOp() { return flowOp; }
+    TIntermTyped* getExpression() { return expression; }
+protected:
+    TOperator flowOp;
+    TIntermTyped* expression;  // non-zero except for "return exp;" statements
+};
+
+//
+// Nodes that correspond to symbols or constants in the source code.
+//
+class TIntermSymbol : public TIntermTyped {
+public:
+       // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
+       // per process globalpoolallocator, then it causes increased memory usage per compile
+       // it is essential to use "symbol = sym" to assign to symbol
+    TIntermSymbol(int i, const TString& sym, const TType& t) : 
+        TIntermTyped(t), id(i)  { symbol = sym;} 
+    virtual int getId() const { return id; }
+    virtual const TString& getSymbol() const { return symbol;  }
+    virtual void traverse(TIntermTraverser*);
+    virtual TIntermSymbol* getAsSymbolNode() { return this; }
+protected:
+    int id;
+    TString symbol;
+};
+
+class TIntermConstantUnion : public TIntermTyped {
+public:
+    TIntermConstantUnion(constUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
+    constUnion* getUnionArrayPointer() const { return unionArrayPointer; }
+    void setUnionArrayPointer(constUnion *c) { unionArrayPointer = c; }
+    virtual TIntermConstantUnion* getAsConstantUnion()  { return this; }
+    virtual void traverse(TIntermTraverser* );
+    virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+protected:
+    constUnion *unionArrayPointer;
+};
+
+//
+// Intermediate class for node types that hold operators.
+//
+class TIntermOperator : public TIntermTyped {
+public:
+    TOperator getOp() { return op; }
+    bool modifiesState() const;
+    bool isConstructor() const;
+    virtual bool promote(TInfoSink&) { return true; }
+protected:
+    TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat)), op(o) {}
+    TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}   
+    TOperator op;
+};
+
+//
+// Nodes for all the basic binary math operators.
+//
+class TIntermBinary : public TIntermOperator {
+public:
+    TIntermBinary(TOperator o) : TIntermOperator(o) {}
+    virtual void traverse(TIntermTraverser*);
+    virtual void setLeft(TIntermTyped* n) { left = n; }
+    virtual void setRight(TIntermTyped* n) { right = n; }
+    virtual TIntermTyped* getLeft() const { return left; }
+    virtual TIntermTyped* getRight() const { return right; }
+    virtual TIntermBinary* getAsBinaryNode() { return this; }
+    virtual bool promote(TInfoSink&);
+protected:
+    TIntermTyped* left;
+    TIntermTyped* right;
+};
+
+//
+// Nodes for unary math operators.
+//
+class TIntermUnary : public TIntermOperator {
+public:
+    TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
+    TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
+    virtual void traverse(TIntermTraverser*);
+    virtual void setOperand(TIntermTyped* o) { operand = o; }
+    virtual TIntermTyped* getOperand() { return operand; }
+    virtual bool promote(TInfoSink&);
+protected:
+    TIntermTyped* operand;
+};
+
+typedef TVector<TIntermNode*> TIntermSequence;
+typedef TVector<int> TQualifierList;
+//
+// Nodes that operate on an arbitrary sized set of children.
+//
+class TIntermAggregate : public TIntermOperator {
+public:
+    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
+    TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
+       ~TIntermAggregate() { delete pragmaTable; }
+    virtual TIntermAggregate* getAsAggregate() { return this; }
+    virtual void setOperator(TOperator o) { op = o; }
+    virtual TIntermSequence& getSequence() { return sequence; }
+       virtual void setName(const TString& n) { name = n; }
+    virtual const TString& getName() const { return name; }
+    virtual void traverse(TIntermTraverser*);
+    virtual void setUserDefined() { userDefined = true; }
+    virtual bool isUserDefined() { return userDefined; }
+    virtual TQualifierList& getQualifier() { return qualifier; }
+       void setOptimize(bool o) { optimize = o; }
+       void setDebug(bool d) { debug = d; }
+       bool getOptimize() { return optimize; }
+       bool getDebug() { return debug; }
+       void addToPragmaTable(const TPragmaTable& pTable);
+       const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
+protected:
+       TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
+       TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
+    TIntermSequence sequence;
+    TQualifierList qualifier;
+       TString name;
+    bool userDefined; // used for user defined function names
+       bool optimize;
+       bool debug;
+       TPragmaTable *pragmaTable;
+};
+
+//
+// For if tests.  Simplified since there is no switch statement.
+//
+class TIntermSelection : public TIntermTyped {
+public:
+    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
+        TIntermTyped(TType(EbtVoid)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
+    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
+        TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
+    virtual void traverse(TIntermTraverser*);
+    virtual TIntermNode* getCondition() const { return condition; }
+    virtual TIntermNode* getTrueBlock() const { return trueBlock; }
+    virtual TIntermNode* getFalseBlock() const { return falseBlock; }
+    virtual TIntermSelection* getAsSelectionNode() { return this; }
+protected:
+    TIntermTyped* condition;
+    TIntermNode* trueBlock;
+    TIntermNode* falseBlock;
+};
+
+//
+// For traversing the tree.  User should derive from this, 
+// put their traversal specific data in it, and then pass
+// it to a Traverse method.
+//
+// When using this, just fill in the methods for nodes you want visited.
+// Return false from a pre-visit to skip visiting that node's subtree.
+//
+class TIntermTraverser {
+public:
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+
+    TIntermTraverser() : 
+        visitSymbol(0), 
+        visitConstantUnion(0),
+        visitBinary(0),
+        visitUnary(0),
+        visitSelection(0),
+        visitAggregate(0),
+        visitLoop(0),
+        visitBranch(0),
+        depth(0),
+        preVisit(true),
+        postVisit(false),
+        rightToLeft(false) {}
+
+    void (*visitSymbol)(TIntermSymbol*, TIntermTraverser*);
+    void (*visitConstantUnion)(TIntermConstantUnion*, TIntermTraverser*);
+    bool (*visitBinary)(bool preVisit, TIntermBinary*, TIntermTraverser*);
+    bool (*visitUnary)(bool preVisit, TIntermUnary*, TIntermTraverser*);
+    bool (*visitSelection)(bool preVisit, TIntermSelection*, TIntermTraverser*);
+    bool (*visitAggregate)(bool preVisit, TIntermAggregate*, TIntermTraverser*);
+    bool (*visitLoop)(bool preVisit, TIntermLoop*, TIntermTraverser*);
+    bool (*visitBranch)(bool preVisit, TIntermBranch*,  TIntermTraverser*);
+
+    int  depth;
+    bool preVisit;
+    bool postVisit;
+    bool rightToLeft;
+};
+
+#endif // __INTERMEDIATE_H
diff --git a/glslang/MachineIndependent/InfoSink.cpp b/glslang/MachineIndependent/InfoSink.cpp
new file mode 100644 (file)
index 0000000..b8c1f5f
--- /dev/null
@@ -0,0 +1,107 @@
+//
+//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.
+//
+
+#include "Include/InfoSink.h"
+
+#ifdef _WIN32
+    #include <windows.h>
+#endif
+
+void TInfoSinkBase::append(const char *s)           
+{
+    if (outputStream & EString) {
+        checkMem(strlen(s)); 
+        sink.append(s); 
+    }
+
+#ifdef _WIN32
+    if (outputStream & EDebugger)
+        OutputDebugString(s);
+#endif
+
+    if (outputStream & EStdOut)
+        fprintf(stdout, "%s", s);
+}
+
+void TInfoSinkBase::append(int count, char c)       
+{ 
+    if (outputStream & EString) {
+        checkMem(count);         
+        sink.append(count, c); 
+    }
+
+#ifdef _WIN32
+    if (outputStream & EDebugger) {
+        char str[2];
+        str[0] = c;
+        str[1] = '\0';
+        OutputDebugString(str);
+    }
+#endif
+
+    if (outputStream & EStdOut)
+        fprintf(stdout, "%c", c);
+}
+
+void TInfoSinkBase::append(const TPersistString& t) 
+{ 
+    if (outputStream & EString) {
+        checkMem(t.size());  
+        sink.append(t); 
+    }
+
+#ifdef _WIN32
+    if (outputStream & EDebugger)
+        OutputDebugString(t.c_str());
+#endif
+
+    if (outputStream & EStdOut)
+        fprintf(stdout, "%s", t.c_str());
+}
+
+void TInfoSinkBase::append(const TString& t)
+{ 
+    if (outputStream & EString) {
+        checkMem(t.size());  
+        sink.append(t.c_str()); 
+    }
+
+#ifdef _WIN32
+    if (outputStream & EDebugger)
+        OutputDebugString(t.c_str());
+#endif
+
+    if (outputStream & EStdOut)
+        fprintf(stdout, "%s", t.c_str());
+}
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
new file mode 100644 (file)
index 0000000..3bb8a0c
--- /dev/null
@@ -0,0 +1,962 @@
+//
+//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.
+//
+
+//
+// Create strings that declare built-in definitions, add built-ins that
+// cannot be expressed in the files, and establish mappings between 
+// built-in functions and operators.
+//
+
+#include "../Include/intermediate.h"
+#include "Initialize.h"
+
+void TBuiltIns::initialize()
+{
+    //
+    // Initialize all the built-in strings for parsing.
+    //
+    TString BuiltInFunctions;
+    TString BuiltInFunctionsVertex;
+    TString BuiltInFunctionsFragment;
+    TString StandardVertexVaryings;
+    TString StandardFragmentVaryings;
+    TString StandardVertexAttributes;
+    TString StandardUniforms;
+
+    {
+        //============================================================================
+        //
+        // Prototypes for built-in functions seen by both vertex and fragment shaders.
+        //
+        //============================================================================
+
+        TString& s = BuiltInFunctions;
+
+        //
+        // Angle and Trigonometric Functions.
+        //
+        s.append(TString("float radians(float degrees);"));
+        s.append(TString("vec2  radians(vec2  degrees);"));
+        s.append(TString("vec3  radians(vec3  degrees);"));
+        s.append(TString("vec4  radians(vec4  degrees);"));
+
+        s.append(TString("float degrees(float radians);"));
+        s.append(TString("vec2  degrees(vec2  radians);"));
+        s.append(TString("vec3  degrees(vec3  radians);"));
+        s.append(TString("vec4  degrees(vec4  radians);"));
+
+        s.append(TString("float sin(float angle);"));
+        s.append(TString("vec2  sin(vec2  angle);"));
+        s.append(TString("vec3  sin(vec3  angle);"));
+        s.append(TString("vec4  sin(vec4  angle);"));
+
+        s.append(TString("float cos(float angle);"));
+        s.append(TString("vec2  cos(vec2  angle);"));
+        s.append(TString("vec3  cos(vec3  angle);"));
+        s.append(TString("vec4  cos(vec4  angle);"));
+
+        s.append(TString("float tan(float angle);"));
+        s.append(TString("vec2  tan(vec2  angle);"));
+        s.append(TString("vec3  tan(vec3  angle);"));
+        s.append(TString("vec4  tan(vec4  angle);"));
+
+        s.append(TString("float asin(float x);"));
+        s.append(TString("vec2  asin(vec2  x);"));
+        s.append(TString("vec3  asin(vec3  x);"));
+        s.append(TString("vec4  asin(vec4  x);"));
+
+        s.append(TString("float acos(float x);"));
+        s.append(TString("vec2  acos(vec2  x);"));
+        s.append(TString("vec3  acos(vec3  x);"));
+        s.append(TString("vec4  acos(vec4  x);"));
+
+        s.append(TString("float atan(float y, float x);"));
+        s.append(TString("vec2  atan(vec2  y, vec2  x);"));
+        s.append(TString("vec3  atan(vec3  y, vec3  x);"));
+        s.append(TString("vec4  atan(vec4  y, vec4  x);"));
+
+        s.append(TString("float atan(float y_over_x);"));
+        s.append(TString("vec2  atan(vec2  y_over_x);"));
+        s.append(TString("vec3  atan(vec3  y_over_x);"));
+        s.append(TString("vec4  atan(vec4  y_over_x);"));
+
+        //
+        // Exponential Functions.
+        //
+        s.append(TString("float pow(float x, float y);"));
+        s.append(TString("vec2  pow(vec2  x, vec2  y);"));
+        s.append(TString("vec3  pow(vec3  x, vec3  y);"));
+        s.append(TString("vec4  pow(vec4  x, vec4  y);"));
+
+        s.append(TString("float exp(float x);"));
+        s.append(TString("vec2  exp(vec2  x);"));
+        s.append(TString("vec3  exp(vec3  x);"));
+        s.append(TString("vec4  exp(vec4  x);"));
+
+        s.append(TString("float log(float x);"));
+        s.append(TString("vec2  log(vec2  x);"));
+        s.append(TString("vec3  log(vec3  x);"));
+        s.append(TString("vec4  log(vec4  x);"));
+
+        s.append(TString("float exp2(float x);"));
+        s.append(TString("vec2  exp2(vec2  x);"));
+        s.append(TString("vec3  exp2(vec3  x);"));
+        s.append(TString("vec4  exp2(vec4  x);"));
+
+        s.append(TString("float log2(float x);"));
+        s.append(TString("vec2  log2(vec2  x);"));
+        s.append(TString("vec3  log2(vec3  x);"));
+        s.append(TString("vec4  log2(vec4  x);"));
+
+        s.append(TString("float sqrt(float x);"));
+        s.append(TString("vec2  sqrt(vec2  x);"));
+        s.append(TString("vec3  sqrt(vec3  x);"));
+        s.append(TString("vec4  sqrt(vec4  x);"));
+
+        s.append(TString("float inversesqrt(float x);"));
+        s.append(TString("vec2  inversesqrt(vec2  x);"));
+        s.append(TString("vec3  inversesqrt(vec3  x);"));
+        s.append(TString("vec4  inversesqrt(vec4  x);"));
+
+        //
+        // Common Functions.
+        //
+        s.append(TString("float abs(float x);"));
+        s.append(TString("vec2  abs(vec2  x);"));
+        s.append(TString("vec3  abs(vec3  x);"));
+        s.append(TString("vec4  abs(vec4  x);"));
+
+        s.append(TString("float sign(float x);"));
+        s.append(TString("vec2  sign(vec2  x);"));
+        s.append(TString("vec3  sign(vec3  x);"));
+        s.append(TString("vec4  sign(vec4  x);"));
+
+        s.append(TString("float floor(float x);"));
+        s.append(TString("vec2  floor(vec2  x);"));
+        s.append(TString("vec3  floor(vec3  x);"));
+        s.append(TString("vec4  floor(vec4  x);"));
+
+        s.append(TString("float ceil(float x);"));
+        s.append(TString("vec2  ceil(vec2  x);"));
+        s.append(TString("vec3  ceil(vec3  x);"));
+        s.append(TString("vec4  ceil(vec4  x);"));
+
+        s.append(TString("float fract(float x);"));
+        s.append(TString("vec2  fract(vec2  x);"));
+        s.append(TString("vec3  fract(vec3  x);"));
+        s.append(TString("vec4  fract(vec4  x);"));
+
+        s.append(TString("float mod(float x, float y);"));
+        s.append(TString("vec2  mod(vec2  x, float y);"));
+        s.append(TString("vec3  mod(vec3  x, float y);"));
+        s.append(TString("vec4  mod(vec4  x, float y);"));
+        s.append(TString("vec2  mod(vec2  x, vec2  y);"));
+        s.append(TString("vec3  mod(vec3  x, vec3  y);"));
+        s.append(TString("vec4  mod(vec4  x, vec4  y);"));
+
+        s.append(TString("float min(float x, float y);"));
+        s.append(TString("vec2  min(vec2  x, float y);"));
+        s.append(TString("vec3  min(vec3  x, float y);"));
+        s.append(TString("vec4  min(vec4  x, float y);"));
+        s.append(TString("vec2  min(vec2  x, vec2  y);"));
+        s.append(TString("vec3  min(vec3  x, vec3  y);"));
+        s.append(TString("vec4  min(vec4  x, vec4  y);"));
+
+        s.append(TString("float max(float x, float y);"));
+        s.append(TString("vec2  max(vec2  x, float y);"));
+        s.append(TString("vec3  max(vec3  x, float y);"));
+        s.append(TString("vec4  max(vec4  x, float y);"));
+        s.append(TString("vec2  max(vec2  x, vec2  y);"));
+        s.append(TString("vec3  max(vec3  x, vec3  y);"));
+        s.append(TString("vec4  max(vec4  x, vec4  y);"));
+
+        s.append(TString("float clamp(float x, float minVal, float maxVal);"));
+        s.append(TString("vec2  clamp(vec2  x, float minVal, float maxVal);"));
+        s.append(TString("vec3  clamp(vec3  x, float minVal, float maxVal);"));
+        s.append(TString("vec4  clamp(vec4  x, float minVal, float maxVal);"));
+        s.append(TString("vec2  clamp(vec2  x, vec2  minVal, vec2  maxVal);"));
+        s.append(TString("vec3  clamp(vec3  x, vec3  minVal, vec3  maxVal);"));
+        s.append(TString("vec4  clamp(vec4  x, vec4  minVal, vec4  maxVal);"));
+
+        s.append(TString("float mix(float x, float y, float a);"));
+        s.append(TString("vec2  mix(vec2  x, vec2  y, float a);"));
+        s.append(TString("vec3  mix(vec3  x, vec3  y, float a);"));
+        s.append(TString("vec4  mix(vec4  x, vec4  y, float a);"));
+        s.append(TString("vec2  mix(vec2  x, vec2  y, vec2  a);"));
+        s.append(TString("vec3  mix(vec3  x, vec3  y, vec3  a);"));
+        s.append(TString("vec4  mix(vec4  x, vec4  y, vec4  a);"));
+
+        s.append(TString("float step(float edge, float x);"));
+        s.append(TString("vec2  step(vec2  edge, vec2  x);"));
+        s.append(TString("vec3  step(vec3  edge, vec3  x);"));
+        s.append(TString("vec4  step(vec4  edge, vec4  x);"));
+        s.append(TString("vec2  step(float edge, vec2  x);"));
+        s.append(TString("vec3  step(float edge, vec3  x);"));
+        s.append(TString("vec4  step(float edge, vec4  x);"));
+
+        s.append(TString("float smoothstep(float edge0, float edge1, float x);"));
+        s.append(TString("vec2  smoothstep(vec2  edge0, vec2  edge1, vec2  x);"));
+        s.append(TString("vec3  smoothstep(vec3  edge0, vec3  edge1, vec3  x);"));
+        s.append(TString("vec4  smoothstep(vec4  edge0, vec4  edge1, vec4  x);"));
+        s.append(TString("vec2  smoothstep(float edge0, float edge1, vec2  x);"));
+        s.append(TString("vec3  smoothstep(float edge0, float edge1, vec3  x);"));
+        s.append(TString("vec4  smoothstep(float edge0, float edge1, vec4  x);"));
+
+        //
+        // Geometric Functions.
+        //
+        s.append(TString("float length(float x);"));
+        s.append(TString("float length(vec2  x);"));
+        s.append(TString("float length(vec3  x);"));
+        s.append(TString("float length(vec4  x);"));
+
+        s.append(TString("float distance(float p0, float p1);"));
+        s.append(TString("float distance(vec2  p0, vec2  p1);"));
+        s.append(TString("float distance(vec3  p0, vec3  p1);"));
+        s.append(TString("float distance(vec4  p0, vec4  p1);"));
+
+        s.append(TString("float dot(float x, float y);"));
+        s.append(TString("float dot(vec2  x, vec2  y);"));
+        s.append(TString("float dot(vec3  x, vec3  y);"));
+        s.append(TString("float dot(vec4  x, vec4  y);"));
+
+        s.append(TString("vec3 cross(vec3 x, vec3 y);"));
+        s.append(TString("float normalize(float x);"));
+        s.append(TString("vec2  normalize(vec2  x);"));
+        s.append(TString("vec3  normalize(vec3  x);"));
+        s.append(TString("vec4  normalize(vec4  x);"));
+
+        s.append(TString("float faceforward(float N, float I, float Nref);"));
+        s.append(TString("vec2  faceforward(vec2  N, vec2  I, vec2  Nref);"));
+        s.append(TString("vec3  faceforward(vec3  N, vec3  I, vec3  Nref);"));
+        s.append(TString("vec4  faceforward(vec4  N, vec4  I, vec4  Nref);"));
+
+        s.append(TString("float reflect(float I, float N);"));
+        s.append(TString("vec2  reflect(vec2  I, vec2  N);"));
+        s.append(TString("vec3  reflect(vec3  I, vec3  N);"));
+        s.append(TString("vec4  reflect(vec4  I, vec4  N);"));
+
+        s.append(TString("float refract(float I, float N, float eta);"));
+        s.append(TString("vec2  refract(vec2  I, vec2  N, float eta);"));
+        s.append(TString("vec3  refract(vec3  I, vec3  N, float eta);"));
+        s.append(TString("vec4  refract(vec4  I, vec4  N, float eta);"));
+
+        //
+        // Matrix Functions.
+        //
+        s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);"));
+        s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
+        s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
+
+        //
+        // Vector relational functions.
+        //
+        s.append(TString("bvec2 lessThan(vec2 x, vec2 y);"));
+        s.append(TString("bvec3 lessThan(vec3 x, vec3 y);"));
+        s.append(TString("bvec4 lessThan(vec4 x, vec4 y);"));
+
+        s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);"));
+        s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);"));
+        s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);"));
+
+        s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);"));
+        s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);"));
+        s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);"));
+
+        s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);"));
+        s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);"));
+        s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);"));
+
+        s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);"));
+        s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);"));
+        s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);"));
+
+        s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);"));
+        s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);"));
+        s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);"));
+
+        s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);"));
+        s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);"));
+        s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);"));
+
+        s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);"));
+        s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);"));
+        s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);"));
+
+        s.append(TString("bvec2 equal(vec2 x, vec2 y);"));
+        s.append(TString("bvec3 equal(vec3 x, vec3 y);"));
+        s.append(TString("bvec4 equal(vec4 x, vec4 y);"));
+
+        s.append(TString("bvec2 equal(ivec2 x, ivec2 y);"));
+        s.append(TString("bvec3 equal(ivec3 x, ivec3 y);"));
+        s.append(TString("bvec4 equal(ivec4 x, ivec4 y);"));
+
+        s.append(TString("bvec2 equal(bvec2 x, bvec2 y);"));
+        s.append(TString("bvec3 equal(bvec3 x, bvec3 y);"));
+        s.append(TString("bvec4 equal(bvec4 x, bvec4 y);"));
+
+        s.append(TString("bvec2 notEqual(vec2 x, vec2 y);"));
+        s.append(TString("bvec3 notEqual(vec3 x, vec3 y);"));
+        s.append(TString("bvec4 notEqual(vec4 x, vec4 y);"));
+
+        s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);"));
+        s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);"));
+        s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);"));
+
+        s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);"));
+        s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);"));
+        s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);"));
+
+        s.append(TString("bool any(bvec2 x);"));
+        s.append(TString("bool any(bvec3 x);"));
+        s.append(TString("bool any(bvec4 x);"));
+
+        s.append(TString("bool all(bvec2 x);"));
+        s.append(TString("bool all(bvec3 x);"));
+        s.append(TString("bool all(bvec4 x);"));
+
+        s.append(TString("bvec2 not(bvec2 x);"));
+        s.append(TString("bvec3 not(bvec3 x);"));
+        s.append(TString("bvec4 not(bvec4 x);"));
+
+        //
+        // Texture Functions.
+        //
+        s.append(TString("vec4 texture1D(sampler1D sampler, float coord);"));
+        s.append(TString("vec4 texture1DProj(sampler1D sampler, vec2 coord);"));
+        s.append(TString("vec4 texture1DProj(sampler1D sampler, vec4 coord);"));
+
+        s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
+        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
+
+        s.append(TString("vec4 texture3D(sampler3D sampler, vec3 coord);"));
+        s.append(TString("vec4 texture3DProj(sampler3D sampler, vec4 coord);"));
+
+        s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
+
+        s.append(TString("vec4 shadow1D(sampler1DShadow sampler, vec3 coord);"));
+
+        s.append(TString("vec4 shadow2D(sampler2DShadow sampler, vec3 coord);"));
+
+        s.append(TString("vec4 shadow1DProj(sampler1DShadow sampler, vec4 coord);"));
+
+        s.append(TString("vec4 shadow2DProj(sampler2DShadow sampler, vec4 coord);"));
+
+        // ARB_texture_rectangle
+        s.append(TString("vec4 texture2DRect(sampler2DRect sampler, vec2 coord);"));
+        s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec3 coord);"));
+        s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec4 coord);"));
+        s.append(TString("vec4 shadow2DRect(sampler2DRectShadow sampler, vec3 coord);"));
+        s.append(TString("vec4 shadow2DRectProj(sampler2DRectShadow sampler, vec4 coord);"));
+
+        //
+        // Noise functions.
+        //
+        s.append(TString("float noise1(float x);"));
+        s.append(TString("float noise1(vec2  x);"));
+        s.append(TString("float noise1(vec3  x);"));
+        s.append(TString("float noise1(vec4  x);"));
+
+        s.append(TString("vec2 noise2(float x);"));
+        s.append(TString("vec2 noise2(vec2  x);"));
+        s.append(TString("vec2 noise2(vec3  x);"));
+        s.append(TString("vec2 noise2(vec4  x);"));
+
+        s.append(TString("vec3 noise3(float x);"));
+        s.append(TString("vec3 noise3(vec2  x);"));
+        s.append(TString("vec3 noise3(vec3  x);"));
+        s.append(TString("vec3 noise3(vec4  x);"));
+
+        s.append(TString("vec4 noise4(float x);"));
+        s.append(TString("vec4 noise4(vec2  x);"));
+        s.append(TString("vec4 noise4(vec3  x);"));
+        s.append(TString("vec4 noise4(vec4  x);"));
+
+        s.append(TString("\n"));
+    }
+    {
+        //============================================================================
+        //
+        // Prototypes for built-in functions seen by vertex shaders only.
+        //
+        //============================================================================
+
+        TString& s = BuiltInFunctionsVertex;
+
+        //
+        // Geometric Functions.
+        //
+        s.append(TString("vec4 ftransform();"));
+
+        //
+        // Texture Functions.
+        //
+        s.append(TString("vec4 texture1DLod(sampler1D sampler, float coord, float lod);"));
+        s.append(TString("vec4 texture1DProjLod(sampler1D sampler, vec2 coord, float lod);"));
+        s.append(TString("vec4 texture1DProjLod(sampler1D sampler, vec4 coord, float lod);"));
+
+        s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
+        s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
+        s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
+
+        s.append(TString("vec4 texture3DLod(sampler3D sampler, vec3 coord, float lod);"));
+        s.append(TString("vec4 texture3DProjLod(sampler3D sampler, vec4 coord, float lod);"));
+        s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+
+        s.append(TString("vec4 shadow1DLod(sampler1DShadow sampler, vec3 coord, float lod);"));
+        s.append(TString("vec4 shadow2DLod(sampler2DShadow sampler, vec3 coord, float lod);"));
+        s.append(TString("vec4 shadow1DProjLod(sampler1DShadow sampler, vec4 coord, float lod);"));
+        s.append(TString("vec4 shadow2DProjLod(sampler2DShadow sampler, vec4 coord, float lod);"));
+
+               s.append(TString("\n"));
+    }
+    {
+        //============================================================================
+        //
+        // Prototypes for built-in functions seen by fragment shaders only.
+        //
+        //============================================================================
+
+        TString& s = BuiltInFunctionsFragment;
+
+        //
+        // Texture Functions.
+        //
+               s.append(TString("vec4 texture1D(sampler1D sampler, float coord, float bias);"));
+        s.append(TString("vec4 texture1DProj(sampler1D sampler, vec2 coord, float bias);"));
+        s.append(TString("vec4 texture1DProj(sampler1D sampler, vec4 coord, float bias);"));
+
+        s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
+        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
+        s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
+
+               s.append(TString("vec4 texture3D(sampler3D sampler, vec3 coord, float bias);"));
+        s.append(TString("vec4 texture3DProj(sampler3D sampler, vec4 coord, float bias);"));
+        s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
+        
+               s.append(TString("vec4 shadow1D(sampler1DShadow sampler, vec3 coord, float bias);"));
+        s.append(TString("vec4 shadow2D(sampler2DShadow sampler, vec3 coord, float bias);"));
+        s.append(TString("vec4 shadow1DProj(sampler1DShadow sampler, vec4 coord, float bias);"));
+        s.append(TString("vec4 shadow2DProj(sampler2DShadow sampler, vec4 coord, float bias);"));
+
+               s.append(TString("float dFdx(float p);"));
+        s.append(TString("vec2  dFdx(vec2  p);"));
+        s.append(TString("vec3  dFdx(vec3  p);"));
+        s.append(TString("vec4  dFdx(vec4  p);"));
+
+        s.append(TString("float dFdy(float p);"));
+        s.append(TString("vec2  dFdy(vec2  p);"));
+        s.append(TString("vec3  dFdy(vec3  p);"));
+        s.append(TString("vec4  dFdy(vec4  p);"));
+
+        s.append(TString("float fwidth(float p);"));
+        s.append(TString("vec2  fwidth(vec2  p);"));
+        s.append(TString("vec3  fwidth(vec3  p);"));
+        s.append(TString("vec4  fwidth(vec4  p);"));
+
+               s.append(TString("\n"));
+    }
+    {
+        //============================================================================
+        //
+        // Standard Uniforms
+        //
+        //============================================================================
+
+        TString& s = StandardUniforms;
+       
+
+        //
+        // OpenGL'uniform' state.  Page numbers are in reference to version
+        // 1.4 of the OpenGL specification.
+        //
+
+        //
+        // Matrix state. p. 31, 32, 37, 39, 40.
+        //
+        s.append(TString("uniform mat4  gl_ModelViewMatrix;"));
+        s.append(TString("uniform mat4  gl_ProjectionMatrix;"));
+        s.append(TString("uniform mat4  gl_ModelViewProjectionMatrix;"));
+
+        //
+        // Derived matrix state that provides inverse and transposed versions
+        // of the matrices above.
+        //
+        s.append(TString("uniform mat3  gl_NormalMatrix;"));
+
+        s.append(TString("uniform mat4  gl_ModelViewMatrixInverse;"));
+        s.append(TString("uniform mat4  gl_ProjectionMatrixInverse;"));
+        s.append(TString("uniform mat4  gl_ModelViewProjectionMatrixInverse;"));
+
+        s.append(TString("uniform mat4  gl_ModelViewMatrixTranspose;"));
+        s.append(TString("uniform mat4  gl_ProjectionMatrixTranspose;"));
+        s.append(TString("uniform mat4  gl_ModelViewProjectionMatrixTranspose;"));
+
+        s.append(TString("uniform mat4  gl_ModelViewMatrixInverseTranspose;"));
+        s.append(TString("uniform mat4  gl_ProjectionMatrixInverseTranspose;"));
+        s.append(TString("uniform mat4  gl_ModelViewProjectionMatrixInverseTranspose;"));
+
+        //
+        // Normal scaling p. 39.
+        //
+        s.append(TString("uniform float gl_NormalScale;"));
+
+        //
+        // Depth range in window coordinates, p. 33
+        //
+        s.append(TString("struct gl_DepthRangeParameters {"));
+        s.append(TString("    float near;"));        // n
+        s.append(TString("    float far;"));         // f
+        s.append(TString("    float diff;"));        // f - n
+        s.append(TString("};"));
+        s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
+
+
+        //
+        // Point Size, p. 66, 67.
+        //
+        s.append(TString("struct gl_PointParameters {"));
+        s.append(TString("    float size;"));
+        s.append(TString("    float sizeMin;"));
+        s.append(TString("    float sizeMax;"));
+        s.append(TString("    float fadeThresholdSize;"));
+        s.append(TString("    float distanceConstantAttenuation;"));
+        s.append(TString("    float distanceLinearAttenuation;"));
+        s.append(TString("    float distanceQuadraticAttenuation;"));
+        s.append(TString("};"));
+         
+        s.append(TString("uniform gl_PointParameters gl_Point;"));
+
+        //
+        // Material State p. 50, 55.
+        //
+        s.append(TString("struct gl_MaterialParameters {"));
+        s.append(TString("    vec4  emission;"));    // Ecm
+        s.append(TString("    vec4  ambient;"));     // Acm
+        s.append(TString("    vec4  diffuse;"));     // Dcm
+        s.append(TString("    vec4  specular;"));    // Scm
+        s.append(TString("    float shininess;"));   // Srm
+        s.append(TString("};"));
+        s.append(TString("uniform gl_MaterialParameters  gl_FrontMaterial;"));
+        s.append(TString("uniform gl_MaterialParameters  gl_BackMaterial;"));
+
+        //
+        // Light State p 50, 53, 55.
+        //
+
+        s.append(TString("struct gl_LightSourceParameters {"));
+        s.append(TString("    vec4  ambient;"));             // Acli
+        s.append(TString("    vec4  diffuse;"));             // Dcli
+        s.append(TString("    vec4  specular;"));            // Scli
+        s.append(TString("    vec4  position;"));            // Ppli
+        s.append(TString("    vec4  halfVector;"));          // Derived: Hi
+        s.append(TString("    vec3  spotDirection;"));       // Sdli
+        s.append(TString("    float spotExponent;"));        // Srli
+        s.append(TString("    float spotCutoff;"));          // Crli
+                                                             // (range: [0.0,90.0], 180.0)
+        s.append(TString("    float spotCosCutoff;"));       // Derived: cos(Crli)
+                                                             // (range: [1.0,0.0],-1.0)
+        s.append(TString("    float constantAttenuation;")); // K0
+        s.append(TString("    float linearAttenuation;"));   // K1
+        s.append(TString("    float quadraticAttenuation;"));// K2
+        s.append(TString("};"));
+
+
+        s.append(TString("struct gl_LightModelParameters {"));
+        s.append(TString("    vec4  ambient;"));       // Acs
+        s.append(TString("};"));
+
+        s.append(TString("uniform gl_LightModelParameters  gl_LightModel;"));
+
+        //
+        // Derived state from products of light and material.
+        //
+
+        s.append(TString("struct gl_LightModelProducts {"));
+        s.append(TString("    vec4  sceneColor;"));     // Derived. Ecm + Acm * Acs
+        s.append(TString("};"));
+
+        s.append(TString("uniform gl_LightModelProducts gl_FrontLightModelProduct;"));
+        s.append(TString("uniform gl_LightModelProducts gl_BackLightModelProduct;"));
+
+        s.append(TString("struct gl_LightProducts {"));
+        s.append(TString("    vec4  ambient;"));        // Acm * Acli
+        s.append(TString("    vec4  diffuse;"));        // Dcm * Dcli
+        s.append(TString("    vec4  specular;"));       // Scm * Scli
+        s.append(TString("};"));
+
+
+
+
+        //
+        // Fog p. 161
+        //
+        s.append(TString("struct gl_FogParameters {"));
+        s.append(TString("    vec4  color;"));
+        s.append(TString("    float density;"));
+        s.append(TString("    float start;"));
+        s.append(TString("    float end;"));
+        s.append(TString("    float scale;"));   //  1 / (gl_FogEnd - gl_FogStart)
+        s.append(TString("};"));
+         
+        s.append(TString("uniform gl_FogParameters gl_Fog;"));
+
+        s.append(TString("\n"));
+    }
+    {
+        //============================================================================
+        //
+        // Vertex attributes, p. 19.
+        //
+        //============================================================================
+
+        TString& s = StandardVertexAttributes;
+
+        s.append(TString("attribute vec4  gl_Color;"));
+        s.append(TString("attribute vec4  gl_SecondaryColor;"));
+        s.append(TString("attribute vec3  gl_Normal;"));
+        s.append(TString("attribute vec4  gl_Vertex;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord0;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord1;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord2;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord3;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord4;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord5;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord6;"));
+        s.append(TString("attribute vec4  gl_MultiTexCoord7;"));
+        s.append(TString("attribute float gl_FogCoord;"));
+
+        s.append(TString("\n"));
+    }
+    {
+        //============================================================================
+        //
+        // Define the output varying interface from the vertex shader.
+        //
+        //============================================================================
+
+        TString& s = StandardVertexVaryings;
+
+        s.append(TString("varying vec4  gl_FrontColor;"));
+        s.append(TString("varying vec4  gl_BackColor;"));
+        s.append(TString("varying vec4  gl_FrontSecondaryColor;"));
+        s.append(TString("varying vec4  gl_BackSecondaryColor;"));
+        s.append(TString("varying vec4  gl_TexCoord[];"));
+        s.append(TString("varying float gl_FogFragCoord;"));
+
+        s.append(TString("\n"));
+    }
+    {
+        //============================================================================
+        //
+        // Define the input varying interface to the fragment shader.
+        //
+        //============================================================================
+
+        TString& s = StandardFragmentVaryings;
+
+        s.append(TString("varying vec4  gl_Color;"));
+        s.append(TString("varying vec4  gl_SecondaryColor;"));
+        s.append(TString("varying vec4  gl_TexCoord[];"));
+        s.append(TString("varying float gl_FogFragCoord;"));
+
+        s.append(TString("\n"));
+    }
+
+    builtInStrings[EShLangFragment].push_back(BuiltInFunctions.c_str());
+    builtInStrings[EShLangFragment].push_back(BuiltInFunctionsFragment);
+    builtInStrings[EShLangFragment].push_back(StandardUniforms);
+    builtInStrings[EShLangFragment].push_back(StandardFragmentVaryings);
+
+    builtInStrings[EShLangVertex].push_back(BuiltInFunctions);
+    builtInStrings[EShLangVertex].push_back(BuiltInFunctionsVertex);
+    builtInStrings[EShLangVertex].push_back(StandardVertexVaryings);
+    builtInStrings[EShLangVertex].push_back(StandardVertexAttributes);
+    builtInStrings[EShLangVertex].push_back(StandardUniforms);
+}
+
+
+void TBuiltIns::initialize(const TBuiltInResource &resources)
+{
+    //
+    // Initialize all the built-in strings for parsing.
+    //
+    TString StandardUniforms;    
+
+    {
+        //============================================================================
+        //
+        // Standard Uniforms
+        //
+        //============================================================================
+
+        TString& s = StandardUniforms;
+       
+        //
+        // Implementation dependent constants.  The example values below
+        // are the minimum values allowed for these maximums.
+        //
+        char builtInConstant[80];
+        sprintf(builtInConstant, "const int  gl_MaxLights = %d;", resources.maxLights); // GL 1.0
+        s.append(TString(builtInConstant));                            
+        
+        sprintf(builtInConstant, "const int  gl_MaxClipPlanes = %d;", resources.maxClipPlanes);  // GL 1.0
+        s.append(TString(builtInConstant));
+        
+        sprintf(builtInConstant, "const int  gl_MaxTextureUnits = %d;", resources.maxTextureUnits); // GL 1.2
+        s.append(TString(builtInConstant));
+        
+        sprintf(builtInConstant, "const int  gl_MaxTextureCoords = %d;", resources.maxTextureCoords); // ARB_fragment_program
+        s.append(TString(builtInConstant));
+        
+        sprintf(builtInConstant, "const int  gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); // ARB_vertex_shader
+        s.append(TString(builtInConstant));
+        
+        sprintf(builtInConstant, "const int  gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents); // ARB_vertex_shader
+        s.append(TString(builtInConstant));       
+        
+        sprintf(builtInConstant, "const int  gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats); // ARB_vertex_shader
+        s.append(TString(builtInConstant));        
+        
+        sprintf(builtInConstant, "const int  gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits); // ARB_vertex_shader
+        s.append(TString(builtInConstant));        
+        
+        sprintf(builtInConstant, "const int  gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits); // ARB_vertex_shader
+        s.append(TString(builtInConstant));        
+        
+        sprintf(builtInConstant, "const int  gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits); // ARB_fragment_shader
+        s.append(TString(builtInConstant));
+        
+        sprintf(builtInConstant, "const int  gl_MaxFragmentUniformComponents = %d;", resources.maxFragmentUniformComponents); // ARB_fragment_shader
+        s.append(TString(builtInConstant));
+        
+        sprintf(builtInConstant, "const int  gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers); // proposed ARB_draw_buffers
+        s.append(TString(builtInConstant));
+
+        //
+        // OpenGL'uniform' state.  Page numbers are in reference to version
+        // 1.4 of the OpenGL specification.
+        //
+
+        //
+        // Matrix state. p. 31, 32, 37, 39, 40.
+        //
+        s.append(TString("uniform mat4  gl_TextureMatrix[gl_MaxTextureCoords];"));
+
+        //
+        // Derived matrix state that provides inverse and transposed versions
+        // of the matrices above.
+        //
+        s.append(TString("uniform mat4  gl_TextureMatrixInverse[gl_MaxTextureCoords];"));
+
+        s.append(TString("uniform mat4  gl_TextureMatrixTranspose[gl_MaxTextureCoords];"));
+
+        s.append(TString("uniform mat4  gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];"));
+
+        //
+        // Clip planes p. 42.
+        //
+        s.append(TString("uniform vec4  gl_ClipPlane[gl_MaxClipPlanes];"));
+
+        //
+        // Light State p 50, 53, 55.
+        //
+        s.append(TString("uniform gl_LightSourceParameters  gl_LightSource[gl_MaxLights];"));
+
+        //
+        // Derived state from products of light.
+        //
+        s.append(TString("uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];"));
+        s.append(TString("uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];"));
+
+        //
+        // Textureg Environment and Generation, p. 152, p. 40-42.
+        //
+        s.append(TString("uniform vec4  gl_TextureEnvColor[gl_MaxTextureImageUnits];"));
+        s.append(TString("uniform vec4  gl_EyePlaneS[gl_MaxTextureCoords];"));
+        s.append(TString("uniform vec4  gl_EyePlaneT[gl_MaxTextureCoords];"));
+        s.append(TString("uniform vec4  gl_EyePlaneR[gl_MaxTextureCoords];"));
+        s.append(TString("uniform vec4  gl_EyePlaneQ[gl_MaxTextureCoords];"));
+        s.append(TString("uniform vec4  gl_ObjectPlaneS[gl_MaxTextureCoords];"));
+        s.append(TString("uniform vec4  gl_ObjectPlaneT[gl_MaxTextureCoords];"));
+        s.append(TString("uniform vec4  gl_ObjectPlaneR[gl_MaxTextureCoords];"));
+        s.append(TString("uniform vec4  gl_ObjectPlaneQ[gl_MaxTextureCoords];"));
+
+        s.append(TString("\n"));
+    }
+
+    builtInStrings[EShLangFragment].push_back(StandardUniforms);
+    builtInStrings[EShLangVertex].push_back(StandardUniforms);
+}
+
+void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable)
+{
+    //
+    // First, insert some special built-in variables that are not in 
+    // the built-in header files.
+    //
+    switch(language) {
+
+    case EShLangFragment: {
+            symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool,  EvqFace, 1)));
+            symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"),   TType(EbtFloat, EvqFragCoord,   4)));
+            symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"),   TType(EbtFloat, EvqFragColor,   4)));
+            symbolTable.insert(*new TVariable(NewPoolTString("gl_FragDepth"),   TType(EbtFloat, EvqFragDepth,   1)));
+
+        }
+        break;
+
+    case EShLangVertex:
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"),    TType(EbtFloat, EvqPosition,    4)));
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"),   TType(EbtFloat, EvqPointSize,   1)));
+        symbolTable.insert(*new TVariable(NewPoolTString("gl_ClipVertex"),  TType(EbtFloat, EvqClipVertex,  4)));
+        break;
+       default: break;
+    }
+
+    //
+    // Next, identify which built-ins from the already loaded headers have
+    // a mapping to an operator.  Those that are not identified as such are
+    // expected to be resolved through a library of functions, versus as
+    // operations.
+    //
+    symbolTable.relateToOperator("not",              EOpVectorLogicalNot);
+
+    symbolTable.relateToOperator("matrixCompMult",   EOpMul);
+    symbolTable.relateToOperator("mod",              EOpMod);
+
+    symbolTable.relateToOperator("equal",            EOpVectorEqual);
+    symbolTable.relateToOperator("notEqual",         EOpVectorNotEqual);
+    symbolTable.relateToOperator("lessThan",         EOpLessThan);
+    symbolTable.relateToOperator("greaterThan",      EOpGreaterThan);
+    symbolTable.relateToOperator("lessThanEqual",    EOpLessThanEqual);
+    symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual);
+    
+    symbolTable.relateToOperator("radians",      EOpRadians);
+    symbolTable.relateToOperator("degrees",      EOpDegrees);
+    symbolTable.relateToOperator("sin",          EOpSin);
+    symbolTable.relateToOperator("cos",          EOpCos);
+    symbolTable.relateToOperator("tan",          EOpTan);
+    symbolTable.relateToOperator("asin",         EOpAsin);
+    symbolTable.relateToOperator("acos",         EOpAcos);
+    symbolTable.relateToOperator("atan",         EOpAtan);
+
+    symbolTable.relateToOperator("pow",          EOpPow);
+    symbolTable.relateToOperator("exp2",         EOpExp2);
+    symbolTable.relateToOperator("log",          EOpLog);
+    symbolTable.relateToOperator("exp",          EOpExp);
+    symbolTable.relateToOperator("log2",         EOpLog2);
+    symbolTable.relateToOperator("sqrt",         EOpSqrt);
+    symbolTable.relateToOperator("inversesqrt",  EOpInverseSqrt);
+
+    symbolTable.relateToOperator("abs",          EOpAbs);
+    symbolTable.relateToOperator("sign",         EOpSign);
+    symbolTable.relateToOperator("floor",        EOpFloor);
+    symbolTable.relateToOperator("ceil",         EOpCeil);
+    symbolTable.relateToOperator("fract",        EOpFract);
+    symbolTable.relateToOperator("min",          EOpMin);
+    symbolTable.relateToOperator("max",          EOpMax);
+    symbolTable.relateToOperator("clamp",        EOpClamp);
+    symbolTable.relateToOperator("mix",          EOpMix);
+    symbolTable.relateToOperator("step",         EOpStep);
+    symbolTable.relateToOperator("smoothstep",   EOpSmoothStep);
+
+    symbolTable.relateToOperator("length",       EOpLength);
+    symbolTable.relateToOperator("distance",     EOpDistance);
+    symbolTable.relateToOperator("dot",          EOpDot);
+    symbolTable.relateToOperator("cross",        EOpCross);
+    symbolTable.relateToOperator("normalize",    EOpNormalize);
+    symbolTable.relateToOperator("forward",      EOpFaceForward);
+    symbolTable.relateToOperator("reflect",      EOpReflect);
+    symbolTable.relateToOperator("refract",      EOpRefract);
+    
+    symbolTable.relateToOperator("any",          EOpAny);
+    symbolTable.relateToOperator("all",          EOpAll);
+
+    switch(language) {
+
+    case EShLangVertex:
+        break;
+    
+    case EShLangFragment:
+        symbolTable.relateToOperator("dFdx",         EOpDPdx);             
+        symbolTable.relateToOperator("dFdy",         EOpDPdy);             
+        symbolTable.relateToOperator("fwidth",       EOpFwidth);
+
+        break;
+
+    case EShLangPack:
+    case EShLangUnpack:
+        symbolTable.relateToOperator("itof",         EOpItof);
+        symbolTable.relateToOperator("ftoi",         EOpFtoi);
+        symbolTable.relateToOperator("skipPixels",   EOpSkipPixels);
+        symbolTable.relateToOperator("readInput",    EOpReadInput);
+        symbolTable.relateToOperator("writePixel",   EOpWritePixel);
+        symbolTable.relateToOperator("bitmapLSB",    EOpBitmapLsb);
+        symbolTable.relateToOperator("bitmapMSB",    EOpBitmapMsb);
+        symbolTable.relateToOperator("writeOutput",  EOpWriteOutput);
+        symbolTable.relateToOperator("readPixel",    EOpReadPixel);
+        break;
+       default: assert(false && "Language not supported");
+    }
+}
+
+void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources)
+{
+    //
+    // First, insert some special built-in variables that are not in 
+    // the built-in header files.
+    //
+    switch(language) {
+
+    case EShLangFragment: {
+            // Set up gl_FragData.  The array size.
+            TType fragData(EbtFloat, EvqFragColor,   4, false, true);
+            fragData.setArraySize(resources.maxDrawBuffers);
+            symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"),    fragData));
+        }
+        break;
+
+       default: break;
+    }
+}
+
+char* GetPreprocessorBuiltinString()
+{
+    static char *PreprocessorBuiltinString = "#define GL_ARB_texture_rectangle 1\n"
+                                             "#define GL_3DL_array_objects 1\n";
+
+    return PreprocessorBuiltinString;
+}
diff --git a/glslang/MachineIndependent/Initialize.h b/glslang/MachineIndependent/Initialize.h
new file mode 100644 (file)
index 0000000..b4f4a03
--- /dev/null
@@ -0,0 +1,63 @@
+//
+//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.
+//
+
+#ifndef _INITIALIZE_INCLUDED_
+#define _INITIALIZE_INCLUDED_
+
+#include "Include/ResourceLimits.h"
+#include "../Include/Common.h"
+#include "../Include/ShHandle.h"
+#include "SymbolTable.h"
+
+typedef TVector<TString> TBuiltInStrings;
+
+class TBuiltIns {
+public:
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    void initialize();
+       void initialize(const TBuiltInResource& resources);
+    TBuiltInStrings* getBuiltInStrings() { return builtInStrings; }
+protected:
+    TBuiltInStrings builtInStrings[EShLangCount];
+};
+
+void IdentifyBuiltIns(EShLanguage, TSymbolTable&);
+void IdentifyBuiltIns(EShLanguage, TSymbolTable&, const TBuiltInResource &resources);
+bool GenerateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink&, TSymbolTable*, EShLanguage language = EShLangCount);
+bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource *resources, TSymbolTable*);
+char* GetPreprocessorBuiltinString();
+extern "C" int InitPreprocessor(void);
+extern "C" int FinalizePreprocessor(void);
+
+#endif // _INITIALIZE_INCLUDED_
diff --git a/glslang/MachineIndependent/IntermTraverse.cpp b/glslang/MachineIndependent/IntermTraverse.cpp
new file mode 100644 (file)
index 0000000..8b379db
--- /dev/null
@@ -0,0 +1,243 @@
+//
+//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.
+//
+
+#include "../Include/intermediate.h"
+
+//
+// Traverse the intermediate representation tree, and
+// call a node type specific function for each node.
+// Done recursively through the member function Traverse().
+// Node types can be skipped if their function to call is 0,
+// but their subtree will still be traversed.
+// Nodes with children can have their whole subtree skipped
+// if preVisit is turned on and the type specific function
+// returns false.
+//
+// preVisit, postVisit, and rightToLeft control what order
+// nodes are visited in.
+//
+
+//
+// Traversal functions for terminals are straighforward....
+//
+void TIntermSymbol::traverse(TIntermTraverser* it)
+{
+    if (it->visitSymbol)
+        it->visitSymbol(this, it);
+}
+
+void TIntermConstantUnion::traverse(TIntermTraverser* it)
+{
+    if (it->visitConstantUnion)
+        it->visitConstantUnion(this, it);
+}
+
+//
+// Traverse a binary node.
+//
+void TIntermBinary::traverse(TIntermTraverser* it)
+{
+    bool visit = true;
+
+    //
+    // visit the node before children if pre-visiting.
+    //
+    if (it->preVisit && it->visitBinary)
+        visit = it->visitBinary(true, this, it);
+    
+    //
+    // Visit the children, in the right order.
+    //
+    if (visit) {
+        ++it->depth;
+        if (it->rightToLeft) {
+            if (right)
+                right->traverse(it);
+            if (left)
+                left->traverse(it);
+        } else {
+            if (left)
+                left->traverse(it);
+            if (right)
+                right->traverse(it);
+        }
+        --it->depth;
+    }
+
+    //
+    // Visit the node after the children, if requested and the traversal
+    // hasn't been cancelled yet.
+    //
+    if (visit && it->postVisit && it->visitBinary)
+        it->visitBinary(false, this, it);
+}
+
+//
+// Traverse a unary node.  Same comments in binary node apply here.
+//
+void TIntermUnary::traverse(TIntermTraverser* it)
+{
+    bool visit = true;
+
+    if (it->preVisit && it->visitUnary)
+        visit = it->visitUnary(true, this, it);
+
+    if (visit) {
+        ++it->depth;
+        operand->traverse(it);
+        --it->depth;
+    }
+    
+    if (visit && it->postVisit && it->visitUnary)
+        it->visitUnary(false, this, it);
+}
+
+//
+// Traverse an aggregate node.  Same comments in binary node apply here.
+//
+void TIntermAggregate::traverse(TIntermTraverser* it)
+{
+    bool visit = true;
+    
+    if (it->preVisit && it->visitAggregate)
+        visit = it->visitAggregate(true, this, it);
+    
+    if (visit) {
+        ++it->depth;
+
+        TIntermSequence::iterator sit;
+        if (it->rightToLeft) {
+            sit = sequence.end();
+            while (sit != sequence.begin()) {
+                --sit;
+                (*sit)->traverse(it);
+            }
+        } else {
+            for (sit = sequence.begin(); sit != sequence.end(); ++sit)
+                (*sit)->traverse(it);
+        }
+        
+        --it->depth;
+    }
+
+    if (visit && it->postVisit && it->visitAggregate)
+        it->visitAggregate(false, this, it);
+}
+
+//
+// Traverse a selection node.  Same comments in binary node apply here.
+//
+void TIntermSelection::traverse(TIntermTraverser* it)
+{
+    bool visit = true;
+
+    if (it->preVisit && it->visitSelection)
+        visit = it->visitSelection(true, this, it);
+    
+    if (visit) {
+        ++it->depth;
+        if (it->rightToLeft) {
+            if (falseBlock)
+                falseBlock->traverse(it);
+                       if (trueBlock)
+                               trueBlock->traverse(it);
+            condition->traverse(it);
+        } else {
+            condition->traverse(it);
+                       if (trueBlock)
+                               trueBlock->traverse(it);
+            if (falseBlock)
+                falseBlock->traverse(it);
+        }
+        --it->depth;
+    }
+
+    if (visit && it->postVisit && it->visitSelection)
+        it->visitSelection(false, this, it);
+}
+
+//
+// Traverse a loop node.  Same comments in binary node apply here.
+//
+void TIntermLoop::traverse(TIntermTraverser* it)
+{
+    bool visit = true;
+
+    if (it->preVisit && it->visitLoop)
+        visit = it->visitLoop(true, this, it);
+    
+    if (visit) {
+        ++it->depth;
+        if (it->rightToLeft) {
+            if (terminal)
+                terminal->traverse(it);
+            if (body)
+                body->traverse(it);
+                       if (test)
+                               test->traverse(it);
+        } else {
+                       if (test)
+                               test->traverse(it);
+            if (body)
+                body->traverse(it);
+            if (terminal)
+                terminal->traverse(it);
+        }
+        --it->depth;
+    }
+
+    if (visit && it->postVisit && it->visitLoop)
+        it->visitLoop(false, this, it);
+}
+
+//
+// Traverse a branch node.  Same comments in binary node apply here.
+//
+void TIntermBranch::traverse(TIntermTraverser* it)
+{
+    bool visit = true;
+
+    if (it->preVisit && it->visitBranch)
+        visit = it->visitBranch(true, this, it);
+    
+    if (visit && expression) {
+        ++it->depth;
+        expression->traverse(it);
+        --it->depth;
+    }
+
+    if (visit && it->postVisit && it->visitBranch)
+        it->visitBranch(false, this, it);
+}
+
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
new file mode 100644 (file)
index 0000000..96c9074
--- /dev/null
@@ -0,0 +1,1514 @@
+//
+//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.
+//
+
+//
+// Build the intermediate representation.
+//
+
+#include "localintermediate.h"
+#include "QualifierAlive.h"
+#include "RemoveTree.h"
+#include <float.h>
+
+bool CompareStructure(const TType& leftNodeType, constUnion* rightUnionArray, constUnion* leftUnionArray);
+
+////////////////////////////////////////////////////////////////////////////
+//
+// First set of functions are to help build the intermediate representation.
+// These functions are not member functions of the nodes.
+// They are called from parser productions.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+// Add a terminal node for an identifier in an expression.
+//
+// Returns the added node.
+//
+TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
+{
+    TIntermSymbol* node = new TIntermSymbol(id, name, type);
+    node->setLine(line);
+
+    return node;
+}
+
+//
+// Connect two nodes with a new parent that does a binary operation on the nodes.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
+{
+    switch (op) {
+    case EOpLessThan:
+    case EOpGreaterThan:
+    case EOpLessThanEqual:
+    case EOpGreaterThanEqual:
+        if (left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector() || left->getType().getBasicType() == EbtStruct) {
+            return 0;
+        }
+        break;
+    case EOpLogicalOr:
+    case EOpLogicalXor:
+    case EOpLogicalAnd:
+        if (left->getType().getBasicType() != EbtBool || left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector()) {
+            return 0;
+        }
+        break;
+    case EOpAdd:
+    case EOpSub:
+    case EOpDiv:
+    case EOpMul:
+        if (left->getType().getBasicType() == EbtStruct || left->getType().getBasicType() == EbtBool)
+            return 0;
+    default: break; 
+    }
+
+    // 
+    // First try converting the children to compatible types.
+    //
+
+    if (!(left->getType().getStruct() && right->getType().getStruct())) {
+        TIntermTyped* child = addConversion(op, left->getType(), right);
+        if (child)
+            right = child;
+        else {
+            child = addConversion(op, right->getType(), left);
+            if (child)
+                left = child;
+            else
+                return 0;
+        }
+    } else {
+        if (left->getType() != right->getType())
+            return 0;
+    }
+
+
+    //
+    // Need a new node holding things together then.  Make
+    // one and promote it to the right type.
+    //
+    TIntermBinary* node = new TIntermBinary(op);
+    if (line == 0)
+        line = right->getLine();
+    node->setLine(line);
+
+    node->setLeft(left);
+    node->setRight(right);
+    if (! node->promote(infoSink))
+        return 0;
+
+    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
+    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
+        
+    if (leftTempConstant)
+        leftTempConstant = left->getAsConstantUnion();
+    
+    if (rightTempConstant)
+        rightTempConstant = right->getAsConstantUnion();
+
+    //
+    // See if we can fold constants.
+    //
+
+    TIntermTyped* typedReturnNode = 0;
+    if ( leftTempConstant && rightTempConstant) {
+        typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
+
+        if (typedReturnNode)
+            return typedReturnNode;
+    }
+
+    return node;
+}
+
+//
+// Connect two nodes through an assignment.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+{
+    //
+    // Like adding binary math, except the conversion can only go
+    // from right to left.
+    //
+    TIntermBinary* node = new TIntermBinary(op);
+    if (line == 0)
+        line = left->getLine();
+    node->setLine(line);
+
+    TIntermTyped* child = addConversion(op, left->getType(), right);
+    if (child == 0)
+        return 0;
+
+    node->setLeft(left);
+    node->setRight(child);
+    if (! node->promote(infoSink))
+        return 0;
+
+    return node;
+}
+
+//
+// Connect two nodes through an index operator, where the left node is the base
+// of an array or struct, and the right node is a direct or indirect offset.
+//
+// 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)
+{
+    TIntermBinary* node = new TIntermBinary(op);
+    if (line == 0)
+        line = index->getLine();
+    node->setLine(line);
+    node->setLeft(base);
+    node->setRight(index);
+
+    // caller should set the type
+
+    return node;
+}
+
+//
+// Add one node as the parent of another that it operates on.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable)
+{
+    TIntermUnary* node;
+    TIntermTyped* child = childNode->getAsTyped();
+
+    if (child == 0) {
+        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
+        return 0;
+    }
+
+    switch (op) {
+    case EOpLogicalNot:
+        if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
+            return 0;
+        }
+        break;
+
+    case EOpPostIncrement:
+    case EOpPreIncrement:
+    case EOpPostDecrement:
+    case EOpPreDecrement:
+    case EOpNegative:
+        if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
+            return 0;
+    default: break;
+    }
+    
+    //
+    // Do we need to promote the operand?
+    //
+    // Note: Implicit promotions were removed from the language.
+    //
+    TBasicType newType = EbtVoid;
+    switch (op) {
+    case EOpConstructInt:   newType = EbtInt;   break;
+    case EOpConstructBool:  newType = EbtBool;  break;
+    case EOpConstructFloat: newType = EbtFloat; break;
+    default: break;
+    }
+
+    if (newType != EbtVoid) {
+        child = addConversion(op, TType(newType, EvqTemporary, child->getNominalSize(), 
+                                                               child->isMatrix(), 
+                                                               child->isArray()),
+                              child);
+        if (child == 0)
+            return 0;
+    }
+
+    //
+    // For constructors, we are now done, it's all in the conversion.
+    //
+    switch (op) {
+    case EOpConstructInt:
+    case EOpConstructBool:
+    case EOpConstructFloat:
+        return child;
+    default: break;
+    }
+    
+    TIntermConstantUnion *childTempConstant = 0;
+    if (child->getAsConstantUnion())
+        childTempConstant = child->getAsConstantUnion();
+        
+    //
+    // Make a new node for the operator.
+    //
+    node = new TIntermUnary(op);
+    if (line == 0)
+        line = child->getLine();
+    node->setLine(line);
+    node->setOperand(child);
+    
+    if (! node->promote(infoSink))
+        return 0;
+
+    if (childTempConstant)  {
+        TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);
+        
+        if (newChild)
+            return newChild;
+    } 
+
+    return node;
+}
+
+//
+// This is the safe way to change the operator on an aggregate, as it
+// does lots of error checking and fixing.  Especially for establishing
+// a function call's operation on it's set of parameters.  Sequences
+// of instructions are also aggregates, but they just direnctly set
+// their operator to EOpSequence.
+//
+// Returns an aggregate node, which could be the one passed in if
+// it was already an aggregate.
+//
+TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line)
+{
+    TIntermAggregate* aggNode;
+
+    //
+    // Make sure we have an aggregate.  If not turn it into one.
+    //
+    if (node) {
+        aggNode = node->getAsAggregate();
+        if (aggNode == 0 || aggNode->getOp() != EOpNull) {
+            //
+            // Make an aggregate containing this node.
+            //
+            aggNode = new TIntermAggregate();
+            aggNode->getSequence().push_back(node);
+            if (line == 0)
+                line = node->getLine();
+        }
+    } else
+        aggNode = new TIntermAggregate();
+
+    //
+    // Set the operator.
+    //
+    aggNode->setOperator(op);
+    if (line != 0)
+        aggNode->setLine(line);
+
+    return aggNode;
+}
+
+//
+// Convert one type to another.
+//
+// Returns the node representing the conversion, which could be the same
+// node passed in if no conversion was needed.
+//
+// Return 0 if a conversion can't be done.
+//
+TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
+{
+    //
+    // Does the base type allow operation?
+    //
+    switch (node->getBasicType()) {
+    case EbtVoid:
+    case EbtSampler1D:
+    case EbtSampler2D:
+    case EbtSampler3D:
+    case EbtSamplerCube:
+    case EbtSampler1DShadow:
+    case EbtSampler2DShadow:
+    case EbtSamplerRect:        // ARB_texture_rectangle
+    case EbtSamplerRectShadow:  // ARB_texture_rectangle
+        return 0;
+    default: break;
+    }
+
+    //
+    // Otherwise, if types are identical, no problem
+    //
+    if (type == node->getType())
+        return node;
+
+    //
+    // If one's a structure, then no conversions.
+    //
+    if (type.getStruct() || node->getType().getStruct())
+        return 0;
+
+    //
+    // If one's an array, then no conversions.
+    //
+    if (type.isArray() || node->getType().isArray())
+        return 0;
+
+    TBasicType promoteTo;
+    
+    switch (op) {
+    //
+    // Explicit conversions
+    //
+    case EOpConstructBool:
+        promoteTo = EbtBool;
+        break;
+    case EOpConstructFloat:
+        promoteTo = EbtFloat;
+        break;
+    case EOpConstructInt:
+        promoteTo = EbtInt;
+        break;
+    default:
+        //
+        // implicit conversions were removed from the language.
+        //
+        if (type.getBasicType() != node->getType().getBasicType())
+            return 0;
+        //
+        // Size and structure could still differ, but that's
+        // handled by operator promotion.
+        //
+        return node;
+    }
+    
+    if (node->getAsConstantUnion()) {
+
+        return (promoteConstantUnion(promoteTo, node->getAsConstantUnion()));
+    } else {
+    
+        //
+        // Add a new newNode for the conversion.
+        //
+        TIntermUnary* newNode = 0;
+
+        TOperator newOp = EOpNull;
+        switch (promoteTo) {
+        case EbtFloat:
+            switch (node->getBasicType()) {
+            case EbtInt:   newOp = EOpConvIntToFloat;  break;
+            case EbtBool:  newOp = EOpConvBoolToFloat; break;
+            default: 
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                return 0;
+            }
+            break;
+        case EbtBool:
+            switch (node->getBasicType()) {
+            case EbtInt:   newOp = EOpConvIntToBool;   break;
+            case EbtFloat: newOp = EOpConvFloatToBool; break;
+            default: 
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                return 0;
+            }
+            break;
+        case EbtInt:
+            switch (node->getBasicType()) {
+            case EbtBool:   newOp = EOpConvBoolToInt;  break;
+            case EbtFloat:  newOp = EOpConvFloatToInt; break;
+            default: 
+                infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                return 0;
+            }
+            break;
+        default: 
+            infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
+            return 0;
+        }
+
+        TType type(promoteTo, EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray());
+        newNode = new TIntermUnary(newOp, type);
+        newNode->setLine(node->getLine());
+        newNode->setOperand(node);
+
+        return newNode;
+    }
+}
+
+//
+// Safe way to combine two nodes into an aggregate.  Works with null pointers, 
+// a node that's not a aggregate yet, etc.
+//
+// Returns the resulting aggregate, unless 0 was passed in for 
+// both existing nodes.
+//
+TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line)
+{
+    if (left == 0 && right == 0)
+        return 0;
+
+    TIntermAggregate* aggNode = 0;
+    if (left)
+        aggNode = left->getAsAggregate();
+    if (!aggNode || aggNode->getOp() != EOpNull) {
+        aggNode = new TIntermAggregate;
+        if (left)
+            aggNode->getSequence().push_back(left);
+    }
+
+    if (right)
+        aggNode->getSequence().push_back(right);
+
+    if (line != 0)
+        aggNode->setLine(line);
+
+    return aggNode;
+}
+
+//
+// Turn an existing node into an aggregate.
+//
+// Returns an aggregate, unless 0 was passed in for the existing node.
+//
+TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line)
+{
+    if (node == 0)
+        return 0;
+
+    TIntermAggregate* aggNode = new TIntermAggregate;
+    aggNode->getSequence().push_back(node);
+
+    if (line != 0)
+        aggNode->setLine(line);
+    else
+        aggNode->setLine(node->getLine());
+
+    return aggNode;
+}
+
+//
+// For "if" test nodes.  There are three children; a condition,
+// a true path, and a false path.  The two paths are in the
+// nodePair.
+//
+// Returns the selection node created.
+//
+TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
+{
+    //
+    // For compile time constant selections, prune the code and 
+    // test now.
+    //
+    
+    if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
+        if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getBConst())
+            return nodePair.node1;
+        else
+            return nodePair.node2;
+    }
+
+    TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
+    node->setLine(line);
+
+    return node;
+}
+
+
+TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+{
+    if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) {
+        return right;
+    } else {
+        TIntermTyped *commaAggregate = growAggregate(left, right, line);
+        commaAggregate->getAsAggregate()->setOperator(EOpComma);    
+        commaAggregate->setType(right->getType());
+        commaAggregate->getTypePointer()->changeQualifier(EvqTemporary);
+        return commaAggregate;
+    }
+}
+
+//
+// For "?:" test nodes.  There are three children; a condition,
+// a true path, and a false path.  The two paths are specified
+// as separate parameters.
+//
+// Returns the selection node created, or 0 if one could not be.
+//
+TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
+{
+    //
+    // Get compatible types.
+    //
+    TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
+    if (child)
+        falseBlock = child;
+    else {
+        child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
+        if (child)
+            trueBlock = child;
+        else
+            return 0;
+    }
+
+    //
+    // See if all the operands are constant, then fold it otherwise not.
+    //
+
+    if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
+        if (cond->getAsConstantUnion()->getUnionArrayPointer()->getBConst())
+            return trueBlock;
+        else
+            return falseBlock;
+    }
+
+    //
+    // Make a selection node.
+    //
+    TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
+    node->setLine(line);
+
+    return node;
+}
+
+//
+// Constant terminal nodes.  Has a union that contains bool, float or int constants
+//
+// Returns the constant union node created.
+//
+
+TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc line)
+{
+    TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
+    node->setLine(line);
+
+    return node;
+}
+
+TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
+{
+    
+    TIntermAggregate* node = new TIntermAggregate(EOpSequence);
+
+    node->setLine(line);
+    TIntermConstantUnion* constIntNode;
+    TIntermSequence &sequenceVector = node->getSequence();
+    constUnion* unionArray;
+
+    for (int i = 0; i < fields.num; i++) {
+        unionArray = new constUnion[1];
+        unionArray->setIConst(fields.offsets[i]);
+        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), line);
+        sequenceVector.push_back(constIntNode);
+    }
+
+    return node;
+}
+
+//
+// Create loop nodes.
+//
+TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line)
+{
+    TIntermNode* node = new TIntermLoop(body, test, terminal, testFirst);
+    node->setLine(line);
+    
+    return node;
+}
+
+//
+// Add branches.
+//
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
+{
+    return addBranch(branchOp, 0, line);
+}
+
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
+{
+    TIntermBranch* node = new TIntermBranch(branchOp, expression);
+    node->setLine(line);
+
+    return node;
+}
+
+//
+// This is to be executed once the final root is put on top by the parsing
+// process.
+//
+bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
+{
+    if (root == 0)
+        return true;
+
+    //
+    // First, finish off the top level sequence, if any
+    //
+    TIntermAggregate* aggRoot = root->getAsAggregate();
+    if (aggRoot && aggRoot->getOp() == EOpNull)
+        aggRoot->setOperator(EOpSequence);
+
+    return true;
+}
+
+//
+// This deletes the tree.
+//
+void TIntermediate::remove(TIntermNode* root)
+{
+    if (root)
+        RemoveAllTreeNodes(root);
+}
+
+////////////////////////////////////////////////////////////////
+//
+// Member functions of the nodes used for building the tree.
+//
+////////////////////////////////////////////////////////////////
+
+//
+// Say whether or not an operation node changes the value of a variable.
+//
+// Returns true if state is modified.
+//
+bool TIntermOperator::modifiesState() const
+{
+    switch (op) {    
+    case EOpPostIncrement: 
+    case EOpPostDecrement: 
+    case EOpPreIncrement:  
+    case EOpPreDecrement:  
+    case EOpAssign:    
+    case EOpAddAssign: 
+    case EOpSubAssign: 
+    case EOpMulAssign: 
+    case EOpVectorTimesMatrixAssign:
+    case EOpVectorTimesScalarAssign:
+    case EOpMatrixTimesScalarAssign:
+    case EOpMatrixTimesMatrixAssign:
+    case EOpDivAssign: 
+    case EOpModAssign: 
+    case EOpAndAssign: 
+    case EOpInclusiveOrAssign: 
+    case EOpExclusiveOrAssign: 
+    case EOpLeftShiftAssign:   
+    case EOpRightShiftAssign:  
+        return true;
+    default:
+        return false;
+    }
+}
+
+//
+// returns true if the operator is for one of the constructors
+//
+bool TIntermOperator::isConstructor() const
+{
+    switch (op) {
+    case EOpConstructVec2:
+    case EOpConstructVec3:
+    case EOpConstructVec4:
+    case EOpConstructMat2:
+    case EOpConstructMat3:
+    case EOpConstructMat4:
+    case EOpConstructFloat:
+    case EOpConstructIVec2:
+    case EOpConstructIVec3:
+    case EOpConstructIVec4:
+    case EOpConstructInt:
+    case EOpConstructBVec2:
+    case EOpConstructBVec3:
+    case EOpConstructBVec4:
+    case EOpConstructBool:
+    case EOpConstructStruct:
+        return true;
+    default:
+        return false;
+    }
+}
+//
+// Make sure the type of a unary operator is appropriate for its 
+// combination of operation and operand type.
+//
+// Returns false in nothing makes sense.
+//
+bool TIntermUnary::promote(TInfoSink&)
+{
+    switch (op) {
+    case EOpLogicalNot:
+        if (operand->getBasicType() != EbtBool)
+            return false;
+        break;
+    case EOpBitwiseNot:
+        if (operand->getBasicType() != EbtInt)
+            return false;
+        break;
+    case EOpNegative:
+    case EOpPostIncrement:
+    case EOpPostDecrement:
+    case EOpPreIncrement:
+    case EOpPreDecrement:
+        if (operand->getBasicType() == EbtBool)
+            return false;
+        break;
+
+    // operators for built-ins are already type checked against their prototype
+    case EOpAny:
+    case EOpAll:
+    case EOpVectorLogicalNot:
+        return true;
+
+    default:
+        if (operand->getBasicType() != EbtFloat)
+            return false;
+    }
+    
+    setType(operand->getType());
+
+    return true;
+}
+
+//
+// Establishes the type of the resultant operation, as well as
+// makes the operator the correct one for the operands.
+//
+// Returns false if operator can't work on operands.
+//
+bool TIntermBinary::promote(TInfoSink& infoSink)
+{
+    int size = left->getNominalSize();
+    if (right->getNominalSize() > size)
+        size = right->getNominalSize();
+
+    TBasicType type = left->getBasicType();
+
+    //
+    // Arrays have to be exact matches.
+    //
+    if ((left->isArray() || right->isArray()) && (left->getType() != right->getType()))
+        return false;
+
+    //
+    // Base assumption:  just make the type the same as the left
+    // operand.  Then only deviations from this need be coded.
+    //
+    setType(TType(type, EvqTemporary, left->getNominalSize(), left->isMatrix()));
+
+    //
+    // Array operations.
+    //
+    if (left->isArray()) {
+
+        switch (op) {
+
+        //
+        // Promote to conditional
+        //
+        case EOpEqual:
+        case EOpNotEqual:
+            setType(TType(EbtBool));
+            break;
+
+        //
+        // Set array information.
+        //
+        case EOpAssign:
+            getType().setArraySize(left->getType().getArraySize());
+            getType().setArrayInformationType(left->getType().getArrayInformationType());
+            break;
+
+        default:
+            return false;
+        }
+
+        return true;
+    }
+    
+    //
+    // All scalars.  Code after this test assumes this case is removed!
+    //
+    if (size == 1) {
+
+        switch (op) {
+
+        //
+        // Promote to conditional
+        //
+        case EOpEqual:
+        case EOpNotEqual:
+        case EOpLessThan:
+        case EOpGreaterThan:
+        case EOpLessThanEqual:
+        case EOpGreaterThanEqual:
+            setType(TType(EbtBool));
+            break;
+
+        //
+        // And and Or operate on conditionals
+        //
+        case EOpLogicalAnd:
+        case EOpLogicalOr:
+            if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
+                return false;           
+            setType(TType(EbtBool));
+            break;
+
+        //
+        // Check for integer only operands.
+        //
+        case EOpMod:
+        case EOpRightShift:
+        case EOpLeftShift:
+        case EOpAnd:
+        case EOpInclusiveOr:
+        case EOpExclusiveOr:
+            if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt)
+                return false;
+            break;
+        case EOpModAssign:
+        case EOpAndAssign:
+        case EOpInclusiveOrAssign:
+        case EOpExclusiveOrAssign:
+        case EOpLeftShiftAssign:
+        case EOpRightShiftAssign:
+            if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt)
+                return false;
+            // fall through
+
+        //
+        // Everything else should have matching types
+        //
+        default:
+            if (left->getBasicType() != right->getBasicType() ||
+                left->isMatrix()     != right->isMatrix())
+                return false;
+        }
+
+        return true;
+    }
+
+    //
+    // Are the sizes compatible?
+    //
+    if ( left->getNominalSize() != size &&  left->getNominalSize() != 1 ||
+        right->getNominalSize() != size && right->getNominalSize() != 1)
+        return false;
+
+    //
+    // Can these two operands be combined?
+    //
+    switch (op) {
+    case EOpMul:
+        if (!left->isMatrix() && right->isMatrix()) {
+            if (left->isVector())
+                op = EOpVectorTimesMatrix;
+            else {
+                op = EOpMatrixTimesScalar;
+                setType(TType(type, EvqTemporary, size, true));
+            }
+        } else if (left->isMatrix() && !right->isMatrix()) {
+            if (right->isVector()) {
+                op = EOpMatrixTimesVector;
+                setType(TType(type, EvqTemporary, size, false));
+            } else {
+                op = EOpMatrixTimesScalar;
+            }
+        } else if (left->isMatrix() && right->isMatrix()) {
+            op = EOpMatrixTimesMatrix;
+        } else if (!left->isMatrix() && !right->isMatrix()) {
+            if (left->isVector() && right->isVector()) {
+                // leave as component product
+            } else if (left->isVector() || right->isVector()) {
+                op = EOpVectorTimesScalar;
+                setType(TType(type, EvqTemporary, size, false));
+            }
+        } else {
+            infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+            return false;
+        }
+        break;
+    case EOpMulAssign:
+        if (!left->isMatrix() && right->isMatrix()) {
+            if (left->isVector())
+                op = EOpVectorTimesMatrixAssign;
+            else {
+                return false;
+            }
+        } else if (left->isMatrix() && !right->isMatrix()) {
+            if (right->isVector()) {
+                return false;
+            } else {
+                op = EOpMatrixTimesScalarAssign;
+            }
+        } else if (left->isMatrix() && right->isMatrix()) {
+            op = EOpMatrixTimesMatrixAssign;
+        } else if (!left->isMatrix() && !right->isMatrix()) {
+            if (left->isVector() && right->isVector()) {
+                // leave as component product
+            } else if (left->isVector() || right->isVector()) {
+                if (! left->isVector())
+                    return false;
+                op = EOpVectorTimesScalarAssign;
+                setType(TType(type, EvqTemporary, size, false));
+            }
+        } else {
+            infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+            return false;
+        }
+        break;      
+    case EOpAssign:
+        if (left->getNominalSize() != right->getNominalSize())
+            return false;
+        // fall through
+    case EOpAdd:
+    case EOpSub:
+    case EOpDiv:
+    case EOpMod:
+    case EOpAddAssign:
+    case EOpSubAssign:
+    case EOpDivAssign:
+    case EOpModAssign:
+        if (left->isMatrix() && right->isVector() ||
+            left->isVector() && right->isMatrix() ||
+            left->getBasicType() != right->getBasicType())
+            return false;
+        setType(TType(type, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
+        break;
+        
+    case EOpEqual:
+    case EOpNotEqual:
+    case EOpLessThan:
+    case EOpGreaterThan:
+    case EOpLessThanEqual:
+    case EOpGreaterThanEqual:
+        if (left->isMatrix() && right->isVector() ||
+            left->isVector() && right->isMatrix() ||
+            left->getBasicType() != right->getBasicType())
+            return false;
+        setType(TType(EbtBool));
+        break;
+
+default:
+        return false;
+    }
+
+    //
+    // One more check for assignment.  The Resulting type has to match the left operand.
+    //
+    switch (op) {
+    case EOpAssign:
+    case EOpAddAssign:
+    case EOpSubAssign:
+    case EOpMulAssign:
+    case EOpDivAssign:
+    case EOpModAssign:
+    case EOpAndAssign:
+    case EOpInclusiveOrAssign:
+    case EOpExclusiveOrAssign:
+    case EOpLeftShiftAssign:
+    case EOpRightShiftAssign:
+        if (getType() != left->getType())
+            return false;
+        break;
+    default: 
+        break;
+    }
+    
+    return true;
+}
+
+bool CompareStruct(const TType& leftNodeType, constUnion* rightUnionArray, constUnion* leftUnionArray)
+{
+    TTypeList* fields = leftNodeType.getStruct();
+
+    size_t structSize = fields->size();
+    int index = 0;
+
+    for (size_t j = 0; j < structSize; j++) {
+        int size = (*fields)[j].type->getObjectSize();
+        for (int i = 0; i < size; i++) {
+            if ((*fields)[j].type->getBasicType() == EbtStruct) {
+                if (!CompareStructure(*(*fields)[j].type, &rightUnionArray[index], &leftUnionArray[index]))
+                    return false;
+            } else {
+                if (leftUnionArray[index] != rightUnionArray[index])
+                    return false;
+                index++;
+            }    
+            
+        }
+    }
+    return true;
+} 
+
+bool CompareStructure(const TType& leftNodeType, constUnion* rightUnionArray, constUnion* leftUnionArray)
+{
+    if (leftNodeType.isArray()) {
+        TType typeWithoutArrayness = leftNodeType;
+        typeWithoutArrayness.clearArrayness();
+
+        int arraySize = leftNodeType.getArraySize();
+
+        for (int i = 0; i < arraySize; ++i) {
+            int offset = typeWithoutArrayness.getObjectSize() * i;
+            if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset]))
+                return false;
+        }
+    } else
+        return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);    
+    
+    return true;
+} 
+
+//
+// The fold functions see if an operation on a constant can be done in place,
+// without generating run-time code.
+//
+// Returns the node to keep using, which may or may not be the node passed in.
+//
+
+TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
+{   
+    constUnion *unionArray = getUnionArrayPointer(); 
+    int objectSize = getType().getObjectSize();
+
+    if (constantNode) {  // binary operations
+        TIntermConstantUnion *node = constantNode->getAsConstantUnion();
+        constUnion *rightUnionArray = node->getUnionArrayPointer();
+        TType returnType = getType();
+
+        // for a case like float f = 1.2 + vec4(2,3,4,5);
+        if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
+            rightUnionArray = new constUnion[objectSize];
+            for (int i = 0; i < objectSize; ++i)
+                rightUnionArray[i] = *node->getUnionArrayPointer(); 
+            returnType = getType();
+        } else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
+            // for a case like float f = vec4(2,3,4,5) + 1.2;
+            unionArray = new constUnion[constantNode->getType().getObjectSize()];
+            for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
+                unionArray[i] = *getUnionArrayPointer(); 
+            returnType = node->getType();
+            objectSize = constantNode->getType().getObjectSize();
+        }
+        
+        constUnion* tempConstArray = 0;
+        TIntermConstantUnion *tempNode;
+        int index = 0;
+        bool boolNodeFlag = false;
+        switch(op) {
+        case EOpAdd: 
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] + rightUnionArray[i];
+            }
+            break;
+        case EOpSub: 
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] - rightUnionArray[i];
+            }
+            break;
+
+        case EOpMul:
+        case EOpVectorTimesScalar:
+        case EOpMatrixTimesScalar: 
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] * rightUnionArray[i];
+            }
+            break;
+        case EOpMatrixTimesMatrix:                
+            if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
+                infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
+                return 0;
+            }
+            {// support MSVC++6.0
+                int size = getNominalSize();
+                tempConstArray = new constUnion[size*size];
+                for (int row = 0; row < size; row++) {
+                    for (int column = 0; column < size; column++) {
+                        tempConstArray[size * column + row].setFConst(0.0f);
+                        for (int i = 0; i < size; i++) {
+                            tempConstArray[size * column + row].setFConst(tempConstArray[size * column + row].getFConst() + unionArray[i * size + row].getFConst() * (rightUnionArray[column * size + i].getFConst())); 
+                        }
+                    }
+                }
+            }
+            break;
+        case EOpDiv: 
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++) {
+                    switch (getType().getBasicType()) {
+                    case EbtFloat: 
+                        if (rightUnionArray[i] == 0.0f) {
+                            infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+                            tempConstArray[i].setFConst(FLT_MAX);
+                        } else
+                            tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
+                    break;
+
+                    case EbtInt:   
+                        if (rightUnionArray[i] == 0) {
+                            infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+                            tempConstArray[i].setIConst(INT_MAX);
+                        } else
+                            tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
+                        break;            
+                    default: 
+                        infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
+                        return 0;
+                    }
+                }
+            }
+            break;
+
+        case EOpMatrixTimesVector: 
+            if (node->getBasicType() != EbtFloat) {
+                infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
+                return 0;
+            }
+            tempConstArray = new constUnion[getNominalSize()];
+            
+            {// support MSVC++6.0                    
+                for (int size = getNominalSize(), i = 0; i < size; i++) {
+                    tempConstArray[i].setFConst(0.0f);
+                    for (int j = 0; j < size; j++) {
+                        tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst()));
+                    }
+                }
+            }
+            
+            tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
+            tempNode->setLine(getLine());
+
+            return tempNode;                
+
+        case EOpVectorTimesMatrix:
+            if (getType().getBasicType() != EbtFloat) {
+                infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
+                return 0;
+            }  
+
+            tempConstArray = new constUnion[getNominalSize()];
+            {// support MSVC++6.0
+                for (int size = getNominalSize(), i = 0; i < size; i++) {
+                    tempConstArray[i].setFConst(0.0f);
+                    for (int j = 0; j < size; j++) {
+                        tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst()));
+                    }
+                }
+            }
+            break;
+
+        case EOpMod:
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] % rightUnionArray[i];
+            }
+            break;
+    
+        case EOpRightShift:
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
+            }
+            break;
+
+        case EOpLeftShift:
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] << rightUnionArray[i];
+            }
+            break;
+    
+        case EOpAnd:
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] & rightUnionArray[i];
+            }
+            break;
+        case EOpInclusiveOr:
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] | rightUnionArray[i];
+            }
+            break;
+        case EOpExclusiveOr:
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
+            }
+            break;
+
+        case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] && rightUnionArray[i];
+            }
+            break;
+
+        case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    tempConstArray[i] = unionArray[i] || rightUnionArray[i];
+            }
+            break;
+
+        case EOpLogicalXor:  
+            tempConstArray = new constUnion[objectSize];
+            {// support MSVC++6.0
+                for (int i = 0; i < objectSize; i++)
+                    switch (getType().getBasicType()) {
+                    case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
+                    default: assert(false && "Default missing");
+                    }
+            }
+            break;
+
+        case EOpLessThan:         
+            assert(objectSize == 1);
+            tempConstArray = new constUnion[1];
+            tempConstArray->setBConst(*unionArray < *rightUnionArray);
+            returnType = TType(EbtBool, EvqConst);
+            break;
+        case EOpGreaterThan:      
+            assert(objectSize == 1);
+            tempConstArray = new constUnion[1];
+            tempConstArray->setBConst(*unionArray > *rightUnionArray);
+            returnType = TType(EbtBool, EvqConst);
+            break;
+        case EOpLessThanEqual:
+        {
+            assert(objectSize == 1);
+            constUnion constant;
+            constant.setBConst(*unionArray > *rightUnionArray);
+            tempConstArray = new constUnion[1];
+            tempConstArray->setBConst(!constant.getBConst());
+            returnType = TType(EbtBool, EvqConst);
+            break;
+        }
+        case EOpGreaterThanEqual: 
+        {
+            assert(objectSize == 1);
+            constUnion constant;
+            constant.setBConst(*unionArray < *rightUnionArray);
+            tempConstArray = new constUnion[1];
+            tempConstArray->setBConst(!constant.getBConst());
+            returnType = TType(EbtBool, EvqConst);
+            break;
+        }
+
+        case EOpEqual: 
+            if (getType().getBasicType() == EbtStruct) {
+                if (!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
+                    boolNodeFlag = true;
+            } else {
+                for (int i = 0; i < objectSize; i++) {    
+                    if (unionArray[i] != rightUnionArray[i]) {
+                        boolNodeFlag = true;
+                        break;  // break out of for loop
+                    }
+                }
+            }
+
+            tempConstArray = new constUnion[1];
+            if (!boolNodeFlag) {
+                tempConstArray->setBConst(true);
+            }
+            else {
+                tempConstArray->setBConst(false);
+            }
+            
+            tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
+            tempNode->setLine(getLine());
+
+            return tempNode;         
+
+        case EOpNotEqual: 
+            if (getType().getBasicType() == EbtStruct) {
+                if (CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
+                    boolNodeFlag = true;
+            } else {
+                for (int i = 0; i < objectSize; i++) {    
+                    if (unionArray[i] == rightUnionArray[i]) {
+                        boolNodeFlag = true;
+                        break;  // break out of for loop
+                    }
+                }
+            }
+
+            tempConstArray = new constUnion[1];
+            if (!boolNodeFlag) {
+                tempConstArray->setBConst(true);
+            }
+            else {
+                tempConstArray->setBConst(false);
+            }
+            
+            tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
+            tempNode->setLine(getLine());
+
+            return tempNode;         
+        
+        default: 
+            infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
+            return 0;
+        }
+        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+        tempNode->setLine(getLine());
+
+        return tempNode;                
+    } else { 
+        //
+        // Do unary operations
+        //
+        TIntermConstantUnion *newNode = 0;
+        constUnion* tempConstArray = new constUnion[objectSize];
+        for (int i = 0; i < objectSize; i++) {
+            switch(op) {
+            case EOpNegative:                                       
+                switch (getType().getBasicType()) {
+                case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
+                case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
+                default: 
+                    infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+                    return 0;
+                }
+                break;
+            case EOpLogicalNot: // this code is written for possible future use, will not get executed currently                                      
+                switch (getType().getBasicType()) {
+                case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
+                default: 
+                    infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+                    return 0;
+                }
+                break;
+            default: 
+                return 0;
+            }
+        }
+        newNode = new TIntermConstantUnion(tempConstArray, getType());
+        newNode->setLine(getLine());
+        return newNode;     
+    }
+
+    return this;
+}
+
+TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) 
+{
+    constUnion *rightUnionArray = node->getUnionArrayPointer();
+    int size = node->getType().getObjectSize();
+
+    constUnion *leftUnionArray = new constUnion[size];
+
+    for (int i=0; i < size; i++) {
+        
+        switch (promoteTo) {
+        case EbtFloat:
+            switch (node->getType().getBasicType()) {
+            case EbtInt:
+                leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getIConst()));
+                break;
+            case EbtBool:
+                leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getBConst()));
+                break;
+            case EbtFloat:
+                leftUnionArray[i] = rightUnionArray[i];
+                break;
+            default: 
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                return 0;
+            }                
+            break;
+        case EbtInt:
+            switch (node->getType().getBasicType()) {
+            case EbtInt:
+                leftUnionArray[i] = rightUnionArray[i];
+                break;
+            case EbtBool:
+                leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
+                break;
+            case EbtFloat:
+                leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getFConst()));
+                break;
+            default: 
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                return 0;
+            }                
+            break;
+        case EbtBool:
+            switch (node->getType().getBasicType()) {
+            case EbtInt:
+                leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
+                break;
+            case EbtBool:
+                leftUnionArray[i] = rightUnionArray[i];
+                break;
+            case EbtFloat:
+                leftUnionArray[i].setBConst(rightUnionArray[i].getFConst() != 0.0f);
+                break;
+            default: 
+                infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                return 0;
+            }                
+            
+            break;
+        default:
+            infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
+            return 0;
+        }
+    
+    }
+    
+    const TType& t = node->getType();
+    
+    return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
+}
+
+void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
+{
+    assert(!pragmaTable);
+    pragmaTable = new TPragmaTable();
+    *pragmaTable = pTable;
+}
+
diff --git a/glslang/MachineIndependent/MMap.h b/glslang/MachineIndependent/MMap.h
new file mode 100644 (file)
index 0000000..82254f0
--- /dev/null
@@ -0,0 +1,84 @@
+//
+//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.
+//
+
+#ifndef _MMAP_INCLUDED_
+#define _MMAP_INCLUDED_
+
+//
+// Encapsulate memory mapped files
+//
+
+class TMMap {
+public:
+    TMMap(const char* fileName) : 
+        fSize(-1), // -1 is the error value returned by GetFileSize()
+        fp(NULL),
+        fBuff(0)   // 0 is the error value returned by MapViewOfFile()
+    {
+        if ((fp = fopen(fileName, "r")) == NULL)
+            return;
+        char c = getc(fp);
+        fSize = 0;
+        while (c != EOF) {
+            fSize++;
+            c = getc(fp);
+        }
+        if (c == EOF)
+            fSize++;
+        rewind(fp);
+        fBuff = (char*)malloc(sizeof(char) * fSize);
+        int count = 0;
+        c = getc(fp);
+        while (c != EOF) {
+            fBuff[count++] = c;
+            c = getc(fp);
+        }
+        fBuff[count++] = c;
+    }
+
+    char* getData() { return fBuff; }
+    int   getSize() { return fSize; }
+
+    ~TMMap() {
+        if (fp != NULL)
+            fclose(fp);
+    }
+    
+private:
+    int             fSize;      // size of file to map in
+    FILE *fp;
+    char*           fBuff;      // the actual data;
+};
+
+#endif // _MMAP_INCLUDED_
diff --git a/glslang/MachineIndependent/Makefile b/glslang/MachineIndependent/Makefile
new file mode 100644 (file)
index 0000000..9704c80
--- /dev/null
@@ -0,0 +1,161 @@
+INCLUDE = -I. -I.. -I../.. -I../Include -I../Public -I../OSDependent/Linux -I../../OGLCompilersDLL
+CC=g++
+INCPREPROCESSOR=./preprocessor
+INCCODEGEN=./../GenericCodeGen
+INCOSDEPENDENT=./../OSDependent/Linux/
+INCINITIALISATION=./../../OGLCompilersDLL/
+LIBPREPROCESSOR=./preprocessor/libPreprocessor.a
+LIBOSDEPENDENT=./../OSDependent/Linux/libOssource.a
+LIBINITIALISATION=./../../OGLCompilersDLL/libInitializeDll.a
+LIBCODEGEN=./../GenericCodeGen/libCodeGen.a
+OBJECTS= Initialize.o IntermTraverse.o \
+       Intermediate.o ParseHelper.o PoolAlloc.o QualifierAlive.o \
+       RemoveTree.o ShaderLang.o intermOut.o parseConst.o SymbolTable.o \
+       InfoSink.o
+
+SRCS= Gen_glslang.cpp Gen_glslang_tab.cpp Initialize.cpp IntermTraverse.cpp \
+       Intermediate.cpp ParseHelper.cpp PoolAlloc.cp QualifierAlive.cpp \
+       RemoveTree.cpp ShaderLang.cpp SymbolTable.cpp intermOut.cpp \
+       parseConst.cpp InfoSink.cpp
+CPPFLAGS=$(DEFINE) $(INCLUDE)
+SHAREDOBJECT=./lib/libglslang.so
+
+default: all
+
+all: $(SHAREDOBJECT)
+
+$(SHAREDOBJECT): Gen_glslang.o Gen_glslang_tab.o $(OBJECTS) \
+       $(LIBPREPROCESSOR) $(LIBCODEGEN) $(LIBOSDEPENDENT) $(LIBINITIALISATION)
+       $(CC) -fPIC -shared -lc -o $@ $(OBJECTS) $(LIBPREPROCESSOR) $(LIBCODEGEN) $(LIBOSDEPENDENT) $(LIBINITIALISATION) Gen_glslang.o Gen_glslang_tab.o
+
+Gen_glslang.o : Gen_glslang.cpp glslang_tab.h
+       $(CC) -c $(INCLUDE) Gen_glslang.cpp -o $@
+
+Gen_glslang_tab.o : Gen_glslang_tab.cpp 
+       $(CC) -c $(INCLUDE) Gen_glslang_tab.cpp -o $@
+
+Gen_glslang.cpp: glslang.l
+       @echo Generating Gen_glslang.cpp
+       @dos2unix glslang.l
+       flex glslang.l
+
+Gen_glslang_tab.cpp glslang_tab.h: glslang.y
+       @echo Generating Gen_glslang_tab.cpp
+       @dos2unix glslang.y
+       bison -t -v -d glslang.y
+       mv glslang.tab.c Gen_glslang_tab.cpp
+       mv glslang.tab.h glslang_tab.h
+
+%.o : %.cpp
+       $(CC) $(CPPFLAGS) -c $<
+
+$(LIBPREPROCESSOR):
+       cd $(INCPREPROCESSOR); make 
+
+$(LIBCODEGEN):
+       cd $(INCCODEGEN); make 
+
+$(LIBINITIALISATION):
+       cd $(INCINITIALISATION); make 
+
+$(LIBOSDEPENDENT):
+       cd $(INCOSDEPENDENT); make 
+
+depend:
+       cd $(INCPREPROCESSOR); make depend
+       cd $(INCCODEGEN); make depend
+       cd $(INCINITIALISATION); make depend
+       cd $(INCOSDEPENDENT); make depend
+       makedepend -Y -- $(CPPFLAGS) -- $(SRCS) 
+#
+# Cleanup
+#
+.PHONY : clean
+clean :
+       $(RM) *.o *.a Gen_glslang_tab.cpp Gen_glslang.cpp glslang_tab.h glslang.output
+       $(RM) ./lib/*.so
+       cd $(INCPREPROCESSOR); make clean
+       cd $(INCCODEGEN); make clean
+       cd $(INCINITIALISATION); make clean
+       cd $(INCOSDEPENDENT); make clean
+       
+# DO NOT DELETE
+
+Gen_glslang.o: ParseHelper.h ../Include/ShHandle.h
+Gen_glslang.o: ../Public/ShaderLang.h ../Include/InfoSink.h
+Gen_glslang.o: ../Include/Common.h ../Include/PoolAlloc.h SymbolTable.h
+Gen_glslang.o: ../Include/Common.h ../Include/intermediate.h
+Gen_glslang.o: ../Include/Types.h ../Include/BaseTypes.h
+Gen_glslang.o: ../Include/ConstantUnion.h ../Include/InfoSink.h
+Gen_glslang.o: localintermediate.h ../Include/intermediate.h
+Gen_glslang.o: ../Public/ShaderLang.h glslang_tab.h ./unistd.h
+Gen_glslang.o: ./preprocessor/preprocess.h ./preprocessor/slglobals.h
+Gen_glslang.o: ./preprocessor/memory.h ./preprocessor/atom.h
+Gen_glslang.o: ./preprocessor/scanner.h ./preprocessor/parser.h
+Gen_glslang.o: ./preprocessor/cpp.h ./preprocessor/tokens.h
+Gen_glslang.o: ./preprocessor/symbols.h ./preprocessor/compile.h
+Gen_glslang_tab.o: SymbolTable.h ../Include/Common.h
+Gen_glslang_tab.o: ../Include/intermediate.h ../Include/Common.h
+Gen_glslang_tab.o: ../Include/PoolAlloc.h ../Include/Types.h
+Gen_glslang_tab.o: ../Include/BaseTypes.h ../Include/ConstantUnion.h
+Gen_glslang_tab.o: ../Include/InfoSink.h ParseHelper.h ../Include/ShHandle.h
+Gen_glslang_tab.o: ../Public/ShaderLang.h
+Gen_glslang_tab.o: ../Include/InfoSink.h localintermediate.h
+Gen_glslang_tab.o: ../Include/intermediate.h ../Public/ShaderLang.h
+Initialize.o: ../Include/intermediate.h Initialize.h
+Initialize.o: ../Include/ResourceLimits.h ../Include/Common.h
+Initialize.o: ../Include/PoolAlloc.h ../Include/ShHandle.h
+Initialize.o: ../Public/ShaderLang.h
+Initialize.o: ../Include/InfoSink.h SymbolTable.h ../Include/Common.h
+Initialize.o: ../Include/intermediate.h ../Include/Types.h
+Initialize.o: ../Include/BaseTypes.h ../Include/ConstantUnion.h
+Initialize.o: ../Include/InfoSink.h
+IntermTraverse.o: ../Include/intermediate.h
+Intermediate.o: ../Include/ShHandle.h
+Intermediate.o: ../Public/ShaderLang.h ../Include/InfoSink.h
+Intermediate.o: ../Include/Common.h ../Include/PoolAlloc.h
+Intermediate.o: localintermediate.h ../Include/intermediate.h
+Intermediate.o: ../Public/ShaderLang.h SymbolTable.h ../Include/Common.h
+Intermediate.o: ../Include/intermediate.h ../Include/Types.h
+Intermediate.o: ../Include/BaseTypes.h ../Include/ConstantUnion.h
+Intermediate.o: ../Include/InfoSink.h QualifierAlive.h RemoveTree.h
+ParseHelper.o: ParseHelper.h ../Include/ShHandle.h
+ParseHelper.o: ../Public/ShaderLang.h ../Include/InfoSink.h
+ParseHelper.o: ../Include/Common.h ../Include/PoolAlloc.h SymbolTable.h
+ParseHelper.o: ../Include/Common.h ../Include/intermediate.h
+ParseHelper.o: ../Include/Types.h ../Include/BaseTypes.h
+ParseHelper.o: ../Include/ConstantUnion.h ../Include/InfoSink.h
+ParseHelper.o: localintermediate.h ../Include/intermediate.h
+ParseHelper.o: ../Public/ShaderLang.h ../Include/InitializeParseContext.h
+ParseHelper.o: ../OSDependent/Linux/osinclude.h
+ParseHelper.o: ../Include/InitializeGlobals.h ../Include/PoolAlloc.h
+QualifierAlive.o: ../Include/intermediate.h
+RemoveTree.o: ../Include/intermediate.h RemoveTree.h
+ShaderLang.o: SymbolTable.h ../Include/Common.h ../Include/intermediate.h
+ShaderLang.o: ../Include/Common.h ../Include/PoolAlloc.h ../Include/Types.h
+ShaderLang.o: ../Include/BaseTypes.h ../Include/ConstantUnion.h
+ShaderLang.o: ../Include/InfoSink.h ParseHelper.h ../Include/ShHandle.h
+ShaderLang.o: ../Public/ShaderLang.h
+ShaderLang.o: ../Include/InfoSink.h localintermediate.h
+ShaderLang.o: ../Include/intermediate.h ../Public/ShaderLang.h
+ShaderLang.o: ../Include/ResourceLimits.h Initialize.h
+SymbolTable.o: SymbolTable.h ../Include/Common.h ../Include/intermediate.h
+SymbolTable.o: ../Include/Common.h ../Include/PoolAlloc.h ../Include/Types.h
+SymbolTable.o: ../Include/BaseTypes.h ../Include/ConstantUnion.h
+SymbolTable.o: ../Include/InfoSink.h
+intermOut.o: localintermediate.h ../Include/intermediate.h
+intermOut.o: ../Public/ShaderLang.h SymbolTable.h ../Include/Common.h
+intermOut.o: ../Include/intermediate.h ../Include/Common.h
+intermOut.o: ../Include/PoolAlloc.h ../Include/Types.h ../Include/BaseTypes.h
+intermOut.o: ../Include/ConstantUnion.h ../Include/InfoSink.h
+intermOut.o: ../Include/ShHandle.h
+intermOut.o: ../Public/ShaderLang.h ../Include/InfoSink.h
+parseConst.o: ParseHelper.h ../Include/ShHandle.h
+parseConst.o: ../Public/ShaderLang.h ../Include/InfoSink.h
+parseConst.o: ../Include/Common.h ../Include/PoolAlloc.h SymbolTable.h
+parseConst.o: ../Include/Common.h ../Include/intermediate.h
+parseConst.o: ../Include/Types.h ../Include/BaseTypes.h
+parseConst.o: ../Include/ConstantUnion.h ../Include/InfoSink.h
+parseConst.o: localintermediate.h ../Include/intermediate.h
+parseConst.o: ../Public/ShaderLang.h
+InfoSink.o: ../Include/InfoSink.h
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
new file mode 100644 (file)
index 0000000..6088bdf
--- /dev/null
@@ -0,0 +1,1494 @@
+//
+//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.
+//
+
+#include "ParseHelper.h"
+#include "Include/InitializeParseContext.h"
+#include "osinclude.h"
+#include <stdarg.h>
+///////////////////////////////////////////////////////////////////////
+//
+// Sub- vector and matrix fields
+//
+////////////////////////////////////////////////////////////////////////
+
+//
+// Look at a '.' field selector string and change it into offsets
+// for a vector.
+//
+bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line)
+{
+    fields.num = (int) compString.size();
+    if (fields.num > 4) {
+        error(line, "illegal vector field selection", compString.c_str(), "");
+        return false;
+    }
+
+    enum {
+        exyzw,
+        ergba,
+        estpq,
+    } fieldSet[4];
+
+    for (int i = 0; i < fields.num; ++i) {
+        switch (compString[i])  {
+        case 'x': 
+            fields.offsets[i] = 0;
+            fieldSet[i] = exyzw;
+            break;
+        case 'r': 
+            fields.offsets[i] = 0;
+            fieldSet[i] = ergba;
+            break;
+        case 's':
+            fields.offsets[i] = 0;
+            fieldSet[i] = estpq;
+            break;
+        case 'y': 
+            fields.offsets[i] = 1;
+            fieldSet[i] = exyzw;
+            break;
+        case 'g': 
+            fields.offsets[i] = 1;
+            fieldSet[i] = ergba;
+            break;
+        case 't':
+            fields.offsets[i] = 1;
+            fieldSet[i] = estpq;
+            break;
+        case 'z': 
+            fields.offsets[i] = 2;
+            fieldSet[i] = exyzw;
+            break;
+        case 'b': 
+            fields.offsets[i] = 2;
+            fieldSet[i] = ergba;
+            break;
+        case 'p':
+            fields.offsets[i] = 2;
+            fieldSet[i] = estpq;
+            break;
+        
+        case 'w': 
+            fields.offsets[i] = 3;
+            fieldSet[i] = exyzw;
+            break;
+        case 'a': 
+            fields.offsets[i] = 3;
+            fieldSet[i] = ergba;
+            break;
+        case 'q':
+            fields.offsets[i] = 3;
+            fieldSet[i] = estpq;
+            break;
+        default:
+            error(line, "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(), "");
+            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(), "");
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+
+//
+// Look at a '.' field selector string and change it into offsets
+// for a matrix.
+//
+bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line)
+{
+    fields.wholeRow = false;
+    fields.wholeCol = false;
+    fields.row = -1;
+    fields.col = -1;
+
+    if (compString.size() != 2) {
+        error(line, "illegal length of matrix field selection", compString.c_str(), "");
+        return false;
+    }
+
+    if (compString[0] == '_') {
+        if (compString[1] < '0' || compString[1] > '3') {
+            error(line, "illegal matrix field selection", compString.c_str(), "");
+            return false;
+        }
+        fields.wholeCol = true;
+        fields.col = compString[1] - '0';
+    } else if (compString[1] == '_') {
+        if (compString[0] < '0' || compString[0] > '3') {
+            error(line, "illegal matrix field selection", compString.c_str(), "");
+            return false;
+        }
+        fields.wholeRow = true;
+        fields.row = compString[0] - '0';
+    } else {
+        if (compString[0] < '0' || compString[0] > '3' ||
+            compString[1] < '0' || compString[1] > '3') {
+            error(line, "illegal matrix field selection", compString.c_str(), "");
+            return false;
+        }
+        fields.row = compString[0] - '0';
+        fields.col = compString[1] - '0';
+    }
+
+    if (fields.row >= matSize || fields.col >= matSize) {
+        error(line, "matrix field selection out of range", compString.c_str(), "");
+        return false;
+    }
+
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// Errors
+//
+////////////////////////////////////////////////////////////////////////
+
+//
+// Track whether errors have occurred.
+//
+void TParseContext::recover()
+{
+    recoveredFromError = true;
+}
+
+//
+// Used by flex/bison to output all syntax and parsing errors.
+//
+void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, 
+                                 const char *szExtraInfoFormat, ...)
+{
+    char szExtraInfo[400];
+    va_list marker;
+    
+    va_start(marker, szExtraInfoFormat);
+    
+    _vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker);
+    
+    /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+    infoSink.info.prefix(EPrefixError);
+    infoSink.info.location(nLine);
+    infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";
+    
+    va_end(marker);
+
+    ++numErrors;
+}
+
+//
+// Same error message for all places assignments don't work.
+//
+void TParseContext::assignError(int line, const char* op, TString left, TString right)
+{
+    error(line, "", 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, char* op, TString operand)
+{
+   error(line, " 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());
+}
+
+//
+// Same error message for all binary operations don't work.
+//
+void TParseContext::binaryOpError(int line, char* op, TString left, TString right)
+{
+    error(line, " 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());
+}
+
+//
+// Both test and if necessary, spit out an error, to see if the node is really
+// an l-value that can be operated on this way.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
+{
+    TIntermSymbol* symNode = node->getAsSymbolNode();
+    TIntermBinary* binaryNode = node->getAsBinaryNode();
+
+    if (binaryNode) {
+        bool errorReturn;
+
+        switch(binaryNode->getOp()) {
+        case EOpIndexDirect:
+        case EOpIndexIndirect:
+        case EOpIndexDirectStruct:
+            return lValueErrorCheck(line, op, binaryNode->getLeft());
+        case EOpVectorSwizzle:
+            errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
+            if (!errorReturn) {
+                int offset[4] = {0,0,0,0};
+
+                TIntermTyped* rightNode = binaryNode->getRight();
+                TIntermAggregate *aggrNode = rightNode->getAsAggregate();
+                
+                for (TIntermSequence::iterator p = aggrNode->getSequence().begin(); 
+                                               p != aggrNode->getSequence().end(); p++) {
+                    int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst();
+                    offset[value]++;     
+                    if (offset[value] > 1) {
+                        error(line, " l-value of swizzle cannot have duplicate components", op, "", "");
+
+                        return true;
+                    }
+                }
+            } 
+
+            return errorReturn;
+        default: 
+            break;
+        }
+        error(line, " l-value required", op, "", "");
+
+        return true;
+    }
+
+
+    const char* symbol = 0;
+    if (symNode != 0)
+        symbol = symNode->getSymbol().c_str();
+
+    char* message = 0;
+    switch (node->getQualifier()) {
+    case EvqConst:          message = "can't modify a const";        break;
+    case EvqConstReadOnly:  message = "can't modify a const";        break;
+    case EvqAttribute:      message = "can't modify an attribute";   break;
+    case EvqUniform:        message = "can't modify a uniform";      break;
+    case EvqVaryingIn:      message = "can't modify a varying";      break;
+    case EvqInput:          message = "can't modify an input";       break;
+    case EvqFace:           message = "can't modify gl_FrontFace";   break;
+    case EvqFragCoord:      message = "can't modify gl_FragCoord";   break;
+    default:
+
+        //
+        // Type that can't be written to?
+        //
+        switch (node->getBasicType()) {
+        case EbtSampler1D:
+        case EbtSampler2D:
+        case EbtSampler3D:
+        case EbtSamplerCube:
+        case EbtSampler1DShadow:
+        case EbtSampler2DShadow:
+        case EbtSamplerRect:       // ARB_texture_rectangle
+        case EbtSamplerRectShadow: // ARB_texture_rectangle
+            message = "can't modify a sampler";
+            break;
+        case EbtVoid:
+            message = "can't modify void";
+            break;
+        default: 
+            break;
+        }
+    }
+
+    if (message == 0 && binaryNode == 0 && symNode == 0) {
+        error(line, " l-value required", op, "", "");
+
+        return true;
+    }
+
+
+    //
+    // Everything else is okay, no error.
+    //
+    if (message == 0)
+        return false;
+
+    //
+    // If we get here, we have an error and a message.
+    //
+    if (symNode)
+        error(line, " l-value required", op, "\"%s\" (%s)", symbol, message);
+    else
+        error(line, " l-value required", op, "(%s)", message);
+
+    return true;
+}
+
+//
+// Both test, and if necessary spit out an error, to see if the node is really
+// a constant.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::constErrorCheck(TIntermTyped* node)
+{
+    if (node->getQualifier() == EvqConst)
+        return false;
+
+    error(node->getLine(), "constant expression required", "", "");
+
+    return true;
+}
+
+//
+// Both test, and if necessary spit out an error, to see if the node is really
+// an integer.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::integerErrorCheck(TIntermTyped* node, char* token)
+{
+    if (node->getBasicType() == EbtInt && node->getNominalSize() == 1)
+        return false;
+
+    error(node->getLine(), "integer expression required", token, "");
+
+    return true;
+}
+
+//
+// Both test, and if necessary spit out an error, to see if we are currently
+// globally scoped.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::globalErrorCheck(int line, bool global, char* token)
+{
+    if (global)
+        return false;
+
+    error(line, "only allowed at global scope", token, "");
+
+    return true;
+}
+
+//
+// For now, keep it simple:  if it starts "gl_", it's reserved, independent
+// of scope.  Except, if the symbol table is at the built-in push-level,
+// which is when we are parsing built-ins.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
+{
+    if (!symbolTable.atBuiltInLevel()) {
+        if (identifier.substr(0, 3) == TString("gl_")) {
+            error(line, "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(), "", "");
+            //return true;
+            infoSink.info.message(EPrefixWarning, "Two consecutive underscores are reserved for future use.", line);
+            return false;
+        }
+    }
+
+    return false;
+}
+
+//
+// Make sure there is enough data provided to the constructor to build
+// something of the type of the constructor.  Also returns the type of
+// the constructor.
+//
+// Returns true if there was an error in construction.
+//
+bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
+{
+    *type = function.getReturnType();
+
+    bool constructingMatrix = false;
+    switch(op) {
+    case EOpConstructMat2:
+    case EOpConstructMat3:
+    case EOpConstructMat4:
+        constructingMatrix = true;
+        break;
+    default: 
+        break;
+    }
+
+    //
+    // Note: It's okay to have too many components available, but not okay to have unused
+    // arguments.  'full' will go to true when enough args have been seen.  If we loop
+    // again, there is an extra argument, so 'overfull' will become true.
+    //
+
+    int size = 0;
+    bool constType = true;
+    bool full = false;
+    bool overFull = false;
+    bool matrixInMatrix = false;
+    bool arrayArg = false;
+    for (int i = 0; i < function.getParamCount(); ++i) {
+        size += function[i].type->getObjectSize();
+        
+        if (constructingMatrix && function[i].type->isMatrix())
+            matrixInMatrix = true;
+        if (full)
+            overFull = true;
+        if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
+            full = true;
+        if (function[i].type->getQualifier() != EvqConst)
+            constType = false;
+        if (function[i].type->isArray())
+            arrayArg = true;
+    }
+    
+    if (constType)
+        type->changeQualifier(EvqConst);
+
+    if (type->isArray() && type->getArraySize() != function.getParamCount()) {
+        error(line, "array constructor needs one argument per array element", "constructor", "");
+        return true;
+    }
+
+    if (arrayArg && op != EOpConstructStruct) {
+        error(line, "constructing from a non-dereferenced array", "constructor", "");
+        return true;
+    }
+
+    if (matrixInMatrix && !type->isArray()) {
+        error(line, "constructing matrix from matrix", "constructor", "(reserved)");
+        return true;
+    }
+
+    if (overFull) {
+        error(line, "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", "");
+        return true;
+    }
+
+    if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
+        (op == EOpConstructStruct && size < type->getObjectSize())) {
+        error(line, "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", "");
+        return true;
+    }
+    if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
+        error(line, "cannot convert a sampler", "constructor", "");
+        return true;
+    }
+    if (typed->getBasicType() == EbtVoid) {
+        error(line, "cannot convert a void", "constructor", "");
+        return true;
+    }
+
+    return false;
+}
+
+// This function checks to see if a void variable has been declared and raise an error message for such a case
+//
+// returns true in case of an error
+//
+bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
+{
+    if (pubType.type == EbtVoid) {
+        error(line, "illegal use of type 'void'", identifier.c_str(), "");
+        return true;
+    } 
+
+    return false;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression or not
+//
+// returns true in case of an error
+//
+bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
+{
+    if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
+        error(line, "boolean expression expected", "", "");
+        return true;
+    } 
+
+    return false;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression or not
+//
+// returns true in case of an error
+//
+bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
+{
+    if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
+        error(line, "boolean expression expected", "", "");
+        return true;
+    } 
+
+    return false;
+}
+
+bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
+{
+    if (pType.type == EbtStruct) {
+        if (containsSampler(*pType.userDef)) {
+            error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler)");
+        
+            return true;
+        }
+        
+        return false;
+    } else if (IsSampler(pType.type)) {
+        error(line, reason, TType::getBasicString(pType.type), "");
+
+        return true;
+    }
+
+    return false;
+}
+
+bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
+{
+    if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
+        pType.type == EbtStruct) {
+        error(line, "cannot be used with a structure", getQualifierString(pType.qualifier), "");
+        
+        return true;
+    }
+
+    if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
+        return true;
+
+    return false;
+}
+
+bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
+{
+    if ((qualifier == EvqOut || qualifier == EvqInOut) && 
+             type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
+        error(line, "samplers cannot be output parameters", type.getBasicString(), "");
+        return true;
+    }
+
+    return false;
+}
+
+bool TParseContext::containsSampler(TType& type)
+{
+    if (IsSampler(type.getBasicType()))
+        return true;
+
+    if (type.getBasicType() == EbtStruct) {
+        TTypeList& structure = *type.getStruct();
+        for (unsigned int i = 0; i < structure.size(); ++i) {
+            if (containsSampler(*structure[i].type))
+                return true;
+        }
+    }
+
+    return false;
+}
+
+bool TParseContext::insertBuiltInArrayAtGlobalLevel()
+{
+    TString *name = NewPoolTString("gl_TexCoord");
+    TSymbol* symbol = symbolTable.find(*name);
+    if (!symbol) {
+        error(0, "INTERNAL ERROR finding symbol", name->c_str(), "");
+        return true;
+    }
+    TVariable* variable = static_cast<TVariable*>(symbol);
+
+    TVariable* newVariable = new TVariable(name, variable->getType());
+
+    if (! symbolTable.insert(*newVariable)) {
+        delete newVariable;
+        error(0, "INTERNAL ERROR inserting new symbol", name->c_str(), "");
+        return true;
+    }
+
+    return false;
+}
+
+
+
+//
+// Do size checking for an array type's size.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
+{
+    TIntermConstantUnion* constant = expr->getAsConstantUnion();
+    if (constant == 0 || constant->getBasicType() != EbtInt) {
+        error(line, "array size must be a constant integer expression", "", "");
+        return true;
+    }
+
+    size = constant->getUnionArrayPointer()->getIConst();
+
+    if (size <= 0) {
+        error(line, "array size must be a positive integer", "", "");
+        size = 1;
+        return true;
+    }
+
+    return false;
+}
+
+//
+// See if this qualifier can be an array.
+//
+// Returns true if there is an error.
+//
+bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
+{
+    if (type.qualifier == EvqAttribute) {
+        error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
+        return true;
+    }
+
+    if (type.qualifier == EvqConst && extensionErrorCheck(line, "GL_3DL_array_objects"))
+        return true;
+
+    return false;
+}
+
+//
+// See if this type can be an array.
+//
+// Returns true if there is an error.
+//
+bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
+{
+    //
+    // Can the type be an array?
+    //
+    if (type.array) {
+        error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str(), "");
+        return true;
+    }
+
+    return false;
+}
+
+//
+// Do all the semantic checking for declaring an array, with and 
+// without a size, and make the right changes to the symbol table.
+//
+// size == 0 means no specified size.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
+{
+    //
+    // Don't check for reserved word use until after we know it's not in the symbol table,
+    // because reserved arrays can be redeclared.
+    //
+
+    bool builtIn = false; 
+    bool sameScope = false;
+    TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope);
+    if (symbol == 0 || !sameScope) {
+        if (reservedErrorCheck(line, identifier))
+            return true;
+        
+        variable = new TVariable(&identifier, TType(type));
+
+        if (type.arraySize)
+            variable->getType().setArraySize(type.arraySize);
+
+        if (! symbolTable.insert(*variable)) {
+            delete variable;
+            error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), "");
+            return true;
+        }
+    } else {
+        if (! symbol->isVariable()) {
+            error(line, "variable expected", identifier.c_str(), "");
+            return true;
+        }
+
+        variable = static_cast<TVariable*>(symbol);
+        if (! variable->getType().isArray()) {
+            error(line, "redeclaring non-array as array", identifier.c_str(), "");
+            return true;
+        }
+        if (variable->getType().getArraySize() > 0) {
+            error(line, "redeclaration of array with size", identifier.c_str(), "");
+            return true;
+        }
+        
+        if (! variable->getType().sameElementType(TType(type))) {
+            error(line, "redeclaration of array with a different type", identifier.c_str(), "");
+            return true;
+        }
+
+        TType* t = variable->getArrayInformationType();
+        while (t != 0) {
+            if (t->getMaxArraySize() > type.arraySize) {
+                error(line, "higher index value already used for the array", identifier.c_str(), "");
+                return true;
+            }
+            t->setArraySize(type.arraySize);
+            t = t->getArrayInformationType();
+        }
+
+        if (type.arraySize)
+            variable->getType().setArraySize(type.arraySize);
+    } 
+
+    if (voidErrorCheck(line, identifier, type))
+        return true;
+
+    return false;
+}
+
+bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
+{
+    bool builtIn = false;
+    TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
+    if (symbol == 0) {
+        error(line, " undeclared identifier", node->getSymbol().c_str(), "");
+        return true;
+    }
+    TVariable* variable = static_cast<TVariable*>(symbol);
+
+    type->setArrayInformationType(variable->getArrayInformationType());
+    variable->updateArrayInformationType(type);
+
+    // special casing to test index value of gl_TexCoord. If the accessed index is >= gl_MaxTextureCoords
+    // its an error
+    if (node->getSymbol() == "gl_TexCoord") {
+        TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords", &builtIn);
+        if (texCoord == 0) {
+            infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", line);
+            return true;
+        }
+
+        int texCoordValue = static_cast<TVariable*>(texCoord)->getConstPointer()[0].getIConst();
+        if (texCoordValue <= size) {
+            error(line, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", "");
+            return true;
+        }
+    }
+
+    // we dont want to update the maxArraySize when this flag is not set, we just want to include this 
+    // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
+    if (!updateFlag)
+        return false;
+
+    size++;
+    variable->getType().setMaxArraySize(size);
+    type->setMaxArraySize(size);
+    TType* tt = type;
+
+    while(tt->getArrayInformationType() != 0) {
+        tt = tt->getArrayInformationType();
+        tt->setMaxArraySize(size);
+    }
+
+    return false;
+}
+
+//
+// Enforce non-initializer type/qualifier rules.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type)
+{
+    //
+    // Make the qualifier make sense.
+    //
+    if (type.qualifier == EvqConst) {
+        type.qualifier = EvqTemporary;
+        error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
+        return true;
+    }
+
+    return false;
+}
+
+//
+// Do semantic checking for a variable declaration that has no initializer,
+// and update the symbol table.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type)
+{
+    if (reservedErrorCheck(line, identifier))
+        recover();
+
+    TVariable* variable = new TVariable(&identifier, TType(type));
+
+    if (! symbolTable.insert(*variable)) {
+        error(line, "redefinition", variable->getName().c_str(), "");
+        delete variable;
+        return true;
+    }
+
+    if (voidErrorCheck(line, identifier, type))
+        return true;
+
+    return false;
+}
+
+bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
+{    
+    if (qualifier != EvqConst && qualifier != EvqTemporary) {
+        error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), "");
+        return true;
+    }
+    if (qualifier == EvqConst && paramQualifier != EvqIn) {
+        error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
+        return true;
+    }
+
+    if (qualifier == EvqConst)
+        type->changeQualifier(EvqConstReadOnly);
+    else
+        type->changeQualifier(paramQualifier);
+
+    return false;
+}
+
+bool TParseContext::extensionErrorCheck(int line, const char* extension)
+{       
+    if (extensionBehavior[extension] == EBhWarn) {
+        infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line);
+        return false;
+    }
+    if (extensionBehavior[extension] == EBhDisable) {
+        error(line, "extension", extension, "is disabled");
+        return true;
+    }
+
+    return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+// Non-Errors.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+//
+// Look up a function name in the symbol table, and make sure it is a function.
+//
+// Return the function symbol if found, otherwise 0.
+//
+const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
+{
+    const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
+
+    if (symbol == 0) {        
+        error(line, "no matching overloaded function found", call->getName().c_str(), "");
+        return 0;
+    }
+
+    if (! symbol->isFunction()) {
+        error(line, "function name expected", call->getName().c_str(), "");
+        return 0;
+    }
+    
+    const TFunction* function = static_cast<const TFunction*>(symbol);
+    
+    return function;
+}
+
+//
+// Initializers show up in several places in the grammar.  Have one set of
+// code to handle them here.
+//
+bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, 
+                                       TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
+{
+    TType type = TType(pType);
+
+    if (variable == 0) {
+        if (reservedErrorCheck(line, identifier))
+            return true;
+
+        if (voidErrorCheck(line, identifier, pType))
+            return true;
+
+        //
+        // add variable to symbol table
+        //
+        variable = new TVariable(&identifier, type);
+        if (! symbolTable.insert(*variable)) {
+            error(line, "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
+        }
+    }
+
+    //
+    // identifier must be of type constant, a global, or a temporary
+    //
+    TQualifier qualifier = variable->getType().getQualifier();
+    if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
+        error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), "");
+        return true;
+    }
+    //
+    // test for and propagate constant
+    //
+
+    if (qualifier == EvqConst) {
+        if (qualifier != initializer->getType().getQualifier()) {
+            error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
+            variable->getType().changeQualifier(EvqTemporary);
+            return true;
+        }
+        if (type != initializer->getType()) {
+            error(line, " non-matching types for const initializer ", 
+                variable->getType().getQualifierString(), "");
+            variable->getType().changeQualifier(EvqTemporary);
+            return true;
+        }
+        if (initializer->getAsConstantUnion()) { 
+            constUnion* unionArray = variable->getConstPointer();
+
+            if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
+                   *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
+            } else {
+                variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
+            }
+        } else if (initializer->getAsSymbolNode()) {
+            const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
+            const TVariable* tVar = static_cast<const TVariable*>(symbol);
+
+            constUnion* constArray = tVar->getConstPointer();
+            variable->shareConstPointer(constArray);
+        } else {
+            error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
+            variable->getType().changeQualifier(EvqTemporary);
+            return true;
+        }
+    }
+    if (qualifier != EvqConst) {
+        TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
+        intermNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, line);
+        if (intermNode == 0) {
+            assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
+            return true;
+        }
+    } else 
+        intermNode = 0;
+
+    return false;
+}
+
+bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
+{
+    if (!aggrNode->isConstructor())
+        return false;
+
+    bool allConstant = true;
+
+    // check if all the child nodes are constants so that they can be inserted into 
+    // the parent node
+    if (aggrNode) {
+        TIntermSequence &childSequenceVector = aggrNode->getSequence() ;
+        for (TIntermSequence::iterator p = childSequenceVector.begin(); 
+                                    p != childSequenceVector.end(); p++) {
+            if (!(*p)->getAsTyped()->getAsConstantUnion())
+                return false;
+        }
+    }
+
+    return allConstant;
+}
+
+// This function is used to test for the correctness of the parameters passed to various constructor functions
+// and also convert them to the right datatype if it is allowed and required. 
+//
+// 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)
+{
+    if (node == 0)
+        return 0;
+
+    TIntermAggregate* aggrNode = node->getAsAggregate();
+    
+    TTypeList::iterator memberTypes;
+    if (op == EOpConstructStruct)
+        memberTypes = type->getStruct()->begin();
+    
+    TType elementType = *type;
+    if (type->isArray())
+        elementType.clearArrayness();
+
+    bool singleArg;
+    if (aggrNode) {
+        if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
+            singleArg = true;
+        else
+            singleArg = false;
+    } else
+        singleArg = true;
+
+    TIntermTyped *newNode;
+    if (singleArg) {
+        // 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(), false);
+        else if (op == EOpConstructStruct)
+            newNode = constructStruct(node, (*memberTypes).type, 1, node->getLine(), false);
+        else
+            newNode = constructBuiltIn(type, op, node, node->getLine(), false);
+
+        if (newNode && newNode->getAsAggregate()) {
+            TIntermTyped* constConstructor = foldConstConstructor(newNode->getAsAggregate(), *type);
+            if (constConstructor)
+                return constConstructor;
+        }
+
+        return newNode;
+    }
+    
+    //
+    // Handle list of arguments.
+    //
+    TIntermSequence &sequenceVector = aggrNode->getSequence() ;    // Stores the information about the parameter to the constructor
+    // if the structure constructor contains more than one parameter, then construct
+    // each parameter
+    
+    int paramCount = 0;  // keeps a track of the constructor parameter number being checked    
+    
+    // for each parameter to the constructor call, check to see if the right type is passed or convert them 
+    // to the right type if possible (and allowed).
+    // for structure constructors, just check if the right type is passed, no conversion is allowed.
+    
+    for (TIntermSequence::iterator p = sequenceVector.begin(); 
+                                   p != sequenceVector.end(); p++, paramCount++) {
+        if (type->isArray())
+            newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
+        else if (op == EOpConstructStruct)
+            newNode = constructStruct(*p, (memberTypes[paramCount]).type, paramCount+1, node->getLine(), true);
+        else
+            newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
+        
+        if (newNode) {
+            sequenceVector.erase(p); 
+            sequenceVector.insert(p, newNode);
+        }
+    }
+
+    TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line);
+    TIntermTyped* constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
+    if (constConstructor)
+        return constConstructor;
+
+    return constructor;
+}
+
+TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
+{
+    bool canBeFolded = areAllChildConst(aggrNode);
+    aggrNode->setType(type);
+    if (canBeFolded) {
+        bool returnVal = false;
+        constUnion* unionArray = new constUnion[type.getObjectSize()];
+        if (aggrNode->getSequence().size() == 1)  {
+            returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable,  type, true);
+        }
+        else {
+            returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable,  type);
+        }
+        if (returnVal)
+            return 0;
+
+        return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
+    }
+
+    return 0;
+}
+
+// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
+// for the parameter to the constructor (passed to this function). Essentially, it converts
+// the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a 
+// float, then float is converted to int.
+//
+// Returns 0 for an error or the constructed node.
+//
+TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset)
+{
+    TIntermTyped* newNode;
+    TOperator basicOp;
+
+    //
+    // First, convert types as needed.
+    //
+    switch (op) {
+    case EOpConstructVec2:
+    case EOpConstructVec3:
+    case EOpConstructVec4:
+    case EOpConstructMat2:
+    case EOpConstructMat3:
+    case EOpConstructMat4:
+    case EOpConstructFloat:
+        basicOp = EOpConstructFloat;
+        break;
+
+    case EOpConstructIVec2:
+    case EOpConstructIVec3:
+    case EOpConstructIVec4:
+    case EOpConstructInt:
+        basicOp = EOpConstructInt;
+        break;
+
+    case EOpConstructBVec2:
+    case EOpConstructBVec3:
+    case EOpConstructBVec4:
+    case EOpConstructBool:
+        basicOp = EOpConstructBool;
+        break;
+
+    default:
+        error(line, "unsupported construction", "", "");
+        recover();
+
+        return 0;
+    }
+    newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable);
+    if (newNode == 0) {
+        error(line, "can't convert", "constructor", "");
+        return 0;
+    }
+
+    //
+    // Now, if there still isn't an operation to do the construction, and we need one, add one.
+    //
+    
+    // Otherwise, skip out early.
+    if (subset || newNode != node && newNode->getType() == *type)
+        return newNode;
+
+    // setAggregateOperator will insert a new node for the constructor, as needed.
+    return intermediate.setAggregateOperator(newNode, op, line);
+}
+
+// This function tests for the type of the parameters to the structures constructors. Raises
+// an error message if the expected type does not match the parameter passed to the constructor.
+//
+// Returns 0 for an error or the input node itself if the expected and the given parameter types match.
+//
+TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset)
+{
+    if (*type == node->getAsTyped()->getType()) {
+        if (subset)
+            return node->getAsTyped();
+        else
+            return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line);
+    } else {
+        error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
+                node->getAsTyped()->getType().getBasicString(), type->getBasicString());
+        recover();
+    }
+
+    return 0;
+}
+
+//
+// This function returns the tree representation for the vector field(s) being accessed from contant vector.
+// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
+// returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
+// 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* typedNode;
+    TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
+
+    constUnion *unionArray;
+    if (tempConstantNode) {
+        unionArray = tempConstantNode->getUnionArrayPointer();
+
+        if (!unionArray) {  // this error message should never be raised
+            infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", line);
+            recover();
+
+            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", "");
+        recover();
+
+        return 0;
+    }
+
+    constUnion* constArray = new constUnion[fields.num];
+
+    for (int i = 0; i < fields.num; i++) {
+        if (fields.offsets[i] >= node->getType().getObjectSize()) {
+            error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]);
+            recover();
+            fields.offsets[i] = 0;
+        }
+        
+        constArray[i] = unionArray[fields.offsets[i]];
+
+    } 
+    typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
+    return typedNode;
+}
+
+//
+// This function returns the column being accessed from a constant matrix. The values are retrieved from
+// the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input 
+// 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* typedNode;
+    TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
+
+    if (index >= node->getType().getNominalSize()) {
+        error(line, "", "[", "matrix field selection out of range '%d'", index);
+        recover();
+        index = 0;
+    }
+
+    if (tempConstantNode) {
+         constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
+         int size = tempConstantNode->getType().getNominalSize();
+         typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
+    } else {
+        error(line, "Cannot offset into the matrix", "Error", "");
+        recover();
+
+        return 0;
+    }
+
+    return typedNode;
+}
+
+
+//
+// This function returns an element of an array accessed from a constant array. The values are retrieved from
+// the symbol table and parse-tree is built for the type of the element. The input 
+// 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* typedNode;
+    TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
+    int arraySize = node->getType().getArraySize();
+    TType arrayElementType = node->getType();
+    arrayElementType.clearArrayness();
+
+    if (index >= node->getType().getArraySize()) {
+        error(line, "", "[", "array field selection out of range '%d'", index);
+        recover();
+        index = 0;
+    }
+
+    int arrayElementSize = arrayElementType.getObjectSize();
+
+    if (tempConstantNode) {
+         constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
+         typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
+    } else {
+        error(line, "Cannot offset into the array", "Error", "");
+        recover();
+
+        return 0;
+    }
+
+    return typedNode;
+}
+
+
+//
+// This function returns the value of a particular field inside a constant structure from the symbol table. 
+// 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)
+{
+    TTypeList* fields = node->getType().getStruct();
+    TIntermTyped *typedNode;
+    int instanceSize = 0;
+    unsigned int index = 0;
+    TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
+
+    for ( index = 0; index < fields->size(); ++index) {
+        if ((*fields)[index].type->getFieldName() == identifier) {
+            break;
+        } else {
+            instanceSize += (*fields)[index].type->getObjectSize();
+        }
+    }
+
+    if (tempConstantNode) {
+         constUnion* constArray = tempConstantNode->getUnionArrayPointer();
+
+         typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
+    } else {
+        error(line, "Cannot offset into the structure", "Error", "");
+        recover();
+
+        return 0;
+    }
+
+    return typedNode;
+}
+
+//
+// Initialize all supported extensions to disable
+//
+void TParseContext::initializeExtensionBehavior()
+{
+    //
+    // example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of 
+    // supported extension
+    //
+    extensionBehavior["GL_ARB_texture_rectangle"] = EBhRequire;
+    extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
+}
+
+OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+
+bool InitializeParseContextIndex()
+{
+    if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
+        assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
+        return false;
+    }
+
+    //
+    // Allocate a TLS index.
+    //
+    GlobalParseContextIndex = OS_AllocTLSIndex();
+    
+    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
+        return false;
+    }
+
+    return true;
+}
+
+bool InitializeGlobalParseContext()
+{
+    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised");
+        return false;
+    }
+
+    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
+    if (lpParseContext != 0) {
+        assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
+        return false;
+    }
+
+    TThreadParseContext *lpThreadData = new TThreadParseContext();
+    if (lpThreadData == 0) {
+        assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
+        return false;
+    }
+
+    lpThreadData->lpGlobalParseContext = 0;
+    OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
+
+    return true;
+}
+
+TParseContextPointer& GetGlobalParseContext()
+{
+    //
+    // Minimal error checking for speed
+    //
+
+    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
+
+    return lpParseContext->lpGlobalParseContext;
+}
+
+bool FreeParseContext()
+{
+    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "FreeParseContext(): Parse Context index not initalised");
+        return false;
+    }
+
+    TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
+    if (lpParseContext)
+        delete lpParseContext;
+
+    return true;
+}
+
+bool FreeParseContextIndex()
+{
+    OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
+
+    if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
+        return false;
+    }
+
+    GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+
+    return OS_FreeTLSIndex(tlsiIndex);
+}
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
new file mode 100644 (file)
index 0000000..ca153ae
--- /dev/null
@@ -0,0 +1,150 @@
+//
+//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.
+//
+#ifndef _PARSER_HELPER_INCLUDED_
+#define _PARSER_HELPER_INCLUDED_
+
+#include "../Include/ShHandle.h"
+#include "SymbolTable.h"
+#include "localintermediate.h"
+
+struct TMatrixFields {
+    bool wholeRow;
+    bool wholeCol;
+    int row;
+    int col;    
+};
+
+typedef enum {
+    EBhRequire,
+    EBhEnable,
+    EBhWarn,
+    EBhDisable
+} TBehavior;
+
+struct TPragma {
+       TPragma(bool o, bool d) : optimize(o), debug(d) { }
+       bool optimize;
+       bool debug;
+       TPragmaTable pragmaTable;
+};
+
+//
+// The following are extra variables needed during parsing, grouped together so
+// they can be passed to the parser without needing a global.
+//
+struct TParseContext {
+    TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) : 
+            intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
+            recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0), 
+            inTypeParen(false), contextPragma(true, false) {  }
+    TIntermediate& intermediate; // to hold and build a parse tree
+    TSymbolTable& symbolTable;   // symbol table that goes with the language currently being parsed
+    TInfoSink& infoSink;
+    EShLanguage language;        // vertex or fragment language (future: pack or unpack)
+    TIntermNode* treeRoot;       // root of parse tree being created
+    bool recoveredFromError;     // true if a parse error has occurred, but we continue to parse
+    int numErrors;
+    bool lexAfterType;           // true if we've recognized a type, so can only be looking for an identifier
+    int loopNestingLevel;        // 0 if outside all loops
+    bool inTypeParen;            // true if in parentheses, looking only for an identifier
+    const TType* currentFunctionType;  // the return type of the function that's currently being parsed
+    bool functionReturnsValue;   // true if a non-void function has a return
+    TMap<TString, TBehavior> extensionBehavior;
+    void initializeExtensionBehavior();
+
+    void C_DECL error(TSourceLoc, const char *szReason, const char *szToken, 
+                      const char *szExtraInfoFormat, ...);
+    bool reservedErrorCheck(int line, const TString& identifier);
+    void recover();
+    
+    bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
+    bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
+    void assignError(int line, const char* op, TString left, TString right);
+    void unaryOpError(int line, char* op, TString operand);
+    void binaryOpError(int line, char* op, TString left, TString right);
+    bool lValueErrorCheck(int line, char* op, TIntermTyped*);
+    bool constErrorCheck(TIntermTyped* node);
+    bool integerErrorCheck(TIntermTyped* node, char* token);
+    bool globalErrorCheck(int line, bool global, char* token);
+    bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
+    bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
+    bool arrayQualifierErrorCheck(int line, TPublicType type);
+    bool arrayTypeErrorCheck(int line, TPublicType type);
+    bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
+    bool insertBuiltInArrayAtGlobalLevel();
+    bool voidErrorCheck(int, const TString&, const TPublicType&);
+    bool boolErrorCheck(int, const TIntermTyped*);
+    bool boolErrorCheck(int, const TPublicType&);
+    bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
+    bool structQualifierErrorCheck(int line, const TPublicType& pType);
+    bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
+    bool containsSampler(TType& type);
+    bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
+    bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
+    bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
+    bool extensionErrorCheck(int line, const char*);
+    const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
+    bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, 
+                            TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
+    bool areAllChildConst(TIntermAggregate* aggrNode);
+    TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
+    TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
+    TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
+    TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
+    TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
+    TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
+    TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
+    TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
+    bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
+       struct TPragma contextPragma;
+       TString HashErrMsg; 
+    bool AfterEOF;
+};
+
+int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
+void PaReservedWord();
+int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
+int PaParseComment(int &lineno, TParseContext&);
+void setInitialState();
+
+typedef TParseContext* TParseContextPointer;
+extern TParseContextPointer& GetGlobalParseContext();
+#define GlobalParseContext GetGlobalParseContext()
+
+typedef struct TThreadParseContextRec
+{
+       TParseContext *lpGlobalParseContext;
+} TThreadParseContext;
+
+#endif // _PARSER_HELPER_INCLUDED_
diff --git a/glslang/MachineIndependent/PoolAlloc.cpp b/glslang/MachineIndependent/PoolAlloc.cpp
new file mode 100644 (file)
index 0000000..9034bb3
--- /dev/null
@@ -0,0 +1,342 @@
+//
+//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.
+//
+
+#include "../Include/PoolAlloc.h"
+#include "../Include/Common.h"
+
+#include "Include/InitializeGlobals.h"
+#include "osinclude.h"
+
+OS_TLSIndex PoolIndex;
+
+void InitializeGlobalPools()
+{
+    TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));    
+    if (globalPools)
+        return;
+
+    TPoolAllocator *globalPoolAllocator = new TPoolAllocator(true);
+
+    TThreadGlobalPools* threadData = new TThreadGlobalPools();
+    
+    threadData->globalPoolAllocator = globalPoolAllocator;
+       
+    OS_SetTLSValue(PoolIndex, threadData);     
+       globalPoolAllocator->push();
+}
+
+void FreeGlobalPools()
+{
+    // Release the allocated memory for this thread.
+    TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));    
+    if (!globalPools)
+        return;
+       
+    GlobalPoolAllocator.popAll();
+    delete &GlobalPoolAllocator;       
+    delete globalPools;
+}
+
+bool InitializePoolIndex()
+{
+    // Allocate a TLS index.
+    if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
+        return false;
+
+    return true;
+}
+
+void FreePoolIndex()
+{
+    // Release the TLS index.
+    OS_FreeTLSIndex(PoolIndex);
+}
+
+TPoolAllocator& GetGlobalPoolAllocator()
+{
+    TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
+
+    return *threadData->globalPoolAllocator;
+}
+
+void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
+{
+    TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
+
+    threadData->globalPoolAllocator = poolAllocator;
+}
+
+//
+// Implement the functionality of the TPoolAllocator class, which
+// is documented in PoolAlloc.h.
+//
+TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignment) : 
+    global(g),
+    pageSize(growthIncrement),
+    alignment(allocationAlignment),
+    freeList(0),
+    inUseList(0),
+    numCalls(0)
+{
+    //
+    // Don't allow page sizes we know are smaller than all common
+    // OS page sizes.
+    //
+    if (pageSize < 4*1024)
+        pageSize = 4*1024;
+
+    //
+    // A large currentPageOffset indicates a new page needs to
+    // be obtained to allocate memory.
+    //
+    currentPageOffset = pageSize;
+
+    //
+    // Adjust alignment to be at least pointer aligned and
+    // power of 2.
+    //
+    size_t minAlign = sizeof(void*);
+    alignment &= ~(minAlign - 1);
+    if (alignment < minAlign)
+        alignment = minAlign;
+    size_t a = 1;
+    while (a < alignment)
+        a <<= 1;
+    alignment = a;
+    alignmentMask = a - 1;
+
+    //
+    // Align header skip
+    //
+    headerSkip = minAlign;
+    if (headerSkip < sizeof(tHeader)) {
+        headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
+    }
+}
+
+TPoolAllocator::~TPoolAllocator()
+{
+    if (!global) {
+        //
+        // Then we know that this object is not being 
+        // allocated after other, globally scoped objects
+        // that depend on it.  So we can delete the "in use" memory.
+        //
+           while (inUseList) {
+               tHeader* next = inUseList->nextPage;
+            inUseList->~tHeader();
+            delete [] reinterpret_cast<char*>(inUseList);
+               inUseList = next;
+           }
+    }
+
+    //
+    // Always delete the free list memory - it can't be being
+    // (correctly) referenced, whether the pool allocator was
+    // global or not.  We should not check the guard blocks
+    // here, because we did it already when the block was
+    // placed into the free list.
+    //
+    while (freeList) {
+        tHeader* next = freeList->nextPage;
+        delete [] reinterpret_cast<char*>(freeList);
+        freeList = next;
+    }
+}
+
+// Support MSVC++ 6.0
+const unsigned char TAllocation::guardBlockBeginVal = 0xfb;
+const unsigned char TAllocation::guardBlockEndVal   = 0xfe;
+const unsigned char TAllocation::userDataFill       = 0xcd;
+
+#   ifdef GUARD_BLOCKS
+    const size_t TAllocation::guardBlockSize = 16;
+#   else
+    const size_t TAllocation::guardBlockSize = 0;
+#   endif
+
+//
+// Check a single guard block for damage
+//
+void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, char* locText) const
+{
+    for (int x = 0; x < guardBlockSize; x++) {
+        if (blockMem[x] != val) {
+            char assertMsg[80];
+
+            // We don't print the assert message.  It's here just to be helpful.
+            sprintf(assertMsg, "PoolAlloc: Damage %s %lu byte allocation at 0x%p\n",
+                    locText, size, data());
+            assert(0 && "PoolAlloc: Damage in guard block");
+        }
+    }
+}
+
+
+void TPoolAllocator::push()
+{
+    tAllocState state = { currentPageOffset, inUseList };
+
+    stack.push_back(state);
+        
+    //
+    // Indicate there is no current page to allocate from.
+    //
+    currentPageOffset = pageSize;
+}
+
+//
+// Do a mass-deallocation of all the individual allocations
+// that have occurred since the last push(), or since the
+// last pop(), or since the object's creation.
+//
+// The deallocated pages are saved for future allocations.
+//
+void TPoolAllocator::pop()
+{
+    if (stack.size() < 1)
+        return;
+
+    tHeader* page = stack.back().page;
+    currentPageOffset = stack.back().offset;
+
+    while (inUseList != page) {
+        // invoke destructor to free allocation list
+        inUseList->~tHeader();
+        
+        tHeader* nextInUse = inUseList->nextPage;
+        if (inUseList->pageCount > 1)
+            delete [] reinterpret_cast<char*>(inUseList);
+        else {
+            inUseList->nextPage = freeList;
+            freeList = inUseList;
+        }
+        inUseList = nextInUse;
+    }
+
+    stack.pop_back();
+}
+
+//
+// Do a mass-deallocation of all the individual allocations
+// that have occurred.
+//
+void TPoolAllocator::popAll()
+{
+    while (stack.size() > 0)
+        pop();
+}
+
+void* TPoolAllocator::allocate(size_t numBytes)
+{
+    // If we are using guard blocks, all allocations are bracketed by
+    // them: [guardblock][allocation][guardblock].  numBytes is how
+    // much memory the caller asked for.  allocationSize is the total
+    // size including guard blocks.  In release build,
+    // guardBlockSize=0 and this all gets optimized away.
+    size_t allocationSize = TAllocation::allocationSize(numBytes);
+    
+    //
+    // Just keep some interesting statistics.
+    //
+    ++numCalls;
+    totalBytes += numBytes;
+
+    //
+    // Do the allocation, most likely case first, for efficiency.
+    // This step could be moved to be inline sometime.
+    //
+    if (currentPageOffset + allocationSize <= pageSize) {
+        //
+        // Safe to allocate from currentPageOffset.
+        //
+        unsigned char* memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset;
+        currentPageOffset += allocationSize;
+        currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask;
+
+        return initializeAllocation(inUseList, memory, numBytes);
+    }
+
+    if (allocationSize + headerSkip > pageSize) {
+        //
+        // Do a multi-page allocation.  Don't mix these with the others.
+        // The OS is efficient and allocating and free-ing multiple pages.
+        //
+        size_t numBytesToAlloc = allocationSize + headerSkip;
+        tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
+        if (memory == 0)
+            return 0;
+
+        // Use placement-new to initialize header
+        new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize);
+        inUseList = memory;
+
+        currentPageOffset = pageSize;  // make next allocation come from a new page
+
+        // No guard blocks for multi-page allocations (yet)
+        return reinterpret_cast<void*>(reinterpret_cast<UINT_PTR>(memory) + headerSkip);
+    }
+
+    //
+    // Need a simple page to allocate from.
+    //
+    tHeader* memory;
+    if (freeList) {
+        memory = freeList;
+        freeList = freeList->nextPage;
+    } else {
+        memory = reinterpret_cast<tHeader*>(::new char[pageSize]);
+        if (memory == 0)
+            return 0;
+    }
+
+    // Use placement-new to initialize header
+    new(memory) tHeader(inUseList, 1);
+    inUseList = memory;
+    
+    unsigned char* ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip;
+    currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
+
+    return initializeAllocation(inUseList, ret, numBytes);
+}
+
+
+//
+// Check all allocations in a list for damage by calling check on each.
+//
+void TAllocation::checkAllocList() const
+{
+    for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
+        alloc->check();
+}
diff --git a/glslang/MachineIndependent/QualifierAlive.cpp b/glslang/MachineIndependent/QualifierAlive.cpp
new file mode 100644 (file)
index 0000000..a88fd43
--- /dev/null
@@ -0,0 +1,91 @@
+//
+//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.
+//
+
+#include "../Include/intermediate.h"
+
+class TAliveTraverser : public TIntermTraverser {
+public:
+    TAliveTraverser(TQualifier q) : TIntermTraverser(), found(false), qualifier(q)
+    {
+        visitSymbol    = AliveSymbol;
+        visitSelection = AliveSelection;
+        rightToLeft    = true;
+    }
+    bool wasFound() { return found; }
+protected:
+    bool found;
+    TQualifier qualifier;
+
+    friend void AliveSymbol(TIntermSymbol*, TIntermTraverser*);
+    friend bool AliveSelection(bool, TIntermSelection*, TIntermTraverser*);
+};
+
+//
+// Report whether or not a variable of the given qualifier type
+// is guaranteed written.  Not always possible to determine if
+// it is written conditionally.
+//
+// ?? It does not do this well yet, this is just a place holder
+// that simply determines if it was reference at all, anywhere.
+//
+bool QualifierWritten(TIntermNode* node, TQualifier qualifier)
+{
+    TAliveTraverser it(qualifier);
+
+    if (node)
+        node->traverse(&it);
+
+    return it.wasFound();
+}
+
+void AliveSymbol(TIntermSymbol* node, TIntermTraverser* it)
+{
+    TAliveTraverser* lit = static_cast<TAliveTraverser*>(it);
+
+    //
+    // If it's what we're looking for, record it.
+    //
+    if (node->getQualifier() == lit->qualifier)
+        lit->found = true;
+}
+
+bool AliveSelection(bool preVisit, TIntermSelection* node, TIntermTraverser* it)
+{
+    TAliveTraverser* lit = static_cast<TAliveTraverser*>(it);
+
+    if (lit->wasFound())
+        return false;
+
+    return true;
+}
diff --git a/glslang/MachineIndependent/QualifierAlive.h b/glslang/MachineIndependent/QualifierAlive.h
new file mode 100644 (file)
index 0000000..60dfa50
--- /dev/null
@@ -0,0 +1,35 @@
+//
+//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.
+//
+
+bool QualifierWritten(TIntermNode* root, TQualifier);
diff --git a/glslang/MachineIndependent/RemoveTree.cpp b/glslang/MachineIndependent/RemoveTree.cpp
new file mode 100644 (file)
index 0000000..196279e
--- /dev/null
@@ -0,0 +1,98 @@
+//
+//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.
+//
+
+#include "../Include/intermediate.h"
+#include "RemoveTree.h"
+//
+// Code to recursively delete the intermediate tree.
+//
+
+void RemoveSymbol(TIntermSymbol* node, TIntermTraverser* it)
+{
+       delete node;
+}
+
+bool RemoveBinary(bool  /*preVisit*/ , TIntermBinary* node, TIntermTraverser*)
+{
+       delete node;
+
+       return true;
+}
+
+bool RemoveUnary(bool /*preVisit */, TIntermUnary* node, TIntermTraverser*)
+{
+    delete node;
+
+       return true;
+}
+
+bool RemoveAggregate(bool  /*preVisit*/ , TIntermAggregate* node, TIntermTraverser*)
+{
+       delete node;
+
+       return true;
+}
+
+bool RemoveSelection(bool  /*preVisit*/ , TIntermSelection* node, TIntermTraverser*)
+{
+       delete node;
+
+       return true;
+}
+
+void RemoveConstantUnion(TIntermConstantUnion* node, TIntermTraverser*)
+{
+       delete node;
+}
+
+//
+// Entry point.
+//
+void RemoveAllTreeNodes(TIntermNode* root)
+{
+    TIntermTraverser it;
+
+    it.visitAggregate     = RemoveAggregate;
+    it.visitBinary        = RemoveBinary;
+    it.visitConstantUnion = RemoveConstantUnion;
+    it.visitSelection     = RemoveSelection;
+    it.visitSymbol        = RemoveSymbol;
+    it.visitUnary         = RemoveUnary;
+
+       it.preVisit = false;
+       it.postVisit = true;
+
+    root->traverse(&it);
+}
+
diff --git a/glslang/MachineIndependent/RemoveTree.h b/glslang/MachineIndependent/RemoveTree.h
new file mode 100644 (file)
index 0000000..a6d70b4
--- /dev/null
@@ -0,0 +1,35 @@
+//
+//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.
+//
+
+void RemoveAllTreeNodes(TIntermNode*);
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
new file mode 100644 (file)
index 0000000..5d932d1
--- /dev/null
@@ -0,0 +1,586 @@
+//
+//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.
+//
+
+//
+// Implement the top-level of interface to the compiler/linker,
+// as defined in ShaderLang.h
+//
+#include "SymbolTable.h"
+#include "ParseHelper.h"
+
+#include "../Include/ShHandle.h"
+#include "InitializeDll.h"
+
+#define SH_EXPORTING
+#include "../Public/ShaderLang.h"
+#include "Initialize.h"
+//
+// A symbol table for each language.  Each has a different
+// set of built-ins, and we want to preserve that from
+// compile to compile.
+//
+TSymbolTable SymbolTables[EShLangCount];
+
+
+TPoolAllocator* PerProcessGPA = 0;
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler/linker.
+//
+
+//
+// Driver must call this first, once, before doing any other
+// compiler/linker operations.
+//
+int ShInitialize()
+{
+    TInfoSink infoSink;
+    bool ret = true;
+
+    if (!InitProcess())
+        return 0;
+
+    // This method should be called once per process. If its called by multiple threads, then 
+    // we need to have thread synchronization code around the initialization of per process
+    // global pool allocator
+    if (!PerProcessGPA) { 
+        TPoolAllocator *builtInPoolAllocator = new TPoolAllocator(true);
+        builtInPoolAllocator->push();
+        TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
+        SetGlobalPoolAllocatorPtr(builtInPoolAllocator);
+
+        TSymbolTable symTables[EShLangCount];
+        GenerateBuiltInSymbolTable(0, infoSink, symTables);
+
+        PerProcessGPA = new TPoolAllocator(true);
+        PerProcessGPA->push();
+        SetGlobalPoolAllocatorPtr(PerProcessGPA);
+
+        SymbolTables[EShLangVertex].copyTable(symTables[EShLangVertex]);
+        SymbolTables[EShLangFragment].copyTable(symTables[EShLangFragment]);
+
+        SetGlobalPoolAllocatorPtr(gPoolAllocator);
+
+        symTables[EShLangVertex].pop();
+        symTables[EShLangFragment].pop();
+
+        builtInPoolAllocator->popAll();
+        delete builtInPoolAllocator;        
+
+    }
+
+    return ret ? 1 : 0;
+}
+
+//
+// Driver calls these to create and destroy compiler/linker
+// objects.
+//
+
+ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions)
+{
+    if (!InitThread())
+        return 0;
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, debugOptions));
+    
+    return reinterpret_cast<void*>(base);
+}
+
+ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions)
+{
+    if (!InitThread())
+        return 0;
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, debugOptions));
+
+    return reinterpret_cast<void*>(base);
+}
+
+ShHandle ShConstructUniformMap()
+{
+    if (!InitThread())
+        return 0;
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructUniformMap());
+
+    return reinterpret_cast<void*>(base);
+}
+
+void ShDestruct(ShHandle handle)
+{
+    if (handle == 0)
+        return;
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+
+    if (base->getAsCompiler())
+        DeleteCompiler(base->getAsCompiler());
+    else if (base->getAsLinker())
+        DeleteLinker(base->getAsLinker());
+    else if (base->getAsUniformMap())
+        DeleteUniformMap(base->getAsUniformMap());
+}
+
+//
+// Cleanup symbol tables
+//
+int __fastcall ShFinalize()
+{  
+  if (PerProcessGPA) {
+    PerProcessGPA->popAll();
+    delete PerProcessGPA;
+  }
+  return 1;
+}
+
+bool GenerateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable* symbolTables, EShLanguage language)
+{
+    TBuiltIns builtIns;
+    
+       if (resources) {
+               builtIns.initialize(*resources);
+               InitializeSymbolTable(builtIns.getBuiltInStrings(), language, infoSink, resources, symbolTables);
+       } else {
+               builtIns.initialize();
+               InitializeSymbolTable(builtIns.getBuiltInStrings(), EShLangVertex, infoSink, resources, symbolTables);
+               InitializeSymbolTable(builtIns.getBuiltInStrings(), EShLangFragment, infoSink, resources, symbolTables);
+       }
+
+    return true;
+}
+
+bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource* resources, TSymbolTable* symbolTables)
+{
+    TIntermediate intermediate(infoSink);      
+    TSymbolTable* symbolTable;
+       
+       if (resources)
+               symbolTable = symbolTables;
+       else
+               symbolTable = &symbolTables[language];
+
+    TParseContext parseContext(*symbolTable, intermediate, language, infoSink);
+
+    GlobalParseContext = &parseContext;
+    
+    setInitialState();
+
+    assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
+       
+    //
+    // Parse the built-ins.  This should only happen once per
+    // language symbol table.
+    //
+    // Push the symbol table to give it an initial scope.  This
+    // push should not have a corresponding pop, so that built-ins
+    // are preserved, and the test for an empty table fails.
+    //
+
+    symbolTable->push();
+    
+    //Initialize the Preprocessor
+    int ret = InitPreprocessor();
+    if (ret) {
+        infoSink.info.message(EPrefixInternalError,  "Unable to intialize the Preprocessor");
+        return false;
+    }
+    
+    for (TBuiltInStrings::iterator i  = BuiltInStrings[parseContext.language].begin();
+                                    i != BuiltInStrings[parseContext.language].end();
+                                    ++i) {
+        const char* builtInShaders[1];
+        int builtInLengths[1];
+
+        builtInShaders[0] = (*i).c_str();
+        builtInLengths[0] = (int) (*i).size();
+
+        if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0) {
+            infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
+            return false;
+        }
+    }
+
+       if (resources) {
+               IdentifyBuiltIns(parseContext.language, *symbolTable, *resources);
+       } else {                                                                           
+               IdentifyBuiltIns(parseContext.language, *symbolTable);
+       }
+
+    FinalizePreprocessor();
+
+    return true;
+}
+
+//
+// Do an actual compile on the given strings.  The result is left 
+// in the given compile object.
+//
+// Return:  The return value of ShCompile is really boolean, indicating
+// success or failure.
+//
+int ShCompile(
+    const ShHandle handle,
+    const char* const shaderStrings[],
+    const int numStrings,
+    const EShOptimizationLevel optLevel,
+    const TBuiltInResource* resources,
+    int debugOptions
+    )
+{
+    if (!InitThread())
+        return 0;
+
+    if (handle == 0)
+        return 0;
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    TCompiler* compiler = base->getAsCompiler();
+    if (compiler == 0)
+        return 0;
+    
+    GlobalPoolAllocator.push();
+    compiler->infoSink.info.erase();
+    compiler->infoSink.debug.erase();
+
+    if (numStrings == 0)
+        return 1;
+
+    TIntermediate intermediate(compiler->infoSink);
+    TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]);
+    
+    GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage());
+
+    TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink);
+    parseContext.initializeExtensionBehavior();
+
+    GlobalParseContext = &parseContext;
+    
+    setInitialState();
+
+    InitPreprocessor();    
+    //
+    // Parse the application's shaders.  All the following symbol table
+    // work will be throw-away, so push a new allocation scope that can
+    // be thrown away, then push a scope for the current shader's globals.
+    //
+    bool success = true;
+    
+    symbolTable.push();
+    if (!symbolTable.atGlobalLevel())
+        parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
+
+    if (parseContext.insertBuiltInArrayAtGlobalLevel())
+        success = false;
+
+    int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext);
+    if (ret)
+        success = false;
+
+    if (success && parseContext.treeRoot) {
+        if (optLevel == EShOptNoGeneration)
+            parseContext.infoSink.info.message(EPrefixNone, "No errors.  No code generation or linking was requested.");
+        else {
+            success = intermediate.postProcess(parseContext.treeRoot, parseContext.language);
+
+            if (success) {
+
+                if (debugOptions & EDebugOpIntermediate)
+                    intermediate.outputTree(parseContext.treeRoot);
+
+                //
+                // Call the machine dependent compiler
+                //
+                if (! compiler->compile(parseContext.treeRoot))
+                    success = false;
+            }
+        }
+    } else if (!success) {
+        parseContext.infoSink.info.prefix(EPrefixError);
+        parseContext.infoSink.info << parseContext.numErrors << " compilation errors.  No code generated.\n\n";
+        success = false;
+        if (debugOptions & EDebugOpIntermediate)
+            intermediate.outputTree(parseContext.treeRoot);
+    }
+
+    intermediate.remove(parseContext.treeRoot);
+
+    //
+    // Ensure symbol table is returned to the built-in level,
+    // throwing away all but the built-ins.
+    //
+    while (! symbolTable.atSharedBuiltInLevel())
+        symbolTable.pop();
+
+    FinalizePreprocessor();
+    //
+    // Throw away all the temporary memory used by the compilation process.
+    //
+    GlobalPoolAllocator.pop();
+
+    return success ? 1 : 0;
+}
+
+//
+// Do an actual link on the given compile objects.
+//
+// Return:  The return value of is really boolean, indicating
+// success or failure.
+//
+int ShLink(
+    const ShHandle linkHandle,
+    const ShHandle compHandles[],
+    const int numHandles,
+    ShHandle uniformMapHandle,
+    short int** uniformsAccessed,
+    int* numUniformsAccessed)
+
+{
+    if (!InitThread())
+        return 0;
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
+    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
+    if (linker == 0)
+        return 0;
+
+    int returnValue;
+    GlobalPoolAllocator.push();
+    returnValue = ShLinkExt(linkHandle, compHandles, numHandles);
+    GlobalPoolAllocator.pop();
+
+    if (returnValue)
+        return 1;
+
+    return 0;
+}
+//
+// This link method will be eventually used once the ICD supports the new linker interface
+//
+int ShLinkExt(
+    const ShHandle linkHandle,
+    const ShHandle compHandles[],
+    const int numHandles)
+{
+    if (linkHandle == 0 || numHandles == 0)
+        return 0;
+
+    THandleList cObjects;
+
+    {// support MSVC++6.0
+        for (int i = 0; i < numHandles; ++i) {
+            if (compHandles[i] == 0)
+                return 0;
+            TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]);
+            if (base->getAsLinker()) {
+                cObjects.push_back(base->getAsLinker());
+            }
+            if (base->getAsCompiler())
+                cObjects.push_back(base->getAsCompiler());
+    
+    
+            if (cObjects[i] == 0)
+                return 0;
+        }
+    }
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
+    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
+
+    if (linker == 0)
+        return 0;
+
+    linker->infoSink.info.erase();
+
+    {// support MSVC++6.0
+        for (int i = 0; i < numHandles; ++i) {
+            if (cObjects[i]->getAsCompiler()) {
+                if (! cObjects[i]->getAsCompiler()->linkable()) {
+                    linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");                
+                    return 0;
+                }
+            }
+        }
+    }
+
+    bool ret = linker->link(cObjects);
+
+    return ret ? 1 : 0;
+}
+
+//
+// ShSetEncrpytionMethod is a place-holder for specifying
+// how source code is encrypted.
+//
+void ShSetEncryptionMethod(ShHandle handle)
+{
+    if (handle == 0)
+        return;
+}
+
+//
+// Return any compiler/linker/uniformmap log of messages for the application.
+//
+const char* ShGetInfoLog(const ShHandle handle)
+{
+    if (!InitThread())
+        return 0;
+
+    if (handle == 0)
+        return 0;
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+    TInfoSink* infoSink;
+
+    if (base->getAsCompiler())
+        infoSink = &(base->getAsCompiler()->getInfoSink());
+    else if (base->getAsLinker())
+        infoSink = &(base->getAsLinker()->getInfoSink());
+
+    infoSink->info << infoSink->debug.c_str();
+    return infoSink->info.c_str();
+}
+
+//
+// Return the resulting binary code from the link process.  Structure
+// is machine dependent.
+//
+const void* ShGetExecutable(const ShHandle handle)
+{
+    if (!InitThread())
+        return 0;
+
+    if (handle == 0)
+        return 0;
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    
+    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
+    if (linker == 0)
+        return 0;
+
+    return linker->getObjectCode();
+}
+
+//
+// Let the linker know where the application said it's attributes are bound.
+// The linker does not use these values, they are remapped by the ICD or
+// hardware.  It just needs them to know what's aliased.
+//
+// Return:  The return value of is really boolean, indicating
+// success or failure.
+//
+int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table)
+{    
+    if (!InitThread())
+        return 0;
+
+    if (handle == 0)
+        return 0;
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
+
+    if (linker == 0)
+        return 0;
+   
+    linker->setAppAttributeBindings(table);
+
+    return 1;
+}
+
+//
+// Let the linker know where the predefined attributes have to live.
+//
+int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table)
+{
+    if (!InitThread())
+        return 0;
+
+    if (handle == 0)
+        return 0;
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
+
+    if (linker == 0)
+        return 0;
+
+    linker->setFixedAttributeBindings(table);
+    return 1;
+}
+
+//
+// Some attribute locations are off-limits to the linker...
+//
+int ShExcludeAttributes(const ShHandle handle, int *attributes, int count)
+{
+    if (!InitThread())
+        return 0;
+
+    if (handle == 0)
+        return 0;
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
+    if (linker == 0)
+        return 0;
+
+    linker->setExcludedAttributes(attributes, count);
+
+    return 1;
+}
+
+//
+// Return the index for OpenGL to use for knowing where a uniform lives.
+//
+// Return:  The return value of is really boolean, indicating
+// success or failure.
+//
+int ShGetUniformLocation(const ShHandle handle, const char* name)
+{
+    if (!InitThread())
+        return 0;
+
+    if (handle == 0)
+        return -1;
+
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    TUniformMap* uniformMap= base->getAsUniformMap();
+    if (uniformMap == 0)
+        return -1;
+
+    return uniformMap->getLocation(name);
+}
+
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
new file mode 100644 (file)
index 0000000..ea89950
--- /dev/null
@@ -0,0 +1,245 @@
+//
+//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.
+//
+
+//
+// Symbol table for parsing.  Most functionaliy and main ideas 
+// are documented in the header file.
+//
+
+#include "SymbolTable.h"
+
+//
+// TType helper function needs a place to live.
+//
+
+//
+// Recursively generate mangled names.
+//
+void TType::buildMangledName(TString& mangledName)
+{
+    if (isMatrix())
+        mangledName += 'm';
+    else if (isVector())
+        mangledName += 'v';
+
+    switch (type) {
+    case EbtFloat:              mangledName += 'f';      break;
+    case EbtInt:                mangledName += 'i';      break;
+    case EbtBool:               mangledName += 'b';      break;
+    case EbtSampler1D:          mangledName += "s1";     break;
+    case EbtSampler2D:          mangledName += "s2";     break;
+    case EbtSampler3D:          mangledName += "s3";     break;
+    case EbtSamplerCube:        mangledName += "sC";     break;
+    case EbtSampler1DShadow:    mangledName += "sS1";    break;
+    case EbtSampler2DShadow:    mangledName += "sS2";    break;
+    case EbtSamplerRect:        mangledName += "sR2";    break;  // ARB_texture_rectangle
+    case EbtSamplerRectShadow:  mangledName += "sSR2";   break;  // ARB_texture_rectangle
+    case EbtStruct:
+        mangledName += "struct-";
+        if (typeName)
+               mangledName += *typeName;
+        {// support MSVC++6.0
+            for (unsigned int i = 0; i < structure->size(); ++i) {
+                mangledName += '-';
+                (*structure)[i].type->buildMangledName(mangledName);
+            }
+        }
+    default: 
+        break;
+    }
+
+    mangledName += static_cast<char>('0' + getNominalSize());
+    if (isArray()) {
+        char buf[10];
+        sprintf(buf, "%d", arraySize);
+        mangledName += '[';
+        mangledName += buf;
+        mangledName += ']';
+    }
+}
+
+int TType::getStructSize() const
+{ 
+    if (!getStruct()) {
+        assert(false && "Not a struct");
+        return 0;
+    }
+
+    if (structureSize == 0)
+        for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
+            structureSize += ((*tl).type)->getObjectSize();
+        
+    return structureSize;
+}
+
+//
+// Dump functions.
+//
+
+void TVariable::dump(TInfoSink& infoSink) const 
+{
+    infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getBasicString();
+    if (type.isArray()) {
+        infoSink.debug << "[0]";
+    }
+    infoSink.debug << "\n";
+}
+
+void TFunction::dump(TInfoSink &infoSink) const
+{
+    infoSink.debug << getName().c_str() << ": " <<  returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
+}
+
+void TSymbolTableLevel::dump(TInfoSink &infoSink) const 
+{
+    tLevel::const_iterator it;
+    for (it = level.begin(); it != level.end(); ++it)
+        (*it).second->dump(infoSink);
+}
+
+void TSymbolTable::dump(TInfoSink &infoSink) const
+{
+    for (int level = currentLevel(); level >= 0; --level) {
+        infoSink.debug << "LEVEL " << level << "\n";
+        table[level]->dump(infoSink);
+    }
+}
+
+//
+// Functions have buried pointers to delete.
+//
+TFunction::~TFunction()
+{
+       for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
+               delete (*i).type;
+}
+
+//
+// Symbol table levels are a map of pointers to symbols that have to be deleted.
+//
+TSymbolTableLevel::~TSymbolTableLevel()
+{
+       for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
+               delete (*it).second;
+}
+
+//
+// Change all function entries in the table with the non-mangled name
+// to be related to the provided built-in operation.  This is a low
+// performance operation, and only intended for symbol tables that
+// live across a large number of compiles.
+//
+void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) 
+{
+    tLevel::iterator it;
+    for (it = level.begin(); it != level.end(); ++it) {
+        if ((*it).second->isFunction()) {
+            TFunction* function = static_cast<TFunction*>((*it).second);
+            if (function->getName() == name)
+                function->relateToOperator(op);
+        }
+    }
+}    
+
+
+TSymbol::TSymbol(const TSymbol& copyOf)
+{
+       name = NewPoolTString(copyOf.name->c_str());
+       uniqueId = copyOf.uniqueId;
+}
+
+TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
+{      
+       type.copyType(copyOf.type, remapper);
+       userType = copyOf.userType;
+       // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
+       assert(copyOf.arrayInformationType == 0); 
+       arrayInformationType = 0;
+
+       if (copyOf.unionArray) {                
+               assert(!copyOf.type.getStruct()); 
+               assert(copyOf.type.getObjectSize() == 1);
+               unionArray = new constUnion[1];
+        unionArray[0] = copyOf.unionArray[0];
+       } else
+               unionArray = 0;
+}
+
+TVariable* TVariable::clone(TStructureMap& remapper) 
+{
+       TVariable *variable = new TVariable(*this, remapper);
+
+       return variable;
+}
+
+TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
+{      
+       for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
+               TParameter param;
+               parameters.push_back(param);
+               parameters.back().copyParam(copyOf.parameters[i], remapper);
+       }
+
+       returnType.copyType(copyOf.returnType, remapper);
+       mangledName = copyOf.mangledName;
+       op = copyOf.op;
+       defined = copyOf.defined;
+}
+
+TFunction* TFunction::clone(TStructureMap& remapper) 
+{
+       TFunction *function = new TFunction(*this, remapper);
+
+       return function;
+}
+
+TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
+{
+       TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
+       tLevel::iterator iter;
+       for (iter = level.begin(); iter != level.end(); ++iter) {
+               symTableLevel->insert(*iter->second->clone(remapper));
+       }
+
+       return symTableLevel;
+}
+
+void TSymbolTable::copyTable(const TSymbolTable& copyOf)
+{
+       TStructureMap remapper;
+       uniqueId = copyOf.uniqueId;
+       for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
+               table.push_back(copyOf.table[i]->clone(remapper));
+       }
+}
diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h
new file mode 100644 (file)
index 0000000..719c0c8
--- /dev/null
@@ -0,0 +1,318 @@
+//
+//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.
+//
+
+#ifndef _SYMBOL_TABLE_INCLUDED_
+#define _SYMBOL_TABLE_INCLUDED_
+
+//
+// Symbol table for parsing.  Has these design characteristics:
+//
+// * Same symbol table can be used to compile many shaders, to preserve
+//   effort of creating and loading with the large numbers of built-in
+//   symbols.
+//
+// * Name mangling will be used to give each function a unique name
+//   so that symbol table lookups are never ambiguous.  This allows
+//   a simpler symbol table structure.
+//
+// * Pushing and popping of scope, so symbol table will really be a stack 
+//   of symbol tables.  Searched from the top, with new inserts going into
+//   the top.
+//
+// * Constants:  Compile time constant symbols will keep their values
+//   in the symbol table.  The parser can substitute constants at parse
+//   time, including doing constant folding and constant propagation.
+//
+// * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
+//   are tracked in the intermediate representation, not the symbol table.
+//
+
+#include "Include/Common.h"
+#include "Include/intermediate.h"
+#include "Include/InfoSink.h"
+//
+// Symbol base class.  (Can build functions or variables out of these...)
+//
+class TSymbol {    
+public:
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    TSymbol(const TString *n) :  name(n) { }
+    virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
+    const TString& getName() const { return *name; }
+    virtual const TString& getMangledName() const { return getName(); }
+    virtual bool isFunction() const { return false; }
+    virtual bool isVariable() const { return false; }
+    void setUniqueId(int id) { uniqueId = id; }
+    int getUniqueId() const { return uniqueId; }
+    virtual void dump(TInfoSink &infoSink) const = 0;  
+       TSymbol(const TSymbol&);
+       virtual TSymbol* clone(TStructureMap& remapper) = 0;
+
+protected:
+    const TString *name;
+    unsigned int uniqueId;      // For real comparing during code generation
+};
+
+//
+// Variable class, meaning a symbol that's not a function.
+// 
+// There could be a separate class heirarchy for Constant variables;
+// Only one of int, bool, or float, (or none) is correct for
+// any particular use, but it's easy to do this way, and doesn't
+// seem worth having separate classes, and "getConst" can't simply return
+// different values for different types polymorphically, so this is 
+// just simple and pragmatic.
+//
+class TVariable : public TSymbol {
+public:
+    TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
+    virtual ~TVariable() { }
+    virtual bool isVariable() const { return true; }    
+    TType& getType() { return type; }    
+    const TType& getType() const { return type; }
+    bool isUserType() const { return userType; }
+    void changeQualifier(TQualifier qualifier) { type.changeQualifier(qualifier); }
+    void updateArrayInformationType(TType *t) { arrayInformationType = t; }
+    TType* getArrayInformationType() { return arrayInformationType; }
+
+    virtual void dump(TInfoSink &infoSink) const;
+
+    constUnion* getConstPointer() { 
+        if (!unionArray)
+            unionArray = new constUnion[type.getObjectSize()];
+
+        return unionArray;
+    }
+
+    constUnion* getConstPointer() const { return unionArray; }
+
+    void shareConstPointer( constUnion *constArray)
+    {
+        delete unionArray;
+        unionArray = constArray;  
+    }
+       TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
+       virtual TVariable* clone(TStructureMap& remapper);
+      
+protected:
+    TType type;
+    bool userType;
+    // we are assuming that Pool Allocator will free the memory allocated to unionArray
+    // when this object is destroyed
+    constUnion *unionArray;
+    TType *arrayInformationType;  // this is used for updating maxArraySize in all the references to a given symbol
+};
+
+//
+// The function sub-class of symbols and the parser will need to
+// share this definition of a function parameter.
+//
+struct TParameter {
+    TString *name;
+    TType* type;
+       void copyParam(const TParameter& param, TStructureMap& remapper) {
+               name = NewPoolTString(param.name->c_str());
+               type = param.type->clone(remapper);
+       }
+};
+
+//
+// The function sub-class of a symbol.  
+//
+class TFunction : public TSymbol {
+public:
+    TFunction(TOperator o) :
+        TSymbol(0),
+        returnType(TType(EbtVoid)),
+        op(o),
+        defined(false) { }
+    TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) : 
+        TSymbol(name), 
+        returnType(retType),
+        mangledName(*name + '('),
+        op(tOp),
+        defined(false) { }
+       virtual ~TFunction();
+    virtual bool isFunction() const { return true; }    
+    
+    void addParameter(TParameter& p) 
+    { 
+        parameters.push_back(p);
+        mangledName = mangledName + p.type->getMangledName();
+    }
+    
+    const TString& getMangledName() const { return mangledName; }
+    const TType& getReturnType() const { return returnType; }
+    void relateToOperator(TOperator o) { op = o; }
+    TOperator getBuiltInOp() const { return op; }
+    void setDefined() { defined = true; }
+    bool isDefined() { return defined; }
+
+    int getParamCount() const { return static_cast<int>(parameters.size()); }    
+          TParameter& operator [](int i)       { return parameters[i]; }
+    const TParameter& operator [](int i) const { return parameters[i]; }
+    
+    virtual void dump(TInfoSink &infoSink) const;
+       TFunction(const TFunction&, TStructureMap& remapper);
+       virtual TFunction* clone(TStructureMap& remapper);
+    
+protected:
+    typedef TVector<TParameter> TParamList;
+       TParamList parameters;
+    TType returnType;
+    TString mangledName;
+    TOperator op;
+    bool defined;
+};
+
+
+class TSymbolTableLevel {
+public:
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+    TSymbolTableLevel() { }
+       ~TSymbolTableLevel();
+    
+    bool insert(TSymbol& symbol) 
+    {
+        //
+        // returning true means symbol was added to the table
+        //
+        tInsertResult result;
+        result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
+        
+        return result.second;
+    }
+
+    TSymbol* find(const TString& name) const
+    {
+        tLevel::const_iterator it = level.find(name);
+        if (it == level.end())
+            return 0;
+        else
+            return (*it).second;
+    }
+
+
+    void relateToOperator(const char* name, TOperator op);
+    void dump(TInfoSink &infoSink) const;
+       TSymbolTableLevel* clone(TStructureMap& remapper);
+    
+protected:
+    typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel;
+    typedef const tLevel::value_type tLevelPair;
+    typedef std::pair<tLevel::iterator, bool> tInsertResult;
+
+    tLevel level;
+};
+
+class TSymbolTable {
+public:
+    TSymbolTable() : uniqueId(0)
+    {
+        //
+        // The symbol table cannot be used until push() is called, but
+        // the lack of an initial call to push() can be used to detect
+        // that the symbol table has not been preloaded with built-ins.
+        //
+    }
+
+    TSymbolTable(TSymbolTable& symTable)
+    {
+        table.push_back(symTable.table[0]);
+        uniqueId = symTable.uniqueId;
+    }
+
+    ~TSymbolTable()
+    {
+        // level 0 is always built In symbols, so we never pop that out
+        while (table.size() > 1)
+            pop();
+    }
+
+    //
+    // When the symbol table is initialized with the built-ins, there should
+    // 'push' calls, so that built-ins are at level 0 and the shader
+    // globals are at level 1.
+    //
+    bool isEmpty() { return table.size() == 0; }
+    bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); }
+    bool atSharedBuiltInLevel() { return table.size() == 1; }  
+    bool atGlobalLevel() { return table.size() <= 3; }
+    void push() { 
+        table.push_back(new TSymbolTableLevel);
+    }
+
+    void pop() { 
+        delete table[currentLevel()]; 
+        table.pop_back(); 
+    }
+
+    bool insert(TSymbol& symbol)
+    {
+        symbol.setUniqueId(++uniqueId);
+        return table[currentLevel()]->insert(symbol);
+    }
+    
+    TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0) 
+    {
+        int level = currentLevel();
+        TSymbol* symbol;
+        do {
+            symbol = table[level]->find(name);
+            --level;
+        } while (symbol == 0 && level >= 0);
+        level++;
+        if (builtIn)
+            *builtIn = level == 0;
+        if (sameScope)
+            *sameScope = level == currentLevel();
+        return symbol;
+    }
+
+    TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 3); return table[2]; }
+    void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
+    int getMaxSymbolId() { return uniqueId; }
+    void dump(TInfoSink &infoSink) const;
+       void copyTable(const TSymbolTable& copyOf);
+
+protected:    
+    int currentLevel() const { return static_cast<int>(table.size()) - 1; }
+    bool atDynamicBuiltInLevel() { return table.size() == 2; }
+
+    std::vector<TSymbolTableLevel*> table;
+    int uniqueId;     // for unique identification in code generation
+};
+
+#endif // _SYMBOL_TABLE_INCLUDED_
diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l
new file mode 100644 (file)
index 0000000..094933e
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+//
+//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.
+//
+*/
+/* Based on
+ANSI C grammar, Lex specification
+
+In 1985, Jeff Lee published this Lex specification together with a Yacc 
+grammar for the April 30, 1985 ANSI C draft.  Tom Stockfisch reposted 
+both to net.sources in 1987; that original, as mentioned in the answer 
+to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net, 
+file usenet/net.sources/ansi.c.grammar.Z. 
+
+I intend to keep this version as close to the current C Standard grammar 
+as possible; please let me know if you discover discrepancies. 
+
+Jutta Degener, 1995 
+*/
+
+D           [0-9]
+L           [a-zA-Z_]
+H           [a-fA-F0-9]
+E           [Ee][+-]?{D}+
+O           [0-7]
+
+%option nounput 
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include "ParseHelper.h"
+#include "glslang_tab.h"
+
+/* windows only pragma */
+#ifdef _MSC_VER
+#pragma warning(disable : 4102)
+#endif
+
+int yy_input(char* buf, int max_size);
+TSourceLoc yylineno;
+
+#ifdef _WIN32
+    extern int yyparse(TParseContext&);
+    #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)    
+#else
+    extern int yyparse(void*);
+    #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
+    #define parseContext (*((TParseContext*)(parseContextLocal)))              
+#endif
+#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size))
+
+%}
+
+%option noyywrap
+%option never-interactive
+%option outfile="Gen_glslang.cpp"
+%x FIELDS
+
+
+%%
+<*>"//"[^\n]*"\n"     { /* ?? carriage and/or line-feed? */ };
+
+"attribute"    {  pyylval->lex.line = yylineno; return(ATTRIBUTE); }
+"const"        {  pyylval->lex.line = yylineno; return(CONST_QUAL); }
+"uniform"      {  pyylval->lex.line = yylineno; return(UNIFORM); }
+"varying"      {  pyylval->lex.line = yylineno; return(VARYING); }
+
+"break"        {  pyylval->lex.line = yylineno; return(BREAK); }
+"continue"     {  pyylval->lex.line = yylineno; return(CONTINUE); }
+"do"           {  pyylval->lex.line = yylineno; return(DO); }
+"for"          {  pyylval->lex.line = yylineno; return(FOR); }
+"while"        {  pyylval->lex.line = yylineno; return(WHILE); }
+
+"if"           {  pyylval->lex.line = yylineno; return(IF); }
+"else"         {  pyylval->lex.line = yylineno; return(ELSE); }
+
+"in"           {  pyylval->lex.line = yylineno; return(IN_QUAL); }
+"out"          {  pyylval->lex.line = yylineno; return(OUT_QUAL); }
+"inout"        {  pyylval->lex.line = yylineno; return(INOUT_QUAL); }
+
+"float"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
+"int"          {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
+"void"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
+"bool"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
+"true"         {  pyylval->lex.line = yylineno; pyylval->lex.b = true;  return(BOOLCONSTANT); }
+"false"        {  pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
+
+"discard"      {  pyylval->lex.line = yylineno; return(DISCARD); }
+"return"       {  pyylval->lex.line = yylineno; return(RETURN); }
+
+"mat2"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
+"mat3"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
+"mat4"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
+
+"vec2"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
+"vec3"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
+"vec4"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); }
+"ivec2"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
+"ivec3"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
+"ivec4"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
+"bvec2"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
+"bvec3"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
+"bvec4"        {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
+
+"sampler1D"       {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1D; }
+"sampler2D"       {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }
+"sampler3D"       {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER3D; }
+"samplerCube"     {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }
+"sampler1DShadow" {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DSHADOW; }
+"sampler2DShadow" {  pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DSHADOW; }
+
+"sampler2DRect"        { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERRECTARB; /* ARB_texture_rectangle */ }
+"sampler2DRectShadow"  { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERRECTSHADOWARB; /* ARB_texture_rectangle */ }
+
+"struct"       {  pyylval->lex.line = yylineno; return(STRUCT); }
+
+"asm"          {  PaReservedWord(); return 0; }
+
+"class"        {  PaReservedWord(); return 0; }
+"union"        {  PaReservedWord(); return 0; }
+"enum"         {  PaReservedWord(); return 0; }
+"typedef"      {  PaReservedWord(); return 0; }
+"template"     {  PaReservedWord(); return 0; }
+"this"         {  PaReservedWord(); return 0; }
+"packed"       {  PaReservedWord(); return 0; }
+
+"goto"         {  PaReservedWord(); return 0; }
+"switch"       {  PaReservedWord(); return 0; }
+"default"      {  PaReservedWord(); return 0; }
+
+"inline"       {  PaReservedWord(); return 0; }
+"noinline"     {  PaReservedWord(); return 0; }
+"volatile"     {  PaReservedWord(); return 0; }
+"public"       {  PaReservedWord(); return 0; }
+"static"       {  PaReservedWord(); return 0; }
+"extern"       {  PaReservedWord(); return 0; }
+"external"     {  PaReservedWord(); return 0; }
+"interface"    {  PaReservedWord(); return 0; }
+
+"long"         {  PaReservedWord(); return 0; }
+"short"        {  PaReservedWord(); return 0; }
+"double"       {  PaReservedWord(); return 0; }
+"half"         {  PaReservedWord(); return 0; }
+"fixed"        {  PaReservedWord(); return 0; }
+"unsigned"     {  PaReservedWord(); return 0; }
+
+"input"        {  PaReservedWord(); return 0; }
+"output"       {  PaReservedWord(); return 0; }
+
+"hvec2"        {  PaReservedWord(); return 0; }
+"hvec3"        {  PaReservedWord(); return 0; }
+"hvec4"        {  PaReservedWord(); return 0; }
+"fvec2"        {  PaReservedWord(); return 0; }
+"fvec3"        {  PaReservedWord(); return 0; }
+"fvec4"        {  PaReservedWord(); return 0; }
+"dvec2"        {  PaReservedWord(); return 0; }
+"dvec3"        {  PaReservedWord(); return 0; }
+"dvec4"        {  PaReservedWord(); return 0; }
+
+"sampler3DRect"        {  PaReservedWord(); return 0; }
+
+"sizeof"       {  PaReservedWord(); return 0; }
+"cast"         {  PaReservedWord(); return 0; }
+
+"namespace"    {  PaReservedWord(); return 0; }
+"using"        {  PaReservedWord(); return 0; }
+
+{L}({L}|{D})*       {  
+   pyylval->lex.line = yylineno; 
+   pyylval->lex.string = NewPoolTString(yytext); 
+   return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol); 
+}
+
+0[xX]{H}+         { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+0{O}+             { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+0{D}+             { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
+{D}+              { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+
+{D}+{E}           { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+"."{D}+({E})?     { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+
+"/*"            {  int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }   
+
+"+="            {  pyylval->lex.line = yylineno; return(ADD_ASSIGN); }
+"-="            {  pyylval->lex.line = yylineno; return(SUB_ASSIGN); }
+"*="            {  pyylval->lex.line = yylineno; return(MUL_ASSIGN); }
+"/="            {  pyylval->lex.line = yylineno; return(DIV_ASSIGN); }
+"%="            {  pyylval->lex.line = yylineno; return(MOD_ASSIGN); }
+"<<="           {  pyylval->lex.line = yylineno; return(LEFT_ASSIGN); }
+">>="           {  pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); }
+"&="            {  pyylval->lex.line = yylineno; return(AND_ASSIGN); }
+"^="            {  pyylval->lex.line = yylineno; return(XOR_ASSIGN); }
+"|="            {  pyylval->lex.line = yylineno; return(OR_ASSIGN); }
+
+"++"            {  pyylval->lex.line = yylineno; return(INC_OP); }
+"--"            {  pyylval->lex.line = yylineno; return(DEC_OP); }
+"&&"            {  pyylval->lex.line = yylineno; return(AND_OP); }
+"||"            {  pyylval->lex.line = yylineno; return(OR_OP); }
+"^^"            {  pyylval->lex.line = yylineno; return(XOR_OP); }
+"<="            {  pyylval->lex.line = yylineno; return(LE_OP); }
+">="            {  pyylval->lex.line = yylineno; return(GE_OP); }
+"=="            {  pyylval->lex.line = yylineno; return(EQ_OP); }
+"!="            {  pyylval->lex.line = yylineno; return(NE_OP); }
+"<<"            {  pyylval->lex.line = yylineno; return(LEFT_OP); }
+">>"            {  pyylval->lex.line = yylineno; return(RIGHT_OP); }
+";"         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); }
+("{"|"<%")      {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); }
+("}"|"%>")      {  pyylval->lex.line = yylineno; return(RIGHT_BRACE); }
+","         {  pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); }
+":"         {  pyylval->lex.line = yylineno; return(COLON); }
+"="         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); }
+"("         {  pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); }
+")"         {  pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); }
+("["|"<:")      {  pyylval->lex.line = yylineno; return(LEFT_BRACKET); }
+("]"|":>")      {  pyylval->lex.line = yylineno; return(RIGHT_BRACKET); }
+"."         { BEGIN(FIELDS);  return(DOT); }
+"!"         {  pyylval->lex.line = yylineno; return(BANG); }
+"-"         {  pyylval->lex.line = yylineno; return(DASH); }
+"~"         {  pyylval->lex.line = yylineno; return(TILDE); }
+"+"         {  pyylval->lex.line = yylineno; return(PLUS); }
+"*"         {  pyylval->lex.line = yylineno; return(STAR); }
+"/"         {  pyylval->lex.line = yylineno; return(SLASH); }
+"%"         {  pyylval->lex.line = yylineno; return(PERCENT); }
+"<"         {  pyylval->lex.line = yylineno; return(LEFT_ANGLE); }
+">"         {  pyylval->lex.line = yylineno; return(RIGHT_ANGLE); }
+"|"         {  pyylval->lex.line = yylineno; return(VERTICAL_BAR); }
+"^"         {  pyylval->lex.line = yylineno; return(CARET); }
+"&"         {  pyylval->lex.line = yylineno; return(AMPERSAND); }
+"?"         {  pyylval->lex.line = yylineno; return(QUESTION); }
+
+<FIELDS>{L}({L}|{D})* { 
+BEGIN(INITIAL);      
+    pyylval->lex.line = yylineno;     
+    pyylval->lex.string = NewPoolTString(yytext); 
+    return FIELD_SELECTION; }
+<FIELDS>[ \t\v\f\r] {}
+
+[ \t\v\n\f\r]   {  }
+<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}
+<*>.    { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";
+          return 0; }
+
+%%
+
+
+//Including Pre-processor.
+extern "C" {
+  #include "./preprocessor/preprocess.h"
+} 
+
+//
+// The YY_INPUT macro just calls this.  Maybe this could be just put into
+// the macro directly.
+//
+
+int yy_input(char* buf, int max_size)
+{
+     char *char_token =NULL;
+     int len;
+
+    if ((len = yylex_CPP(buf, max_size)) == 0)
+        return 0;
+    if (len >= max_size) 
+        YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+
+    buf[len] = ' ';
+       return len+1;
+}
+
+
+//
+// Parse an array of strings using yyparse.  We set up globals used by
+// yywrap.
+//
+// Returns 0 for success, as per yyparse().
+//
+int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal)
+{
+    int argv0len;
+    
+    ScanFromString(argv[0]); 
+    
+    //Storing the Current Compiler Parse context into the cpp structure.
+       cpp->pC = (void*)&parseContextLocal;
+       
+       if (!argv || argc == 0)
+        return 1;
+    
+    for (int i = 0; i < argc; ++i) {
+        if (!argv[i]) {
+            parseContextLocal.error(0, "Null shader source string", "", "");
+            parseContextLocal.recover();
+            return 1;
+        }
+    }
+    
+    if (!strLen) {
+        argv0len = (int) strlen(argv[0]);
+        strLen   = &argv0len;
+    }
+    yyrestart(0);
+    (&parseContextLocal)->AfterEOF = false;
+    cpp->PaWhichStr = 0;
+    cpp->PaArgv     = argv;
+    cpp->PaArgc     = argc;
+    cpp->PaStrLen   = strLen;
+    cpp->notAVersionToken = 0;
+    yylineno   = 1;
+   
+    if (*cpp->PaStrLen >= 0) {    
+        int ret;
+        #ifdef _WIN32
+            ret = yyparse(parseContextLocal);            
+        #else
+            ret = yyparse((void*)(&parseContextLocal));
+        #endif
+        if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
+             return 1;
+        else
+             return 0;
+    }
+    else
+        return 0;
+}
+
+void yyerror(char *s) 
+{
+    if (((TParseContext *)cpp->pC)->AfterEOF) {
+        if (cpp->tokensBeforeEOF == 1) {
+            GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
+            GlobalParseContext->recover();
+        }
+    } else {
+        GlobalParseContext->error(yylineno, "syntax error", yytext, s, "");
+        GlobalParseContext->recover();
+    }            
+}
+
+void PaReservedWord()
+{
+    GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", "");
+    GlobalParseContext->recover();
+}
+
+int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol)
+{
+    symbol = parseContextLocal.symbolTable.find(id);
+    if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) {
+        TVariable* variable = static_cast<TVariable*>(symbol);
+        if (variable->isUserType()) {
+            parseContextLocal.lexAfterType = true;
+            return TYPE_NAME;
+        }
+    }
+    
+    return IDENTIFIER;
+}
+
+int PaParseComment(int &lineno, TParseContext& parseContextLocal)
+{
+    int transitionFlag = 0;
+    int nextChar;
+    
+    while (transitionFlag != 2) {
+        nextChar = yyinput();
+        if (nextChar == '\n')
+             lineno++;
+        switch (nextChar) {
+        case '*' :
+            transitionFlag = 1;
+            break;
+        case '/' :  /* if star is the previous character, then it is the end of comment */
+            if (transitionFlag == 1) {
+                return 1 ;
+            }
+            break;
+        case EOF :
+            /* Raise error message here */
+            parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", "");
+            GlobalParseContext->recover();
+            return YY_NULL; 
+        default :  /* Any other character will be a part of the comment */
+            transitionFlag = 0;
+        }
+    }
+    return 1;
+}
+
+extern "C" {
+
+void CPPDebugLogMsg(const char *msg)
+{
+    ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg);
+}
+
+void CPPWarningToInfoLog(const char *msg)
+{
+    ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno); 
+}
+
+void CPPShInfoLogMsg(const char *msg)
+{
+    ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,"");
+    GlobalParseContext->recover();
+}
+
+void CPPErrorToInfoLog(char *msg)
+{
+    ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,"");
+    GlobalParseContext->recover();
+}
+
+void SetLineNumber(int line)
+{
+    yylineno &= ~SourceLocLineMask;
+    yylineno |= line;
+}
+
+void SetStringNumber(int string)
+{
+    yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask);
+}
+
+int GetStringNumber(void)
+{
+    return yylineno >> 16;
+}
+
+int GetLineNumber(void)
+{
+    return yylineno & SourceLocLineMask;
+}
+
+void IncLineNumber(void)
+{
+    if ((yylineno & SourceLocLineMask) <= SourceLocLineMask)
+        ++yylineno;
+}
+
+void DecLineNumber(void)
+{
+    if ((yylineno & SourceLocLineMask) > 0)
+        --yylineno;
+}
+
+void HandlePragma(const char **tokens, int numTokens)
+{    
+    if (!strcmp(tokens[0], "optimize")) {
+        if (numTokens != 4) {
+            CPPShInfoLogMsg("optimize pragma syntax is incorrect");
+            return;
+        }
+        
+        if (strcmp(tokens[1], "(")) {
+            CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
+            return;
+        }
+            
+        if (!strcmp(tokens[2], "on"))
+            ((TParseContext *)cpp->pC)->contextPragma.optimize = true;
+        else if (!strcmp(tokens[2], "off"))
+            ((TParseContext *)cpp->pC)->contextPragma.optimize = false;
+        else {
+            CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
+            return;
+        }
+        
+        if (strcmp(tokens[3], ")")) {
+            CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
+            return;
+        }
+    } else if (!strcmp(tokens[0], "debug")) {
+        if (numTokens != 4) {
+            CPPShInfoLogMsg("debug pragma syntax is incorrect");
+            return;
+        }
+        
+        if (strcmp(tokens[1], "(")) {
+            CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
+            return;
+        }
+            
+        if (!strcmp(tokens[2], "on"))
+            ((TParseContext *)cpp->pC)->contextPragma.debug = true;
+        else if (!strcmp(tokens[2], "off"))
+            ((TParseContext *)cpp->pC)->contextPragma.debug = false;
+        else {
+            CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
+            return;
+        }
+        
+        if (strcmp(tokens[3], ")")) {
+            CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
+            return;
+        }
+    } else {
+
+#ifdef PRAGMA_TABLE
+        //
+        // implementation specific pragma
+        // use ((TParseContext *)cpp->pC)->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 = ((TParseContext *)cpp->pC)->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 = ((TParseContext *)cpp->pC)->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(char *string)
+{
+    TString strSrc;
+    strSrc = TString(string);
+
+    ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc;
+}
+
+const char* GetStrfromTStr(void)
+{
+    cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str();
+    return cpp->ErrMsg;
+}
+
+void ResetTString(void)
+{
+    ((TParseContext *)cpp->pC)->HashErrMsg = "";
+}
+
+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 {
+        CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
+        return EBhDisable;
+    }        
+}
+
+void  updateExtensionBehavior(const char* extName, const char* behavior)
+{
+    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) {
+            CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");  
+            return;
+        } else {
+            for (iter =  ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter)
+                iter->second = behaviorVal;
+        }        
+    } else {
+        iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName));
+        if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) {
+            switch (behaviorVal) {
+            case EBhRequire:
+                CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());  
+                break;
+            case EBhEnable:
+            case EBhWarn:
+            case EBhDisable:
+                msg = TString("extension '") + extName + "' is not supported";
+                ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); 
+                break;
+            }
+            return;
+        } else
+            iter->second = behaviorVal;
+    }
+}
+        
+}  // extern "C"
+
+void setInitialState()
+{
+    yy_start = 1;
+}
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
new file mode 100644 (file)
index 0000000..c3fe427
--- /dev/null
@@ -0,0 +1,2317 @@
+//
+//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.
+//
+
+/**
+ * This is bison grammar and production code for parsing the OpenGL 2.0 shading
+ * languages.
+ */
+%{
+
+/* Based on:
+ANSI C Yacc grammar
+
+In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a 
+matching Lex specification) for the April 30, 1985 draft version of the 
+ANSI C standard.  Tom Stockfisch reposted it to net.sources in 1987; that
+original, as mentioned in the answer to question 17.25 of the comp.lang.c
+FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z.
+I intend to keep this version as close to the current C Standard grammar as 
+possible; please let me know if you discover discrepancies. 
+
+Jutta Degener, 1995 
+*/
+
+#include "SymbolTable.h"
+#include "ParseHelper.h"
+#include "../Public/ShaderLang.h"
+
+#ifdef _WIN32
+    #define YYPARSE_PARAM parseContext
+    #define YYPARSE_PARAM_DECL TParseContext&
+    #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)
+    #define YYLEX_PARAM parseContext
+#else
+    #define YYPARSE_PARAM parseContextLocal
+    #define parseContext (*((TParseContext*)(parseContextLocal)))
+    #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
+    #define YYLEX_PARAM (void*)(parseContextLocal)
+    extern void yyerror(char*);    
+#endif
+
+#define FRAG_VERT_ONLY(S, L) {                                                  \
+    if (parseContext.language != EShLangFragment &&                             \
+        parseContext.language != EShLangVertex) {                               \
+        parseContext.error(L, " supported in vertex/fragment shaders only ", S, "", "");   \
+        parseContext.recover();                                                            \
+    }                                                                           \
+}
+
+#define VERTEX_ONLY(S, L) {                                                     \
+    if (parseContext.language != EShLangVertex) {                               \
+        parseContext.error(L, " supported in vertex shaders only ", S, "", "");            \
+        parseContext.recover();                                                            \
+    }                                                                           \
+}
+
+#define FRAG_ONLY(S, L) {                                                       \
+    if (parseContext.language != EShLangFragment) {                             \
+        parseContext.error(L, " supported in fragment shaders only ", S, "", "");          \
+        parseContext.recover();                                                            \
+    }                                                                           \
+}
+
+#define PACK_ONLY(S, L) {                                                       \
+    if (parseContext.language != EShLangPack) {                                 \
+        parseContext.error(L, " supported in pack shaders only ", S, "", "");              \
+        parseContext.recover();                                                            \
+    }                                                                           \
+}
+
+#define UNPACK_ONLY(S, L) {                                                     \
+    if (parseContext.language != EShLangUnpack) {                               \
+        parseContext.error(L, " supported in unpack shaders only ", S, "", "");            \
+        parseContext.recover();                                                            \
+    }                                                                           \
+}
+
+#define PACK_UNPACK_ONLY(S, L) {                                                \
+    if (parseContext.language != EShLangUnpack &&                               \
+        parseContext.language != EShLangPack) {                                 \
+        parseContext.error(L, " supported in pack/unpack shaders only ", S, "", "");       \
+        parseContext.recover();                                                            \
+    }                                                                           \
+}
+%}
+%union {
+    struct {
+        TSourceLoc line;
+        union {
+            TString *string;
+            float f;
+            int i;
+            bool b;
+        };
+        TSymbol* symbol;
+    } lex;
+    struct {
+        TSourceLoc line;
+        TOperator op;
+        union {
+            TIntermNode* intermNode;
+            TIntermNodePair nodePair;
+            TIntermTyped* intermTypedNode;
+            TIntermAggregate* intermAggregate;
+        };
+        union {
+            TPublicType type;
+            TQualifier qualifier;
+            TFunction* function;
+            TParameter param;
+            TTypeLine typeLine;
+            TTypeList* typeList;
+        };
+    } interm;
+}
+
+%{
+#ifndef _WIN32
+    extern int yylex(YYSTYPE*, void*);
+#endif
+%}
+
+%pure_parser /* Just in case is called from multiple threads */
+%expect 1 /* One shift reduce conflict because of if | else */
+%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
+%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
+%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
+%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
+%token <lex> STRUCT VOID_TYPE WHILE
+%token <lex> SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
+
+%token <lex> SAMPLERRECTARB SAMPLERRECTSHADOWARB // ARB_texture_rectangle
+
+%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
+%token <lex> FIELD_SELECTION
+%token <lex> LEFT_OP RIGHT_OP
+%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
+%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
+%token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
+%token <lex> SUB_ASSIGN
+
+%token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
+%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
+%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
+
+%type <interm> assignment_operator unary_operator
+%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
+%type <interm.intermTypedNode> expression integer_expression assignment_expression
+%type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
+%type <interm.intermTypedNode> relational_expression equality_expression 
+%type <interm.intermTypedNode> conditional_expression constant_expression
+%type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
+%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
+%type <interm.intermTypedNode> function_call initializer condition conditionopt
+
+%type <interm.intermNode> translation_unit function_definition
+%type <interm.intermNode> statement simple_statement
+%type <interm.intermAggregate>  statement_list compound_statement 
+%type <interm.intermNode> declaration_statement selection_statement expression_statement
+%type <interm.intermNode> declaration external_declaration
+%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
+%type <interm.nodePair> selection_rest_statement for_rest_statement
+%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope
+%type <interm> single_declaration init_declarator_list
+
+%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
+%type <interm.qualifier> parameter_qualifier
+
+%type <interm.type> type_qualifier fully_specified_type type_specifier 
+%type <interm.type> type_specifier_nonarray
+%type <interm.type> struct_specifier 
+%type <interm.typeLine> struct_declarator 
+%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
+%type <interm.function> function_header function_declarator function_identifier
+%type <interm.function> function_header_with_parameters function_call_header 
+%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
+%type <interm> function_call_or_method
+
+%start translation_unit 
+%%
+
+variable_identifier 
+    : IDENTIFIER {
+        // The symbol table search was done in the lexical phase
+        const TSymbol* symbol = $1.symbol;
+        const TVariable* variable;
+        if (symbol == 0) {
+            parseContext.error($1.line, "undeclared identifier", $1.string->c_str(), "");
+            parseContext.recover();
+            TType type(EbtFloat);
+            TVariable* fakeVariable = new TVariable($1.string, type);
+            parseContext.symbolTable.insert(*fakeVariable);
+            variable = fakeVariable;
+        } else {
+            // This identifier can only be a variable type symbol 
+            if (! symbol->isVariable()) {
+                parseContext.error($1.line, "variable expected", $1.string->c_str(), "");
+                parseContext.recover();
+            }
+            variable = static_cast<const TVariable*>(symbol);
+        }
+
+        // don't delete $1.string, it's used by error recovery, and the pool
+        // pop will reclaim the memory
+
+        if (variable->getType().getQualifier() == EvqConst ) {
+            constUnion* constArray = variable->getConstPointer();
+            TType t(variable->getType());
+            $$ = parseContext.intermediate.addConstantUnion(constArray, t, $1.line);        
+        } else
+            $$ = parseContext.intermediate.addSymbol(variable->getUniqueId(), 
+                                                     variable->getName(), 
+                                                     variable->getType(), $1.line);
+    }
+    ;
+
+primary_expression
+    : variable_identifier {
+        $$ = $1;
+    }
+    | INTCONSTANT {
+        //
+        // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders, 
+        // check for overflow for constants
+        //
+        if (abs($1.i) >= (1 << 16)) {
+            parseContext.error($1.line, " integer constant overflow", "", "");
+            parseContext.recover();
+        }
+        constUnion *unionArray = new constUnion[1];
+        unionArray->setIConst($1.i);
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
+    }
+    | FLOATCONSTANT {
+        constUnion *unionArray = new constUnion[1];
+        unionArray->setFConst($1.f);
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);
+    }
+    | BOOLCONSTANT {
+        constUnion *unionArray = new constUnion[1];
+        unionArray->setBConst($1.b);
+        $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.line);
+    }
+    | LEFT_PAREN expression RIGHT_PAREN {
+        $$ = $2;
+    }
+    ;
+
+postfix_expression
+    : primary_expression { 
+        $$ = $1;
+    } 
+    | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
+        if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
+            if ($1->getAsSymbolNode())
+                parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), "");
+            else
+                parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
+            parseContext.recover();
+        }
+        if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
+            if ($1->isArray()) { // constant folding for arrays
+                $$ = parseContext.addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+            } else if ($1->isVector()) {  // constant folding for vectors
+                TVectorFields fields;                
+                fields.num = 1;
+                fields.offsets[0] = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array
+                $$ = parseContext.addConstVectorNode(fields, $1, $2.line);
+            } else if ($1->isMatrix()) { // constant folding for matrices
+                $$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+            } 
+        } else {
+            if ($3->getQualifier() == EvqConst) {
+                if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) {
+                    parseContext.error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+                    parseContext.recover();
+                } else {
+                    if ($1->isArray()) {
+                        if ($1->getType().getArraySize() == 0) {
+                            if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) {
+                                if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line))
+                                    parseContext.recover(); 
+                            } else {
+                                if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
+                                    parseContext.recover(); 
+                            }
+                        } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) {
+                            parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+                            parseContext.recover();
+                        }
+                    }
+                    $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
+                }
+            } else {
+                if ($1->isArray() && $1->getType().getArraySize() == 0) {
+                    parseContext.error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
+                    parseContext.recover();
+                }
+                
+                $$ = parseContext.intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
+            }
+        } 
+        if ($$ == 0) {
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setFConst(0.0f);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $2.line);
+        } else if ($1->isArray()) {
+            if ($1->getType().getStruct())
+                $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
+            else
+                $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
+                
+            if ($1->getType().getQualifier() == EvqConst)
+                $$->getTypePointer()->changeQualifier(EvqConst);
+        } else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)         
+            $$->setType(TType($1->getBasicType(), EvqConst, $1->getNominalSize()));     
+        else if ($1->isMatrix())            
+            $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize()));     
+        else if ($1->isVector() && $1->getType().getQualifier() == EvqConst)          
+            $$->setType(TType($1->getBasicType(), EvqConst));     
+        else if ($1->isVector())       
+            $$->setType(TType($1->getBasicType(), EvqTemporary));
+        else
+            $$->setType($1->getType()); 
+    }
+    | function_call {
+        $$ = $1;
+    }
+    | postfix_expression DOT FIELD_SELECTION {        
+        if ($1->isArray()) {
+            parseContext.error($3.line, "cannot apply dot operator to an array", ".", "");
+            parseContext.recover();
+        }
+
+        if ($1->isVector()) {
+            TVectorFields fields;
+            if (! parseContext.parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
+                fields.num = 1;
+                fields.offsets[0] = 0;
+                parseContext.recover();
+            }
+
+            if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
+                $$ = parseContext.addConstVectorNode(fields, $1, $3.line);
+                if ($$ == 0) {
+                    parseContext.recover();
+                    $$ = $1;
+                }
+                else
+                    $$->setType(TType($1->getBasicType(), EvqConst, (int) (*$3.string).size()));
+            } else {
+                if (fields.num == 1) {
+                    constUnion *unionArray = new constUnion[1];
+                    unionArray->setIConst(fields.offsets[0]);
+                    TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
+                    $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+                    $$->setType(TType($1->getBasicType()));
+                } else {
+                    TString vectorString = *$3.string;
+                    TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, $3.line);                
+                    $$ = parseContext.intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
+                    $$->setType(TType($1->getBasicType(),EvqTemporary, (int) vectorString.size()));  
+                }
+            }
+        } else if ($1->isMatrix()) {
+            TMatrixFields fields;
+            if (! parseContext.parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
+                fields.wholeRow = false;
+                fields.wholeCol = false;
+                fields.row = 0;
+                fields.col = 0;
+                parseContext.recover();
+            }
+
+            if (fields.wholeRow || fields.wholeCol) {
+                parseContext.error($2.line, " non-scalar fields not implemented yet", ".", "");
+                parseContext.recover();
+                constUnion *unionArray = new constUnion[1];
+                unionArray->setIConst(0);
+                TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
+                $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);                
+                $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize()));
+            } else {
+                constUnion *unionArray = new constUnion[1];
+                unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
+                TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
+                $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);                
+                $$->setType(TType($1->getBasicType()));
+            }
+        } else if ($1->getBasicType() == EbtStruct) {
+            bool fieldFound = false;
+            TTypeList* fields = $1->getType().getStruct();
+            if (fields == 0) {
+                parseContext.error($2.line, "structure has no fields", "Internal Error", "");
+                parseContext.recover();
+                $$ = $1;
+            } else {
+                unsigned int i;
+                for (i = 0; i < fields->size(); ++i) {
+                    if ((*fields)[i].type->getFieldName() == *$3.string) {
+                        fieldFound = true;
+                        break;
+                    }                
+                }
+                if (fieldFound) {
+                    if ($1->getType().getQualifier() == EvqConst) {
+                        $$ = parseContext.addConstStruct(*$3.string, $1, $2.line);
+                        if ($$ == 0) {
+                            parseContext.recover();
+                            $$ = $1;
+                        }
+                        else {
+                            $$->setType(*(*fields)[i].type);
+                            // change the qualifier of the return type, not of the structure field
+                            // as the structure definition is shared between various structures.
+                            $$->getTypePointer()->changeQualifier(EvqConst);
+                        }
+                    } else {
+                        constUnion *unionArray = new constUnion[1];
+                        unionArray->setIConst(i);
+                        TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
+                        $$ = parseContext.intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);                
+                        $$->setType(*(*fields)[i].type);
+                    }
+                } else {
+                    parseContext.error($2.line, " no such field in structure", $3.string->c_str(), "");
+                    parseContext.recover();
+                    $$ = $1;
+                }
+            }
+        } else {
+            parseContext.error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
+            parseContext.recover();
+            $$ = $1;
+        }
+        // don't delete $3.string, it's from the pool
+    }
+    | postfix_expression INC_OP {
+        if (parseContext.lValueErrorCheck($2.line, "++", $1))
+            parseContext.recover();
+        $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.unaryOpError($2.line, "++", $1->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    | postfix_expression DEC_OP {
+        if (parseContext.lValueErrorCheck($2.line, "--", $1))
+            parseContext.recover();
+        $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.unaryOpError($2.line, "--", $1->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+integer_expression 
+    : expression {
+        if (parseContext.integerErrorCheck($1, "[]"))
+            parseContext.recover();
+        $$ = $1; 
+    }
+    ;
+
+function_call 
+    : function_call_or_method {
+        TFunction* fnCall = $1.function;
+        TOperator op = fnCall->getBuiltInOp();
+        
+        if (op == EOpArrayLength) {
+            if ($1.intermNode->getAsTyped() == 0 || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
+                parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
+                parseContext.recover();
+            }
+
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setIConst($1.intermNode->getAsTyped()->getType().getArraySize());
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
+        } else if (op != EOpNull) {
+            //
+            // Then this should be a constructor.
+            // Don't go through the symbol table for constructors.  
+            // Their parameters will be verified algorithmically.
+            //
+            TType type(EbtVoid);  // use this to get the type back
+            if (parseContext.constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
+                $$ = 0;
+            } else {
+                //
+                // It's a constructor, of type 'type'.
+                //
+                $$ = parseContext.addConstructor($1.intermNode, &type, op, fnCall, $1.line);
+            }
+            
+            if ($$ == 0) {        
+                parseContext.recover();
+                $$ = parseContext.intermediate.setAggregateOperator(0, op, $1.line);
+            }
+            $$->setType(type);
+        } else {
+            //
+            // Not a constructor.  Find it in the symbol table.
+            //
+            const TFunction* fnCandidate;
+            bool builtIn;
+            fnCandidate = parseContext.findFunction($1.line, fnCall, &builtIn);
+            if (fnCandidate) {
+                //
+                // A declared function.  But, it might still map to a built-in
+                // operation.
+                //
+                op = fnCandidate->getBuiltInOp();
+                if (builtIn && op != EOpNull) {
+                    //
+                    // A function call mapped to a built-in operation.
+                    //
+                    if (fnCandidate->getParamCount() == 1) {
+                        //
+                        // Treat it like a built-in unary operator.
+                        //
+                        $$ = parseContext.intermediate.addUnaryMath(op, $1.intermNode, 0, parseContext.symbolTable);
+                        if ($$ == 0)  {
+                            parseContext.error($1.intermNode->getLine(), " wrong operand type", "Internal Error", 
+                                "built in unary operator function.  Type: %s",
+                                static_cast<TIntermTyped*>($1.intermNode)->getCompleteString().c_str());
+                            YYERROR;
+                        }
+                    } else {
+                        $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
+                    }
+                } else {
+                    // This is a real function call
+                    
+                    $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
+                    $$->setType(fnCandidate->getReturnType());                   
+                    
+                    // this is how we know whether the given function is a builtIn function or a user defined function
+                    // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
+                    // if builtIn == true, it's definitely a builtIn function with EOpNull
+                    if (!builtIn) 
+                        $$->getAsAggregate()->setUserDefined(); 
+                    $$->getAsAggregate()->setName(fnCandidate->getMangledName());
+
+                    TQualifier qual;
+                    TQualifierList& qualifierList = $$->getAsAggregate()->getQualifier();
+                    for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
+                        qual = (*fnCandidate)[i].type->getQualifier();
+                        if (qual == EvqOut || qual == EvqInOut) {
+                            if (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+                                parseContext.error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
+                                parseContext.recover();
+                            }
+                        }
+                        qualifierList.push_back(qual);
+                    }
+                }
+                $$->setType(fnCandidate->getReturnType());
+            } else {
+                // error message was put out by PaFindFunction()
+                // Put on a dummy node for error recovery
+                constUnion *unionArray = new constUnion[1];
+                unionArray->setFConst(0.0f);
+                $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);
+                parseContext.recover();
+            }
+        }
+        delete fnCall;
+    }
+    ;
+
+function_call_or_method
+    : function_call_generic {
+        $$ = $1;
+    }
+    | postfix_expression DOT function_call_generic {
+        if ($1->isArray() && $3.function->getName() == "length") {
+            //
+            // implement array.length()
+            //
+            if (parseContext.extensionErrorCheck($3.line, "GL_3DL_array_objects")) {
+                parseContext.recover();
+                $$ = $3;
+            } else {
+                $$ = $3;
+                $$.intermNode = $1;
+                $$.function->relateToOperator(EOpArrayLength);
+            }
+        } else {
+            parseContext.error($3.line, "methods are not supported", "", "");
+            parseContext.recover();
+            $$ = $3;
+        }
+    }
+    ;
+
+function_call_generic
+    : function_call_header_with_parameters RIGHT_PAREN {
+        $$ = $1;
+        $$.line = $2.line;
+    }
+    | function_call_header_no_parameters RIGHT_PAREN {
+        $$ = $1;
+        $$.line = $2.line;
+    }
+    ;
+    
+function_call_header_no_parameters 
+    : function_call_header VOID_TYPE {
+        $$.function = $1;
+        $$.intermNode = 0;
+    }
+    | function_call_header {
+        $$.function = $1;
+        $$.intermNode = 0;
+    }
+    ;
+
+function_call_header_with_parameters
+    : function_call_header assignment_expression {
+        TParameter param = { 0, new TType($2->getType()) };
+        $1->addParameter(param);
+        $$.function = $1;
+        $$.intermNode = $2;
+    }
+    | function_call_header_with_parameters COMMA assignment_expression {
+        TParameter param = { 0, new TType($3->getType()) };
+        $1.function->addParameter(param);
+        $$.function = $1.function;
+        $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.line);
+    }
+    ;
+
+function_call_header 
+    : function_identifier LEFT_PAREN {
+        $$ = $1;
+    }
+    ;
+
+// Grammar Note:  Constructors look like functions, but are recognized as types.
+    
+function_identifier
+    : type_specifier {
+        //
+        // Constructor
+        //
+        if ($1.array) {
+            if (parseContext.extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
+                parseContext.recover();
+                $1.setArray(false);
+            }
+        }
+
+        if ($1.userDef) {
+            TString tempString = "";
+            TType type($1);
+            TFunction *function = new TFunction(&tempString, type, EOpConstructStruct);
+            $$ = function;
+        } else {
+            TOperator op = EOpNull;
+            switch ($1.type) {
+            case EbtFloat:
+                if ($1.matrix) {
+                    switch($1.size) {
+                    case 2:                                     op = EOpConstructMat2;  break;
+                    case 3:                                     op = EOpConstructMat3;  break;
+                    case 4:                                     op = EOpConstructMat4;  break;
+                    }         
+                } else {      
+                    switch($1.size) {
+                    case 1:                                     op = EOpConstructFloat; break;
+                    case 2:                                     op = EOpConstructVec2;  break;
+                    case 3:                                     op = EOpConstructVec3;  break;
+                    case 4:                                     op = EOpConstructVec4;  break;
+                    }       
+                }  
+                break;               
+            case EbtInt:
+                switch($1.size) {
+                case 1:                                         op = EOpConstructInt;   break;
+                case 2:       FRAG_VERT_ONLY("ivec2", $1.line); op = EOpConstructIVec2; break;
+                case 3:       FRAG_VERT_ONLY("ivec3", $1.line); op = EOpConstructIVec3; break;
+                case 4:       FRAG_VERT_ONLY("ivec4", $1.line); op = EOpConstructIVec4; break;
+                }         
+                break;    
+            case EbtBool:
+                switch($1.size) {
+                case 1:                                         op = EOpConstructBool;  break;
+                case 2:       FRAG_VERT_ONLY("bvec2", $1.line); op = EOpConstructBVec2; break;
+                case 3:       FRAG_VERT_ONLY("bvec3", $1.line); op = EOpConstructBVec3; break;
+                case 4:       FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
+                }         
+                break;
+            }
+            if (op == EOpNull) {                    
+                parseContext.error($1.line, "cannot construct this type", TType::getBasicString($1.type), "");
+                parseContext.recover();
+                $1.type = EbtFloat;
+                op = EOpConstructFloat;
+            }            
+            TString tempString = "";
+            TType type($1);
+            TFunction *function = new TFunction(&tempString, type, op);
+            $$ = function;
+        }
+    }
+    | IDENTIFIER {
+        if (parseContext.reservedErrorCheck($1.line, *$1.string)) 
+            parseContext.recover();
+        TType type(EbtVoid);
+        TFunction *function = new TFunction($1.string, type);
+        $$ = function;
+    }
+    | FIELD_SELECTION {
+        if (parseContext.reservedErrorCheck($1.line, *$1.string)) 
+            parseContext.recover();
+        TType type(EbtVoid);
+        TFunction *function = new TFunction($1.string, type);
+        $$ = function;
+    }
+    ;
+
+unary_expression
+    : postfix_expression {
+        $$ = $1;
+    }
+    | INC_OP unary_expression {
+        if (parseContext.lValueErrorCheck($1.line, "++", $2))
+            parseContext.recover();
+        $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.unaryOpError($1.line, "++", $2->getCompleteString());
+            parseContext.recover();
+            $$ = $2;
+        }
+    }
+    | DEC_OP unary_expression {
+        if (parseContext.lValueErrorCheck($1.line, "--", $2))
+            parseContext.recover();
+        $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.unaryOpError($1.line, "--", $2->getCompleteString());
+            parseContext.recover();
+            $$ = $2;
+        }
+    }
+    | unary_operator unary_expression {
+        if ($1.op != EOpNull) {
+            $$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.line, parseContext.symbolTable);
+            if ($$ == 0) {
+                char* errorOp = "";
+                switch($1.op) {
+                case EOpNegative:   errorOp = "-"; break;
+                case EOpLogicalNot: errorOp = "!"; break;
+                case EOpBitwiseNot: errorOp = "~"; break;
+                               default: break;
+                }
+                parseContext.unaryOpError($1.line, errorOp, $2->getCompleteString());
+                parseContext.recover();
+                $$ = $2;
+            }
+        } else
+            $$ = $2;
+    }
+    ;
+// Grammar Note:  No traditional style type casts.
+
+unary_operator
+    : PLUS  { $$.line = $1.line; $$.op = EOpNull; }
+    | DASH  { $$.line = $1.line; $$.op = EOpNegative; }
+    | BANG  { $$.line = $1.line; $$.op = EOpLogicalNot; }
+    | TILDE { PACK_UNPACK_ONLY("~", $1.line);  
+              $$.line = $1.line; $$.op = EOpBitwiseNot; }
+    ;
+// Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.
+
+multiplicative_expression
+    : unary_expression { $$ = $1; }
+    | multiplicative_expression STAR unary_expression {
+        FRAG_VERT_ONLY("*", $2.line);
+        $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    | multiplicative_expression SLASH unary_expression {
+        FRAG_VERT_ONLY("/", $2.line); 
+        $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    | multiplicative_expression PERCENT unary_expression {
+        PACK_UNPACK_ONLY("%", $2.line);
+        $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+additive_expression
+    : multiplicative_expression { $$ = $1; }
+    | additive_expression PLUS multiplicative_expression {  
+        $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    | additive_expression DASH multiplicative_expression {
+        $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        } 
+    }
+    ;
+
+shift_expression
+    : additive_expression { $$ = $1; }
+    | shift_expression LEFT_OP additive_expression {
+        PACK_UNPACK_ONLY("<<", $2.line);
+        $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    | shift_expression RIGHT_OP additive_expression {
+        PACK_UNPACK_ONLY(">>", $2.line);
+        $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+relational_expression
+    : shift_expression { $$ = $1; }
+    | relational_expression LEFT_ANGLE shift_expression { 
+        $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        }
+    }
+    | relational_expression RIGHT_ANGLE shift_expression  { 
+        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        }
+    }
+    | relational_expression LE_OP shift_expression  { 
+        $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        }
+    }
+    | relational_expression GE_OP shift_expression  { 
+        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        }
+    }
+    ;
+
+equality_expression
+    : relational_expression { $$ = $1; }
+    | equality_expression EQ_OP relational_expression  {
+        $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        } else if (($1->isArray() || $3->isArray()) && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects"))
+            parseContext.recover();
+    }
+    | equality_expression NE_OP relational_expression { 
+        $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        } else if (($1->isArray() || $3->isArray()) && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects"))
+            parseContext.recover();
+    }
+    ;
+
+and_expression
+    : equality_expression { $$ = $1; }
+    | and_expression AMPERSAND equality_expression {
+        PACK_UNPACK_ONLY("&", $2.line);
+        $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+exclusive_or_expression
+    : and_expression { $$ = $1; }
+    | exclusive_or_expression CARET and_expression {
+        PACK_UNPACK_ONLY("^", $2.line);
+        $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+inclusive_or_expression
+    : exclusive_or_expression { $$ = $1; }
+    | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
+        PACK_UNPACK_ONLY("|", $2.line);
+        $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+logical_and_expression
+    : inclusive_or_expression { $$ = $1; }
+    | logical_and_expression AND_OP inclusive_or_expression {
+        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        }
+    }
+    ;
+
+logical_xor_expression
+    : logical_and_expression { $$ = $1; }
+    | logical_xor_expression XOR_OP logical_and_expression  { 
+        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        }
+    }
+    ;
+
+logical_or_expression
+    : logical_xor_expression { $$ = $1; }
+    | logical_or_expression OR_OP logical_xor_expression  { 
+        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, parseContext.symbolTable);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            constUnion *unionArray = new constUnion[1];
+            unionArray->setBConst(false);
+            $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
+        }
+    }
+    ;
+
+conditional_expression
+    : logical_or_expression { $$ = $1; }
+    | logical_or_expression QUESTION expression COLON assignment_expression {
+       if (parseContext.boolErrorCheck($2.line, $1))
+            parseContext.recover();
+       
+        $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.line);
+        if ($3->getType() != $5->getType())
+            $$ = 0;
+            
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
+            parseContext.recover();
+            $$ = $5;
+        }
+    }
+    ;
+
+assignment_expression
+    : conditional_expression { $$ = $1; }
+    | unary_expression assignment_operator assignment_expression {        
+        if (parseContext.lValueErrorCheck($2.line, "assign", $1))
+            parseContext.recover();
+        $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.line);
+        if ($$ == 0) {
+            parseContext.assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $1;
+        } else if (($1->isArray() || $3->isArray()) && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects"))
+            parseContext.recover();
+    }
+    ;
+
+assignment_operator
+    : EQUAL        {                                    $$.line = $1.line; $$.op = EOpAssign; }
+    | MUL_ASSIGN   { FRAG_VERT_ONLY("*=", $1.line);     $$.line = $1.line; $$.op = EOpMulAssign; }
+    | DIV_ASSIGN   { FRAG_VERT_ONLY("/=", $1.line);     $$.line = $1.line; $$.op = EOpDivAssign; }
+    | MOD_ASSIGN   { PACK_UNPACK_ONLY("%=", $1.line);   $$.line = $1.line; $$.op = EOpModAssign; }
+    | ADD_ASSIGN   {                                    $$.line = $1.line; $$.op = EOpAddAssign; }
+    | SUB_ASSIGN   {                                    $$.line = $1.line; $$.op = EOpSubAssign; }
+    | LEFT_ASSIGN  { PACK_UNPACK_ONLY("<<=", $1.line);  $$.line = $1.line; $$.op = EOpLeftShiftAssign; }
+    | RIGHT_ASSIGN { PACK_UNPACK_ONLY("<<=", $1.line);  $$.line = $1.line; $$.op = EOpRightShiftAssign; }
+    | AND_ASSIGN   { PACK_UNPACK_ONLY("&=",  $1.line);  $$.line = $1.line; $$.op = EOpAndAssign; }
+    | XOR_ASSIGN   { PACK_UNPACK_ONLY("^=",  $1.line);  $$.line = $1.line; $$.op = EOpExclusiveOrAssign; }
+    | OR_ASSIGN    { PACK_UNPACK_ONLY("|=",  $1.line);  $$.line = $1.line; $$.op = EOpInclusiveOrAssign; }
+    ;
+
+expression
+    : assignment_expression {
+        $$ = $1;
+    }
+    | expression COMMA assignment_expression {
+        $$ = parseContext.intermediate.addComma($1, $3, $2.line);
+        if ($$ == 0) {
+            parseContext.binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
+            parseContext.recover();
+            $$ = $3;
+        }
+    }
+    ;
+
+constant_expression
+    : conditional_expression {
+        if (parseContext.constErrorCheck($1))
+            parseContext.recover();
+        $$ = $1;
+    }
+    ;
+
+declaration
+    : function_prototype SEMICOLON   { $$ = 0; }
+    | init_declarator_list SEMICOLON { 
+        if ($1.intermAggregate)
+            $1.intermAggregate->setOperator(EOpSequence); 
+        $$ = $1.intermAggregate; 
+    }
+    ;
+
+function_prototype 
+    : function_declarator RIGHT_PAREN  {
+        //
+        // Multiple declarations of the same function are allowed.
+        //
+        // If this is a definition, the definition production code will check for redefinitions 
+        // (we don't know at this point if it's a definition or not).
+        //
+        // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
+        //        
+        TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find($1->getMangledName()));
+        if (prevDec) {
+            if (prevDec->getReturnType() != $1->getReturnType()) {
+                parseContext.error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), "");
+                parseContext.recover();
+            }
+            for (int i = 0; i < prevDec->getParamCount(); ++i) {
+                if ((*prevDec)[i].type->getQualifier() != (*$1)[i].type->getQualifier()) {
+                    parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getQualifierString(), "");
+                    parseContext.recover();
+                }
+            }
+        }
+        
+        //
+        // If this is a redeclaration, it could also be a definition,
+        // in which case, we want to use the variable names from this one, and not the one that's
+        // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
+        //
+        $$.function = $1;
+        $$.line = $2.line;
+
+        parseContext.symbolTable.insert(*$$.function);
+    }
+    ;
+
+function_declarator 
+    : function_header {
+        $$ = $1;
+    }
+    | function_header_with_parameters { 
+        $$ = $1;  
+    }
+    ;
+
+
+function_header_with_parameters
+    : function_header parameter_declaration {
+        // Add the parameter 
+        $$ = $1;
+        if ($2.param.type->getBasicType() != EbtVoid)
+            $1->addParameter($2.param);
+        else
+            delete $2.param.type;
+    }
+    | function_header_with_parameters COMMA parameter_declaration {   
+        //
+        // Only first parameter of one-parameter functions can be void
+        // The check for named parameters not being void is done in parameter_declarator 
+        //
+        if ($3.param.type->getBasicType() == EbtVoid) {
+            //
+            // This parameter > first is void
+            //
+            parseContext.error($2.line, "cannot be an argument type except for '(void)'", "void", "");
+            parseContext.recover();
+            delete $3.param.type;
+        } else {
+            // Add the parameter 
+            $$ = $1; 
+            $1->addParameter($3.param);
+        }
+    }
+    ;
+
+function_header 
+    : fully_specified_type IDENTIFIER LEFT_PAREN {
+        if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
+            parseContext.error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), "");
+            parseContext.recover();
+        }
+        // make sure a sampler is not involved as well...
+        if (parseContext.structQualifierErrorCheck($2.line, $1))
+            parseContext.recover();
+        
+        // Add the function as a prototype after parsing it (we do not support recursion) 
+        TFunction *function;
+        TType type($1);
+        function = new TFunction($2.string, type);
+        $$ = function;
+    }
+    ;
+
+parameter_declarator
+    // Type + name 
+    : type_specifier IDENTIFIER {
+        if ($1.type == EbtVoid) {
+            parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
+            parseContext.recover();
+        }
+        if (parseContext.reservedErrorCheck($2.line, *$2.string))
+            parseContext.recover();
+        TParameter param = {$2.string, new TType($1)};
+        $$.line = $2.line;
+        $$.param = param;
+    }
+    | type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        // Check that we can make an array out of this type
+        if (parseContext.arrayTypeErrorCheck($3.line, $1))
+            parseContext.recover();
+            
+        if (parseContext.reservedErrorCheck($2.line, *$2.string))
+            parseContext.recover();
+            
+        int size;
+        if (parseContext.arraySizeErrorCheck($3.line, $4, size))
+            parseContext.recover();
+        $1.setArray(true, size);
+             
+        TType* type = new TType($1);
+        TParameter param = { $2.string, type };
+        $$.line = $2.line;
+        $$.param = param;
+    }
+    ;
+
+parameter_declaration 
+    // 
+    // The only parameter qualifier a parameter can have are 
+    // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
+    //
+    
+    //
+    // Type + name 
+    //
+    : type_qualifier parameter_qualifier parameter_declarator {
+        $$ = $3;
+        if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+            parseContext.recover();
+    }
+    | parameter_qualifier parameter_declarator {
+        $$ = $2;
+        if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+            parseContext.recover();
+        if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+            parseContext.recover();
+    }
+    //
+    // Only type 
+    //
+    | type_qualifier parameter_qualifier parameter_type_specifier {
+        $$ = $3;
+        if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+            parseContext.recover();
+    }
+    | parameter_qualifier parameter_type_specifier {
+        $$ = $2;
+        if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+            parseContext.recover();
+        if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+            parseContext.recover();
+    }
+    ;
+    
+parameter_qualifier
+    : /* empty */ {
+        $$ = EvqIn;
+    }
+    | IN_QUAL {
+        $$ = EvqIn;
+    }
+    | OUT_QUAL {
+        $$ = EvqOut;
+    }
+    | INOUT_QUAL {
+        $$ = EvqInOut;
+    }
+    ;
+
+parameter_type_specifier 
+    : type_specifier {
+        TParameter param = { 0, new TType($1) };
+        $$.param = param;
+    }
+    ;
+
+init_declarator_list
+    : single_declaration {
+        $$ = $1;
+    } 
+    | init_declarator_list COMMA IDENTIFIER {
+        $$ = $1;
+        if (parseContext.structQualifierErrorCheck($3.line, $$.type))
+            parseContext.recover();
+        
+        if (parseContext.nonInitConstErrorCheck($3.line, *$3.string, $$.type))
+            parseContext.recover();
+
+        if (parseContext.nonInitErrorCheck($3.line, *$3.string, $$.type))
+            parseContext.recover();
+    }
+    | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
+        if (parseContext.structQualifierErrorCheck($3.line, $1.type))
+            parseContext.recover();
+            
+        if (parseContext.nonInitConstErrorCheck($3.line, *$3.string, $1.type))
+            parseContext.recover();
+
+        $$ = $1;
+        
+        if (parseContext.arrayTypeErrorCheck($4.line, $1.type) || parseContext.arrayQualifierErrorCheck($4.line, $1.type))
+            parseContext.recover();
+        else {
+            $1.type.setArray(true);
+            TVariable* variable;
+            if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+                parseContext.recover();
+        }
+    }
+    | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        if (parseContext.structQualifierErrorCheck($3.line, $1.type))
+            parseContext.recover();
+            
+        if (parseContext.nonInitConstErrorCheck($3.line, *$3.string, $1.type))
+            parseContext.recover();
+        
+        $$ = $1;
+
+        if (parseContext.arrayTypeErrorCheck($4.line, $1.type) || parseContext.arrayQualifierErrorCheck($4.line, $1.type))
+            parseContext.recover();
+        else {
+            int size;
+            if (parseContext.arraySizeErrorCheck($4.line, $5, size))
+                parseContext.recover();
+            $1.type.setArray(true, size);        
+            TVariable* variable;
+            if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+                parseContext.recover();
+        }
+    }
+    | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
+        if (parseContext.structQualifierErrorCheck($3.line, $1.type))
+            parseContext.recover();
+            
+        $$ = $1;
+            
+        TVariable* variable = 0;
+        if (parseContext.arrayTypeErrorCheck($4.line, $1.type) || parseContext.arrayQualifierErrorCheck($4.line, $1.type))
+            parseContext.recover();
+        else {
+                       $1.type.setArray(true, $7->getType().getArraySize());
+            if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+                parseContext.recover();
+        }
+
+        if (parseContext.extensionErrorCheck($$.line, "GL_3DL_array_objects"))
+            parseContext.recover();
+        else {
+            TIntermNode* intermNode;
+            if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $7, intermNode, variable)) {
+                //
+                // build the intermediate representation
+                //
+                if (intermNode)
+                    $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $6.line);
+                else
+                    $$.intermAggregate = $1.intermAggregate;
+            } else {
+                parseContext.recover();
+                $$.intermAggregate = 0;
+            }
+        }
+    }
+    | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
+        if (parseContext.structQualifierErrorCheck($3.line, $1.type))
+            parseContext.recover();
+            
+        $$ = $1;
+            
+        TVariable* variable = 0;
+        if (parseContext.arrayTypeErrorCheck($4.line, $1.type) || parseContext.arrayQualifierErrorCheck($4.line, $1.type))
+            parseContext.recover();
+        else {
+            int size;
+            if (parseContext.arraySizeErrorCheck($4.line, $5, size))
+                parseContext.recover();
+            $1.type.setArray(true, size);
+            if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+                parseContext.recover();
+        }
+
+        if (parseContext.extensionErrorCheck($$.line, "GL_3DL_array_objects"))
+            parseContext.recover();
+        else {
+            TIntermNode* intermNode;
+            if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $8, intermNode, variable)) {
+                //
+                // build the intermediate representation
+                //
+                if (intermNode)
+                    $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $7.line);
+                else
+                    $$.intermAggregate = $1.intermAggregate;
+            } else {
+                parseContext.recover();
+                $$.intermAggregate = 0;
+            }
+        }
+    }
+    | init_declarator_list COMMA IDENTIFIER EQUAL initializer {
+        if (parseContext.structQualifierErrorCheck($3.line, $1.type))
+            parseContext.recover();
+        
+        $$ = $1;
+        
+        TIntermNode* intermNode;
+        if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) {
+            //
+            // build the intermediate representation
+            //
+            if (intermNode)
+                $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.line);
+            else
+                $$.intermAggregate = $1.intermAggregate;
+        } else {
+            parseContext.recover();
+            $$.intermAggregate = 0;
+        }
+    }
+    ;
+
+single_declaration 
+    : fully_specified_type {
+        $$.type = $1;
+        $$.intermAggregate = 0;
+    }    
+    | fully_specified_type IDENTIFIER {
+        $$.intermAggregate = 0;
+        $$.type = $1;
+
+        if (parseContext.structQualifierErrorCheck($2.line, $$.type))
+            parseContext.recover();
+        
+        if (parseContext.nonInitConstErrorCheck($2.line, *$2.string, $$.type))
+            parseContext.recover();
+
+        if (parseContext.nonInitErrorCheck($2.line, *$2.string, $$.type))
+            parseContext.recover();
+    }
+    | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
+        $$.intermAggregate = 0;
+        if (parseContext.structQualifierErrorCheck($2.line, $1))
+            parseContext.recover();
+
+        if (parseContext.nonInitConstErrorCheck($2.line, *$2.string, $1))
+            parseContext.recover();
+
+        $$.type = $1;
+
+        if (parseContext.arrayTypeErrorCheck($3.line, $1) || parseContext.arrayQualifierErrorCheck($3.line, $1))
+            parseContext.recover();
+        else {
+            $1.setArray(true);        
+            TVariable* variable;
+            if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
+                parseContext.recover();
+        }
+    }
+    | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        $$.intermAggregate = 0;
+        if (parseContext.structQualifierErrorCheck($2.line, $1))
+            parseContext.recover();
+
+        if (parseContext.nonInitConstErrorCheck($2.line, *$2.string, $1))
+            parseContext.recover();
+            
+        $$.type = $1;
+
+        if (parseContext.arrayTypeErrorCheck($3.line, $1) || parseContext.arrayQualifierErrorCheck($3.line, $1))
+            parseContext.recover();
+        else {
+            int size;
+            if (parseContext.arraySizeErrorCheck($3.line, $4, size))
+                parseContext.recover();
+            
+            $1.setArray(true, size);
+            TVariable* variable;
+            if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
+                parseContext.recover();
+        }
+    }
+    | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
+        $$.intermAggregate = 0;
+
+        if (parseContext.structQualifierErrorCheck($2.line, $1))
+            parseContext.recover();
+
+        $$.type = $1;
+
+        TVariable* variable = 0;
+        if (parseContext.arrayTypeErrorCheck($3.line, $1) || parseContext.arrayQualifierErrorCheck($3.line, $1))
+            parseContext.recover();
+        else {
+            $1.setArray(true, $6->getType().getArraySize());
+            if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
+                parseContext.recover();
+        }
+
+        if (parseContext.extensionErrorCheck($$.line, "GL_3DL_array_objects"))
+            parseContext.recover();
+        else {        
+            TIntermNode* intermNode;
+            if (!parseContext.executeInitializer($2.line, *$2.string, $1, $6, intermNode, variable)) {
+                //
+                // Build intermediate representation
+                //
+                if (intermNode)
+                    $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $5.line);
+                else
+                    $$.intermAggregate = 0;
+            } else {
+                parseContext.recover();
+                $$.intermAggregate = 0;
+            }
+        }
+    }
+    | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
+        $$.intermAggregate = 0;
+
+        if (parseContext.structQualifierErrorCheck($2.line, $1))
+            parseContext.recover();
+
+        $$.type = $1;
+
+        TVariable* variable = 0;
+        if (parseContext.arrayTypeErrorCheck($3.line, $1) || parseContext.arrayQualifierErrorCheck($3.line, $1))
+            parseContext.recover();
+        else {
+            int size;
+            if (parseContext.arraySizeErrorCheck($3.line, $4, size))
+                parseContext.recover();
+            
+            $1.setArray(true, size);
+            if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
+                parseContext.recover();
+        }
+
+        if (parseContext.extensionErrorCheck($$.line, "GL_3DL_array_objects"))
+            parseContext.recover();
+        else {        
+            TIntermNode* intermNode;
+            if (!parseContext.executeInitializer($2.line, *$2.string, $1, $7, intermNode, variable)) {
+                //
+                // Build intermediate representation
+                //
+                if (intermNode)
+                    $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $6.line);
+                else
+                    $$.intermAggregate = 0;
+            } else {
+                parseContext.recover();
+                $$.intermAggregate = 0;
+            }
+        }        
+    }
+    | fully_specified_type IDENTIFIER EQUAL initializer {
+        if (parseContext.structQualifierErrorCheck($2.line, $1))
+            parseContext.recover();
+
+        $$.type = $1;
+
+        TIntermNode* intermNode;
+        if (!parseContext.executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
+            //
+            // Build intermediate representation
+            //
+            if (intermNode)
+                $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.line);
+            else
+                $$.intermAggregate = 0;
+        } else {
+            parseContext.recover();
+            $$.intermAggregate = 0;
+        }
+    }
+    
+//
+// Place holder for the pack/unpack languages.
+//
+//    | buffer_specifier {
+//        $$.intermAggregate = 0;
+//    }
+    ;
+
+// Grammar Note:  No 'enum', or 'typedef'.
+
+//
+// Place holder for the pack/unpack languages.
+//
+//%type <interm> buffer_declaration
+//%type <interm.type> buffer_specifier input_or_output buffer_declaration_list 
+//buffer_specifier
+//    : input_or_output LEFT_BRACE buffer_declaration_list RIGHT_BRACE {
+//    }
+//    ;
+//
+//input_or_output
+//    : INPUT {
+//        if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "input"))
+//            parseContext.recover();
+//        UNPACK_ONLY("input", $1.line);
+//        $$.qualifier = EvqInput;        
+//    }
+//    | OUTPUT {
+//        if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "output"))
+//            parseContext.recover();
+//        PACK_ONLY("output", $1.line);
+//        $$.qualifier = EvqOutput;
+//    }
+//    ;
+
+//
+// Place holder for the pack/unpack languages.
+//
+//buffer_declaration_list
+//    : buffer_declaration {
+//    }
+//    | buffer_declaration_list buffer_declaration {
+//    }
+//    ;
+
+//
+// Input/output semantics:
+//   float must be 16 or 32 bits
+//   float alignment restrictions?
+//   check for only one input and only one output
+//   sum of bitfields has to be multiple of 32
+//
+
+//
+// Place holder for the pack/unpack languages.
+//
+//buffer_declaration
+//    : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
+//        if (parseContext.reservedErrorCheck($2.line, *$2.string, parseContext))
+//            parseContext.recover();
+//        $$.variable = new TVariable($2.string, $1);
+//        if (! parseContext.symbolTable.insert(*$$.variable)) {
+//            parseContext.error($2.line, "redefinition", $$.variable->getName().c_str(), "");
+//            parseContext.recover();
+//            // don't have to delete $$.variable, the pool pop will take care of it
+//        }
+//    }
+//    ;
+
+fully_specified_type
+    : type_specifier {
+        $$ = $1;
+                
+        if ($1.array) {
+            if (parseContext.extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
+                parseContext.recover();
+                $1.setArray(false);
+            }
+        }
+    }
+    | type_qualifier type_specifier  {        
+        if ($2.array && parseContext.extensionErrorCheck($2.line, "GL_3DL_array_objects")) {
+            parseContext.recover();
+            $2.setArray(false);
+        }
+        if ($2.array && parseContext.arrayQualifierErrorCheck($2.line, $1)) {
+            parseContext.recover();
+            $2.setArray(false);
+        }
+        
+        if ($1.qualifier == EvqAttribute &&
+            ($2.type == EbtBool || $2.type == EbtInt)) {
+            parseContext.error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
+            parseContext.recover();
+        }
+        if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
+            ($2.type == EbtBool || $2.type == EbtInt)) {
+            parseContext.error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
+            parseContext.recover();
+        }
+        $$ = $2; 
+        $$.qualifier = $1.qualifier;
+    }
+    ;
+
+type_qualifier
+    : CONST_QUAL {
+        $$.setBasic(EbtVoid, EvqConst, $1.line);
+    }
+    | ATTRIBUTE { 
+        VERTEX_ONLY("attribute", $1.line);
+        if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute"))
+            parseContext.recover();
+        $$.setBasic(EbtVoid, EvqAttribute, $1.line);
+    }
+    | VARYING {
+        if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"))
+            parseContext.recover();
+        if (parseContext.language == EShLangVertex)
+            $$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
+        else
+            $$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
+    }
+    | UNIFORM {
+        if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
+            parseContext.recover();
+        $$.setBasic(EbtVoid, EvqUniform, $1.line);
+    }
+    ;
+
+type_specifier
+    : type_specifier_nonarray {
+        $$ = $1;
+    }
+    | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        $$ = $1;
+        
+        if (parseContext.arrayTypeErrorCheck($2.line, $1))
+            parseContext.recover();
+        else {
+            int size;
+            if (parseContext.arraySizeErrorCheck($2.line, $3, size))
+                parseContext.recover();
+            $$.setArray(true, size);
+        }
+    }
+    ;
+
+type_specifier_nonarray
+    : VOID_TYPE {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtVoid, qual, $1.line); 
+    }
+    | FLOAT_TYPE {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, $1.line);
+    }
+    | INT_TYPE {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, $1.line);
+    }
+    | BOOL_TYPE {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, $1.line);
+    }
+//    | UNSIGNED INT_TYPE { 
+//        PACK_UNPACK_ONLY("unsigned", $1.line); 
+//        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+//        $$.setBasic(EbtInt, qual, $1.line); 
+//    }
+    | VEC2 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setAggregate(2);
+    }
+    | VEC3 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setAggregate(3);
+    }
+    | VEC4 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setAggregate(4);
+    }
+    | BVEC2 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, $1.line);
+        $$.setAggregate(2);
+    }
+    | BVEC3 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, $1.line);
+        $$.setAggregate(3);
+    }
+    | BVEC4 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, $1.line);
+        $$.setAggregate(4);
+    }
+    | IVEC2 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, $1.line);
+        $$.setAggregate(2);
+    }
+    | IVEC3 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, $1.line);
+        $$.setAggregate(3);
+    }
+    | IVEC4 {
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, $1.line);
+        $$.setAggregate(4);
+    }
+    | MATRIX2 {
+        FRAG_VERT_ONLY("mat2", $1.line); 
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setAggregate(2, true);
+    }
+    | MATRIX3 { 
+        FRAG_VERT_ONLY("mat3", $1.line); 
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setAggregate(3, true);
+    }
+    | MATRIX4 { 
+        FRAG_VERT_ONLY("mat4", $1.line);
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, $1.line);
+        $$.setAggregate(4, true);
+    } 
+    | SAMPLER1D {
+        FRAG_VERT_ONLY("sampler1D", $1.line);
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler1D, qual, $1.line);
+    } 
+    | SAMPLER2D {
+        FRAG_VERT_ONLY("sampler2D", $1.line);
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler2D, qual, $1.line);
+    } 
+    | SAMPLER3D {
+        FRAG_VERT_ONLY("sampler3D", $1.line);
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler3D, qual, $1.line);
+    } 
+    | SAMPLERCUBE {
+        FRAG_VERT_ONLY("samplerCube", $1.line);
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSamplerCube, qual, $1.line);
+    } 
+    | SAMPLER1DSHADOW {
+        FRAG_VERT_ONLY("sampler1DShadow", $1.line);
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler1DShadow, qual, $1.line);
+    } 
+    | SAMPLER2DSHADOW {
+        FRAG_VERT_ONLY("sampler2DShadow", $1.line);
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler2DShadow, qual, $1.line);
+    } 
+    | SAMPLERRECTARB {
+        // ARB_texture_rectangle
+
+        FRAG_VERT_ONLY("samplerRectARB", $1.line);
+        if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle"))
+            parseContext.recover();
+        
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSamplerRect, qual, $1.line);
+    }
+    | SAMPLERRECTSHADOWARB {
+        // ARB_texture_rectangle
+
+        FRAG_VERT_ONLY("samplerRectShadowARB", $1.line);
+        if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle"))
+            parseContext.recover();
+
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSamplerRectShadow, qual, $1.line);
+    }
+    | struct_specifier {
+        FRAG_VERT_ONLY("struct", $1.line);
+        $$ = $1;
+        $$.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+    }
+    | TYPE_NAME {     
+        //
+        // This is for user defined type names.  The lexical phase looked up the 
+        // type.
+        //
+        TType& structure = static_cast<TVariable*>($1.symbol)->getType();
+        TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtStruct, qual, $1.line);
+        $$.userDef = &structure;
+    }
+    ;
+
+struct_specifier
+    : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
+        TType* structure = new TType($4, *$2.string);
+        TVariable* userTypeDef = new TVariable($2.string, *structure, true);
+        if (! parseContext.symbolTable.insert(*userTypeDef)) {
+            parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct");
+            parseContext.recover();
+        }
+        $$.setBasic(EbtStruct, EvqTemporary, $1.line);
+        $$.userDef = structure;
+    }
+    | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE {
+        TType* structure = new TType($3, TString(""));
+        $$.setBasic(EbtStruct, EvqTemporary, $1.line);
+        $$.userDef = structure;
+    }
+    ;
+    
+struct_declaration_list
+    : struct_declaration {
+        $$ = $1;
+    }
+    | struct_declaration_list struct_declaration {
+        $$ = $1;
+        for (unsigned int i = 0; i < $2->size(); ++i) {
+            for (unsigned int j = 0; j < $$->size(); ++j) {
+                if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
+                    parseContext.error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
+                    parseContext.recover();
+                }
+            }
+            $$->push_back((*$2)[i]);
+        }
+    }
+    ;
+    
+struct_declaration
+    : type_specifier struct_declarator_list SEMICOLON {
+        $$ = $2;
+        
+        if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
+            parseContext.recover();
+        }
+        for (unsigned int i = 0; i < $$->size(); ++i) {
+            //
+            // Careful not to replace already know aspects of type, like array-ness
+            //
+            (*$$)[i].type->setType($1.type, $1.size, $1.matrix, $1.userDef);
+
+            // don't allow arrays of arrays
+            if ((*$$)[i].type->isArray()) {
+                if (parseContext.arrayTypeErrorCheck($1.line, $1))
+                    parseContext.recover();
+            }
+            if ($1.array)
+                (*$$)[i].type->setArraySize($1.arraySize);
+            if ($1.userDef)
+                (*$$)[i].type->setTypeName($1.userDef->getTypeName());
+        }
+    }
+    ;
+        
+struct_declarator_list
+    : struct_declarator {
+        $$ = NewPoolTTypeList();
+        $$->push_back($1);
+    }
+    | struct_declarator_list COMMA struct_declarator {
+        $$->push_back($3);
+    }
+    ;
+    
+struct_declarator
+    : IDENTIFIER {
+        $$.type = new TType(EbtVoid);
+        $$.line = $1.line;
+        $$.type->setFieldName(*$1.string);
+    }
+    | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        $$.type = new TType(EbtVoid);
+        $$.line = $1.line;
+        $$.type->setFieldName(*$1.string);
+        
+        int size;
+        if (parseContext.arraySizeErrorCheck($2.line, $3, size))
+            parseContext.recover();
+        $$.type->setArraySize(size);
+    }
+    ;
+
+initializer
+    : assignment_expression { $$ = $1; }
+    ;
+
+declaration_statement 
+    : declaration { $$ = $1; }
+    ;
+
+statement
+    : compound_statement  { $$ = $1; }
+    | simple_statement    { $$ = $1; }
+    ;
+
+// Grammar Note:  No labeled statements; 'goto' is not supported.
+
+simple_statement 
+    : declaration_statement { $$ = $1; }
+    | expression_statement  { $$ = $1; } 
+    | selection_statement   { $$ = $1; }
+    | iteration_statement   { $$ = $1; }
+    | jump_statement        { $$ = $1; }
+    ;
+
+compound_statement
+    : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
+    | LEFT_BRACE { parseContext.symbolTable.push(); } statement_list { parseContext.symbolTable.pop(); } RIGHT_BRACE {
+        if ($3 != 0)            
+            $3->setOperator(EOpSequence); 
+        $$ = $3;
+    }
+    ;
+
+statement_no_new_scope 
+    : compound_statement_no_new_scope { $$ = $1; }
+    | simple_statement                { $$ = $1; }
+    ;
+
+compound_statement_no_new_scope 
+    // Statement that doesn't create a new scope, for selection_statement, iteration_statement 
+    : LEFT_BRACE RIGHT_BRACE { 
+        $$ = 0; 
+    }
+    | LEFT_BRACE statement_list RIGHT_BRACE { 
+        if ($2)
+            $2->setOperator(EOpSequence); 
+        $$ = $2; 
+    }
+    ;
+
+statement_list
+    : statement {
+        $$ = parseContext.intermediate.makeAggregate($1, 0); 
+    }
+    | statement_list statement { 
+        $$ = parseContext.intermediate.growAggregate($1, $2, 0);
+    }
+    ;
+
+expression_statement
+    : SEMICOLON  { $$ = 0; }
+    | expression SEMICOLON  { $$ = static_cast<TIntermNode*>($1); }
+    ;
+
+selection_statement
+    : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { 
+        if (parseContext.boolErrorCheck($1.line, $3))
+            parseContext.recover();
+        $$ = parseContext.intermediate.addSelection($3, $5, $1.line);
+    }
+    ;
+
+selection_rest_statement 
+    : statement ELSE statement {
+        $$.node1 = $1;
+        $$.node2 = $3;
+    }
+    | statement { 
+        $$.node1 = $1;
+        $$.node2 = 0;
+    }
+    ;
+
+// Grammar Note:  No 'switch'.  Switch statements not supported.
+
+condition
+    // In 1996 c++ draft, conditions can include single declarations 
+    : expression {
+        $$ = $1;
+        if (parseContext.boolErrorCheck($1->getLine(), $1))
+            parseContext.recover();          
+    }
+    | fully_specified_type IDENTIFIER EQUAL initializer {
+        TIntermNode* intermNode;
+        if (parseContext.structQualifierErrorCheck($2.line, $1))
+            parseContext.recover();
+        if (parseContext.boolErrorCheck($2.line, $1))
+            parseContext.recover();
+        
+        if (!parseContext.executeInitializer($2.line, *$2.string, $1, $4, intermNode))
+            $$ = $4;
+        else {
+            parseContext.recover();
+            $$ = 0;
+        }
+    }
+    ;
+
+iteration_statement
+    : WHILE LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope { 
+        parseContext.symbolTable.pop();
+        $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.line);
+        --parseContext.loopNestingLevel;
+    }
+    | DO { ++parseContext.loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
+        if (parseContext.boolErrorCheck($8.line, $6))
+            parseContext.recover();
+                    
+        $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line);
+        --parseContext.loopNestingLevel;
+    }
+    | FOR LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
+        parseContext.symbolTable.pop();
+        $$ = parseContext.intermediate.makeAggregate($4, $2.line);
+        $$ = parseContext.intermediate.growAggregate(
+                $$,
+                parseContext.intermediate.addLoop($7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.line),
+                $1.line);
+        $$->getAsAggregate()->setOperator(EOpSequence);
+        --parseContext.loopNestingLevel;
+    }
+    ;
+
+for_init_statement 
+    : expression_statement {
+        $$ = $1; 
+    } 
+    | declaration_statement {
+        $$ = $1;
+    }
+    ;
+
+conditionopt 
+    : condition { 
+        $$ = $1; 
+    }
+    | /* May be null */ { 
+        $$ = 0; 
+    }
+    ;
+
+for_rest_statement 
+    : conditionopt SEMICOLON { 
+        $$.node1 = $1;
+        $$.node2 = 0;
+    }
+    | conditionopt SEMICOLON expression  {
+        $$.node1 = $1;
+        $$.node2 = $3;
+    }
+    ;
+
+jump_statement
+    : CONTINUE SEMICOLON {
+        if (parseContext.loopNestingLevel <= 0) {
+            parseContext.error($1.line, "continue statement only allowed in loops", "", "");
+            parseContext.recover();
+        }        
+        $$ = parseContext.intermediate.addBranch(EOpContinue, $1.line);
+    }
+    | BREAK SEMICOLON {
+        if (parseContext.loopNestingLevel <= 0) {
+            parseContext.error($1.line, "break statement only allowed in loops", "", "");
+            parseContext.recover();
+        }        
+        $$ = parseContext.intermediate.addBranch(EOpBreak, $1.line);
+    }
+    | RETURN SEMICOLON {
+        $$ = parseContext.intermediate.addBranch(EOpReturn, $1.line);
+        if (parseContext.currentFunctionType->getBasicType() != EbtVoid) {
+            parseContext.error($1.line, "non-void function must return a value", "return", "");
+            parseContext.recover();
+        }
+    }
+    | RETURN expression SEMICOLON {        
+        $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.line);
+        parseContext.functionReturnsValue = true;
+        if (parseContext.currentFunctionType->getBasicType() == EbtVoid) {
+            parseContext.error($1.line, "void function cannot return a value", "return", "");
+            parseContext.recover();
+        } else if (*(parseContext.currentFunctionType) != $2->getType()) {
+            parseContext.error($1.line, "function return is not matching type:", "return", "");
+            parseContext.recover();
+        }
+    }
+    | DISCARD SEMICOLON {
+        FRAG_ONLY("discard", $1.line);
+        $$ = parseContext.intermediate.addBranch(EOpKill, $1.line);
+    }        
+    ;
+
+// Grammar Note:  No 'goto'.  Gotos are not supported.
+
+translation_unit
+    : external_declaration { 
+        $$ = $1; 
+        parseContext.treeRoot = $$; 
+    }
+    | translation_unit external_declaration {
+        $$ = parseContext.intermediate.growAggregate($1, $2, 0);
+        parseContext.treeRoot = $$;
+    }
+    ;
+
+external_declaration
+    : function_definition { 
+        $$ = $1; 
+    }
+    | declaration { 
+        $$ = $1; 
+    }
+    ;
+
+function_definition
+    : function_prototype {
+        TFunction& function = *($1.function);
+        TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find(function.getMangledName()));
+        //
+        // Note:  'prevDec' could be 'function' if this is the first time we've seen function
+        // as it would have just been put in the symbol table.  Otherwise, we're looking up
+        // an earlier occurance.
+        //
+        if (prevDec->isDefined()) {
+            //
+            // Then this function already has a body.
+            //
+            parseContext.error($1.line, "function already has a body", function.getName().c_str(), "");
+            parseContext.recover();
+        }
+        prevDec->setDefined();
+        
+        //
+        // Raise error message if main function takes any parameters or return anything other than void
+        //
+        if (function.getName() == "main") {
+            if (function.getParamCount() > 0) {
+                parseContext.error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), "");
+                parseContext.recover();
+            }
+            if (function.getReturnType().getBasicType() != EbtVoid) {
+                parseContext.error($1.line, "", function.getReturnType().getBasicString(), "main function cannot return a value");
+                parseContext.recover();
+            }            
+        }
+   
+        //
+        // New symbol table scope for body of function plus its arguments
+        //
+        parseContext.symbolTable.push();
+        
+        //
+        // Remember the return type for later checking for RETURN statements.
+        //
+        parseContext.currentFunctionType = &(prevDec->getReturnType());
+        parseContext.functionReturnsValue = false;
+        
+        // 
+        // Insert parameters into the symbol table.
+        // If the parameter has no name, it's not an error, just don't insert it 
+        // (could be used for unused args).
+        //
+        // Also, accumulate the list of parameters into the HIL, so lower level code
+        // knows where to find parameters.
+        //
+        TIntermAggregate* paramNodes = new TIntermAggregate;
+        for (int i = 0; i < function.getParamCount(); i++) {
+            TParameter& param = function[i];
+            if (param.name != 0) {
+                TVariable *variable = new TVariable(param.name, *param.type);
+                // 
+                // Insert the parameters with name in the symbol table.
+                //
+                if (! parseContext.symbolTable.insert(*variable)) {
+                    parseContext.error($1.line, "redefinition", variable->getName().c_str(), "");
+                    parseContext.recover();
+                    delete variable;
+                }
+                //
+                // Transfer ownership of name pointer to symbol table.
+                //
+                param.name = 0;
+                
+                //
+                // Add the parameter to the HIL
+                //                
+                paramNodes = parseContext.intermediate.growAggregate(
+                                               paramNodes, 
+                                               parseContext.intermediate.addSymbol(variable->getUniqueId(),
+                                                                       variable->getName(),
+                                                                       variable->getType(), $1.line), 
+                                               $1.line);
+            } else {
+                paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
+            }
+        }
+        parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
+        $1.intermAggregate = paramNodes;
+        parseContext.loopNestingLevel = 0;
+    }
+    compound_statement_no_new_scope {
+        //?? Check that all paths return a value if return type != void ?
+        //   May be best done as post process phase on intermediate code
+        if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) {
+            parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
+            parseContext.recover();
+        }
+        parseContext.symbolTable.pop();
+        $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0);
+        parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.line);
+        $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
+        $$->getAsAggregate()->setType($1.function->getReturnType());
+        
+        // store the pragma information for debug and optimize and other vendor specific 
+        // information. This information can be queried from the parse tree
+        $$->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize);
+        $$->getAsAggregate()->setDebug(parseContext.contextPragma.debug);
+        $$->getAsAggregate()->addToPragmaTable(parseContext.contextPragma.pragmaTable);
+    }
+    ;
+
+%%
diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
new file mode 100644 (file)
index 0000000..a01899a
--- /dev/null
@@ -0,0 +1,491 @@
+//
+//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.
+//
+
+#include "localintermediate.h"
+
+//
+// Two purposes:
+// 1.  Show an example of how to iterate tree.  Functions can
+//     also directly call Traverse() on children themselves to
+//     have finer grained control over the process than shown here.
+//     See the last function for how to get started.
+// 2.  Print out a text based description of the tree.
+//
+
+//
+// Use this class to carry along data from node to node in 
+// the traversal
+//
+class TOutputTraverser : public TIntermTraverser {
+public:
+    TOutputTraverser(TInfoSink& i) : infoSink(i) { }
+    TInfoSink& infoSink;
+};
+
+TString TType::getCompleteString() const
+{
+    char buf[100];
+    char *p = &buf[0];
+
+    if (qualifier != EvqTemporary && qualifier != EvqGlobal)
+        p += sprintf(p, "%s ", getQualifierString());
+    if (array)
+        p += sprintf(p, "array of ");
+    if (matrix)
+        p += sprintf(p, "%dX%d matrix of ", size, size);
+    else if (size > 1)
+        p += sprintf(p, "%d-component vector of ", size);
+
+    sprintf(p, "%s", getBasicString());
+
+    return TString(buf);
+}   
+
+//
+// Helper functions for printing, not part of traversing.
+//
+
+void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
+{
+    int i;
+
+    infoSink.debug << FormatSourceLoc(node->getLine());
+    
+    for (i = 0; i < depth; ++i)
+        infoSink.debug << "  ";
+}
+
+//
+// The rest of the file are the traversal functions.  The last one
+// is the one that starts the traversal.
+//
+// Return true from interior nodes to have the external traversal
+// continue on to children.  If you process children yourself,
+// return false.
+//
+
+void OutputSymbol(TIntermSymbol* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+
+    OutputTreeText(oit->infoSink, node, oit->depth);
+
+    char buf[100];
+    sprintf(buf, "'%s' (%s)\n",
+           node->getSymbol().c_str(),
+           node->getCompleteString().c_str());
+
+    oit->infoSink.debug << buf;
+}
+
+bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+    TInfoSink& out = oit->infoSink;
+
+    OutputTreeText(out, node, oit->depth);
+
+    switch (node->getOp()) {
+    case EOpAssign:                   out.debug << "move second child to first child";           break;
+    case EOpAddAssign:                out.debug << "add second child into first child";          break;
+    case EOpSubAssign:                out.debug << "subtract second child into first child";     break;
+    case EOpMulAssign:                out.debug << "multiply second child into first child";     break;
+    case EOpVectorTimesMatrixAssign:  out.debug << "matrix mult second child into first child";  break;
+    case EOpVectorTimesScalarAssign:  out.debug << "vector scale second child into first child"; break;
+    case EOpMatrixTimesScalarAssign:  out.debug << "matrix scale second child into first child"; break;
+    case EOpMatrixTimesMatrixAssign:  out.debug << "matrix mult second child into first child"; break;
+    case EOpDivAssign:                out.debug << "divide second child into first child";       break;
+    case EOpModAssign:                out.debug << "mod second child into first child";          break;
+    case EOpAndAssign:                out.debug << "and second child into first child";          break;
+    case EOpInclusiveOrAssign:        out.debug << "or second child into first child";           break;
+    case EOpExclusiveOrAssign:        out.debug << "exclusive or second child into first child"; break;
+    case EOpLeftShiftAssign:          out.debug << "left shift second child into first child";   break;
+    case EOpRightShiftAssign:         out.debug << "right shift second child into first child";  break;
+
+    case EOpIndexDirect:   out.debug << "direct index";   break;
+    case EOpIndexIndirect: out.debug << "indirect index"; break;
+    case EOpIndexDirectStruct:   out.debug << "direct index for structure";   break;
+    case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
+
+    case EOpAdd:    out.debug << "add";                     break;
+    case EOpSub:    out.debug << "subtract";                break;
+    case EOpMul:    out.debug << "component-wise multiply"; break;
+    case EOpDiv:    out.debug << "divide";                  break;
+    case EOpMod:    out.debug << "mod";                     break;
+    case EOpRightShift:  out.debug << "right-shift";  break;
+    case EOpLeftShift:   out.debug << "left-shift";   break;
+    case EOpAnd:         out.debug << "bitwise and";  break;
+    case EOpInclusiveOr: out.debug << "inclusive-or"; break;
+    case EOpExclusiveOr: out.debug << "exclusive-or"; break;
+    case EOpEqual:            out.debug << "Compare Equal";                 break;
+    case EOpNotEqual:         out.debug << "Compare Not Equal";             break;
+    case EOpLessThan:         out.debug << "Compare Less Than";             break;
+    case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
+    case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
+    case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
+
+    case EOpVectorTimesScalar: out.debug << "vector-scale";          break;
+    case EOpVectorTimesMatrix: out.debug << "vector-times-matrix";   break;
+    case EOpMatrixTimesVector: out.debug << "matrix-times-vector";   break;
+    case EOpMatrixTimesScalar: out.debug << "matrix-scale";          break;
+    case EOpMatrixTimesMatrix: out.debug << "matrix-multiply";       break;
+
+    case EOpLogicalOr:  out.debug << "logical-or";   break;
+    case EOpLogicalXor: out.debug << "logical-xor"; break;
+    case EOpLogicalAnd: out.debug << "logical-and"; break;
+    default: out.debug << "<unknown op>";
+    }
+
+    out.debug << " (" << node->getCompleteString() << ")";
+
+    out.debug << "\n";
+
+    return true;
+}
+
+bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+    TInfoSink& out = oit->infoSink;
+
+    OutputTreeText(out, node, oit->depth);
+
+    switch (node->getOp()) {        
+    case EOpNegative:       out.debug << "Negate value";         break;
+    case EOpVectorLogicalNot:
+    case EOpLogicalNot:     out.debug << "Negate conditional";   break;
+    case EOpBitwiseNot:     out.debug << "Bitwise not";          break;
+
+    case EOpPostIncrement:  out.debug << "Post-Increment";       break;
+    case EOpPostDecrement:  out.debug << "Post-Decrement";       break;
+    case EOpPreIncrement:   out.debug << "Pre-Increment";        break;
+    case EOpPreDecrement:   out.debug << "Pre-Decrement";        break;
+
+    case EOpConvIntToBool:  out.debug << "Convert int to bool";  break;
+    case EOpConvFloatToBool:out.debug << "Convert float to bool";break;
+    case EOpConvBoolToFloat:out.debug << "Convert bool to float";break;
+    case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
+    case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
+    case EOpConvBoolToInt:  out.debug << "Convert bool to int";  break;
+
+    case EOpRadians:        out.debug << "radians";              break;
+    case EOpDegrees:        out.debug << "degrees";              break;
+    case EOpSin:            out.debug << "sine";                 break;
+    case EOpCos:            out.debug << "cosine";               break;
+    case EOpTan:            out.debug << "tangent";              break;
+    case EOpAsin:           out.debug << "arc sine";             break;
+    case EOpAcos:           out.debug << "arc cosine";           break;
+    case EOpAtan:           out.debug << "arc tangent";          break;
+
+    case EOpExp:            out.debug << "exp";                  break;
+    case EOpLog:            out.debug << "log";                  break;
+    case EOpExp2:           out.debug << "exp2";                 break;
+    case EOpLog2:           out.debug << "log2";                 break;
+    case EOpSqrt:           out.debug << "sqrt";                 break;
+    case EOpInverseSqrt:    out.debug << "inverse sqrt";         break;
+
+    case EOpAbs:            out.debug << "Absolute value";       break;
+    case EOpSign:           out.debug << "Sign";                 break;
+    case EOpFloor:          out.debug << "Floor";                break;
+    case EOpCeil:           out.debug << "Ceiling";              break;
+    case EOpFract:          out.debug << "Fraction";             break;
+
+    case EOpLength:         out.debug << "length";               break;
+    case EOpNormalize:      out.debug << "normalize";            break;
+    case EOpDPdx:           out.debug << "dPdx";                 break;               
+    case EOpDPdy:           out.debug << "dPdy";                 break;   
+    case EOpFwidth:         out.debug << "fwidth";               break;                   
+    
+    case EOpAny:            out.debug << "any";                  break;
+    case EOpAll:            out.debug << "all";                  break;
+
+    default: out.debug.message(EPrefixError, "Bad unary op");
+    }
+
+    out.debug << " (" << node->getCompleteString() << ")";
+
+    out.debug << "\n";
+
+    return true;
+}
+
+bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+    TInfoSink& out = oit->infoSink;
+
+    if (node->getOp() == EOpNull) {
+        out.debug.message(EPrefixError, "node is still EOpNull!");
+        return true;
+    }
+
+    OutputTreeText(out, node, oit->depth);
+
+    switch (node->getOp()) {
+    case EOpSequence:      out.debug << "Sequence\n"; return true;
+    case EOpComma:         out.debug << "Comma\n"; return true;
+    case EOpFunction:      out.debug << "Function Definition: " << node->getName(); break;
+    case EOpFunctionCall:  out.debug << "Function Call: " << node->getName(); break;
+    case EOpParameters:    out.debug << "Function Parameters: ";              break;
+    
+    case EOpConstructFloat: out.debug << "Construct float"; break;
+    case EOpConstructVec2:  out.debug << "Construct vec2";  break;
+    case EOpConstructVec3:  out.debug << "Construct vec3";  break;
+    case EOpConstructVec4:  out.debug << "Construct vec4";  break;
+    case EOpConstructBool:  out.debug << "Construct bool";  break;
+    case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
+    case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
+    case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
+    case EOpConstructInt:   out.debug << "Construct int";   break;
+    case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
+    case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
+    case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
+    case EOpConstructMat2:  out.debug << "Construct mat2";  break;
+    case EOpConstructMat3:  out.debug << "Construct mat3";  break;
+    case EOpConstructMat4:  out.debug << "Construct mat4";  break;
+    case EOpConstructStruct:  out.debug << "Construct structure";  break;
+        
+    case EOpLessThan:         out.debug << "Compare Less Than";             break;
+    case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
+    case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
+    case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
+    case EOpVectorEqual:      out.debug << "Equal";                         break;
+    case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
+
+    case EOpMod:           out.debug << "mod";         break;
+    case EOpPow:           out.debug << "pow";         break;
+
+    case EOpAtan:          out.debug << "arc tangent"; break;
+
+    case EOpMin:           out.debug << "min";         break;
+    case EOpMax:           out.debug << "max";         break;
+    case EOpClamp:         out.debug << "clamp";       break;
+    case EOpMix:           out.debug << "mix";         break;
+    case EOpStep:          out.debug << "step";        break;
+    case EOpSmoothStep:    out.debug << "smoothstep";  break;
+
+    case EOpDistance:      out.debug << "distance";                break;
+    case EOpDot:           out.debug << "dot-product";             break;
+    case EOpCross:         out.debug << "cross-product";           break;
+    case EOpFaceForward:   out.debug << "face-forward";            break;
+    case EOpReflect:       out.debug << "reflect";                 break;
+    case EOpRefract:       out.debug << "refract";                 break;
+    case EOpMul:           out.debug << "component-wise multiply"; break;
+
+    case EOpItof:          out.debug << "itof";        break;
+    case EOpFtoi:          out.debug << "ftoi";        break;
+    case EOpSkipPixels:    out.debug << "skipPixels";  break;
+    case EOpReadInput:     out.debug << "readInput";   break;
+    case EOpWritePixel:    out.debug << "writePixel";  break;
+    case EOpBitmapLsb:     out.debug << "bitmapLSB";   break;
+    case EOpBitmapMsb:     out.debug << "bitmapMSB";   break;
+    case EOpWriteOutput:   out.debug << "writeOutput"; break;
+    case EOpReadPixel:     out.debug << "readPixel";   break;
+
+    default: out.debug.message(EPrefixError, "Bad aggregation op");
+    }
+
+    if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
+        out.debug << " (" << node->getCompleteString() << ")";
+    
+    out.debug << "\n";
+
+    return true;
+}
+
+bool OutputSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+    TInfoSink& out = oit->infoSink;
+
+    OutputTreeText(out, node, oit->depth);
+
+    out.debug << "Test condition and select";
+    out.debug << " (" << node->getCompleteString() << ")\n";
+    
+    ++oit->depth;
+    
+    OutputTreeText(oit->infoSink, node, oit->depth);
+    out.debug << "Condition\n";
+    node->getCondition()->traverse(it);
+
+    OutputTreeText(oit->infoSink, node, oit->depth);
+       if (node->getTrueBlock()) {
+               out.debug << "true case\n";
+               node->getTrueBlock()->traverse(it);
+       } else
+               out.debug << "true case is null\n";
+    
+    if (node->getFalseBlock()) {
+        OutputTreeText(oit->infoSink, node, oit->depth);
+        out.debug << "false case\n";
+        node->getFalseBlock()->traverse(it);
+    }
+    
+    --oit->depth;
+
+    return false;
+}
+
+void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+    TInfoSink& out = oit->infoSink;
+    
+    int size = node->getType().getObjectSize();
+
+    for (int i = 0; i < size; i++) {
+        OutputTreeText(out, node, oit->depth);
+        switch (node->getUnionArrayPointer()[i].getType()) {
+        case EbtBool:
+            if (node->getUnionArrayPointer()[i].getBConst())
+                out.debug << "true";
+            else
+                out.debug << "false";
+
+            out.debug << " (" << "const bool" << ")";
+
+            out.debug << "\n";
+            break;
+        case EbtFloat:
+            {
+                char buf[300];
+                sprintf(buf, "%f (%s)", node->getUnionArrayPointer()[i].getFConst(), "const float");
+
+                out.debug << buf << "\n";           
+            }
+            break;
+        case EbtInt:
+            {
+                char buf[300];
+                sprintf(buf, "%d (%s)", node->getUnionArrayPointer()[i].getIConst(), "const int");
+
+                out.debug << buf << "\n";
+                break;
+            }
+        default: 
+            out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
+            break;
+        }
+    }
+}
+
+bool OutputLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+    TInfoSink& out = oit->infoSink;
+
+    OutputTreeText(out, node, oit->depth);
+    
+    out.debug << "Loop with condition ";
+    if (! node->testFirst())
+        out.debug << "not ";
+    out.debug << "tested first\n";
+    
+    ++oit->depth;
+    
+    OutputTreeText(oit->infoSink, node, oit->depth);
+    if (node->getTest()) {
+        out.debug << "Loop Condition\n";
+        node->getTest()->traverse(it);
+    } else
+        out.debug << "No loop condition\n";
+    
+    OutputTreeText(oit->infoSink, node, oit->depth);
+    if (node->getBody()) {
+        out.debug << "Loop Body\n";
+        node->getBody()->traverse(it);
+    } else
+        out.debug << "No loop body\n";
+
+    if (node->getTerminal()) {
+        OutputTreeText(oit->infoSink, node, oit->depth);
+        out.debug << "Loop Terminal Expression\n";
+        node->getTerminal()->traverse(it);
+    }
+
+    --oit->depth;
+
+    return false;
+}
+
+bool OutputBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
+{
+    TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
+    TInfoSink& out = oit->infoSink;
+
+    OutputTreeText(out, node, oit->depth);
+
+    switch (node->getFlowOp()) {
+    case EOpKill:      out.debug << "Branch: Kill";           break;
+    case EOpBreak:     out.debug << "Branch: Break";          break;
+    case EOpContinue:  out.debug << "Branch: Continue";       break;
+    case EOpReturn:    out.debug << "Branch: Return";         break;
+    default:               out.debug << "Branch: Unknown Branch"; break;
+    }
+
+    if (node->getExpression()) {
+        out.debug << " with expression\n";
+        ++oit->depth;
+        node->getExpression()->traverse(it);
+        --oit->depth;
+    } else
+        out.debug << "\n";
+
+    return false;
+}
+
+//
+// This function is the one to call externally to start the traversal.
+// Individual functions can be initialized to 0 to skip processing of that
+// type of node.  It's children will still be processed.
+//
+void TIntermediate::outputTree(TIntermNode* root)
+{
+    if (root == 0)
+        return;
+
+    TOutputTraverser it(infoSink);
+
+    it.visitAggregate = OutputAggregate;
+    it.visitBinary = OutputBinary;
+    it.visitConstantUnion = OutputConstantUnion;
+    it.visitSelection = OutputSelection;
+    it.visitSymbol = OutputSymbol;
+    it.visitUnary = OutputUnary;
+    it.visitLoop = OutputLoop;
+    it.visitBranch = OutputBranch;
+
+    root->traverse(&it);
+}
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
new file mode 100644 (file)
index 0000000..ae30c73
--- /dev/null
@@ -0,0 +1,86 @@
+//
+//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.
+//
+
+#ifndef _LOCAL_INTERMEDIATE_INCLUDED_
+#define _LOCAL_INTERMEDIATE_INCLUDED_
+
+#include "../Include/intermediate.h"
+#include "../Public/ShaderLang.h"
+#include "SymbolTable.h"
+
+struct TVectorFields {
+    int offsets[4];
+    int num;
+};
+
+//
+// Set of helper functions to help parse and build the tree.
+//
+class TInfoSink;
+class TIntermediate {
+public:    
+    POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
+
+    TIntermediate(TInfoSink& i) : infoSink(i) { }
+    TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
+    TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
+    TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, TSymbolTable&);
+    TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
+    TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
+    TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, TSourceLoc, TSymbolTable&);
+    TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
+    TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc);
+    TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, TSourceLoc);
+    TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc);
+    TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
+    TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
+    TIntermConstantUnion* addConstantUnion(constUnion*, const TType&, TSourceLoc);
+    TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
+    bool parseConstTree(TSourceLoc, TIntermNode*, constUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);        
+    TIntermNode* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
+    TIntermBranch* addBranch(TOperator, TSourceLoc);
+    TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
+    TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
+    bool postProcess(TIntermNode*, EShLanguage);
+       void remove(TIntermNode*);
+    void outputTree(TIntermNode*);
+    
+protected:
+    TInfoSink& infoSink;
+
+private:
+    void operator=(TIntermediate&); // prevent assignments
+};
+
+#endif // _LOCAL_INTERMEDIATE_INCLUDED_
diff --git a/glslang/MachineIndependent/parseConst.cpp b/glslang/MachineIndependent/parseConst.cpp
new file mode 100644 (file)
index 0000000..ae07319
--- /dev/null
@@ -0,0 +1,266 @@
+//
+//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.
+//
+
+#include "ParseHelper.h"
+
+//
+// Use this class to carry along data from node to node in 
+// the traversal
+//
+class TConstTraverser : public TIntermTraverser {
+public:
+    TConstTraverser(constUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
+        constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), matrixSize(0) {  index = 0; tOp = EOpNull;}
+    int index ;
+    constUnion *unionArray;
+    TOperator tOp;
+    TType type;
+    TOperator constructorType;
+    bool singleConstantParam;
+    TInfoSink& infoSink;
+    TSymbolTable& symbolTable;
+    bool error;
+    int size; // size of the constructor ( 4 for vec4)
+    bool isMatrix;
+    int matrixSize; // dimension of the matrix (nominal size and not the instance size)
+};
+
+//
+// The rest of the file are the traversal functions.  The last one
+// is the one that starts the traversal.
+//
+// Return true from interior nodes to have the external traversal
+// continue on to children.  If you process children yourself,
+// return false.
+//
+
+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());
+    return;
+
+}
+
+bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
+{
+    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
+    
+    TQualifier qualifier = node->getType().getQualifier();
+    
+    if (qualifier != EvqConst) {
+        char buf[200];
+        sprintf(buf, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
+        oit->infoSink.info.message(EPrefixError, buf, node->getLine());
+        oit->error = true;
+        return false;  
+    }
+
+   oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
+    
+    return false;
+}
+
+bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
+{
+    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
+
+    char buf[200];
+    sprintf(buf, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
+    oit->infoSink.info.message(EPrefixError, buf, node->getLine());
+    oit->error = true;
+    return false;  
+}
+
+bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
+{
+    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
+
+    if (!node->isConstructor() && node->getOp() != EOpComma) {
+        char buf[200];
+        sprintf(buf, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
+        oit->infoSink.info.message(EPrefixError, buf, node->getLine());
+        oit->error = true;
+        return false;  
+    }
+
+    if (node->getSequence().size() == 0) {
+        oit->error = true;
+        return false;
+    }
+
+    bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
+    if (flag) 
+    {
+        oit->singleConstantParam = true; 
+        oit->constructorType = node->getOp();
+        oit->size = node->getType().getObjectSize();
+
+        if (node->getType().isMatrix()) {
+            oit->isMatrix = true;
+            oit->matrixSize = node->getType().getNominalSize();
+        }
+    }       
+
+    for (TIntermSequence::iterator p = node->getSequence().begin(); 
+                                   p != node->getSequence().end(); p++) {
+
+        if (node->getOp() == EOpComma)
+            oit->index = 0;           
+
+        (*p)->traverse(oit);
+    }   
+    if (flag) 
+    {
+        oit->singleConstantParam = false;   
+        oit->constructorType = EOpNull;
+        oit->size = 0;
+        oit->isMatrix = false;
+        oit->matrixSize = 0;
+    }
+    return false;
+}
+
+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->error = true;
+    return false;
+}
+
+void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
+{
+    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
+    constUnion* leftUnionArray = oit->unionArray;
+    int instanceSize = oit->type.getObjectSize();
+
+    if (oit->index >= instanceSize)
+        return;
+
+    if (!oit->singleConstantParam) {
+        int size = node->getType().getObjectSize();
+    
+        constUnion *rightUnionArray = node->getUnionArrayPointer();
+        for (int i=0; i < size; i++) {
+            if (oit->index >= instanceSize)
+                return;
+            leftUnionArray[oit->index] = rightUnionArray[i];
+
+            (oit->index)++;
+        }
+    } else {
+        int size, totalSize, matrixSize;
+        bool isMatrix = false;
+        size = oit->size;
+        matrixSize = oit->matrixSize;
+        isMatrix = oit->isMatrix;
+        totalSize = oit->index + size ;
+        constUnion *rightUnionArray = node->getUnionArrayPointer();
+        if (!isMatrix) {
+            int count = 0;
+            for (int i = oit->index; i < totalSize; i++) {
+                if (i >= instanceSize)
+                    return;
+
+                leftUnionArray[i] = rightUnionArray[count];
+
+                (oit->index)++;
+                
+                if (node->getType().getObjectSize() > 1)
+                    count++;
+            }
+        } else {  // for matrix constructors
+            int count = 0;
+            int index = oit->index;
+            for (int i = index; i < totalSize; i++) {
+                if (i >= instanceSize)
+                    return;
+                if (index - i == 0 || (i - index) % (matrixSize + 1) == 0 )
+                    leftUnionArray[i] = rightUnionArray[count];
+                else 
+                    leftUnionArray[i].setFConst(0.0f);
+
+                (oit->index)++;
+
+                if (node->getType().getObjectSize() > 1)
+                    count++;                
+            }
+        }
+    }
+}
+
+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->error = true;
+    return false;
+}
+
+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->error = true;
+    return false;
+}
+
+//
+// This function is the one to call externally to start the traversal.
+// Individual functions can be initialized to 0 to skip processing of that
+// type of node.  It's children will still be processed.
+//
+bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, constUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
+{
+    if (root == 0)
+        return false;
+
+    TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t);
+    
+    it.visitAggregate = ParseAggregate;
+    it.visitBinary = ParseBinary;
+    it.visitConstantUnion = ParseConstantUnion;
+    it.visitSelection = ParseSelection;
+    it.visitSymbol = ParseSymbol;
+    it.visitUnary = ParseUnary;
+    it.visitLoop = ParseLoop;
+    it.visitBranch = ParseBranch;
+
+    root->traverse(&it);
+    if (it.error)
+        return true;
+    else
+        return false;
+}
diff --git a/glslang/MachineIndependent/preprocessor/Makefile b/glslang/MachineIndependent/preprocessor/Makefile
new file mode 100644 (file)
index 0000000..b6402ce
--- /dev/null
@@ -0,0 +1,38 @@
+CC = gcc
+
+OBJECTS = atom.o cpp.o cppstruct.o memory.o scanner.o symbols.o tokens.o
+AR=ar
+SRCS=scanner.c atom.c memory.c tokens. cpp.c cppstruct.c symbols.c
+
+default: all
+all : libPreprocessor.a
+libPreprocessor.a : $(OBJECTS)
+       $(AR) rvu $@ $(OBJECTS)
+       ranlib $@
+
+%.o : %.c
+       $(CC) -c $<
+
+#
+# Cleanup
+#
+.PHONY : clean
+clean :
+       $(RM) *.o *.a
+
+depend:
+       makedepend  -Y -- $(SRCS)
+
+# DO NOT DELETE
+
+scanner.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
+scanner.o: symbols.h compile.h
+atom.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
+atom.o: symbols.h compile.h
+memory.o: memory.h
+cpp.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
+cpp.o: symbols.h compile.h
+cppstruct.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
+cppstruct.o: symbols.h compile.h
+symbols.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
+symbols.o: symbols.h compile.h
diff --git a/glslang/MachineIndependent/preprocessor/atom.c b/glslang/MachineIndependent/preprocessor/atom.c
new file mode 100644 (file)
index 0000000..39af441
--- /dev/null
@@ -0,0 +1,768 @@
+//
+//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.
+\****************************************************************************/
+
+//
+// atom.c
+//
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "slglobals.h"
+
+#undef malloc
+#undef realloc
+#undef free
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////// String table: //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+static const struct {
+    int val;
+    const char *str;
+} tokens[] = {
+    { CPP_AND_OP,         "&&" },
+    { CPP_AND_ASSIGN,     "&=" },
+    { CPP_SUB_ASSIGN,     "-=" },
+    { CPP_MOD_ASSIGN,     "%=" },
+    { 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_LE_OP,          "<=" },
+    { CPP_LEFT_OP,        "<<" },
+    { CPP_LEFT_ASSIGN,    "<<=" },
+    { CPP_LEFT_BRACKET,   "<:" },
+    { CPP_LEFT_BRACE,     "<%" }, 
+    { 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>" },
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////// String table: //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#define INIT_STRING_TABLE_SIZE 16384
+
+typedef struct StringTable_Rec {
+    char *strings;
+    int nextFree;
+    int size;
+} StringTable;
+
+/*
+ * InitStringTable() - Initialize the string table.
+ *
+ */
+
+static int InitStringTable(StringTable *stable)
+{
+    stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
+    if (!stable->strings)
+        return 0;
+    // Zero-th offset means "empty" so don't use it.
+    stable->nextFree = 1;
+    stable->size = INIT_STRING_TABLE_SIZE;
+    return 1;
+} // InitStringTable
+
+/*
+ * FreeStringTable() - Free the string table.
+ *
+ */
+
+static void FreeStringTable(StringTable *stable)
+{
+    if (stable->strings)
+        free(stable->strings);
+    stable->strings = NULL;
+    stable->nextFree = 0;
+    stable->size = 0;
+} // FreeStringTable
+
+/*
+ * HashString() - Hash a string with the base hash function.
+ *
+ */
+
+static int HashString(const char *s)
+{
+    int hval = 0;
+
+    while (*s) {
+        hval = (hval*13507 + *s*197) ^ (hval >> 2);
+        s++;
+    }
+    return hval & 0x7fffffff;
+} // HashString
+
+/*
+ * HashString2() - Hash a string with the incrimenting hash function.
+ *
+ */
+
+static int HashString2(const char *s)
+{
+    int hval = 0;
+
+    while (*s) {
+        hval = (hval*729 + *s*37) ^ (hval >> 1);
+        s++;
+    }
+    return hval;
+} // HashString2
+
+/*
+ * AddString() - Add a string to a string table.  Return it's offset.
+ *
+ */
+
+static int AddString(StringTable *stable, const char *s)
+{
+    int len, loc;
+    char *str;
+
+    len = (int) strlen(s);
+    if (stable->nextFree + len + 1 >= stable->size) {
+        assert(stable->size < 1000000);
+        str = (char *) malloc(stable->size*2);
+        memcpy(str, stable->strings, stable->size);
+        free(stable->strings);
+        stable->strings = str;
+    }
+    loc = stable->nextFree;
+    strcpy(&stable->strings[loc], s);
+    stable->nextFree += len + 1;
+    return loc;
+} // AddString
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////// Hash table: ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#define INIT_HASH_TABLE_SIZE 2047
+#define HASH_TABLE_MAX_COLLISIONS 3
+
+typedef struct HashEntry_Rec {
+    int index;      // String table offset of string representation
+    int value;      // Atom (symbol) value
+} HashEntry;
+
+typedef struct HashTable_Rec {
+    HashEntry *entry;
+    int size;
+    int entries;
+    int counts[HASH_TABLE_MAX_COLLISIONS + 1];
+} HashTable;
+
+/*
+ * InitHashTable() - Initialize the hash table.
+ *
+ */
+
+static int InitHashTable(HashTable *htable, int fsize)
+{
+    int ii;
+
+    htable->entry = (HashEntry *) malloc(sizeof(HashEntry)*fsize);
+    if (!htable->entry)
+        return 0;
+    htable->size = fsize;
+    for (ii = 0; ii < fsize; ii++) {
+        htable->entry[ii].index = 0;
+        htable->entry[ii].value = 0;
+    }
+    htable->entries = 0;
+    for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++)
+        htable->counts[ii] = 0;
+    return 1;
+} // InitHashTable
+
+/*
+ * FreeHashTable() - Free the hash table.
+ *
+ */
+
+static void FreeHashTable(HashTable *htable)
+{
+    if (htable->entry)
+        free(htable->entry);
+    htable->entry = NULL;
+    htable->size = 0;
+    htable->entries = 0;
+} // FreeHashTable
+
+/*
+ * Empty() - See if a hash table entry is empty.
+ *
+ */
+
+static int Empty(HashTable *htable, int hashloc)
+{
+    assert(hashloc >= 0 && hashloc < htable->size);
+    if (htable->entry[hashloc].index == 0) {
+        return 1;
+    } else {
+        return 0;
+    }
+} // Empty
+
+/*
+ * Match() - See if a hash table entry is matches a string.
+ *
+ */
+
+static int Match(HashTable *htable, StringTable *stable, const char *s, int hashloc)
+{
+    int strloc;
+
+    strloc = htable->entry[hashloc].index;
+    if (!strcmp(s, &stable->strings[strloc])) {
+        return 1;
+    } else {
+        return 0;
+    }
+} // Match
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////// Atom table: ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#define INIT_ATOM_TABLE_SIZE 1024
+
+
+struct AtomTable_Rec {
+    StringTable stable; // String table.
+    HashTable htable;   // Hashes string to atom number and token value.  Multiple strings can
+                        // have the same token value but each unique string is a unique atom.
+    int *amap;          // Maps atom value to offset in string table.  Atoms all map to unique
+                        // strings except for some undefined values in the lower, fixed part
+                        // of the atom table that map to "<undefined>".  The lowest 256 atoms
+                        // correspond to single character ASCII values except for alphanumeric
+                        // characters and '_', which can be other tokens.  Next come the
+                        // language tokens with their atom values equal to the token value.
+                        // Then come predefined atoms, followed by user specified identifiers.
+    int *arev;          // Reversed atom for symbol table use.
+    int nextFree;
+    int size;
+};
+
+static AtomTable latable = { { 0 } };
+AtomTable *atable = &latable;
+
+static int AddAtomFixed(AtomTable *atable, const char *s, int atom);
+
+/*
+ * GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
+ *
+ */
+
+static int GrowAtomTable(AtomTable *atable, int size)
+{
+    int *newmap, *newrev;
+
+    if (atable->size < size) {
+        if (atable->amap) {
+            newmap = realloc(atable->amap, sizeof(int)*size);
+            newrev = realloc(atable->arev, sizeof(int)*size);
+        } else {
+            newmap = malloc(sizeof(int)*size);
+            newrev = malloc(sizeof(int)*size);
+            atable->size = 0;
+        }
+        if (!newmap || !newrev) {
+            /* failed to grow -- error */
+            if (newmap)
+                atable->amap = newmap;
+            if (newrev)
+                atable->amap = newrev;
+            return -1;
+        }
+        memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
+        memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
+        atable->amap = newmap;
+        atable->arev = newrev;
+        atable->size = size;
+    }
+    return 0;
+} // GrowAtomTable
+
+/*
+ * lReverse() - Reverse the bottom 20 bits of a 32 bit int.
+ *
+ */
+
+static int lReverse(int fval)
+{
+    unsigned int in = fval;
+    int result = 0, cnt = 0;
+
+    while(in) {
+        result <<= 1;
+        result |= in&1;
+        in >>= 1;
+        cnt++;
+    }
+
+    // Don't use all 31 bits.  One million atoms is plenty and sometimes the
+    // upper bits are used for other things.
+
+    if (cnt < 20)
+        result <<= 20 - cnt;
+    return result;
+} // lReverse
+
+/*
+ * AllocateAtom() - Allocate a new atom.  Associated with the "undefined" value of -1.
+ *
+ */
+
+static int AllocateAtom(AtomTable *atable)
+{
+    if (atable->nextFree >= atable->size)
+        GrowAtomTable(atable, atable->nextFree*2);
+    atable->amap[atable->nextFree] = -1;
+    atable->arev[atable->nextFree] = lReverse(atable->nextFree);
+    atable->nextFree++;
+    return atable->nextFree - 1;
+} // AllocateAtom
+
+/*
+ * SetAtomValue() - Allocate a new atom associated with "hashindex".
+ *
+ */
+
+static void SetAtomValue(AtomTable *atable, int atomnumber, int hashindex)
+{
+    atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
+    atable->htable.entry[hashindex].value = atomnumber;
+} // SetAtomValue
+
+/*
+ * FindHashLoc() - Find the hash location for this string.  Return -1 it hash table is full.
+ *
+ */
+
+static int FindHashLoc(AtomTable *atable, const char *s)
+{
+    int hashloc, hashdelta, count;
+    int FoundEmptySlot = 0;
+    int collision[HASH_TABLE_MAX_COLLISIONS + 1];
+
+    hashloc = HashString(s) % atable->htable.size;
+    if (!Empty(&atable->htable, hashloc)) {
+        if (Match(&atable->htable, &atable->stable, s, hashloc))
+            return hashloc;
+        collision[0] = hashloc;
+        hashdelta = HashString2(s);
+        count = 0;
+        while (count < HASH_TABLE_MAX_COLLISIONS) {
+            hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
+            if (!Empty(&atable->htable, hashloc)) {
+                if (Match(&atable->htable, &atable->stable, s, hashloc)) {
+                    return hashloc;
+                }
+            } else {
+                FoundEmptySlot = 1;
+                break;
+            }
+            count++;
+            collision[count] = hashloc;
+        }
+
+        if (!FoundEmptySlot) {
+            if (cpp->options.DumpAtomTable) {
+                int ii;
+                char str[200];
+                sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
+                       HASH_TABLE_MAX_COLLISIONS);
+                CPPShInfoLogMsg(str);
+
+                sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
+                CPPShInfoLogMsg(str);
+                for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) {
+                    sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
+                           ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
+                    CPPShInfoLogMsg(str);
+                }
+            }
+            return -1;
+        } else {
+            atable->htable.counts[count]++;
+        }
+    }
+    return hashloc;
+} // FindHashLoc
+
+/*
+ * IncreaseHashTableSize()
+ *
+ */
+
+static int IncreaseHashTableSize(AtomTable *atable)
+{
+    int ii, strloc, oldhashloc, value, size;
+    AtomTable oldtable;
+    char *s;
+
+    // Save the old atom table and create a new one:
+
+    oldtable = *atable;
+    size = oldtable.htable.size*2 + 1;
+    if (!InitAtomTable(atable, size))
+        return 0;
+
+    // Add all the existing values to the new atom table preserving their atom values:
+
+    for (ii = atable->nextFree; ii < oldtable.nextFree; ii++) {
+        strloc = oldtable.amap[ii];
+        s = &oldtable.stable.strings[strloc];
+        oldhashloc = FindHashLoc(&oldtable, s);
+        assert(oldhashloc >= 0);
+        value = oldtable.htable.entry[oldhashloc].value;
+        AddAtomFixed(atable, s, value);
+    }
+    FreeAtomTable(&oldtable);
+    return 1;
+} // IncreaseHashTableSize
+
+/*
+ * LookUpAddStringHash() - Lookup a string in the hash table.  If it's not there, add it and
+ *        initialize the atom value in the hash table to 0.  Return the hash table index.
+ */
+
+static int LookUpAddStringHash(AtomTable *atable, const char *s)
+{
+    int hashloc, strloc;
+
+    while(1) {
+        hashloc = FindHashLoc(atable, s);
+        if (hashloc >= 0)
+            break;
+        IncreaseHashTableSize(atable);
+    }
+
+    if (Empty(&atable->htable, hashloc)) {
+        atable->htable.entries++;
+        strloc = AddString(&atable->stable, s);
+        atable->htable.entry[hashloc].index = strloc;
+        atable->htable.entry[hashloc].value = 0;
+    }
+    return hashloc;
+} // LookUpAddStringHash
+
+/*
+ * LookUpAddString() - Lookup a string in the hash table.  If it's not there, add it and
+ *        initialize the atom value in the hash table to the next atom number.
+ *        Return the atom value of string.
+ */
+
+int LookUpAddString(AtomTable *atable, const char *s)
+{
+    int hashindex, atom;
+
+    hashindex = LookUpAddStringHash(atable, s);
+    atom = atable->htable.entry[hashindex].value;
+    if (atom == 0) {
+        atom = AllocateAtom(atable);
+        SetAtomValue(atable, atom, hashindex);
+    }
+    return atom;
+} // LookUpAddString
+
+/*
+ * GetAtomString()
+ *
+ */
+
+const  char *GetAtomString(AtomTable *atable, int atom)
+{
+    int soffset;
+
+    if (atom > 0 && atom < atable->nextFree) {
+        soffset = atable->amap[atom];
+        if (soffset > 0 && soffset < atable->stable.nextFree) {
+            return &atable->stable.strings[soffset];
+        } else {
+            return "<internal error: bad soffset>";
+        }
+    } else {
+        if (atom == 0) {
+            return "<null atom>";
+        } else {
+            if (atom == EOF) {
+                return "<EOF>";
+            } else {
+                return "<invalid atom>";
+            }
+        }
+    }
+} // GetAtomString
+
+/*
+ * GetReversedAtom()
+ *
+ */
+
+int GetReversedAtom(AtomTable *atable, int atom)
+{
+    if (atom > 0 && atom < atable->nextFree) {
+        return atable->arev[atom];
+    } else {
+        return 0;
+    }
+} // GetReversedAtom
+
+/*
+ * AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
+ *         Return it's atom index.
+ */
+
+int AddAtom(AtomTable *atable, const char *s)
+{
+    int atom;
+
+    atom = LookUpAddString(atable, s);
+    return atom;
+} // AddAtom
+
+/*
+ * AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
+ *         Assign it the atom value of "atom".
+ */
+
+static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
+{
+    int hashindex, lsize;
+
+    hashindex = LookUpAddStringHash(atable, s);
+    if (atable->nextFree >= atable->size || atom >= atable->size) {
+        lsize = atable->size*2;
+        if (lsize <= atom)
+            lsize = atom + 1;
+        GrowAtomTable(atable, lsize);
+    }
+    atable->amap[atom] = atable->htable.entry[hashindex].index;
+    atable->htable.entry[hashindex].value = atom;
+    //if (atom >= atable->nextFree)
+    //    atable->nextFree = atom + 1;
+    while (atom >= atable->nextFree) {
+        atable->arev[atable->nextFree] = lReverse(atable->nextFree);
+        atable->nextFree++;
+    }
+    return atom;
+} // AddAtomFixed
+
+/*
+ * InitAtomTable() - Initialize the atom table.
+ *
+ */
+
+int InitAtomTable(AtomTable *atable, int htsize)
+{
+    int ii;
+
+    htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
+    if (!InitStringTable(&atable->stable))
+        return 0;
+    if (!InitHashTable(&atable->htable, htsize))
+        return 0;
+
+    atable->nextFree = 0;
+    atable->amap = NULL;
+    atable->size = 0;
+    GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
+    if (!atable->amap)
+        return 0;
+
+    // Initialize lower part of atom table to "<undefined>" atom:
+
+    AddAtomFixed(atable, "<undefined>", 0);
+    for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++)
+        atable->amap[ii] = atable->amap[0];
+
+    // Add single character tokens to the atom table:
+
+    {
+               const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
+        char t[2];
+
+        t[1] = '\0';
+        while (*s) {
+            t[0] = *s;
+            AddAtomFixed(atable, t, s[0]);
+            s++;
+        }
+    }
+
+    // Add multiple character scanner tokens :
+
+    for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
+        AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
+
+    // Add error symbol if running in error mode:
+
+    if (cpp->options.ErrorMode)
+        AddAtomFixed(atable, "error", ERROR_SY);
+
+    AddAtom(atable, "<*** end fixed atoms ***>");
+
+    return 1;
+} // InitAtomTable
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// Debug Printing Functions: //////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PrintAtomTable()
+ *
+ */
+
+void PrintAtomTable(AtomTable *atable)
+{
+    int ii;
+    char str[200];
+
+    for (ii = 0; ii < atable->nextFree; ii++) {
+        sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
+        CPPDebugLogMsg(str);
+    }
+    sprintf(str, "Hash table: size=%d, entries=%d, collisions=",
+           atable->htable.size, atable->htable.entries);
+    CPPDebugLogMsg(str);
+    for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) {
+        sprintf(str, " %d", atable->htable.counts[ii]);
+        CPPDebugLogMsg(str);
+    }
+
+} // PrintAtomTable
+
+
+/*
+ * GetStringOfAtom()
+ *
+ */
+
+char* GetStringOfAtom(AtomTable *atable, int atom)
+{
+        char* chr_str;
+        chr_str=&atable->stable.strings[atable->amap[atom]];
+        return chr_str;
+} // GetStringOfAtom
+
+/*
+ * FreeAtomTable() - Free the atom table and associated memory
+ *
+ */
+
+void FreeAtomTable(AtomTable *atable)
+{
+    FreeStringTable(&atable->stable);
+    FreeHashTable(&atable->htable);
+    if (atable->amap)
+        free(atable->amap);
+    if (atable->arev)
+        free(atable->arev);
+    atable->amap = NULL;
+    atable->arev = NULL;
+    atable->nextFree = 0;
+    atable->size = 0;
+} // FreeAtomTable
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////// End of atom.c ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/glslang/MachineIndependent/preprocessor/atom.h b/glslang/MachineIndependent/preprocessor/atom.h
new file mode 100644 (file)
index 0000000..6d8898d
--- /dev/null
@@ -0,0 +1,96 @@
+//
+//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.
+\****************************************************************************/
+//
+// atom.h
+//
+
+#if !defined(__ATOM_H)
+#define __ATOM_H 1
+
+typedef struct AtomTable_Rec AtomTable;
+
+extern AtomTable *atable;
+
+int InitAtomTable(AtomTable *atable, int htsize);
+void FreeAtomTable(AtomTable *atable);
+int AddAtom(AtomTable *atable, const char *s);
+void PrintAtomTable(AtomTable *atable);
+int LookUpAddString(AtomTable *atable, const char *s);
+const char *GetAtomString(AtomTable *atable, int atom);
+int GetReversedAtom(AtomTable *atable, int atom);
+char* GetStringOfAtom(AtomTable *atable, int atom);
+#endif // !defined(__ATOM_H)
diff --git a/glslang/MachineIndependent/preprocessor/compile.h b/glslang/MachineIndependent/preprocessor/compile.h
new file mode 100644 (file)
index 0000000..08a9280
--- /dev/null
@@ -0,0 +1,132 @@
+//
+//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)
diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c
new file mode 100644 (file)
index 0000000..221f1a8
--- /dev/null
@@ -0,0 +1,1037 @@
+//
+//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.
+\****************************************************************************/
+//
+// cpp.c
+//
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "slglobals.h"
+
+static int CPPif(yystypepp * yylvalpp);
+
+/* Don't use memory.c's replacements, as we clean up properly here */
+#undef malloc
+#undef free
+
+static int bindAtom = 0;
+static int constAtom = 0;
+static int defaultAtom = 0;
+static int defineAtom = 0;
+static int definedAtom = 0;
+static int elseAtom = 0;
+static int elifAtom = 0;
+static int endifAtom = 0;
+static int ifAtom = 0;
+static int ifdefAtom = 0;
+static int ifndefAtom = 0;
+static int includeAtom = 0;
+static int lineAtom = 0;
+static int pragmaAtom = 0;
+static int texunitAtom = 0;
+static int undefAtom = 0;
+static int errorAtom = 0;
+static int __LINE__Atom = 0;
+static int __FILE__Atom = 0;
+static int __VERSION__Atom = 0;
+static int versionAtom = 0;
+static int extensionAtom = 0;
+
+static Scope *macros = 0;
+#define MAX_MACRO_ARGS  64
+#define MAX_IF_NESTING  64
+
+static SourceLoc ifloc; /* outermost #if */
+
+int InitCPP(void)
+{
+    char        buffer[64], *t;
+    const char  *f;
+    // Add various atoms needed by the CPP line scanner:
+    bindAtom = LookUpAddString(atable, "bind");
+    constAtom = LookUpAddString(atable, "const");
+    defaultAtom = LookUpAddString(atable, "default");
+    defineAtom = LookUpAddString(atable, "define");
+    definedAtom = LookUpAddString(atable, "defined");
+    elifAtom = LookUpAddString(atable, "elif");
+    elseAtom = LookUpAddString(atable, "else");
+    endifAtom = LookUpAddString(atable, "endif");
+    ifAtom = LookUpAddString(atable, "if");
+    ifdefAtom = LookUpAddString(atable, "ifdef");
+    ifndefAtom = LookUpAddString(atable, "ifndef");
+    includeAtom = LookUpAddString(atable, "include");
+    lineAtom = LookUpAddString(atable, "line");
+    pragmaAtom = LookUpAddString(atable, "pragma");
+    texunitAtom = LookUpAddString(atable, "texunit");
+    undefAtom = LookUpAddString(atable, "undef");
+       errorAtom = LookUpAddString(atable, "error");
+    __LINE__Atom = LookUpAddString(atable, "__LINE__");
+    __FILE__Atom = LookUpAddString(atable, "__FILE__");
+       __VERSION__Atom = LookUpAddString(atable, "__VERSION__");
+    versionAtom = LookUpAddString(atable, "version");
+    extensionAtom = LookUpAddString(atable, "extension");
+    macros = NewScopeInPool(mem_CreatePool(0, 0));
+    strcpy(buffer, "PROFILE_");
+    t = buffer + strlen(buffer);
+    f = cpp->options.profileString;
+    while ((isalnum(*f) || *f == '_') && t < buffer + sizeof(buffer) - 1)
+        *t++ = toupper(*f++);
+    *t = 0;
+       return 1;
+} // InitCPP
+
+int FreeCPP(void)
+{
+    if (macros)
+    {
+        mem_FreePool(macros->pool);
+        macros = 0;
+    }
+
+    return 1;
+}
+
+int FinalCPP(void)
+{
+       if (cpp->ifdepth)
+               CPPErrorToInfoLog("#if mismatch");
+    return 1;
+}
+
+static int CPPdefine(yystypepp * yylvalpp)
+{
+    int token, name, args[MAX_MACRO_ARGS], argc;
+    const char *message;
+    MacroSymbol mac;
+    Symbol *symb;
+    SourceLoc dummyLoc;
+    memset(&mac, 0, sizeof(mac));
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != CPP_IDENTIFIER) {
+        CPPErrorToInfoLog("#define");
+        return token;
+    }
+    name = yylvalpp->sc_ident;
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token == '(' && !yylvalpp->sc_int) {
+        // gather arguments
+        argc = 0;
+        do {
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (argc == 0 && token == ')') break;
+            if (token != CPP_IDENTIFIER) {
+                               CPPErrorToInfoLog("#define");
+                return token;
+            }
+            if (argc < MAX_MACRO_ARGS)
+                args[argc++] = yylvalpp->sc_ident;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        } while (token == ',');
+        if (token != ')') {
+            CPPErrorToInfoLog("#define");
+            return token;
+        }
+        mac.argc = argc;
+        mac.args = mem_Alloc(macros->pool, argc * sizeof(int));
+        memcpy(mac.args, args, argc * sizeof(int));
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       }
+    mac.body = NewTokenStream(GetAtomString(atable, name), macros->pool);
+    while (token != '\n') {
+        while (token == '\\') {
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (token == '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            else
+                RecordToken(mac.body, '\\', yylvalpp);
+        }
+        RecordToken(mac.body, token, yylvalpp);
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    };
+
+    symb = LookUpSymbol(macros, name);
+    if (symb) {
+        if (!symb->details.mac.undef) {
+            // already defined -- need to make sure they are identical
+            if (symb->details.mac.argc != mac.argc) goto error;
+            for (argc=0; argc < mac.argc; argc++)
+                if (symb->details.mac.args[argc] != mac.args[argc])
+                    goto error;
+            RewindTokenStream(symb->details.mac.body);
+            RewindTokenStream(mac.body);
+            do {
+                int old_lval, old_token;
+                old_token = ReadToken(symb->details.mac.body, yylvalpp);
+                old_lval = yylvalpp->sc_int;
+                token = ReadToken(mac.body, yylvalpp);
+                if (token != old_token || yylvalpp->sc_int != old_lval) { 
+                error:
+                    StoreStr("Macro Redefined");
+                    StoreStr(GetStringOfAtom(atable,name));
+                    message=GetStrfromTStr();
+                    DecLineNumber();
+                    CPPShInfoLogMsg(message);
+                    IncLineNumber();
+                    ResetTString();
+                    break; }
+            } while (token > 0);
+        }
+        //FreeMacro(&symb->details.mac);
+    } else {
+        dummyLoc.file = 0;
+        dummyLoc.line = 0;
+        symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
+    }
+    symb->details.mac = mac;
+    return '\n';
+} // CPPdefine
+
+static int CPPundef(yystypepp * yylvalpp)
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    Symbol *symb;
+       if(token == '\n'){
+               CPPErrorToInfoLog("#undef");
+           return token;
+    }
+    if (token != CPP_IDENTIFIER)
+          goto error;
+    symb = LookUpSymbol(macros, yylvalpp->sc_ident);
+    if (symb) {
+        symb->details.mac.undef = 1;
+    }
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != '\n') {
+    error:
+        CPPErrorToInfoLog("#undef");
+    }
+    return token;
+} // CPPundef
+
+/* CPPelse -- skip forward to appropriate spot.  This is actually used
+** to skip to and #endif after seeing an #else, AND to skip to a #else,
+** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false
+*/
+
+static int CPPelse(int matchelse, yystypepp * yylvalpp)
+{
+    int atom,depth=0;
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       
+       while (token > 0) {
+        if (token != '#') {
+                   while (token != '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            continue;
+        }
+               if ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) != CPP_IDENTIFIER)
+                       continue;
+        atom = yylvalpp->sc_ident;
+        if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){
+            depth++; cpp->ifdepth++; cpp->elsetracker++;
+               }
+               else if (atom == endifAtom) {
+            if(--depth<=0){
+                       cpp->elsedepth[cpp->elsetracker]=0;
+                           --cpp->elsetracker;
+                if (cpp->ifdepth) 
+                    --cpp->ifdepth;
+                break;
+            }             
+                --cpp->elsetracker;
+                --cpp->ifdepth;
+            }
+        else if (((int)(matchelse) != 0)&& depth==0) {
+                       if (atom == elseAtom ) {
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token != '\n') {
+                    CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
+                    while (token != '\n')
+                        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                } 
+                               break;
+                       } 
+                       else if (atom == elifAtom) {
+                /* we decrement cpp->ifdepth here, because CPPif will increment
+                 * it and we really want to leave it alone */
+                               if (cpp->ifdepth){
+                                       --cpp->ifdepth;
+                                   --cpp->elsetracker;
+                               }
+                return CPPif(yylvalpp);
+            }
+               }
+        else if((atom==elseAtom) && (!ChkCorrectElseNesting())){
+            CPPErrorToInfoLog("#else after a #else");
+            cpp->CompileError=1;
+        }
+       };
+    return token;
+}
+
+enum eval_prec {
+    MIN_PREC,
+    COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
+    MAX_PREC
+};
+
+static int op_logor(int a, int b) { return a || b; }
+static int op_logand(int a, int b) { return a && b; }
+static int op_or(int a, int b) { return a | b; }
+static int op_xor(int a, int b) { return a ^ b; }
+static int op_and(int a, int b) { return a & b; }
+static int op_eq(int a, int b) { return a == b; }
+static int op_ne(int a, int b) { return a != b; }
+static int op_ge(int a, int b) { return a >= b; }
+static int op_le(int a, int b) { return a <= b; }
+static int op_gt(int a, int b) { return a > b; }
+static int op_lt(int a, int b) { return a < b; }
+static int op_shl(int a, int b) { return a << b; }
+static int op_shr(int a, int b) { return a >> b; }
+static int op_add(int a, int b) { return a + b; }
+static int op_sub(int a, int b) { return a - b; }
+static int op_mul(int a, int b) { return a * b; }
+static int op_div(int a, int b) { return a / b; }
+static int op_mod(int a, int b) { return a % b; }
+static int op_pos(int a) { return a; }
+static int op_neg(int a) { return -a; }
+static int op_cmpl(int a) { return ~a; }
+static int op_not(int a) { return !a; }
+
+struct {
+    int token, prec, (*op)(int, int);
+} binop[] = {
+    { CPP_OR_OP, LOGOR, op_logor },
+    { CPP_AND_OP, LOGAND, op_logand },
+    { '|', OR, op_or },
+    { '^', XOR, op_xor },
+    { '&', AND, op_and },
+    { CPP_EQ_OP, EQUAL, op_eq },
+    { CPP_NE_OP, EQUAL, op_ne },
+    { '>', RELATION, op_gt },
+    { CPP_GE_OP, RELATION, op_ge },
+    { '<', RELATION, op_lt },
+    { CPP_LE_OP, RELATION, op_le },
+    { CPP_LEFT_OP, SHIFT, op_shl },
+    { CPP_RIGHT_OP, SHIFT, op_shr },
+    { '+', ADD, op_add },
+    { '-', ADD, op_sub },
+    { '*', MUL, op_mul },
+    { '/', MUL, op_div },
+    { '%', MUL, op_mod },
+};
+
+struct {
+    int token, (*op)(int);
+} unop[] = {
+    { '+', op_pos },
+    { '-', op_neg },
+    { '~', op_cmpl },
+    { '!', op_not },
+};
+
+#define ALEN(A) (sizeof(A)/sizeof(A[0]))
+
+static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
+{
+    int         i, val;
+    Symbol      *s;
+    if (token == CPP_IDENTIFIER) {
+        if (yylvalpp->sc_ident == definedAtom) {
+            int needclose = 0;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (token == '(') {
+                needclose = 1;
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            }
+            if (token != CPP_IDENTIFIER)
+                goto error;
+            *res = (s = LookUpSymbol(macros, yylvalpp->sc_ident))
+                        ? !s->details.mac.undef : 0;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (needclose) {
+                if (token != ')')
+                    goto error;
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            }
+               } else if (MacroExpand(yylvalpp->sc_ident, yylvalpp)) {
+                       token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            return eval(token, prec, res, err, yylvalpp);
+        } else {
+            goto error;
+        }
+       } else if (token == CPP_INTCONSTANT) {
+        *res = yylvalpp->sc_int;
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    } else if (token == '(') {
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        token = eval(token, MIN_PREC, res, err, yylvalpp);
+        if (!*err) {
+            if (token != ')')
+                goto error;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        }
+    } else {
+        for (i = ALEN(unop) - 1; i >= 0; i--) {
+            if (unop[i].token == token)
+                break;
+        }
+        if (i >= 0) {
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            token = eval(token, UNARY, res, err, yylvalpp);
+            *res = unop[i].op(*res);
+        } else {
+            goto error;
+        }
+    }
+    while (!*err) {
+        if (token == ')' || token == '\n') break;
+        for (i = ALEN(binop) - 1; i >= 0; i--) {
+            if (binop[i].token == token)
+                break;
+        }
+        if (i < 0 || binop[i].prec <= prec)
+            break;
+        val = *res;
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        token = eval(token, binop[i].prec, res, err, yylvalpp);
+        *res = binop[i].op(val, *res);
+    }
+    return token;
+error:
+    CPPErrorToInfoLog("incorrect preprocessor directive");
+    *err = 1;
+    *res = 0;
+    return token;
+} // eval
+
+static int CPPif(yystypepp * yylvalpp) {
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    int res = 0, err = 0;
+       cpp->elsetracker++;
+    if (!cpp->ifdepth++)
+        ifloc = *cpp->tokenLoc;
+       if(cpp->ifdepth >MAX_IF_NESTING){
+        CPPErrorToInfoLog("max #if nesting depth exceeded");
+               return 0;
+       }
+       token = eval(token, MIN_PREC, &res, &err, yylvalpp);
+    if (token != '\n') {
+        CPPWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
+        while (token != '\n')
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    } 
+    if (!res && !err) {
+        token = CPPelse(1, yylvalpp);
+    }
+
+    return token;
+} // CPPif
+
+static int CPPifdef(int defined, yystypepp * yylvalpp)
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    int name = yylvalpp->sc_ident;
+       if(++cpp->ifdepth >MAX_IF_NESTING){
+           CPPErrorToInfoLog("max #if nesting depth exceeded");
+               return 0;
+       }
+       cpp->elsetracker++;
+    if (token != CPP_IDENTIFIER) {
+            defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef");
+    } else {
+        Symbol *s = LookUpSymbol(macros, name);
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        if (token != '\n') {
+            CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
+            while (token != '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        }
+        if (((s && !s->details.mac.undef) ? 1 : 0) != defined)
+            token = CPPelse(1, yylvalpp);
+    }
+    return token;
+} // CPPifdef
+
+static int CPPline(yystypepp * yylvalpp) 
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       if(token=='\n'){
+               DecLineNumber();
+        CPPErrorToInfoLog("#line");
+        IncLineNumber();
+               return token;
+       }
+       else if (token == CPP_INTCONSTANT) {
+               yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+               SetLineNumber(yylvalpp->sc_int);
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        
+               if (token == CPP_INTCONSTANT) {
+            yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+                       SetStringNumber(yylvalpp->sc_int);
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                       if(token!='\n')
+                               CPPErrorToInfoLog("#line");
+        }
+               else if (token == '\n'){
+                       return token;
+               }
+               else{
+            CPPErrorToInfoLog("#line");
+               }
+       }
+       else{
+          CPPErrorToInfoLog("#line");
+       }
+    return token;
+}
+
+static int CPPerror(yystypepp * yylvalpp) {
+
+       int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    const char *message;
+       
+    while (token != '\n') {
+               if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
+            StoreStr(yylvalpp->symbol_name);
+               }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
+                       StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
+               }else {
+                   StoreStr(GetStringOfAtom(atable,token));
+               }
+               token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       }
+       DecLineNumber();
+       //store this msg into the shader's information log..set the Compile Error flag!!!!
+       message=GetStrfromTStr();
+    CPPShInfoLogMsg(message);
+    ResetTString();
+    cpp->CompileError=1;
+    IncLineNumber();
+    return '\n';
+}//CPPerror
+
+static int CPPpragma(yystypepp * yylvalpp)
+{
+       char SrcStrName[2];
+       char** allTokens;
+       int tokenCount = 0;
+       int maxTokenCount = 10;
+       const char* SrcStr;
+       int i;
+
+       int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       
+       if (token=='\n') {
+               DecLineNumber();
+        CPPErrorToInfoLog("#pragma");
+        IncLineNumber();
+           return token;
+       }
+       
+       allTokens = (char**)malloc(sizeof(char*) * maxTokenCount);      
+
+       while (token != '\n') {
+               if (tokenCount >= maxTokenCount) {
+                       maxTokenCount *= 2;
+                       allTokens = (char**)realloc((char**)allTokens, sizeof(char*) * maxTokenCount);
+               }
+               switch (token) {
+               case CPP_IDENTIFIER:
+                       SrcStr = GetAtomString(atable, yylvalpp->sc_ident);
+                       allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
+                       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_FLOATCONSTANT:
+                       SrcStr = yylvalpp->symbol_name;
+                       allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
+                       strcpy(allTokens[tokenCount++], SrcStr);
+                       break;
+               case -1:
+            // EOF
+            CPPShInfoLogMsg("#pragma directive must end with a newline");                      
+                       return token;
+               default:
+                       SrcStrName[0] = token;
+                       SrcStrName[1] = '\0';
+                       allTokens[tokenCount] = (char*)malloc(2);
+                       strcpy(allTokens[tokenCount++], SrcStrName);
+               }
+               token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       }
+
+       cpp->currentInput->ungetch(cpp->currentInput, token, yylvalpp);
+       HandlePragma((const char**)allTokens, tokenCount);
+       token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       
+       for (i = 0; i < tokenCount; ++i) {
+               free (allTokens[i]);
+       }
+       free (allTokens);       
+
+       return token;    
+} // CPPpragma
+
+#define GL2_VERSION_NUMBER 110
+
+static int CPPversion(yystypepp * yylvalpp)
+{
+
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+
+    if (cpp->notAVersionToken == 1)
+        CPPShInfoLogMsg("#version must occur before any other statement in the program");
+
+    if(token=='\n'){
+               DecLineNumber();
+        CPPErrorToInfoLog("#version");
+        IncLineNumber();
+               return token;
+       }
+    if (token != CPP_INTCONSTANT)
+        CPPErrorToInfoLog("#version");
+       
+    yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+       //SetVersionNumber(yylvalpp->sc_int);
+    
+    if (yylvalpp->sc_int != GL2_VERSION_NUMBER)
+        CPPShInfoLogMsg("Version number not supported by GL2");
+
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    
+       if (token == '\n'){
+               return token;
+       }
+       else{
+        CPPErrorToInfoLog("#version");
+       }
+    return token;
+} // CPPversion
+
+static int CPPextension(yystypepp * yylvalpp)
+{
+
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    char extensionName[80];
+
+    if(token=='\n'){
+               DecLineNumber();
+        CPPShInfoLogMsg("extension name not specified");
+        IncLineNumber();
+               return token;
+       }
+
+    if (token != CPP_IDENTIFIER)
+        CPPErrorToInfoLog("#extension");
+    
+    strcpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
+           
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != ':') {
+        CPPShInfoLogMsg("':' missing after extension name");
+        return token;
+    }
+    
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != CPP_IDENTIFIER) {
+        CPPShInfoLogMsg("behavior for extension not specified");
+        return token;
+    }
+
+    updateExtensionBehavior(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
+
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       if (token == '\n'){
+               return token;
+       }
+       else{
+        CPPErrorToInfoLog("#extension");
+       }
+    return token;
+} // CPPextension
+
+int readCPPline(yystypepp * yylvalpp)
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    const char *message;
+    int isVersion = 0;
+
+    if (token == CPP_IDENTIFIER) {
+        if (yylvalpp->sc_ident == defineAtom) {
+             token = CPPdefine(yylvalpp);
+        } else if (yylvalpp->sc_ident == elseAtom) {
+                        if(ChkCorrectElseNesting()){
+                 if (!cpp->ifdepth ){
+                     CPPErrorToInfoLog("#else mismatch");
+                     cpp->CompileError=1;
+                 }
+                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                 if (token != '\n') {
+                     CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
+                     while (token != '\n')
+                         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                 }
+                            token = CPPelse(0, yylvalpp);
+             }else{
+                 CPPErrorToInfoLog("#else after a #else");
+                 cpp->ifdepth=0;
+                 cpp->notAVersionToken = 1;
+                 return 0;
+             }
+               } else if (yylvalpp->sc_ident == elifAtom) {
+            if (!cpp->ifdepth){
+                 CPPErrorToInfoLog("#elif mismatch");
+                 cpp->CompileError=1;
+            } 
+            // this token is really a dont care, but we still need to eat the tokens
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); 
+            while (token != '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                   token = CPPelse(0, yylvalpp);
+        } else if (yylvalpp->sc_ident == endifAtom) {
+                        cpp->elsedepth[cpp->elsetracker]=0;
+                    --cpp->elsetracker;
+             if (!cpp->ifdepth){
+                 CPPErrorToInfoLog("#endif mismatch");
+                 cpp->CompileError=1;
+             }
+             else
+                                --cpp->ifdepth;
+           } else if (yylvalpp->sc_ident == ifAtom) {
+             token = CPPif(yylvalpp);
+        } else if (yylvalpp->sc_ident == ifdefAtom) {
+             token = CPPifdef(1, yylvalpp);
+        } else if (yylvalpp->sc_ident == ifndefAtom) {
+             token = CPPifdef(0, yylvalpp);
+        } else if (yylvalpp->sc_ident == lineAtom) {
+             token = CPPline(yylvalpp);
+        } else if (yylvalpp->sc_ident == pragmaAtom) {
+             token = CPPpragma(yylvalpp);
+        } else if (yylvalpp->sc_ident == undefAtom) {
+             token = CPPundef(yylvalpp);
+        } else if (yylvalpp->sc_ident == errorAtom) {
+             token = CPPerror(yylvalpp);
+        } else if (yylvalpp->sc_ident == versionAtom) {
+            token = CPPversion(yylvalpp);
+            isVersion = 1;
+        } else if (yylvalpp->sc_ident == extensionAtom) {
+            token = CPPextension(yylvalpp);
+        } else {
+            StoreStr("Invalid Directive");
+            StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
+            message=GetStrfromTStr();
+            CPPShInfoLogMsg(message);
+            ResetTString();
+        }
+    }
+    while (token != '\n' && token != 0 && token != EOF) {
+               token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+       }
+        
+    cpp->notAVersionToken = !isVersion;
+
+    return token;
+} // readCPPline
+
+void FreeMacro(MacroSymbol *s) {
+    DeleteTokenStream(s->body);
+}
+
+static int eof_scan(InputSrc *in, yystypepp * yylvalpp) { return -1; }
+static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) { }
+
+static void PushEofSrc() {
+    InputSrc *in = malloc(sizeof(InputSrc));
+    memset(in, 0, sizeof(InputSrc));
+    in->scan = eof_scan;
+    in->getch = eof_scan;
+    in->ungetch = noop;
+    in->prev = cpp->currentInput;
+    cpp->currentInput = in;
+}
+
+static void PopEofSrc() {
+    if (cpp->currentInput->scan == eof_scan) {
+        InputSrc *in = cpp->currentInput;
+        cpp->currentInput = in->prev;
+        free(in);
+    }
+}
+
+static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp) {
+    int token;
+    TokenStream *n;
+    RewindTokenStream(a);
+    do {
+        token = ReadToken(a, yylvalpp);
+        if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->sc_ident))
+            break;
+    } while (token > 0);
+    if (token <= 0) return a;
+    n = NewTokenStream("macro arg", 0);
+    PushEofSrc();
+    ReadFromTokenStream(a, 0, 0);
+    while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) {
+        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp))
+            continue;
+        RecordToken(n, token, yylvalpp);
+    }
+    PopEofSrc();
+    DeleteTokenStream(a);
+    return n;
+} // PrescanMacroArg
+
+typedef struct MacroInputSrc {
+    InputSrc    base;
+    MacroSymbol *mac;
+    TokenStream **args;
+} MacroInputSrc;
+
+/* macro_scan ---
+** return the next token for a macro expanion, handling macro args 
+*/
+static int macro_scan(MacroInputSrc *in, yystypepp * yylvalpp) {
+    int i;
+    int token = ReadToken(in->mac->body, yylvalpp);
+    if (token == CPP_IDENTIFIER) {
+        for (i = in->mac->argc-1; i>=0; i--)
+            if (in->mac->args[i] == yylvalpp->sc_ident) break;
+        if (i >= 0) {
+            ReadFromTokenStream(in->args[i], yylvalpp->sc_ident, 0);
+            return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        }
+    }
+    if (token > 0) return token;
+    in->mac->busy = 0;
+    cpp->currentInput = in->base.prev;
+    if (in->args) {
+        for (i=in->mac->argc-1; i>=0; i--)
+            DeleteTokenStream(in->args[i]);
+        free(in->args);
+    }
+    free(in);
+    return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+} // macro_scan
+
+/* MacroExpand
+** check an identifier (atom) to see if it a macro that should be expanded.
+** If it is, push an InputSrc that will produce the appropriate expansion
+** and return TRUE.  If not, return FALSE.
+*/
+
+int MacroExpand(int atom, yystypepp * yylvalpp)
+{
+    Symbol              *sym = LookUpSymbol(macros, atom);
+    MacroInputSrc       *in;
+    int i,j, token, depth=0;
+    const char *message;
+       if (atom == __LINE__Atom) {
+        yylvalpp->sc_int = GetLineNumber();
+        sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
+        UngetToken(CPP_INTCONSTANT, yylvalpp);
+        return 1;
+    }
+    if (atom == __FILE__Atom) {
+        yylvalpp->sc_int = GetStringNumber();
+        sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
+        UngetToken(CPP_INTCONSTANT, yylvalpp);
+        return 1;
+    }
+       if (atom == __VERSION__Atom) {
+        strcpy(yylvalpp->symbol_name,"100");
+        yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
+        UngetToken(CPP_INTCONSTANT, yylvalpp);
+        return 1;
+    }
+    if (!sym || sym->details.mac.undef) return 0;
+    if (sym->details.mac.busy) return 0;        // no recursive expansions
+    in = malloc(sizeof(*in));
+    memset(in, 0, sizeof(*in));
+    in->base.scan = (void *)macro_scan;
+    in->base.line = cpp->currentInput->line;
+    in->base.name = cpp->currentInput->name;
+    in->mac = &sym->details.mac;
+    if (sym->details.mac.args) {
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+               if (token != '(') {
+            UngetToken(token, yylvalpp);
+            yylvalpp->sc_ident = atom;
+            return 0;
+        }
+        in->args = malloc(in->mac->argc * sizeof(TokenStream *));
+        for (i=0; i<in->mac->argc; i++)
+            in->args[i] = NewTokenStream("macro arg", 0);
+               i=0;j=0;
+        do{
+            depth = 0;
+                       while(1) {
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token <= 0) {
+                    StoreStr("EOF in Macro ");
+                    StoreStr(GetStringOfAtom(atable,atom));
+                    message=GetStrfromTStr();
+                    CPPShInfoLogMsg(message);
+                    ResetTString();
+                    return 1;
+                }
+                if((in->mac->argc==0) && (token!=')')) break;
+                if (depth == 0 && (token == ',' || token == ')')) break;
+                if (token == '(') depth++;
+                if (token == ')') depth--;
+                RecordToken(in->args[i], token, yylvalpp);
+                j=1;
+                       }
+            if (token == ')') {
+                if((in->mac->argc==1) &&j==0)
+                    break;
+                i++;
+                break;
+            }
+            i++;
+               }while(i < in->mac->argc);
+
+        if (i < in->mac->argc) {
+            StoreStr("Too few args in Macro ");
+            StoreStr(GetStringOfAtom(atable,atom));
+            message=GetStrfromTStr();
+            CPPShInfoLogMsg(message);
+            ResetTString();
+        } else if (token != ')') {
+            depth=0;
+                       while (token >= 0 && (depth > 0 || token != ')')) {
+                if (token == ')') depth--;
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token == '(') depth++;
+            }
+                       
+            if (token <= 0) {
+                StoreStr("EOF in Macro ");
+                StoreStr(GetStringOfAtom(atable,atom));
+                message=GetStrfromTStr();
+                CPPShInfoLogMsg(message);
+                ResetTString();
+                return 1;
+            }
+            StoreStr("Too many args in Macro ");
+            StoreStr(GetStringOfAtom(atable,atom));
+            message=GetStrfromTStr();
+            CPPShInfoLogMsg(message);
+            ResetTString();
+               }
+               for (i=0; i<in->mac->argc; i++) {
+            in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
+        }
+    }
+#if 0
+    printf("  <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
+           loc.line, GetAtomString(atable, atom));
+    for (i=0; i<in->mac->argc; i++) {
+        printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
+        DumpTokenStream(stdout, in->args[i]);
+        printf("'\n");
+    }
+#endif
+       /*retain the input source*/
+    in->base.prev = cpp->currentInput;
+    sym->details.mac.busy = 1;
+    RewindTokenStream(sym->details.mac.body);
+    cpp->currentInput = &in->base;
+    return 1;
+} // MacroExpand
+
+int ChkCorrectElseNesting(void)
+{
+    if(cpp->elsedepth[cpp->elsetracker]==0){
+         cpp->elsedepth[cpp->elsetracker]=1;
+      return 1;          
+    }
+    return 0;
+}
+
+
diff --git a/glslang/MachineIndependent/preprocessor/cpp.h b/glslang/MachineIndependent/preprocessor/cpp.h
new file mode 100644 (file)
index 0000000..10ecd12
--- /dev/null
@@ -0,0 +1,119 @@
+//
+//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.
+\****************************************************************************/
+//
+// cpp.h
+//
+
+#if !defined(__CPP_H)
+#define __CPP_H 1
+
+#include "parser.h"
+#include "tokens.h"
+
+int InitCPP(void);
+int FinalCPP(void);
+int  readCPPline(yystypepp * yylvalpp);
+int MacroExpand(int atom, yystypepp * yylvalpp);
+int ChkCorrectElseNesting(void);
+
+typedef struct MacroSymbol {
+    int argc;
+    int *args;
+    TokenStream *body;
+    unsigned busy:1;
+    unsigned undef:1;
+} MacroSymbol;
+
+void FreeMacro(MacroSymbol *);
+int PredefineMacro(char *);
+
+void  CPPDebugLogMsg(const char *msg);      // Prints information into debug log
+void  CPPShInfoLogMsg(const char*);         // Store cpp Err Msg into Sh.Info.Log
+void  CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log
+void  HandlePragma(const char**, int numTokens);  // #pragma directive container.
+void  ResetTString(void);                   // #error Message as TString.
+void  CPPErrorToInfoLog(char*);             // Stick all cpp errors into Sh.Info.log   .
+void  StoreStr(char*);                      // Store the TString in Parse Context.
+void  SetLineNumber(int);                   // Set line number.  
+void  SetStringNumber(int);                 // Set string number.    
+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  updateExtensionBehavior(const char* extName, const char* behavior);
+int   FreeCPP(void);
+
+#endif // !(defined(__CPP_H)
diff --git a/glslang/MachineIndependent/preprocessor/cppstruct.c b/glslang/MachineIndependent/preprocessor/cppstruct.c
new file mode 100644 (file)
index 0000000..b1b15fa
--- /dev/null
@@ -0,0 +1,185 @@
+//
+//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.
+\****************************************************************************/
+//
+// cppstruct.c
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "slglobals.h"
+
+CPPStruct  *cpp      = NULL;
+static int  refCount = 0;
+
+int InitPreprocessor(void);
+int ResetPreprocessor(void);
+int FreeCPPStruct(void);
+int FinalizePreprocessor(void);
+
+/*
+ * InitCPPStruct() - Initilaize the CPP structure.
+ *
+ */
+
+int InitCPPStruct(void)
+{
+    int len;
+    char *p;
+
+    cpp = (CPPStruct *) malloc(sizeof(CPPStruct));
+    if (cpp == NULL)
+        return 0;
+
+    refCount++;
+
+    // Initialize public members:
+    cpp->pLastSourceLoc = &cpp->lastSourceLoc;
+    
+       p = (char *) &cpp->options;
+    len = sizeof(cpp->options);
+    while (--len >= 0)
+        p[len] = 0;
+     
+    ResetPreprocessor();
+    return 1;
+} // InitCPPStruct
+
+int ResetPreprocessor(void)
+{
+    // Initialize private members:
+
+    cpp->lastSourceLoc.file = 0;
+    cpp->lastSourceLoc.line = 0;
+       cpp->pC=0;
+    cpp->CompileError=0; 
+       cpp->ifdepth=0;
+    for(cpp->elsetracker=0; cpp->elsetracker<64; cpp->elsetracker++)
+               cpp->elsedepth[cpp->elsetracker]=0; 
+       cpp->elsetracker=0;
+    cpp->tokensBeforeEOF = 0;
+    return 1;
+}
+
+//Intializing the Preprocessor.
+
+int InitPreprocessor(void)
+{
+   #  define CPP_STUFF true
+        #  ifdef CPP_STUFF
+            FreeCPPStruct();
+            InitCPPStruct();
+            cpp->options.Quiet = 1;
+            cpp->options.profileString = "generic";
+            if (!InitAtomTable(atable, 0))
+                return 1;
+            if (!InitScanner(cpp))
+                   return 1;
+       #  endif
+  return 0; 
+}
+
+//FreeCPPStruct() - Free the CPP structure.
+
+int FreeCPPStruct(void)
+{
+    if (refCount)
+    {
+       free(cpp);
+       refCount--;
+    }
+    
+    return 1;
+}
+
+//Finalizing the Preprocessor.
+
+int FinalizePreprocessor(void)
+{
+   #  define CPP_STUFF true
+        #  ifdef CPP_STUFF
+            FreeAtomTable(atable);
+            FreeCPPStruct();
+            FreeScanner();
+       #  endif
+  return 0; 
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////// End of cppstruct.c //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/glslang/MachineIndependent/preprocessor/memory.c b/glslang/MachineIndependent/preprocessor/memory.c
new file mode 100644 (file)
index 0000000..74e20ff
--- /dev/null
@@ -0,0 +1,191 @@
+//
+//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.
+\****************************************************************************/
+//
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __STDC99__
+#include <stdint.h>
+#elif defined (_WIN64)
+typedef unsigned __int64 uintptr_t;
+#else 
+typedef unsigned int uintptr_t;
+#endif
+
+#include "memory.h"
+
+// default alignment and chunksize, if called with 0 arguments
+#define CHUNKSIZE       (64*1024)
+#define ALIGN           8
+
+// we need to call the `real' malloc and free, not our replacements
+#undef malloc
+#undef free
+
+struct chunk {
+    struct chunk        *next;
+};
+
+struct cleanup {
+    struct cleanup      *next;
+    void                (*fn)(void *);
+    void                *arg;
+};
+
+struct MemoryPool_rec {
+    struct chunk        *next;
+    uintptr_t           free, end;
+    size_t              chunksize;
+    uintptr_t           alignmask;
+    struct cleanup      *cleanup;
+};
+
+MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align)
+{
+    MemoryPool  *pool;
+
+    if (align == 0) align = ALIGN;
+    if (chunksize == 0) chunksize = CHUNKSIZE;
+    if (align & (align-1)) return 0;
+    if (chunksize < sizeof(MemoryPool)) return 0;
+    if (chunksize & (align-1)) return 0;
+    if (!(pool = malloc(chunksize))) return 0;
+    pool->next = 0;
+    pool->chunksize = chunksize;
+    pool->alignmask = (uintptr_t)(align)-1;  
+    pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
+    pool->end = (uintptr_t)pool + chunksize;
+    pool->cleanup = 0;
+    return pool;
+}
+
+void mem_FreePool(MemoryPool *pool)
+{
+    struct cleanup      *cleanup;
+    struct chunk        *p, *next;
+
+    for (cleanup = pool->cleanup; cleanup; cleanup = cleanup->next) {
+        cleanup->fn(cleanup->arg);
+    }
+    for (p = (struct chunk *)pool; p; p = next) {
+        next = p->next;
+        free(p);
+    }
+}
+
+void *mem_Alloc(MemoryPool *pool, size_t size)
+{
+    struct chunk *ch;
+    void *rv = (void *)pool->free;
+    size = (size + pool->alignmask) & ~pool->alignmask;
+    if (size <= 0) size = pool->alignmask;
+    pool->free += size;
+    if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
+        size_t minreq = (size + sizeof(struct chunk) + pool->alignmask)
+                      & ~pool->alignmask;
+        pool->free = (uintptr_t)rv;
+        if (minreq >= pool->chunksize) {
+            // request size is too big for the chunksize, so allocate it as
+            // a single chunk of the right size
+            ch = malloc(minreq);
+            if (!ch) return 0;
+        } else {
+            ch = malloc(pool->chunksize);
+            if (!ch) return 0;
+            pool->free = (uintptr_t)ch + minreq;
+            pool->end = (uintptr_t)ch + pool->chunksize;
+        }
+        ch->next = pool->next;
+        pool->next = ch;
+        rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
+    }
+    return rv;
+}
+
+int mem_AddCleanup(MemoryPool *pool, void (*fn)(void *), void *arg) {
+    struct cleanup *cleanup;
+
+    pool->free = (pool->free + sizeof(void *) - 1) & ~(sizeof(void *)-1);
+    cleanup = mem_Alloc(pool, sizeof(struct cleanup));
+    if (!cleanup) return -1;
+    cleanup->next = pool->cleanup;
+    cleanup->fn = fn;
+    cleanup->arg = arg;
+    pool->cleanup = cleanup;
+    return 0;
+}
diff --git a/glslang/MachineIndependent/preprocessor/memory.h b/glslang/MachineIndependent/preprocessor/memory.h
new file mode 100644 (file)
index 0000000..dbd6fbd
--- /dev/null
@@ -0,0 +1,89 @@
+//
+//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.
+\****************************************************************************/
+//
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+typedef struct MemoryPool_rec MemoryPool;
+
+extern MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
+extern void mem_FreePool(MemoryPool *);
+extern void *mem_Alloc(MemoryPool *p, size_t size);
+extern void *mem_Realloc(MemoryPool *p, void *old, size_t oldsize, size_t newsize);
+extern int mem_AddCleanup(MemoryPool *p, void (*fn)(void *), void *arg);
+
+#endif /* __MEMORY_H */
diff --git a/glslang/MachineIndependent/preprocessor/parser.h b/glslang/MachineIndependent/preprocessor/parser.h
new file mode 100644 (file)
index 0000000..1b42844
--- /dev/null
@@ -0,0 +1,126 @@
+//
+//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.
+\****************************************************************************/
+
+#ifndef BISON_PARSER_H
+# define BISON_PARSER_H
+
+#ifndef yystypepp
+typedef struct {
+    int    sc_int;
+    float  sc_fval;
+    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
+# define       CPP_ADD_ASSIGN  261
+# define       CPP_DIV_ASSIGN  262
+# define       CPP_MUL_ASSIGN  263
+# define       CPP_EQ_OP               264
+# define    CPP_XOR_OP         265 
+# define       ERROR_SY            266
+# define       CPP_FLOATCONSTANT       267
+# define       CPP_GE_OP               268
+# define       CPP_RIGHT_OP        269
+# define       CPP_IDENTIFIER      270
+# define       CPP_INTCONSTANT     271
+# define       CPP_LE_OP               272
+# define       CPP_LEFT_OP             273
+# define       CPP_DEC_OP      274
+# define       CPP_NE_OP               275
+# define       CPP_OR_OP               276
+# 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
+# define       CPP_OR_ASSIGN   283
+# define       CPP_XOR_ASSIGN  284
+# define       CPP_LEFT_BRACKET        285
+# define       CPP_RIGHT_BRACKET       286
+# define       CPP_LEFT_BRACE  287
+# define       CPP_RIGHT_BRACE 288
+
+#endif /* not BISON_PARSER_H */
diff --git a/glslang/MachineIndependent/preprocessor/preprocess.h b/glslang/MachineIndependent/preprocessor/preprocess.h
new file mode 100644 (file)
index 0000000..8f8a596
--- /dev/null
@@ -0,0 +1,84 @@
+//
+//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.
+\****************************************************************************/
+
+# include "slglobals.h"
+extern CPPStruct *cpp;
+int InitCPPStruct(void);
+int InitScanner(CPPStruct *cpp);
+int InitAtomTable(AtomTable *atable, int htsize);
+int ScanFromString(char *s);
+char* GetStringOfAtom(AtomTable *atable, int atom);
diff --git a/glslang/MachineIndependent/preprocessor/scanner.c b/glslang/MachineIndependent/preprocessor/scanner.c
new file mode 100644 (file)
index 0000000..6d562a4
--- /dev/null
@@ -0,0 +1,794 @@
+//
+//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.
+\****************************************************************************/
+//
+// scanner.c
+//
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if 0
+    #include <ieeefp.h>
+    #else
+    #define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
+                       ((*(int *)&(x) & 0x007fffffL)==0000000000L))
+#endif
+
+#include "slglobals.h"
+
+
+typedef struct StringInputSrc {
+    InputSrc base;
+    char *p;
+} StringInputSrc;
+
+static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
+{
+    return EOF;
+} // eof_scan
+
+static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
+
+static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
+
+static int byte_scan(InputSrc *, yystypepp * yylvalpp);
+
+#define EOL_SY '\n'
+
+#if defined(_WIN32)
+    #define DBG_BREAKPOINT() __asm int 3
+    #elif defined(_M_AMD64)
+    #define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
+    #else
+    #define DBG_BREAKPOINT()
+    #endif
+
+    #if defined(_WIN32) && !defined(_M_AMD64)
+    __int64 RDTSC ( void ) {
+
+        __int64 v;
+    
+        __asm __emit 0x0f
+        __asm __emit 0x31
+        __asm mov dword ptr v, eax
+        __asm mov dword ptr v+4, edx
+    
+        return v;
+    }
+#endif
+
+
+int InitScanner(CPPStruct *cpp)
+{
+    // Add various atoms needed by the CPP line scanner:
+    if (!InitCPP())
+        return 0;
+
+    cpp->mostRecentToken = 0;
+    cpp->tokenLoc = &cpp->ltokenLoc;
+
+    cpp->ltokenLoc.file = 0;
+    cpp->ltokenLoc.line = 0;
+
+    cpp->currentInput = &eof_inputsrc;
+    cpp->previous_token = '\n';
+    cpp->notAVersionToken = 0;
+
+    return 1;
+} // InitScanner
+
+int FreeScanner(void)
+{
+    return (FreeCPP());
+}
+
+/*
+ * str_getch()
+ * takes care of reading from multiple strings.
+ * returns the next-char from the input stream.
+ * returns EOF when the complete shader is parsed.
+ */
+static int str_getch(StringInputSrc *in)
+{
+       for(;;){
+          if (*in->p){
+             if (*in->p == '\n') {
+             in->base.line++;
+             IncLineNumber();
+          }
+          return *in->p++;
+          }
+          if(++(cpp->PaWhichStr) < cpp->PaArgc){
+                 free(in);
+                 SetStringNumber(cpp->PaWhichStr);
+         SetLineNumber(1);
+                 ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
+                 in=(StringInputSrc*)cpp->currentInput;
+             continue;             
+          }
+          else{
+             cpp->currentInput = in->base.prev;
+             cpp->PaWhichStr=0;
+          free(in);
+          return EOF;
+       }  
+       }
+} // str_getch
+
+static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
+    if (in->p[-1] == ch)in->p--;
+       else {
+               *(in->p)='\0'; //this would take care of shifting to the previous string.
+           cpp->PaWhichStr--;
+       }  
+       if (ch == '\n') {
+        in->base.line--;
+        DecLineNumber();
+    }
+} // str_ungetch
+
+int ScanFromString(char *s)
+{
+    
+       StringInputSrc *in = malloc(sizeof(StringInputSrc));
+    memset(in, 0, sizeof(StringInputSrc));
+       in->p = s;
+    in->base.line = 1;
+    in->base.scan = byte_scan;
+    in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
+    in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
+    in->base.prev = cpp->currentInput;
+    cpp->currentInput = &in->base;
+
+    return 1;
+} // ScanFromString;
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// Floating point constants: /////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+/*
+ * lBuildFloatValue() - Quick and dirty conversion to floating point.  Since all
+ *         we need is single precision this should be quite precise.
+ */
+
+static float lBuildFloatValue(const char *str, int len, int exp)
+{
+    double val, expval, ten;
+    int ii, llen, absexp;
+    float rv;
+
+    val = 0.0;
+    llen = len;
+    for (ii = 0; ii < len; ii++)
+        val = val*10.0 + (str[ii] - '0');
+    if (exp != 0) {
+        absexp = exp > 0 ? exp : -exp;
+        expval = 1.0f;
+        ten = 10.0;
+        while (absexp) {
+            if (absexp & 1)
+                expval *= ten;
+            ten *= ten;
+            absexp >>= 1;
+        }
+        if (exp >= 0) {
+            val *= expval;
+        } else {
+            val /= expval;
+        }
+    }
+    rv = (float)val;
+    if (isinff(rv)) {
+               CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW");
+    }
+    return rv;
+} // lBuildFloatValue
+
+
+/*
+ * lFloatConst() - Scan a floating point constant.  Assumes that the scanner
+ *         has seen at least one digit, followed by either a decimal '.' or the
+ *         letter 'e'.
+ */
+
+static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
+{
+    int HasDecimal, declen, exp, ExpSign;
+    int str_len;
+    float lval;
+    
+    HasDecimal = 0;
+    declen = 0;
+    exp = 0;
+       
+    str_len=len;
+    if (ch == '.') {
+               str[len++]=ch;
+        HasDecimal = 1;
+        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        while (ch >= '0' && ch <= '9') {
+            if (len < MAX_SYMBOL_NAME_LEN) {
+                declen++;
+                if (len > 0 || ch != '0') {
+                    str[len] = ch;
+                    len++;str_len++;
+                }
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            } else {
+                CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
+                len = 1,str_len=1;
+            }
+        }
+    }
+
+    // Exponent:
+
+    if (ch == 'e' || ch == 'E') {
+        ExpSign = 1;
+               str[len++]=ch;
+        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        if (ch == '+') {
+            str[len++]=ch;  
+                       ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        } else if (ch == '-') {
+            ExpSign = -1;
+                       str[len++]=ch;
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        }
+        if (ch >= '0' && ch <= '9') {
+            while (ch >= '0' && ch <= '9') {
+                exp = exp*10 + ch - '0';
+                               str[len++]=ch;
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            }
+        } else {
+            CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
+        }
+        exp *= ExpSign;
+    }
+      
+    if (len == 0) {
+        lval = 0.0f;
+               strcpy(str,"0.0");
+    } else {
+        str[len]='\0';      
+        lval = lBuildFloatValue(str, str_len, exp - declen);
+    }
+    // Suffix:
+    
+    yylvalpp->sc_fval = lval;
+    strcpy(yylvalpp->symbol_name,str);
+    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);            
+    return CPP_FLOATCONSTANT;
+} // lFloatConst
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////// Normal Scanner //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+    
+static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
+{
+    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
+    char string_val[MAX_STRING_LEN + 1];
+    int AlreadyComplained;
+    int len, ch, ii, ival = 0;
+
+    for (;;) {
+        yylvalpp->sc_int = 0;
+        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+               
+        while (ch == ' ' || ch == '\t' || ch == '\r') {
+            yylvalpp->sc_int = 1;
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        }
+               
+        cpp->ltokenLoc.file = cpp->currentInput->name;
+        cpp->ltokenLoc.line = cpp->currentInput->line;
+        len = 0;
+        switch (ch) {
+        default:
+                       return ch; // Single character token
+        case EOF:
+            return -1;
+               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':
+        case 'P': case 'Q': case 'R': case 'S': case 'T':
+        case 'U': case 'V': case 'W': case 'X': case 'Y':
+        case 'Z': case '_':
+        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':
+        case 'p': case 'q': case 'r': case 's': case 't':
+        case 'u': case 'v': case 'w': case 'x': case 'y':
+        case 'z':            
+            do {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);                                        
+                } else {
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                }
+            } while ((ch >= 'a' && ch <= 'z') ||
+                     (ch >= 'A' && ch <= 'Z') ||
+                     (ch >= '0' && ch <= '9') ||
+                     ch == '_');
+            if (len >= MAX_SYMBOL_NAME_LEN)
+                len = MAX_SYMBOL_NAME_LEN - 1;
+            symbol_name[len] = '\0';
+            cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+            return CPP_IDENTIFIER;
+            break;
+        case '0':
+            yylvalpp->symbol_name[len++] = ch;
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == 'x' || ch == 'X') {
+                               yylvalpp->symbol_name[len++] = ch;
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                if ((ch >= '0' && ch <= '9') ||
+                    (ch >= 'A' && ch <= 'F') ||
+                    (ch >= 'a' && ch <= 'f'))
+                {
+                    AlreadyComplained = 0;
+                    ival = 0;
+                    do {
+                                               yylvalpp->symbol_name[len++] = ch;
+                        if (ival <= 0x0fffffff) {
+                            if (ch >= '0' && ch <= '9') {
+                                ii = ch - '0';
+                            } else if (ch >= 'A' && ch <= 'F') {
+                                ii = ch - 'A' + 10;
+                            } else {
+                                ii = ch - 'a' + 10;
+                            }
+                            ival = (ival << 4) | ii;
+                        } else {
+                            if (!AlreadyComplained)
+                                CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
+                            AlreadyComplained = 1;
+                        }
+                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    } while ((ch >= '0' && ch <= '9') ||
+                             (ch >= 'A' && ch <= 'F') ||
+                             (ch >= 'a' && ch <= 'f'));
+                } else {
+                    CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
+                }
+                yylvalpp->symbol_name[len] = '\0';
+                               cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                               yylvalpp->sc_int = ival;
+                return CPP_INTCONSTANT;
+            } else if (ch >= '0' && ch <= '7') { // octal integer constants
+                AlreadyComplained = 0;
+                ival = 0;
+                do {
+                    yylvalpp->symbol_name[len++] = ch;
+                    if (ival <= 0x1fffffff) {
+                        ii = ch - '0';
+                        ival = (ival << 3) | ii;
+                    } else {
+                        if (!AlreadyComplained)
+                           CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
+                        AlreadyComplained = 1;
+                    }
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                } while (ch >= '0' && ch <= '7');
+                if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') 
+                     return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+                yylvalpp->symbol_name[len] = '\0';
+                               cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                               yylvalpp->sc_int = ival;
+                return CPP_INTCONSTANT;
+            } else {
+                               cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                               ch = '0';
+            }
+            // Fall through...
+        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 > 0 || ch != '0') {
+                        yylvalpp->symbol_name[len] = ch;
+                   len++;
+                    }
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                }
+            } while (ch >= '0' && ch <= '9');
+            if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
+                return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+            } else {
+                yylvalpp->symbol_name[len] = '\0';
+                               cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                ival = 0;
+                AlreadyComplained = 0;
+                for (ii = 0; ii < len; ii++) {
+                    ch = yylvalpp->symbol_name[ii] - '0';
+                    if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
+                        if (!AlreadyComplained)
+                           CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
+                        AlreadyComplained = 1;
+                    }
+                    ival = ival*10 + ch;
+                }
+                yylvalpp->sc_int = ival;
+                if(ival==0)
+                   strcpy(yylvalpp->symbol_name,"0");
+                return CPP_INTCONSTANT;
+            }
+            break;
+        case '-':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '-') {
+                return CPP_DEC_OP;
+            } else if (ch == '=') {
+                return CPP_SUB_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '-';
+            }
+        case '+':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '+') {
+                return CPP_INC_OP;
+            } else if (ch == '=') {
+                return CPP_ADD_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '+';
+            }
+        case '*':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_MUL_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '*';
+            }
+        case '%':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_MOD_ASSIGN;
+            } else if (ch == '>'){
+                return CPP_RIGHT_BRACE;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '%';
+            }
+        case ':':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '>') {
+                return CPP_RIGHT_BRACKET;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return ':';
+            }
+        case '^':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '^') {
+                return CPP_XOR_OP;
+            } else {
+                if (ch == '=')
+                    return CPP_XOR_ASSIGN;
+                else{
+                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                  return '^';
+                }
+            }
+        
+        case '=':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_EQ_OP;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '=';
+            }
+        case '!':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_NE_OP;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '!';
+            }
+        case '|':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '|') {
+                return CPP_OR_OP;
+            } else {
+                if (ch == '=')
+                    return CPP_OR_ASSIGN;
+                else{
+                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                  return '|';
+                }
+            }
+        case '&':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '&') {
+                return CPP_AND_OP;
+            } else {
+                if (ch == '=')
+                    return CPP_AND_ASSIGN;
+                else{
+                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                  return '&';
+                }
+            }
+        case '<':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '<') {
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                if(ch == '=')
+                    return CPP_LEFT_ASSIGN;
+                else{
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return CPP_LEFT_OP;
+                }
+            } else {
+                if (ch == '=') {
+                    return CPP_LE_OP;
+                } else {
+                    if (ch == '%')
+                        return CPP_LEFT_BRACE;
+                    else if (ch == ':')
+                        return CPP_LEFT_BRACKET;
+                    else{
+                        cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                        return '<';
+                    }
+                }
+            }
+        case '>':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '>') {
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                if(ch == '=')
+                    return CPP_RIGHT_ASSIGN;
+                else{
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return CPP_RIGHT_OP;
+                }
+            } else {
+                if (ch == '=') {
+                    return CPP_GE_OP;
+                } else {
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return '>';
+                }
+            }
+        case '.':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch >= '0' && ch <= '9') {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
+            } else {
+                if (ch == '.') {
+                    return -1; // Special EOF hack
+                } else {
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return '.';
+                }
+            }
+        case '/':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '/') {
+                do {
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                } while (ch != '\n' && ch != EOF);
+                if (ch == EOF)
+                    return -1;
+                return '\n';
+            } else if (ch == '*') {
+                int nlcount = 0;
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                do {
+                    while (ch != '*') {
+                        if (ch == '\n') nlcount++;
+                        if (ch == EOF) {
+                            CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+                            return -1;
+                        }
+                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    }
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    if (ch == EOF) {
+                        CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+                        return -1;
+                    }
+                } while (ch != '/');
+                if (nlcount) {
+                    return '\n';
+                }
+                // Go try it again...
+            } else if (ch == '=') {
+                return CPP_DIV_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '/';
+            }
+            break;
+        case '"':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            while (ch != '"' && ch != '\n' && ch != EOF) {
+                if (ch == '\\') {
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    if (ch == '\n' || ch == EOF) {
+                        break;
+                    }
+                }
+                if (len < MAX_STRING_LEN) {
+                    string_val[len] = ch;
+                    len++;
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                }
+            };
+            string_val[len] = '\0';
+            if (ch == '"') {
+                yylvalpp->sc_ident = LookUpAddString(atable, string_val);
+                return CPP_STRCONSTANT;
+            } else {
+                CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
+                return ERROR_SY;
+            }
+        }
+    }
+} // byte_scan
+
+int yylex_CPP(char* buf, int maxSize)
+{    
+       yystypepp yylvalpp;
+    int token = '\n';   
+
+    for(;;) {
+
+        char* tokenString = 0;
+        token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
+               if(check_EOF(token))
+                   return 0;
+        if (token == '#') {
+            if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
+                           token = readCPPline(&yylvalpp);
+                if(check_EOF(token))
+                    return 0;
+                           continue;
+            } else {
+                CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
+                return 0;
+            }
+        }
+        cpp->previous_token = token;
+        // expand macros
+        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
+            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);
+           }
+
+        if (tokenString) {
+            if ((signed)strlen(tokenString) >= maxSize) {
+                cpp->tokensBeforeEOF = 1;
+                return maxSize;               
+            } else  if (strlen(tokenString) > 0) {
+                           strcpy(buf, tokenString);
+                cpp->tokensBeforeEOF = 1;
+                return (int)strlen(tokenString);
+            }  
+
+            return 0;
+        }
+    }
+
+    return 0;
+} // yylex
+
+//Checks if the token just read is EOF or not.
+int check_EOF(int token)
+{
+   if(token==-1){
+       if(cpp->ifdepth >0){
+               CPPErrorToInfoLog("#endif missing!! Compilation stopped");
+        cpp->CompileError=1;
+       }
+      return 1;
+   }
+   return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////// End of scanner.c //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/glslang/MachineIndependent/preprocessor/scanner.h b/glslang/MachineIndependent/preprocessor/scanner.h
new file mode 100644 (file)
index 0000000..fb4d057
--- /dev/null
@@ -0,0 +1,118 @@
+//
+//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.
+\****************************************************************************/
+//
+// scanner.h
+//
+
+#if !defined(__SCANNER_H)
+#define __SCANNER_H 1
+
+#define MAX_SYMBOL_NAME_LEN 128
+#define MAX_STRING_LEN 512
+
+#include "parser.h"
+
+// Not really atom table stuff but needed first...
+
+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 
+void CPPErrorToInfoLog(char *);   // sticking the msg,line into the Shader's.Info.log
+void SetLineNumber(int);
+void SetStringNumber(int);
+void IncLineNumber(void);
+void DecLineNumber(void);
+int FreeScanner(void);                 // Free the cpp scanner
+#endif // !(defined(__SCANNER_H)
+
diff --git a/glslang/MachineIndependent/preprocessor/slglobals.h b/glslang/MachineIndependent/preprocessor/slglobals.h
new file mode 100644 (file)
index 0000000..ebe27c3
--- /dev/null
@@ -0,0 +1,115 @@
+//
+//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.
+\****************************************************************************/
+//
+// slglobals.h
+//
+
+#if !defined(__SLGLOBALS_H)
+#define __SLGLOBALS_H 1
+
+typedef struct CPPStruct_Rec CPPStruct;
+
+extern CPPStruct *cpp;
+
+#undef  CPPC_DEBUG_THE_COMPILER
+#if defined(_DEBUG)
+#define CPPC_DEBUG_THE_COMPILER 1
+#endif
+
+#undef  CPPC_ENABLE_TOOLS
+#define CPPC_ENABLE_TOOLS 1
+
+#include "memory.h"
+#include "atom.h"
+#include "scanner.h"
+#include "cpp.h"
+#include "tokens.h"
+#include "symbols.h"
+#include "compile.h"
+#if !defined(NO_PARSER)
+#include "parser.h"
+#endif
+
+#if !defined(NULL)
+#define NULL 0
+#endif
+
+#endif // !(defined(__SLGLOBALS_H)
+
+
+    
+
diff --git a/glslang/MachineIndependent/preprocessor/symbols.c b/glslang/MachineIndependent/preprocessor/symbols.c
new file mode 100644 (file)
index 0000000..2929ef1
--- /dev/null
@@ -0,0 +1,318 @@
+//
+//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.
+\****************************************************************************/
+//
+// symbols.c
+//
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "slglobals.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+Scope *ScopeList = NULL;
+Scope *CurrentScope = NULL;
+Scope *GlobalScope = NULL;
+
+static void unlinkScope(void *_scope) {
+    Scope *scope = _scope;
+
+    if (scope->next)
+        scope->next->prev = scope->prev;
+    if (scope->prev)
+        scope->prev->next = scope->next;
+    else
+        ScopeList = scope->next;
+}
+
+/*
+ * NewScope()
+ *
+ */
+Scope *NewScopeInPool(MemoryPool *pool)
+{
+    Scope *lScope;
+
+    lScope = mem_Alloc(pool, sizeof(Scope));
+    lScope->pool = pool;
+    lScope->parent = NULL;
+    lScope->funScope = NULL;
+    lScope->symbols = NULL;
+    
+    lScope->level = 0;
+
+    lScope->programs = NULL;
+    if ((lScope->next = ScopeList))
+        ScopeList->prev = lScope;
+    lScope->prev = 0;
+    ScopeList = lScope;
+    mem_AddCleanup(pool, unlinkScope, lScope);
+    return lScope;
+} // NewScope
+
+/*
+ * PushScope()
+ *
+ */
+
+void PushScope(Scope *fScope)
+{
+    Scope *lScope;
+
+    if (CurrentScope) {
+        fScope->level = CurrentScope->level + 1;
+        if (fScope->level == 1) {
+            if (!GlobalScope) {
+                /* HACK - CTD -- if GlobalScope==NULL and level==1, we're
+                 * defining a function in the superglobal scope.  Things
+                 * will break if we leave the level as 1, so we arbitrarily
+                 * set it to 2 */
+                fScope->level = 2;
+            }
+        }
+        if (fScope->level >= 2) {
+            lScope = fScope;
+            while (lScope->level > 2)
+                lScope = lScope->next;
+            fScope->funScope = lScope;
+        }
+    } else {
+        fScope->level = 0;
+    }
+    fScope->parent = CurrentScope;
+    CurrentScope = fScope;
+} // PushScope
+
+/*
+ * PopScope()
+ *
+ */
+
+Scope *PopScope(void)
+{
+    Scope *lScope;
+
+    lScope = CurrentScope;
+    if (CurrentScope)
+        CurrentScope = CurrentScope->parent;
+    return lScope;
+} // PopScope
+
+/*
+ * NewSymbol() - Allocate a new symbol node;
+ *
+ */
+
+Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
+{
+    Symbol *lSymb;
+    char *pch;
+    int ii;
+
+    lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
+    lSymb->left = NULL;
+    lSymb->right = NULL;
+    lSymb->next = NULL;
+    lSymb->name = name;
+    lSymb->loc = *loc;
+    lSymb->kind = kind;
+    
+    // Clear union area:
+
+    pch = (char *) &lSymb->details;
+    for (ii = 0; ii < sizeof(lSymb->details); ii++)
+        *pch++ = 0;
+    return lSymb;
+} // NewSymbol
+
+/*
+ * lAddToTree() - Using a binary tree is not a good idea for basic atom values because they
+ *         are generated in order.  We'll fix this later (by reversing the bit pattern).
+ */
+
+static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
+{
+    Symbol *lSymb;
+    int lrev, frev;
+
+    lSymb = *fSymbols;
+    if (lSymb) {
+        frev = GetReversedAtom(atable, fSymb->name);
+        while (lSymb) {
+            lrev = GetReversedAtom(atable, lSymb->name);
+            if (lrev == frev) {
+                CPPErrorToInfoLog("GetAtomString(atable, fSymb->name)");
+                break;
+            } else {
+                if (lrev > frev) {
+                    if (lSymb->left) {
+                        lSymb = lSymb->left;
+                    } else {
+                        lSymb->left = fSymb;
+                        break;
+                    }
+                } else {
+                    if (lSymb->right) {
+                        lSymb = lSymb->right;
+                    } else {
+                        lSymb->right = fSymb;
+                        break;
+                    }
+                }
+            }
+        }
+    } else {
+        *fSymbols = fSymb;
+    }
+} // lAddToTree
+
+
+/*
+ * AddSymbol() - Add a variable, type, or function name to a scope.
+ *
+ */
+
+Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
+{
+    Symbol *lSymb;
+
+    if (!fScope)
+        fScope = CurrentScope;
+    lSymb = NewSymbol(loc, fScope, atom, kind);
+    lAddToTree(&fScope->symbols, lSymb);
+    return lSymb;
+} // AddSymbol
+
+
+/*********************************************************************************************/
+/************************************ Symbol Semantic Functions ******************************/
+/*********************************************************************************************/
+
+/*
+ * LookUpLocalSymbol()
+ *
+ */
+
+Symbol *LookUpLocalSymbol(Scope *fScope, int atom)
+{
+    Symbol *lSymb;
+    int rname, ratom;
+
+    ratom = GetReversedAtom(atable, atom);
+    if (!fScope)
+        fScope = CurrentScope;
+    lSymb = fScope->symbols;
+    while (lSymb) {
+        rname = GetReversedAtom(atable, lSymb->name);
+        if (rname == ratom) {
+            return lSymb;
+        } else {
+            if (rname > ratom) {
+                lSymb = lSymb->left;
+            } else {
+                lSymb = lSymb->right;
+            }
+        }
+    }
+    return NULL;
+} // LookUpLocalSymbol
+
+/*
+ * LookUpSymbol()
+ *
+ */
+
+Symbol *LookUpSymbol(Scope *fScope, int atom)
+{
+    Symbol *lSymb;
+
+    if (!fScope)
+        fScope = CurrentScope;
+    while (fScope) {
+        lSymb = LookUpLocalSymbol(fScope, atom);
+        if (lSymb)
+            return lSymb;
+        fScope = fScope->parent;
+    }
+    return NULL;
+} // LookUpSymbol
+
diff --git a/glslang/MachineIndependent/preprocessor/symbols.h b/glslang/MachineIndependent/preprocessor/symbols.h
new file mode 100644 (file)
index 0000000..618418c
--- /dev/null
@@ -0,0 +1,145 @@
+//
+//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.
+\****************************************************************************/
+//
+// symbols.h
+//
+
+#if !defined(__SYMBOLS_H)
+#define __SYMBOLS_H 1
+
+#include "memory.h"
+
+typedef enum symbolkind {
+   MACRO_S
+} symbolkind;
+
+// Typedefs for things defined here in "symbols.h":
+
+typedef struct Scope_Rec Scope;
+typedef struct Symbol_Rec Symbol;
+
+typedef struct SymbolList_Rec {
+    struct SymbolList_Rec *next;
+    Symbol *symb;
+} SymbolList;
+
+struct Scope_Rec {
+    Scope *next, *prev;     // doubly-linked list of all scopes
+    Scope *parent;
+    Scope *funScope;        // Points to base scope of enclosing function
+    MemoryPool *pool;       // pool used for allocation in this scope
+    Symbol *symbols;
+    
+       int level;              // 0 = super globals, 1 = globals, etc.
+
+    // Only used at global scope (level 1):
+    SymbolList *programs;   // List of programs for this compilation.
+};
+
+
+// Symbol table is a simple binary tree.
+
+#include "cpp.h"        // to get MacroSymbol def
+
+struct Symbol_Rec {
+    Symbol *left, *right;
+    Symbol *next;
+    int name;       // Name atom
+    SourceLoc loc;
+    symbolkind kind;
+    union {
+        MacroSymbol mac;
+    } details;
+};
+
+extern Scope *CurrentScope;
+extern Scope *GlobalScope;
+extern Scope *ScopeList;
+
+Scope *NewScopeInPool(MemoryPool *);
+#define NewScope()      NewScopeInPool(CurrentScope->pool)
+void PushScope(Scope *fScope);
+Scope *PopScope(void);
+Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind);
+Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
+Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
+Symbol *LookUpSymbol(Scope *fScope, int atom);
+void CPPErrorToInfoLog(char *);
+
+
+#endif // !defined(__SYMBOLS_H)
+
diff --git a/glslang/MachineIndependent/preprocessor/tokens.c b/glslang/MachineIndependent/preprocessor/tokens.c
new file mode 100644 (file)
index 0000000..c2f7911
--- /dev/null
@@ -0,0 +1,472 @@
+//
+//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.
+\****************************************************************************/
+//
+// tokens.c
+//
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "slglobals.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * idstr()
+ * Copy a string to a malloc'ed block and convert it into something suitable
+ * for an ID
+ *
+ */
+
+static char *idstr(const char *fstr, MemoryPool *pool)
+{
+    size_t len;
+    char *str, *t;
+    const char *f;
+
+    len = strlen(fstr);
+    if (!pool)
+        str = (char *) malloc(len + 1);
+    else
+        str = (char *) mem_Alloc(pool, len + 1);
+    
+    for (f=fstr, t=str; *f; f++) {
+        if (isalnum(*f)) *t++ = *f;
+        else if (*f == '.' || *f == '/') *t++ = '_';
+    }
+    *t = 0;
+    return str;
+} // idstr
+
+
+/*
+ * lNewBlock()
+ *
+ */
+
+static TokenBlock *lNewBlock(TokenStream *fTok, MemoryPool *pool)
+{
+    TokenBlock *lBlock;
+
+    if (!pool)
+        lBlock = (TokenBlock *) malloc(sizeof(TokenBlock) + 256);
+    else
+        lBlock = (TokenBlock *) mem_Alloc(pool, sizeof(TokenBlock) + 256);
+    lBlock->count = 0;
+    lBlock->current = 0;
+    lBlock->data = (unsigned char *) lBlock + sizeof(TokenBlock);
+    lBlock->max = 256;
+    lBlock->next = NULL;
+    if (fTok->head) {
+        fTok->current->next = lBlock;
+    } else {
+        fTok->head = lBlock;
+    }
+    fTok->current = lBlock;
+    return lBlock;
+} // lNewBlock
+
+/*
+ * lAddByte()
+ *
+ */
+
+static void lAddByte(TokenStream *fTok, unsigned char fVal)
+{
+    TokenBlock *lBlock;
+    lBlock = fTok->current;
+    if (lBlock->count >= lBlock->max)
+        lBlock = lNewBlock(fTok, 0);
+    lBlock->data[lBlock->count++] = fVal;
+} // lAddByte
+
+
+
+/*
+ * lReadByte() - Get the next byte from a stream.
+ *
+ */
+
+static int lReadByte(TokenStream *pTok)
+{
+    TokenBlock *lBlock;
+    int lval = -1;
+
+    lBlock = pTok->current;
+    if (lBlock) {
+        if (lBlock->current >= lBlock->count) {
+            lBlock = lBlock->next;
+            if (lBlock)
+                lBlock->current = 0;
+            pTok->current = lBlock;
+        }
+        if (lBlock)
+            lval = lBlock->data[lBlock->current++];
+    }
+    return lval;
+} // lReadByte
+
+/////////////////////////////////////// Global Functions://////////////////////////////////////
+
+/*
+ * NewTokenStream()
+ *
+ */
+
+TokenStream *NewTokenStream(const char *name, MemoryPool *pool)
+{
+    TokenStream *pTok;
+
+    if (!pool)
+        pTok = (TokenStream *) malloc(sizeof(TokenStream));
+    else
+        pTok = (TokenStream*)mem_Alloc(pool, sizeof(TokenStream));
+    pTok->next = NULL;
+    pTok->name = idstr(name, pool);
+    pTok->head = NULL;
+    pTok->current = NULL;
+    lNewBlock(pTok, pool);
+    return pTok;
+} // NewTokenStream
+
+/*
+ * DeleteTokenStream()
+ *
+ */
+
+void DeleteTokenStream(TokenStream *pTok)
+{
+    TokenBlock *pBlock, *nBlock;
+
+    if (pTok) {
+        pBlock = pTok->head;
+        while (pBlock) {
+            nBlock = pBlock->next;
+            free(pBlock);
+            pBlock = nBlock;
+        }
+        if (pTok->name)
+            free(pTok->name);
+        free(pTok);
+    }
+} // DeleteTokenStream
+
+/*
+ * RecordToken() - Add a token to the end of a list for later playback or printout.
+ *
+ */
+
+void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
+{
+    const char *s;
+    unsigned char *str=NULL;
+
+    if (token > 256)
+        lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
+    else
+        lAddByte(pTok, (unsigned char)(token & 0x7f));
+    switch (token) {
+    case CPP_IDENTIFIER:
+    case CPP_TYPEIDENTIFIER:
+    case CPP_STRCONSTANT:
+        s = GetAtomString(atable, yylvalpp->sc_ident);
+        while (*s)
+            lAddByte(pTok, (unsigned char) *s++);
+        lAddByte(pTok, 0);
+        break;
+    case CPP_FLOATCONSTANT:
+    case CPP_INTCONSTANT:
+         str=yylvalpp->symbol_name;
+         while (*str){
+            lAddByte(pTok,(unsigned char) *str);
+            *str++;
+         }
+         lAddByte(pTok, 0);
+         break;
+    case '(':
+        lAddByte(pTok, (unsigned char)(yylvalpp->sc_int ? 1 : 0));
+    default:
+        break;
+    }
+} // RecordToken
+
+/*
+ * RewindTokenStream() - Reset a token stream in preperation for reading.
+ *
+ */
+
+void RewindTokenStream(TokenStream *pTok)
+{
+    if (pTok->head) {
+        pTok->current = pTok->head;
+        pTok->current->current = 0;
+    }
+} // RewindTokenStream
+
+/*
+ * ReadToken() - Read the next token from a stream.
+ *
+ */
+
+int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
+{
+    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
+    char string_val[MAX_STRING_LEN + 1];
+    int ltoken, len;
+    char ch;
+
+    ltoken = lReadByte(pTok);
+    if (ltoken >= 0) {
+        if (ltoken > 127)
+            ltoken += 128;
+        switch (ltoken) {
+        case CPP_IDENTIFIER:
+        case CPP_TYPEIDENTIFIER:
+            len = 0;
+            ch = lReadByte(pTok);
+            while ((ch >= 'a' && ch <= 'z') ||
+                     (ch >= 'A' && ch <= 'Z') ||
+                     (ch >= '0' && ch <= '9') ||
+                     ch == '_')
+            {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = lReadByte(pTok);
+                }
+            }
+            symbol_name[len] = '\0';
+            assert(ch == '\0');
+            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+            return CPP_IDENTIFIER;
+            break;
+        case CPP_STRCONSTANT:
+            len = 0;
+            while ((ch = lReadByte(pTok)) != 0)
+                if (len < MAX_STRING_LEN)
+                    string_val[len++] = ch;
+            string_val[len] = 0;
+            yylvalpp->sc_ident = LookUpAddString(atable, string_val);
+            break;
+        case CPP_FLOATCONSTANT:
+            len = 0;
+            ch = lReadByte(pTok);
+            while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
+            {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = lReadByte(pTok);
+                }
+            }
+            symbol_name[len] = '\0';
+            assert(ch == '\0');
+            strcpy(yylvalpp->symbol_name,symbol_name);
+            yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
+            break;
+        case CPP_INTCONSTANT:
+            len = 0;
+            ch = lReadByte(pTok);
+            while ((ch >= '0' && ch <= '9'))
+            {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = lReadByte(pTok);
+                }
+            }
+            symbol_name[len] = '\0';
+            assert(ch == '\0');
+            strcpy(yylvalpp->symbol_name,symbol_name);
+            yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+            break;
+        case '(':
+            yylvalpp->sc_int = lReadByte(pTok);
+            break;
+        }
+        return ltoken;
+    }
+    return EOF_SY;
+} // ReadToken
+
+typedef struct TokenInputSrc {
+    InputSrc            base;
+    TokenStream         *tokens;
+    int                 (*final)(CPPStruct *);
+} TokenInputSrc;
+
+static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
+{
+    int token = ReadToken(in->tokens, yylvalpp);
+    int (*final)(CPPStruct *);
+    cpp->tokenLoc->file = cpp->currentInput->name;
+    cpp->tokenLoc->line = cpp->currentInput->line;
+    if (token == '\n') {
+        in->base.line++;
+        return token;
+    }
+    if (token > 0) return token;
+    cpp->currentInput = in->base.prev;
+    final = in->final;
+    free(in);
+    if (final && !final(cpp)) return -1;
+    return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+}
+
+int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
+{
+    TokenInputSrc *in = malloc(sizeof(TokenInputSrc));
+    memset(in, 0, sizeof(TokenInputSrc));
+    in->base.name = name;
+    in->base.prev = cpp->currentInput;
+    in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
+    in->base.line = 1;
+    in->tokens = ts;
+    in->final = final;
+    RewindTokenStream(ts);
+    cpp->currentInput = &in->base;
+    return 1;
+}
+
+typedef struct UngotToken {
+    InputSrc    base;
+    int         token;
+    yystypepp     lval;
+} UngotToken;
+
+static int reget_token(UngotToken *t, yystypepp * yylvalpp)
+{
+    int token = t->token;
+    *yylvalpp = t->lval;
+    cpp->currentInput = t->base.prev;
+    free(t);
+    return token;
+}
+
+void UngetToken(int token, yystypepp * yylvalpp) {
+    UngotToken *t = malloc(sizeof(UngotToken));
+    memset(t, 0, sizeof(UngotToken));
+    t->token = token;
+    t->lval = *yylvalpp;
+    t->base.scan = (void *)reget_token;
+    t->base.prev = cpp->currentInput;
+    t->base.name = cpp->currentInput->name;
+    t->base.line = cpp->currentInput->line;
+    cpp->currentInput = &t->base;
+}
+
+
+void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
+    int token;
+    char str[100];
+
+    if (fp == 0) fp = stdout;
+    RewindTokenStream(s);
+    while ((token = ReadToken(s, yylvalpp)) > 0) {
+        switch (token) {
+        case CPP_IDENTIFIER:
+        case CPP_TYPEIDENTIFIER:
+            sprintf(str, "%s ", GetAtomString(atable, yylvalpp->sc_ident));
+            break;
+        case CPP_STRCONSTANT:
+            sprintf(str, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
+            break;
+        case CPP_FLOATCONSTANT:
+            //printf("%g9.6 ", yylvalpp->sc_fval);
+            break;
+        case CPP_INTCONSTANT:
+            //printf("%d ", yylvalpp->sc_int);
+            break;
+        default:
+            if (token >= 127)
+                sprintf(str, "%s ", GetAtomString(atable, token));
+            else
+                sprintf(str, "%c", token);
+            break;
+        }
+        CPPDebugLogMsg(str);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////// End of tokens.c ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/glslang/MachineIndependent/preprocessor/tokens.h b/glslang/MachineIndependent/preprocessor/tokens.h
new file mode 100644 (file)
index 0000000..dda09ca
--- /dev/null
@@ -0,0 +1,122 @@
+//
+//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.
+\****************************************************************************/
+//
+// tokens.h
+//
+
+#if !defined(__TOKENS_H)
+#define __TOKENS_H 1
+
+#include "parser.h"
+
+#define EOF_SY (-1)
+
+typedef struct TokenBlock_Rec TokenBlock;
+
+typedef struct TokenStream_Rec {
+    struct TokenStream_Rec *next;
+    char *name;
+    TokenBlock *head;
+    TokenBlock *current;
+} TokenStream;
+
+struct TokenBlock_Rec {
+    TokenBlock *next;
+    int current;
+    int count;
+    int max;
+    unsigned char *data;
+};
+
+extern TokenStream stdlib_cpp_stream;
+
+
+TokenStream *NewTokenStream(const char *name, MemoryPool *pool);
+void DeleteTokenStream(TokenStream *pTok); 
+void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp);
+void RewindTokenStream(TokenStream *pTok);
+int ReadToken(TokenStream *pTok, yystypepp * yylvalpp);
+int ReadFromTokenStream(TokenStream *pTok, int name, int (*final)(CPPStruct *));
+void UngetToken(int, yystypepp * yylvalpp);
+
+#if defined(CPPC_ENABLE_TOOLS)
+
+void DumpTokenStream(FILE *, TokenStream *, yystypepp * yylvalpp);
+
+#endif // defined(CPPC_ENABLE_TOOLS)
+
+#endif // !defined(__TOKENS_H)
diff --git a/glslang/MachineIndependent/unistd.h b/glslang/MachineIndependent/unistd.h
new file mode 100644 (file)
index 0000000..c7c9147
--- /dev/null
@@ -0,0 +1 @@
+// This is a NULL file and is meant to be empty
diff --git a/glslang/OSDependent/Linux/Makefile b/glslang/OSDependent/Linux/Makefile
new file mode 100644 (file)
index 0000000..dc8d074
--- /dev/null
@@ -0,0 +1,62 @@
+####
+#### This Makefile should be used in the Linux Compiler build.  This Makefile build the OSDependent 
+#### component as a static library.
+####
+
+#
+# Compilation related
+#
+INCLUDE = -I. -I../.. -I../../Include -I../../../OGLCompilersDLL 
+WARNINGS = -Wall -Wwrite-strings -Wpointer-arith -Wcast-align -Wstrict-prototypes \
+       -Wnested-externs
+DEFINE = -Dlinux -D__i386__
+  
+CPP = g++
+CPPOPTIONS = -O3 -Wno-deprecated -D_ALT_NS=1
+CPPOPTIONS = -g -Wno-deprecated -D_ALT_NS=1 
+CPPFLAGS = $(CPPOPTIONS) $(DEFINE) $(INCLUDE)
+
+#
+# Linking related
+#
+AR = ar
+STATIC_OPTION = rcs
+
+#
+# Misc
+#
+export PERL = perl
+export RM = rm -f
+export MV = mv -f
+export DEPEND = g++ -M
+
+#
+# Object file variables are defined here.
+#
+OSSRCS = ossource.cpp
+OSOBJS = ossource.o
+
+LIBNAME = libOssource.a
+
+all : $(LIBNAME)
+
+$(LIBNAME) : $(OSOBJS)
+        $(AR) $(STATIC_OPTION) $(LIBNAME) $(OSOBJS) 
+
+%.o : %.cpp
+       $(CPP) $(CPPFLAGS) -c $<
+
+
+#
+# Dependency
+#
+depend : $(OSSRCS)
+       $(DEPEND) $(CPPFLAGS) $(OSSRCS) > depend
+include depend
+
+#
+# Cleanup
+#
+.PHONY : clean
+clean :
+       $(RM) *.o *.a
diff --git a/glslang/OSDependent/Linux/osinclude.h b/glslang/OSDependent/Linux/osinclude.h
new file mode 100644 (file)
index 0000000..883c993
--- /dev/null
@@ -0,0 +1,78 @@
+//
+//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.
+//
+
+#ifndef __OSINCLUDE_H
+#define __OSINCLUDE_H
+
+//
+// This file contains any Linux specific functions.
+//
+
+#if !(defined(linux))
+#error Trying to include a Linux specific file in a non-Linux build.
+#endif
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <assert.h>
+#include <errno.h>
+#include "Include/InitializeGlobals.h"
+#include "Include/PoolAlloc.h"
+
+#define _vsnprintf vsnprintf
+
+
+void DetachThreadLinux(void *);
+
+//
+// Thread Local Storage Operations
+//
+typedef unsigned int OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX 0xFFFFFFFF
+
+OS_TLSIndex OS_AllocTLSIndex();
+bool        OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
+bool        OS_FreeTLSIndex(OS_TLSIndex nIndex); 
+
+
+inline void * OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+       //
+       // This function should return 0 if nIndex is invalid.
+       //
+       assert(nIndex != OS_INVALID_TLS_INDEX);
+       return pthread_getspecific(nIndex); 
+}
+
+#endif // __OSINCLUDE_H
diff --git a/glslang/OSDependent/Linux/ossource.cpp b/glslang/OSDependent/Linux/ossource.cpp
new file mode 100644 (file)
index 0000000..08757b7
--- /dev/null
@@ -0,0 +1,141 @@
+//
+//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.
+//
+
+//
+// This file contains the Linux specific functions
+//
+#include "osinclude.h"
+#include "InitializeDll.h"
+
+#if !(defined(linux))
+#error Trying to build a Linux specific file in a non-Linux build.
+#endif
+
+
+//
+// Thread cleanup
+//
+
+//
+// Wrapper for Linux call to DetachThread.  This is required as pthread_cleanup_push() expects 
+// the cleanup routine to return void.
+// 
+void DetachThreadLinux(void *)
+{
+       DetachThread();
+}
+
+
+//
+// Registers cleanup handler, sets cancel type and state, and excecutes the thread specific
+// cleanup handler.  This function will be called in the Standalone.cpp for regression 
+// testing.  When OpenGL applications are run with the driver code, Linux OS does the 
+// thread cleanup.
+// 
+void OS_CleanupThreadData(void)
+{
+       int old_cancel_state, old_cancel_type;
+       void *cleanupArg = NULL;
+
+       //
+       // Set thread cancel state and push cleanup handler.
+       //
+       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
+       pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);
+
+       //
+       // Put the thread in deferred cancellation mode.
+       //
+       pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);
+
+       //
+       // Pop cleanup handler and execute it prior to unregistering the cleanup handler.
+       //
+       pthread_cleanup_pop(1);
+
+       //
+       // Restore the thread's previous cancellation mode.
+       //
+       pthread_setcanceltype(old_cancel_state, NULL);
+}
+
+
+//
+// Thread Local Storage Operations
+//
+OS_TLSIndex OS_AllocTLSIndex()
+{
+       pthread_key_t pPoolIndex;
+
+       //
+       // Create global pool key.
+       //
+       if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
+               assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
+               return false;
+       }
+       else
+               return pPoolIndex;
+}
+
+
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+{
+       if (nIndex == OS_INVALID_TLS_INDEX) {
+               assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
+               return false;
+       }
+
+       if (pthread_setspecific(nIndex, lpvValue) == 0)
+               return true;
+       else
+               return false;
+}
+
+
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
+{
+       if (nIndex == OS_INVALID_TLS_INDEX) {
+               assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
+               return false;
+       }
+
+       //
+       // Delete the global pool key.
+       //
+       if (pthread_key_delete(nIndex) == 0)
+               return true;
+       else
+               return false;
+}
diff --git a/glslang/OSDependent/Windows/main.cpp b/glslang/OSDependent/Windows/main.cpp
new file mode 100644 (file)
index 0000000..ee4ad55
--- /dev/null
@@ -0,0 +1,69 @@
+//
+//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.
+//
+
+#include "InitializeDll.h"
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+       switch (fdwReason)
+       {
+               case DLL_PROCESS_ATTACH:
+
+            if (!InitProcess())
+                return FALSE;
+            break;
+               case DLL_THREAD_ATTACH:
+
+            if (!InitThread())
+                return FALSE;
+            break;
+
+               case DLL_THREAD_DETACH:
+
+                       if (!DetachThread())
+                               return FALSE;
+                       break;
+
+               case DLL_PROCESS_DETACH:
+
+                       DetachProcess();
+                       break;
+
+               default:
+                       assert(0 && "DllMain(): Reason for calling DLL Main is unknown");
+                       return FALSE;
+       }
+
+       return TRUE;
+}
diff --git a/glslang/OSDependent/Windows/osinclude.h b/glslang/OSDependent/Windows/osinclude.h
new file mode 100644 (file)
index 0000000..652f558
--- /dev/null
@@ -0,0 +1,69 @@
+//
+//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.
+//
+
+#ifndef __OSINCLUDE_H
+#define __OSINCLUDE_H
+
+//
+// This file contains contains the window's specific datatypes and
+// declares any windows specific functions.
+//
+
+#if !(defined(_WIN32) || defined(_WIN64))
+#error Trying to include a windows specific file in a non windows build.
+#endif
+
+#define STRICT
+#define VC_EXTRALEAN 1
+#include <windows.h>
+#include <assert.h>
+
+
+//
+// Thread Local Storage Operations
+//
+typedef DWORD OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
+
+OS_TLSIndex OS_AllocTLSIndex();
+bool        OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
+bool        OS_FreeTLSIndex(OS_TLSIndex nIndex);
+
+inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+       assert(nIndex != OS_INVALID_TLS_INDEX);
+       return TlsGetValue(nIndex);
+}
+
+#endif // __OSINCLUDE_H
diff --git a/glslang/OSDependent/Windows/ossource.cpp b/glslang/OSDependent/Windows/ossource.cpp
new file mode 100644 (file)
index 0000000..3c2cb85
--- /dev/null
@@ -0,0 +1,85 @@
+//
+//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.
+//
+
+#include "osinclude.h"
+//
+// This file contains contains the window's specific functions
+//
+
+#if !(defined(_WIN32) || defined(_WIN64))
+#error Trying to build a windows specific file in a non windows build.
+#endif
+
+
+//
+// Thread Local Storage Operations
+//
+OS_TLSIndex OS_AllocTLSIndex()
+{
+       DWORD dwIndex = TlsAlloc();
+       if (dwIndex == TLS_OUT_OF_INDEXES) {
+               assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
+               return OS_INVALID_TLS_INDEX;
+       }
+
+       return dwIndex;
+}
+
+
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+{
+       if (nIndex == OS_INVALID_TLS_INDEX) {
+               assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
+               return false;
+       }
+
+       if (TlsSetValue(nIndex, lpvValue))
+               return true;
+       else
+               return false;
+}
+
+
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
+{
+       if (nIndex == OS_INVALID_TLS_INDEX) {
+               assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
+               return false;
+       }
+
+       if (TlsFree(nIndex))
+               return true;
+       else
+               return false;
+}
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
new file mode 100644 (file)
index 0000000..581ad3c
--- /dev/null
@@ -0,0 +1,212 @@
+//
+//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.
+//
+#ifndef _COMPILER_INTERFACE_INCLUDED_
+#define _COMPILER_INTERFACE_INCLUDED_
+
+#include "../Include/ResourceLimits.h"
+
+#ifdef _WIN32
+#define C_DECL __cdecl
+#ifdef SH_EXPORTING
+    #define SH_IMPORT_EXPORT __declspec(dllexport)
+#else
+    #define SH_IMPORT_EXPORT __declspec(dllimport)
+#endif
+#else
+#define SH_IMPORT_EXPORT
+#define __fastcall
+#define C_DECL
+#endif
+
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler/linker.
+//
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+//
+// Driver must call this first, once, before doing any other
+// compiler/linker operations.
+//
+SH_IMPORT_EXPORT int ShInitialize();
+//
+// Driver should call this at shutdown.
+//
+SH_IMPORT_EXPORT int __fastcall ShFinalize();
+//
+// Types of languages the compiler can consume.
+//
+typedef enum {
+       EShLangVertex,
+       EShLangFragment,
+       EShLangPack,
+    EShLangUnpack,
+    EShLangCount,
+} EShLanguage;
+
+//
+// Types of output the linker will create.
+//
+typedef enum {
+    EShExVertexFragment,
+    EShExPackFragment,
+    EShExUnpackFragment,
+    EShExFragment
+} EShExecutable;
+
+//
+// Optimization level for the compiler.
+//
+typedef enum {
+    EShOptNoGeneration,
+    EShOptNone,
+    EShOptSimple,       // Optimizations that can be done quickly
+    EShOptFull,         // Optimizations that will take more time
+} EShOptimizationLevel;
+
+//
+// Build a table for bindings.  This can be used for locating
+// attributes, uniforms, globals, etc., as needed.
+//
+typedef struct {
+    char* name;
+    int binding;
+} ShBinding;
+
+typedef struct {
+    int numBindings;
+       ShBinding* bindings;  // array of bindings
+} ShBindingTable;
+
+//
+// ShHandle held by but opaque to the driver.  It is allocated,
+// managed, and de-allocated by the compiler/linker. It's contents 
+// are defined by and used by the compiler and linker.  For example,
+// symbol table information and object code passed from the compiler 
+// to the linker can be stored where ShHandle points.
+//
+// If handle creation fails, 0 will be returned.
+//
+typedef void* ShHandle;
+
+//
+// Driver calls these to create and destroy compiler/linker
+// objects.
+//
+SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions);  // one per shader
+SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions);  // one per shader pair
+SH_IMPORT_EXPORT ShHandle ShConstructUniformMap();                 // one per uniform namespace (currently entire program object)
+SH_IMPORT_EXPORT void ShDestruct(ShHandle);
+
+//
+// The return value of ShCompile is boolean, indicating
+// success or failure.
+//
+// The info-log should be written by ShCompile into 
+// ShHandle, so it can answer future queries.
+//
+SH_IMPORT_EXPORT int ShCompile(
+    const ShHandle,
+    const char* const shaderStrings[],
+    const int numStrings,
+    const EShOptimizationLevel,
+    const TBuiltInResource *resources,
+    int debugOptions
+    );
+
+
+//
+// Similar to ShCompile, but accepts an opaque handle to an
+// intermediate language structure.
+//
+SH_IMPORT_EXPORT int ShCompileIntermediate(
+    ShHandle compiler,
+    ShHandle intermediate,
+    const EShOptimizationLevel,
+    int debuggable           // boolean
+    );
+
+SH_IMPORT_EXPORT int ShLink(
+    const ShHandle,               // linker object
+    const ShHandle h[],           // compiler objects to link together
+    const int numHandles,
+    ShHandle uniformMap,          // updated with new uniforms
+    short int** uniformsAccessed,  // returned with indexes of uniforms accessed
+    int* numUniformsAccessed);         
+
+SH_IMPORT_EXPORT int ShLinkExt(
+    const ShHandle,               // linker object
+    const ShHandle h[],           // compiler objects to link together
+    const int numHandles);
+
+//
+// ShSetEncrpytionMethod is a place-holder for specifying
+// how source code is encrypted.
+//
+SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle);
+
+//
+// All the following return 0 if the information is not
+// available in the object passed down, or the object is bad.
+//
+SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle);
+SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle);
+SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*);   // to detect user aliasing
+SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*);     // to force any physical mappings
+SH_IMPORT_EXPORT int ShGetPhysicalAttributeBindings(const ShHandle, const ShBindingTable**); // for all attributes
+//
+// Tell the linker to never assign a vertex attribute to this list of physical attributes
+//
+SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
+
+//
+// Returns the location ID of the named uniform.
+// Returns -1 if error.
+//
+SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
+
+enum TDebugOptions {
+       EDebugOpNone               = 0x000,
+       EDebugOpIntermediate       = 0x001,
+       EDebugOpAssembly           = 0x002,
+    EDebugOpObjectCode         = 0x004,
+       EDebugOpLinkMaps           = 0x008
+};
+#ifdef __cplusplus
+    }
+#endif
+
+#endif // _COMPILER_INTERFACE_INCLUDED_
diff --git a/tools/bison.exe b/tools/bison.exe
new file mode 100644 (file)
index 0000000..4881bf6
Binary files /dev/null and b/tools/bison.exe differ
diff --git a/tools/bison.hairy b/tools/bison.hairy
new file mode 100644 (file)
index 0000000..260b687
--- /dev/null
@@ -0,0 +1,334 @@
+\r
+extern int timeclock;\r
+\r
+\r
+int yyerror;           /*  Yyerror and yycost are set by guards.       */\r
+int yycost;            /*  If yyerror is set to a nonzero value by a   */\r
+                       /*  guard, the reduction with which the guard   */\r
+                       /*  is associated is not performed, and the     */\r
+                       /*  error recovery mechanism is invoked.        */\r
+                       /*  Yycost indicates the cost of performing     */\r
+                       /*  the reduction given the attributes of the   */\r
+                       /*  symbols.                                    */\r
+\r
+\r
+/*  YYMAXDEPTH indicates the size of the parser's state and value      */\r
+/*  stacks.                                                            */\r
+\r
+#ifndef        YYMAXDEPTH\r
+#define        YYMAXDEPTH      500\r
+#endif\r
+\r
+/*  YYMAXRULES must be at least as large as the number of rules that   */\r
+/*  could be placed in the rule queue.  That number could be determined        */\r
+/*  from the grammar and the size of the stack, but, as yet, it is not.        */\r
+\r
+#ifndef        YYMAXRULES\r
+#define        YYMAXRULES      100\r
+#endif\r
+\r
+#ifndef        YYMAXBACKUP\r
+#define YYMAXBACKUP    100\r
+#endif\r
+\r
+\r
+short  yyss[YYMAXDEPTH];       /*  the state stack                     */\r
+YYSTYPE        yyvs[YYMAXDEPTH];       /*  the semantic value stack            */\r
+YYLTYPE yyls[YYMAXDEPTH];      /*  the location stack                  */\r
+short  yyrq[YYMAXRULES];       /*  the rule queue                      */\r
+int    yychar;                 /*  the lookahead symbol                */\r
+\r
+YYSTYPE        yylval;                 /*  the semantic value of the           */\r
+                               /*  lookahead symbol                    */\r
+\r
+YYSTYPE yytval;                        /*  the semantic value for the state    */\r
+                               /*  at the top of the state stack.      */\r
+\r
+YYSTYPE yyval;                 /*  the variable used to return         */\r
+                               /*  semantic values from the action     */\r
+                               /*  routines                            */\r
+\r
+YYLTYPE yylloc;                /*  location data for the lookahead     */\r
+                               /*  symbol                              */\r
+\r
+YYLTYPE yytloc;                /*  location data for the state at the  */\r
+                               /*  top of the state stack              */\r
+\r
+\r
+int    yynunlexed;\r
+short  yyunchar[YYMAXBACKUP];\r
+YYSTYPE        yyunval[YYMAXBACKUP];\r
+YYLTYPE yyunloc[YYMAXBACKUP];\r
+\r
+short *yygssp;                 /*  a pointer to the top of the state   */\r
+                               /*  stack; only set during error        */\r
+                               /*  recovery.                           */\r
+\r
+YYSTYPE *yygvsp;               /*  a pointer to the top of the value   */\r
+                               /*  stack; only set during error        */\r
+                               /*  recovery.                           */\r
+\r
+YYLTYPE *yyglsp;               /*  a pointer to the top of the         */\r
+                               /*  location stack; only set during     */\r
+                               /*  error recovery.                     */\r
+\r
+\r
+/*  Yyget is an interface between the parser and the lexical analyzer. */\r
+/*  It is costly to provide such an interface, but it avoids requiring */\r
+/*  the lexical analyzer to be able to back up the scan.               */\r
+\r
+yyget()\r
+{\r
+  if (yynunlexed > 0)\r
+    {\r
+      yynunlexed--;\r
+      yychar = yyunchar[yynunlexed];\r
+      yylval = yyunval[yynunlexed];\r
+      yylloc = yyunloc[yynunlexed];\r
+    }\r
+  else if (yychar <= 0)\r
+    yychar = 0;\r
+  else\r
+    {\r
+      yychar = yylex();\r
+      if (yychar < 0)\r
+       yychar = 0;\r
+      else yychar = YYTRANSLATE(yychar);\r
+    }\r
+}\r
+\r
+\r
+\r
+yyunlex(chr, val, loc)\r
+int chr;\r
+YYSTYPE val;\r
+YYLTYPE loc;\r
+{\r
+  yyunchar[yynunlexed] = chr;\r
+  yyunval[yynunlexed] = val;\r
+  yyunloc[yynunlexed] = loc;\r
+  yynunlexed++;\r
+}\r
+\r
+\r
+\r
+yyrestore(first, last)\r
+register short *first;\r
+register short *last;\r
+{\r
+  register short *ssp;\r
+  register short *rp;\r
+  register int symbol;\r
+  register int state;\r
+  register int tvalsaved;\r
+\r
+  ssp = yygssp;\r
+  yyunlex(yychar, yylval, yylloc);\r
+\r
+  tvalsaved = 0;\r
+  while (first != last)\r
+    {\r
+      symbol = yystos[*ssp];\r
+      if (symbol < YYNTBASE)\r
+       {\r
+         yyunlex(symbol, yytval, yytloc);\r
+         tvalsaved = 1;\r
+         ssp--;\r
+       }\r
+\r
+      ssp--;\r
+\r
+      if (first == yyrq)\r
+       first = yyrq + YYMAXRULES;\r
+\r
+      first--;\r
+\r
+      for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)\r
+       {\r
+         if (symbol < YYNTBASE)\r
+           state = yytable[yypact[*ssp] + symbol];\r
+         else\r
+           {\r
+             state = yypgoto[symbol - YYNTBASE] + *ssp;\r
+\r
+             if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)\r
+               state = yytable[state];\r
+             else\r
+               state = yydefgoto[symbol - YYNTBASE];\r
+           }\r
+\r
+         *++ssp = state;\r
+       }\r
+    }\r
+\r
+  if ( ! tvalsaved && ssp > yyss)\r
+    {\r
+      yyunlex(yystos[*ssp], yytval, yytloc);\r
+      ssp--;\r
+    }\r
+\r
+  yygssp = ssp;\r
+}\r
+\r
+\r
+\r
+int\r
+yyparse()\r
+{\r
+  register int yystate;\r
+  register int yyn;\r
+  register short *yyssp;\r
+  register short *yyrq0;\r
+  register short *yyptr;\r
+  register YYSTYPE *yyvsp;\r
+\r
+  int yylen;\r
+  YYLTYPE *yylsp;\r
+  short *yyrq1;\r
+  short *yyrq2;\r
+\r
+  yystate = 0;\r
+  yyssp = yyss - 1;\r
+  yyvsp = yyvs - 1;\r
+  yylsp = yyls - 1;\r
+  yyrq0 = yyrq;\r
+  yyrq1 = yyrq0;\r
+  yyrq2 = yyrq0;\r
+\r
+  yychar = yylex();\r
+  if (yychar < 0)\r
+    yychar = 0;\r
+  else yychar = YYTRANSLATE(yychar);\r
+\r
+yynewstate:\r
+\r
+  if (yyssp >= yyss + YYMAXDEPTH - 1)\r
+    {\r
+      yyabort("Parser Stack Overflow");\r
+      YYABORT;\r
+    }\r
+\r
+  *++yyssp = yystate;\r
+\r
+yyresume:\r
+\r
+  yyn = yypact[yystate];\r
+  if (yyn == YYFLAG)\r
+    goto yydefault;\r
+\r
+  yyn += yychar;\r
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)\r
+    goto yydefault;\r
+\r
+  yyn = yytable[yyn];\r
+  if (yyn < 0)\r
+    {\r
+      yyn = -yyn;\r
+      goto yyreduce;\r
+    }\r
+  else if (yyn == 0)\r
+    goto yyerrlab;\r
+\r
+  yystate = yyn;\r
+\r
+  yyptr = yyrq2;\r
+  while (yyptr != yyrq1)\r
+    {\r
+      yyn = *yyptr++;\r
+      yylen = yyr2[yyn];\r
+      yyvsp -= yylen;\r
+      yylsp -= yylen;\r
+\r
+      yyguard(yyn, yyvsp, yylsp);\r
+      if (yyerror)\r
+       goto yysemerr;\r
+\r
+      yyaction(yyn, yyvsp, yylsp);\r
+      *++yyvsp = yyval;\r
+\r
+      yylsp++;\r
+      if (yylen == 0)\r
+       {\r
+         yylsp->timestamp = timeclock;\r
+         yylsp->first_line = yytloc.first_line;\r
+         yylsp->first_column = yytloc.first_column;\r
+         yylsp->last_line = (yylsp-1)->last_line;\r
+         yylsp->last_column = (yylsp-1)->last_column;\r
+         yylsp->text = 0;\r
+       }\r
+      else\r
+       {\r
+         yylsp->last_line = (yylsp+yylen-1)->last_line;\r
+         yylsp->last_column = (yylsp+yylen-1)->last_column;\r
+       }\r
+         \r
+      if (yyptr == yyrq + YYMAXRULES)\r
+        yyptr = yyrq;\r
+    }\r
+\r
+  if (yystate == YYFINAL)\r
+    YYACCEPT;\r
+\r
+  yyrq2 = yyptr;\r
+  yyrq1 = yyrq0;\r
+\r
+  *++yyvsp = yytval;\r
+  *++yylsp = yytloc;\r
+  yytval = yylval;\r
+  yytloc = yylloc;\r
+  yyget();\r
+\r
+  goto yynewstate;\r
+\r
+yydefault:\r
+\r
+  yyn = yydefact[yystate];\r
+  if (yyn == 0)\r
+    goto yyerrlab;\r
+\r
+yyreduce:\r
+\r
+  *yyrq0++ = yyn;\r
+\r
+  if (yyrq0 == yyrq + YYMAXRULES)\r
+    yyrq0 = yyrq;\r
+\r
+  if (yyrq0 == yyrq2)\r
+    {\r
+      yyabort("Parser Rule Queue Overflow");\r
+      YYABORT;\r
+    }\r
+\r
+  yyssp -= yyr2[yyn];\r
+  yyn = yyr1[yyn];\r
+\r
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;\r
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)\r
+    yystate = yytable[yystate];\r
+  else\r
+    yystate = yydefgoto[yyn - YYNTBASE];\r
+\r
+  goto yynewstate;\r
+\r
+yysemerr:\r
+  *--yyptr = yyn;\r
+  yyrq2 = yyptr;\r
+  yyvsp += yyr2[yyn];\r
+\r
+yyerrlab:\r
+\r
+  yygssp = yyssp;\r
+  yygvsp = yyvsp;\r
+  yyglsp = yylsp;\r
+  yyrestore(yyrq0, yyrq2);\r
+  yyrecover();\r
+  yystate = *yygssp;\r
+  yyssp = yygssp;\r
+  yyvsp = yygvsp;\r
+  yyrq0 = yyrq;\r
+  yyrq1 = yyrq0;\r
+  yyrq2 = yyrq0;\r
+  goto yyresume;\r
+}\r
+\r
+$\r
diff --git a/tools/bison.simple b/tools/bison.simple
new file mode 100644 (file)
index 0000000..690fb2e
--- /dev/null
@@ -0,0 +1,699 @@
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */\r
+\r
+/* Skeleton output parser for bison,\r
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.\r
+\r
+   This program is free software; you can redistribute it and/or modify\r
+   it under the terms of the GNU General Public License as published by\r
+   the Free Software Foundation; either version 2, or (at your option)\r
+   any later version.\r
+\r
+   This program is distributed in the hope that it will be useful,\r
+   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+   GNU General Public License for more details.\r
+\r
+   You should have received a copy of the GNU General Public License\r
+   along with this program; if not, write to the Free Software\r
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */\r
+\r
+/* As a special exception, when this file is copied by Bison into a\r
+   Bison output file, you may use that output file without restriction.\r
+   This special exception was added by the Free Software Foundation\r
+   in version 1.24 of Bison.  */\r
+\r
+#ifdef __GNUC__\r
+#define alloca __builtin_alloca\r
+#else /* not __GNUC__ */\r
+#if HAVE_ALLOCA_H\r
+#include <alloca.h>\r
+#else /* not HAVE_ALLOCA_H */\r
+#ifdef _AIX\r
+ #pragma alloca\r
+#else /* not _AIX */\r
+char *alloca ();\r
+#endif /* not _AIX */\r
+#endif /* not HAVE_ALLOCA_H */\r
+#endif /* not __GNUC__ */\r
+\r
+extern void yyerror(char* s);\r
+\r
+#ifndef alloca\r
+#ifdef __GNUC__\r
+#define alloca __builtin_alloca\r
+#else /* not GNU C.  */\r
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)\r
+#include <alloca.h>\r
+#else /* not sparc */\r
+#if (defined (MSDOS) && !defined (__TURBOC__)) || defined (WIN32)\r
+#include <malloc.h>\r
+#else /* not MSDOS, or __TURBOC__ */\r
+#if defined(_AIX)\r
+#include <malloc.h>\r
+ #pragma alloca\r
+#else /* not MSDOS, __TURBOC__, or _AIX */\r
+#ifdef __hpux\r
+#ifdef __cplusplus\r
+extern "C" {\r
+void *alloca (unsigned int);\r
+};\r
+#else /* not __cplusplus */\r
+void *alloca ();\r
+#endif /* not __cplusplus */\r
+#endif /* __hpux */\r
+#endif /* not _AIX */\r
+#endif /* not MSDOS, or __TURBOC__ */\r
+#endif /* not sparc.  */\r
+#endif /* not GNU C.  */\r
+#endif /* alloca not defined.  */\r
+\r
+/* This is the parser code that is written into each bison parser\r
+  when the %semantic_parser declaration is not specified in the grammar.\r
+  It was written by Richard Stallman by simplifying the hairy parser\r
+  used when %semantic_parser is specified.  */\r
+\r
+/* Note: there must be only one dollar sign in this file.\r
+   It is replaced by the list of actions, each action\r
+   as one case of the switch.  */\r
+\r
+#define yyerrok                (yyerrstatus = 0)\r
+#define yyclearin      (yychar = YYEMPTY)\r
+#define YYEMPTY                -2\r
+#define YYEOF          0\r
+#define YYACCEPT       return(0)\r
+#define YYABORT        return(1)\r
+#define YYERROR                goto yyerrlab1\r
+/* Like YYERROR except do call yyerror.\r
+   This remains here temporarily to ease the\r
+   transition to the new meaning of YYERROR, for GCC.\r
+   Once GCC version 2 has supplanted version 1, this can go.  */\r
+#define YYFAIL         goto yyerrlab\r
+#define YYRECOVERING()  (!!yyerrstatus)\r
+#define YYBACKUP(token, value) \\r
+do                                                             \\r
+  if (yychar == YYEMPTY && yylen == 1)                         \\r
+    { yychar = (token), yylval = (value);                      \\r
+      yychar1 = YYTRANSLATE (yychar);                          \\r
+      YYPOPSTACK;                                              \\r
+      goto yybackup;                                           \\r
+    }                                                          \\r
+  else                                                         \\r
+    { yyerror ("syntax error: cannot back up"); YYERROR; }     \\r
+while (0)\r
+\r
+#define YYTERROR       1\r
+#define YYERRCODE      256\r
+\r
+#ifndef YYPURE\r
+#define YYLEX          yylex()\r
+#endif\r
+\r
+#ifdef YYPURE\r
+#ifdef YYLSP_NEEDED\r
+#ifdef YYLEX_PARAM\r
+#define YYLEX          yylex(&yylval, &yylloc, YYLEX_PARAM)\r
+#else\r
+#define YYLEX          yylex(&yylval, &yylloc)\r
+#endif\r
+#else /* not YYLSP_NEEDED */\r
+#ifdef YYLEX_PARAM\r
+#define YYLEX          yylex(&yylval, YYLEX_PARAM)\r
+#else\r
+#define YYLEX          yylex(&yylval)\r
+#endif\r
+#endif /* not YYLSP_NEEDED */\r
+#endif\r
+\r
+/* If nonreentrant, generate the variables here */\r
+\r
+#ifndef YYPURE\r
+\r
+int    yychar;                 /*  the lookahead symbol                */\r
+YYSTYPE        yylval;                 /*  the semantic value of the           */\r
+                               /*  lookahead symbol                    */\r
+\r
+#ifdef YYLSP_NEEDED\r
+YYLTYPE yylloc;                        /*  location data for the lookahead     */\r
+                               /*  symbol                              */\r
+#endif\r
+\r
+int yynerrs;                   /*  number of parse errors so far       */\r
+#endif  /* not YYPURE */\r
+\r
+#if YYDEBUG != 0\r
+int yydebug;                   /*  nonzero means print parse trace     */\r
+/* Since this is uninitialized, it does not stop multiple parsers\r
+   from coexisting.  */\r
+#endif\r
+\r
+/*  YYINITDEPTH indicates the initial size of the parser's stacks      */\r
+\r
+#ifndef        YYINITDEPTH\r
+#define YYINITDEPTH 200\r
+#endif\r
+\r
+/*  YYMAXDEPTH is the maximum size the stacks can grow to\r
+    (effective only if the built-in stack extension method is used).  */\r
+\r
+#if YYMAXDEPTH == 0\r
+#undef YYMAXDEPTH\r
+#endif\r
+\r
+#ifndef YYMAXDEPTH\r
+#define YYMAXDEPTH 10000\r
+#endif\r
+\r
+/* Prevent warning if -Wstrict-prototypes.  */\r
+#ifdef __GNUC__\r
+int yyparse (void);\r
+#endif\r
+\f\r
+#if __GNUC__ > 1               /* GNU C and GNU C++ define this.  */\r
+#define __yy_memcpy(FROM,TO,COUNT)     __builtin_memcpy(TO,FROM,COUNT)\r
+#else                          /* not GNU C or C++ */\r
+#ifndef __cplusplus\r
+\r
+/* This is the most reliable way to avoid incompatibilities\r
+   in available built-in functions on various systems.  */\r
+static void\r
+__yy_memcpy (from, to, count)\r
+     char *from;\r
+     char *to;\r
+     size_t count;\r
+{\r
+  register char *f = from;\r
+  register char *t = to;\r
+  register size_t i = count;\r
+\r
+  while (i-- > 0)\r
+    *t++ = *f++;\r
+}\r
+\r
+#else /* __cplusplus */\r
+\r
+/* This is the most reliable way to avoid incompatibilities\r
+   in available built-in functions on various systems.  */\r
+static void\r
+__yy_memcpy (char *from, char *to, size_t count)\r
+{\r
+  register char *f = from;\r
+  register char *t = to;\r
+  register size_t i = count;\r
+\r
+  while (i-- > 0)\r
+    *t++ = *f++;\r
+}\r
+\r
+#endif\r
+#endif\r
+\r
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed\r
+   into yyparse.  The argument should have type void *.\r
+   It should actually point to an object.\r
+   Grammar actions can access the variable by casting it\r
+   to the proper pointer type.  */\r
+\r
+#ifdef YYPARSE_PARAM\r
+#ifndef YYPARSE_PARAM_DECL\r
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;\r
+#endif \r
+#else\r
+#define YYPARSE_PARAM\r
+#define YYPARSE_PARAM_DECL\r
+#endif\r
+\r
+extern YY_DECL;\r
+\r
+int\r
+yyparse(YYPARSE_PARAM_DECL YYPARSE_PARAM) {\r
+  register int yystate;\r
+  register int yyn;\r
+  register short *yyssp;\r
+  register YYSTYPE *yyvsp;\r
+  int yyerrstatus;     /*  number of tokens to shift before error messages enabled */\r
+  int yychar1 = 0;             /*  lookahead token as an internal (translated) token number */\r
+\r
+  short        yyssa[YYINITDEPTH];     /*  the state stack                     */\r
+  YYSTYPE yyvsa[YYINITDEPTH];  /*  the semantic value stack            */\r
+\r
+  short *yyss = yyssa;         /*  refer to the stacks thru separate pointers */\r
+  YYSTYPE *yyvs = yyvsa;       /*  to allow yyoverflow to reallocate them elsewhere */\r
+\r
+#ifdef YYLSP_NEEDED\r
+  YYLTYPE yylsa[YYINITDEPTH];  /*  the location stack                  */\r
+  YYLTYPE *yyls = yylsa;\r
+  YYLTYPE *yylsp;\r
+\r
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)\r
+#else\r
+#define YYPOPSTACK   (yyvsp--, yyssp--)\r
+#endif\r
+\r
+  size_t yystacksize = YYINITDEPTH;\r
+\r
+#ifdef YYPURE\r
+  int yychar;\r
+  YYSTYPE yylval;\r
+  int yynerrs;\r
+#ifdef YYLSP_NEEDED\r
+  YYLTYPE yylloc;\r
+#endif\r
+#endif\r
+\r
+  YYSTYPE yyval;               /*  the variable used to return         */\r
+                               /*  semantic values from the action     */\r
+                               /*  routines                            */\r
+\r
+  int yylen;\r
+\r
+#if YYDEBUG != 0\r
+  if (yydebug)\r
+    fprintf(stderr, "Starting parse\n");\r
+#endif\r
+\r
+  yystate = 0;\r
+  yyerrstatus = 0;\r
+  yynerrs = 0;\r
+  yychar = YYEMPTY;            /* Cause a token to be read.  */\r
+\r
+  /* Initialize stack pointers.\r
+     Waste one element of value and location stack\r
+     so that they stay on the same level as the state stack.\r
+     The wasted elements are never initialized.  */\r
+\r
+  yyssp = yyss - 1;\r
+  yyvsp = yyvs;\r
+#ifdef YYLSP_NEEDED\r
+  yylsp = yyls;\r
+#endif\r
+\r
+/* Push a new state, which is found in  yystate  .  */\r
+/* In all cases, when you get here, the value and location stacks\r
+   have just been pushed. so pushing a state here evens the stacks.  */\r
+yynewstate:\r
+\r
+  *++yyssp = yystate;\r
+\r
+  if (yyssp >= yyss + yystacksize - 1)\r
+    {\r
+      /* Give user a chance to reallocate the stack */\r
+      /* Use copies of these so that the &'s don't force the real ones into memory. */\r
+      YYSTYPE *yyvs1 = yyvs;\r
+      short *yyss1 = yyss;\r
+#ifdef YYLSP_NEEDED\r
+      YYLTYPE *yyls1 = yyls;\r
+#endif\r
+\r
+      /* Get the current used size of the three stacks, in elements.  */\r
+      size_t size = yyssp - yyss + 1;\r
+\r
+#ifdef yyoverflow\r
+      /* Each stack pointer address is followed by the size of\r
+        the data in use in that stack, in bytes.  */\r
+#ifdef YYLSP_NEEDED\r
+      /* This used to be a conditional around just the two extra args,\r
+        but that might be undefined if yyoverflow is a macro.  */\r
+      yyoverflow("parser stack overflow",\r
+                &yyss1, size * sizeof (*yyssp),\r
+                &yyvs1, size * sizeof (*yyvsp),\r
+                &yyls1, size * sizeof (*yylsp),\r
+                &yystacksize);\r
+#else\r
+      yyoverflow("parser stack overflow",\r
+                &yyss1, size * sizeof (*yyssp),\r
+                &yyvs1, size * sizeof (*yyvsp),\r
+                &yystacksize);\r
+#endif\r
+\r
+      yyss = yyss1; yyvs = yyvs1;\r
+#ifdef YYLSP_NEEDED\r
+      yyls = yyls1;\r
+#endif\r
+#else /* no yyoverflow */\r
+      /* Extend the stack our own way.  */\r
+      if (yystacksize >= YYMAXDEPTH)\r
+       {\r
+         yyerror("parser stack overflow");\r
+         return 2;\r
+       }\r
+      yystacksize *= 2;\r
+      if (yystacksize > YYMAXDEPTH)\r
+       yystacksize = YYMAXDEPTH;\r
+      yyss = (short *) alloca (yystacksize * sizeof (*yyssp));\r
+      __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));\r
+      yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));\r
+      __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));\r
+#ifdef YYLSP_NEEDED\r
+      yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));\r
+      __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));\r
+#endif\r
+#endif /* no yyoverflow */\r
+\r
+      yyssp = yyss + size - 1;\r
+      yyvsp = yyvs + size - 1;\r
+#ifdef YYLSP_NEEDED\r
+      yylsp = yyls + size - 1;\r
+#endif\r
+\r
+#if YYDEBUG != 0\r
+      if (yydebug)\r
+       fprintf(stderr, "Stack size increased to %d\n", yystacksize);\r
+#endif\r
+\r
+      if (yyssp >= yyss + yystacksize - 1)\r
+       YYABORT;\r
+    }\r
+\r
+#if YYDEBUG != 0\r
+  if (yydebug)\r
+    fprintf(stderr, "Entering state %d\n", yystate);\r
+#endif\r
+\r
+  goto yybackup;\r
+ yybackup:\r
+\r
+/* Do appropriate processing given the current state.  */\r
+/* Read a lookahead token if we need one and don't already have one.  */\r
+/* yyresume: */\r
+\r
+  /* First try to decide what to do without reference to lookahead token.  */\r
+\r
+  yyn = yypact[yystate];\r
+  if (yyn == YYFLAG)\r
+    goto yydefault;\r
+\r
+  /* Not known => get a lookahead token if don't already have one.  */\r
+\r
+  /* yychar is either YYEMPTY or YYEOF\r
+     or a valid token in external form.  */\r
+\r
+  if (yychar == YYEMPTY)\r
+    {\r
+#if YYDEBUG != 0\r
+      if (yydebug)\r
+       fprintf(stderr, "Reading a token: ");\r
+#endif\r
+      yychar = YYLEX;\r
+    }\r
+\r
+  /* Convert token to internal form (in yychar1) for indexing tables with */\r
+\r
+  if (yychar <= 0)             /* This means end of input. */\r
+    {\r
+      yychar1 = 0;\r
+      yychar = YYEOF;          /* Don't call YYLEX any more */\r
+\r
+#if YYDEBUG != 0\r
+      if (yydebug)\r
+       fprintf(stderr, "Now at end of input.\n");\r
+#endif\r
+    }\r
+  else\r
+    {\r
+      yychar1 = YYTRANSLATE(yychar);\r
+\r
+#if YYDEBUG != 0\r
+      if (yydebug)\r
+       {\r
+         fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);\r
+         /* Give the individual parser a way to print the precise meaning\r
+            of a token, for further debugging info.  */\r
+#ifdef YYPRINT\r
+         YYPRINT (stderr, yychar, yylval);\r
+#endif\r
+         fprintf (stderr, ")\n");\r
+       }\r
+#endif\r
+    }\r
+\r
+  yyn += yychar1;\r
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)\r
+    goto yydefault;\r
+\r
+  yyn = yytable[yyn];\r
+\r
+  /* yyn is what to do for this token type in this state.\r
+     Negative => reduce, -yyn is rule number.\r
+     Positive => shift, yyn is new state.\r
+       New state is final state => don't bother to shift,\r
+       just return success.\r
+     0, or most negative number => error.  */\r
+\r
+  if (yyn < 0)\r
+    {\r
+      if (yyn == YYFLAG)\r
+       goto yyerrlab;\r
+      yyn = -yyn;\r
+      goto yyreduce;\r
+    }\r
+  else if (yyn == 0)\r
+    goto yyerrlab;\r
+\r
+  if (yyn == YYFINAL)\r
+    YYACCEPT;\r
+\r
+  /* Shift the lookahead token.  */\r
+\r
+#if YYDEBUG != 0\r
+  if (yydebug)\r
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);\r
+#endif\r
+\r
+  /* Discard the token being shifted unless it is eof.  */\r
+  if (yychar != YYEOF)\r
+    yychar = YYEMPTY;\r
+\r
+  *++yyvsp = yylval;\r
+#ifdef YYLSP_NEEDED\r
+  *++yylsp = yylloc;\r
+#endif\r
+\r
+  /* count tokens shifted since error; after three, turn off error status.  */\r
+  if (yyerrstatus) yyerrstatus--;\r
+\r
+  yystate = yyn;\r
+  goto yynewstate;\r
+\r
+/* Do the default action for the current state.  */\r
+yydefault:\r
+\r
+  yyn = yydefact[yystate];\r
+  if (yyn == 0)\r
+    goto yyerrlab;\r
+\r
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */\r
+yyreduce:\r
+  yylen = yyr2[yyn];\r
+  if (yylen > 0)\r
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */\r
+\r
+#if YYDEBUG != 0\r
+  if (yydebug)\r
+    {\r
+      int i;\r
+\r
+      fprintf (stderr, "Reducing via rule %d (line %d), ",\r
+              yyn, yyrline[yyn]);\r
+\r
+      /* Print the symbols being reduced, and their result.  */\r
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)\r
+       fprintf (stderr, "%s ", yytname[yyrhs[i]]);\r
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);\r
+    }\r
+#endif\r
+\r
+$   /* the action file gets copied in in place of this dollarsign */\r
+  yyvsp -= yylen;\r
+  yyssp -= yylen;\r
+#ifdef YYLSP_NEEDED\r
+  yylsp -= yylen;\r
+#endif\r
+\r
+#if YYDEBUG != 0\r
+  if (yydebug)\r
+    {\r
+      short *ssp1 = yyss - 1;\r
+      fprintf (stderr, "state stack now");\r
+      while (ssp1 != yyssp)\r
+       fprintf (stderr, " %d", *++ssp1);\r
+      fprintf (stderr, "\n");\r
+    }\r
+#endif\r
+\r
+  *++yyvsp = yyval;\r
+\r
+#ifdef YYLSP_NEEDED\r
+  yylsp++;\r
+  if (yylen == 0)\r
+    {\r
+      yylsp->first_line = yylloc.first_line;\r
+      yylsp->first_column = yylloc.first_column;\r
+      yylsp->last_line = (yylsp-1)->last_line;\r
+      yylsp->last_column = (yylsp-1)->last_column;\r
+      yylsp->text = 0;\r
+    }\r
+  else\r
+    {\r
+      yylsp->last_line = (yylsp+yylen-1)->last_line;\r
+      yylsp->last_column = (yylsp+yylen-1)->last_column;\r
+    }\r
+#endif\r
+\r
+  /* Now "shift" the result of the reduction.\r
+     Determine what state that goes to,\r
+     based on the state we popped back to\r
+     and the rule number reduced by.  */\r
+\r
+  yyn = yyr1[yyn];\r
+\r
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;\r
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)\r
+    yystate = yytable[yystate];\r
+  else\r
+    yystate = yydefgoto[yyn - YYNTBASE];\r
+\r
+  goto yynewstate;\r
+\r
+yyerrlab:   /* here on detecting error */\r
+\r
+  if (! yyerrstatus)\r
+    /* If not already recovering from an error, report this error.  */\r
+    {\r
+      ++yynerrs;\r
+\r
+#ifdef YYERROR_VERBOSE\r
+      yyn = yypact[yystate];\r
+\r
+      if (yyn > YYFLAG && yyn < YYLAST)\r
+       {\r
+         int size = 0;\r
+         char *msg;\r
+         int x, count;\r
+\r
+         count = 0;\r
+         /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */\r
+         for (x = (yyn < 0 ? -yyn : 0);\r
+              x < (sizeof(yytname) / sizeof(char *)); x++)\r
+           if (yycheck[x + yyn] == x)\r
+             size += strlen(yytname[x]) + 15, count++;\r
+         msg = (char *) malloc(size + 15);\r
+         if (msg != 0)\r
+           {\r
+             strcpy(msg, "parse error");\r
+\r
+             if (count < 5)\r
+               {\r
+                 count = 0;\r
+                 for (x = (yyn < 0 ? -yyn : 0);\r
+                      x < (sizeof(yytname) / sizeof(char *)); x++)\r
+                   if (yycheck[x + yyn] == x)\r
+                     {\r
+                       strcat(msg, count == 0 ? ", expecting `" : " or `");\r
+                       strcat(msg, yytname[x]);\r
+                       strcat(msg, "'");\r
+                       count++;\r
+                     }\r
+               }\r
+             yyerror(msg);\r
+             free(msg);\r
+           }\r
+         else\r
+           yyerror ("parse error; also virtual memory exceeded");\r
+       }\r
+      else\r
+#endif /* YYERROR_VERBOSE */\r
+       yyerror("parse error");\r
+    }\r
+\r
+  goto yyerrlab1;\r
+yyerrlab1:   /* here on error raised explicitly by an action */\r
+\r
+  if (yyerrstatus == 3)\r
+    {\r
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */\r
+\r
+      /* return failure if at end of input */\r
+      if (yychar == YYEOF)\r
+       YYABORT;\r
+\r
+#if YYDEBUG != 0\r
+      if (yydebug)\r
+       fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);\r
+#endif\r
+\r
+      yychar = YYEMPTY;\r
+    }\r
+\r
+  /* Else will try to reuse lookahead token\r
+     after shifting the error token.  */\r
+\r
+  yyerrstatus = 3;             /* Each real token shifted decrements this */\r
+\r
+  goto yyerrhandle;\r
+\r
+yyerrdefault:  /* current state does not do anything special for the error token. */\r
+\r
+#if 0\r
+  /* This is wrong; only states that explicitly want error tokens\r
+     should shift them.  */\r
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/\r
+  if (yyn) goto yydefault;\r
+#endif\r
+\r
+yyerrpop:   /* pop the current state because it cannot handle the error token */\r
+\r
+  if (yyssp == yyss) YYABORT;\r
+  yyvsp--;\r
+  yystate = *--yyssp;\r
+#ifdef YYLSP_NEEDED\r
+  yylsp--;\r
+#endif\r
+\r
+#if YYDEBUG != 0\r
+  if (yydebug)\r
+    {\r
+      short *ssp1 = yyss - 1;\r
+      fprintf (stderr, "Error: state stack now");\r
+      while (ssp1 != yyssp)\r
+       fprintf (stderr, " %d", *++ssp1);\r
+      fprintf (stderr, "\n");\r
+    }\r
+#endif\r
+\r
+yyerrhandle:\r
+\r
+  yyn = yypact[yystate];\r
+  if (yyn == YYFLAG)\r
+    goto yyerrdefault;\r
+\r
+  yyn += YYTERROR;\r
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)\r
+    goto yyerrdefault;\r
+\r
+  yyn = yytable[yyn];\r
+  if (yyn < 0)\r
+    {\r
+      if (yyn == YYFLAG)\r
+       goto yyerrpop;\r
+      yyn = -yyn;\r
+      goto yyreduce;\r
+    }\r
+  else if (yyn == 0)\r
+    goto yyerrpop;\r
+\r
+  if (yyn == YYFINAL)\r
+    YYACCEPT;\r
+\r
+#if YYDEBUG != 0\r
+  if (yydebug)\r
+    fprintf(stderr, "Shifting error token, ");\r
+#endif\r
+\r
+  *++yyvsp = yylval;\r
+#ifdef YYLSP_NEEDED\r
+  *++yylsp = yylloc;\r
+#endif\r
+\r
+  yystate = yyn;\r
+  goto yynewstate;\r
+}\r
diff --git a/tools/flex.exe b/tools/flex.exe
new file mode 100644 (file)
index 0000000..58f10ce
Binary files /dev/null and b/tools/flex.exe differ