summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Krol <mjkrol@gmail.org>2005-01-17 16:01:49 +0000
committerMichal Krol <mjkrol@gmail.org>2005-01-17 16:01:49 +0000
commit7d079fd7802763efd8c2d8856117b5df0b3a14e4 (patch)
tree0a9acf31e2dda0cffa14e15672a05f078515b04c
parentcc9ab78158049cee104101c608d4fa8082079214 (diff)
2005-oct-19 3dlabs slang compiler, tweaked a little bit
-rwxr-xr-xsrc/mesa/shader/slang/Include/BaseTypes.h133
-rwxr-xr-xsrc/mesa/shader/slang/Include/Common.h285
-rwxr-xr-xsrc/mesa/shader/slang/Include/ConstantUnion.h50
-rwxr-xr-xsrc/mesa/shader/slang/Include/InfoSink.h135
-rwxr-xr-xsrc/mesa/shader/slang/Include/InitializeGlobals.h43
-rwxr-xr-xsrc/mesa/shader/slang/Include/InitializeParseContext.h44
-rwxr-xr-xsrc/mesa/shader/slang/Include/PoolAlloc.h354
-rwxr-xr-xsrc/mesa/shader/slang/Include/ResourceLimits.h52
-rwxr-xr-xsrc/mesa/shader/slang/Include/ShHandle.h199
-rwxr-xr-xsrc/mesa/shader/slang/Include/Types.h223
-rwxr-xr-xsrc/mesa/shader/slang/Include/intermediate.h505
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp2822
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp3666
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/InfoSink.cpp107
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Initialize.cpp868
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Initialize.h56
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp243
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/Intermediate.cpp2057
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/MMap.h84
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/ParseHelper.cpp1406
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/ParseHelper.h137
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp348
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp91
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/QualifierAlive.h35
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/RemoveTree.cpp98
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/RemoveTree.h35
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/ShaderLang.cpp590
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/SymbolTable.cpp156
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/SymbolTable.h305
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/glslang_tab.h121
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/intermOut.cpp496
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/localintermediate.h90
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/parseConst.cpp345
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/atom.c768
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/atom.h96
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/compile.h131
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c978
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h118
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c184
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/memory.c191
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/memory.h89
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/parser.h126
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h84
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c787
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h118
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h115
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c318
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h145
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c464
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h122
-rwxr-xr-xsrc/mesa/shader/slang/MachineIndependent/unistd.h1
-rwxr-xr-xsrc/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp151
-rwxr-xr-xsrc/mesa/shader/slang/OGLCompilersDLL/Initialisation.h47
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Linux/osinclude.h77
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Linux/ossource.cpp140
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Windows/osinclude.h68
-rwxr-xr-xsrc/mesa/shader/slang/OSDependent/Windows/ossource.cpp123
-rwxr-xr-xsrc/mesa/shader/slang/Public/ShaderLang.h232
-rwxr-xr-xsrc/mesa/shader/slang/Public/ShaderLangExt.h189
59 files changed, 22041 insertions, 0 deletions
diff --git a/src/mesa/shader/slang/Include/BaseTypes.h b/src/mesa/shader/slang/Include/BaseTypes.h
new file mode 100755
index 0000000000..635e76e8dd
--- /dev/null
+++ b/src/mesa/shader/slang/Include/BaseTypes.h
@@ -0,0 +1,133 @@
+//
+//Copyright (C) 2002-2004 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,
+ EbtSampler1D,
+ EbtSampler2D,
+ EbtSampler3D,
+ EbtSamplerCube,
+ EbtSampler1DShadow,
+ EbtSampler2DShadow,
+ EbtStruct,
+ EbtAddress,
+};
+
+__inline bool IsSampler(TBasicType type)
+{
+ return type >= EbtSampler1D && type <= EbtSampler2DShadow;
+}
+
+//
+// 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/src/mesa/shader/slang/Include/Common.h b/src/mesa/shader/slang/Include/Common.h
new file mode 100755
index 0000000000..ea37ccd388
--- /dev/null
+++ b/src/mesa/shader/slang/Include/Common.h
@@ -0,0 +1,285 @@
+//
+//Copyright (C) 2002-2004 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
+
+#include <assert.h>
+
+/* 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 "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 *) { }
+
+#ifdef _M_AMD64
+//
+// The current version of STL that comes with the PSDK (as required for the AMD64 compiler)
+// has a very old version of the STL which is very out of date. As a result, various additions needed
+// making to it to get the compilers compiling!
+//
+
+//
+// A new version of the Map template class - the operator[] now returns the correct type reference
+//
+template <class _K, class _Ty, class _Pr = std::less<_K>, class _A = std::allocator<_Ty> >
+class TBaseMap : public std::map <_K, _Ty, _Pr, _A >
+{
+public :
+ _Ty& operator[] (const _K& _Kv)
+ {
+ iterator _P = insert(value_type(_Kv, _Ty())).first;
+ return ((*_P).second);
+ }
+
+ explicit TBaseMap(const _Pr& _Pred = _Pr(), const _A& _Al = _A())
+ : std::map<_K, _Ty, _Pr, _A >(_Pred, _Al) {};
+
+
+};
+
+//
+// A new version of the List template class - the begin function now checks for NULL to eliminate access violations
+//
+template <class _Ty, class _A = std::allocator<_Ty> >
+class TBaseList : public std::list <_Ty, _A >
+{
+public :
+ iterator begin()
+ {
+ return (iterator(_Head == 0 ? 0 : _Acc::_Next(_Head)));
+ }
+
+ const_iterator begin() const
+ {
+ return (const_iterator(_Head == 0 ? 0 : _Acc::_Next(_Head)));
+ }
+
+ //
+ // These are required - apparently!
+ //
+ explicit TBaseList(const _A& _Al = _A())
+ : std::list<_Ty, _A >(_Al) {};
+ explicit TBaseList(size_type _N, const _Ty& _V = _Ty(), const _A& _Al = _A())
+ : std::list<_Ty, _A >(N, _V, _Al) {};
+
+};
+
+//
+// A new version of the set class - this defines the required insert method
+//
+template<class _K, class _Pr = std::less<_K>, class _A = std::allocator<_K> >
+class TBaseSet : public std::set <_K, _Pr, _A>
+{
+public :
+
+ //
+ // This method wasn't defined
+ //
+ template<class _Iter>
+ void insert(_Iter _First, _Iter _Last)
+ { // insert [_First, _Last)
+ for (; _First != _Last; ++_First)
+ this->insert(*_First);
+ }
+
+ //
+ // These methods were not resolved if I declared the previous method??
+ //
+ _Pairib insert(const value_type& _X)
+ {
+ _Imp::_Pairib _Ans = _Tr.insert(_X);
+ return (_Pairib(_Ans.first, _Ans.second));
+ }
+
+ iterator insert(iterator _P, const value_type& _X)
+ {
+ return (_Tr.insert((_Imp::iterator&)_P, _X));
+ }
+
+ void insert(_It _F, _It _L)
+ {
+ for (; _F != _L; ++_F)
+ _Tr.insert(*_F);
+ }
+
+};
+
+#else
+
+#define TBaseMap std::map
+#define TBaseList std::list
+#define TBaseSet std::set
+
+#endif //_M_AMD64
+
+//
+// Pool version of string.
+//
+typedef pool_allocator<char> TStringAllocator;
+typedef std::basic_string <char, std::char_traits<char>, TStringAllocator > TString;
+inline TString* NewPoolTString(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 >() {}
+ TMap(const tAllocator& a) : 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
+
+ // we assume base 10 or 16 for all cases
+ if (base == 10)
+ sprintf(text, "%d", i);
+ else if (base == 16)
+ sprintf(text, "%x", i);
+ else
+ assert (!"String(int): unsupported base");
+
+ 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, line);
+
+ return TPersistString(locText);
+}
+
+#endif // _COMMON_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/ConstantUnion.h b/src/mesa/shader/slang/Include/ConstantUnion.h
new file mode 100755
index 0000000000..56059ea1ec
--- /dev/null
+++ b/src/mesa/shader/slang/Include/ConstantUnion.h
@@ -0,0 +1,50 @@
+//
+//Copyright (C) 2002-2004 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)
+ union {
+ int iConst; // used for ivec
+ bool bConst; // used for bvec
+ float fConst; // used for vec, mat
+ } ;
+};
+
+#endif // _CONSTANT_UNION_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/InfoSink.h b/src/mesa/shader/slang/Include/InfoSink.h
new file mode 100755
index 0000000000..be945796bc
--- /dev/null
+++ b/src/mesa/shader/slang/Include/InfoSink.h
@@ -0,0 +1,135 @@
+//
+//Copyright (C) 2002-2004 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
+};
+
+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;
+ 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/src/mesa/shader/slang/Include/InitializeGlobals.h b/src/mesa/shader/slang/Include/InitializeGlobals.h
new file mode 100755
index 0000000000..7620c39d8b
--- /dev/null
+++ b/src/mesa/shader/slang/Include/InitializeGlobals.h
@@ -0,0 +1,43 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/Include/InitializeParseContext.h b/src/mesa/shader/slang/Include/InitializeParseContext.h
new file mode 100755
index 0000000000..ee6e8cefe6
--- /dev/null
+++ b/src/mesa/shader/slang/Include/InitializeParseContext.h
@@ -0,0 +1,44 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/Include/PoolAlloc.h b/src/mesa/shader/slang/Include/PoolAlloc.h
new file mode 100755
index 0000000000..317ce0447d
--- /dev/null
+++ b/src/mesa/shader/slang/Include/PoolAlloc.h
@@ -0,0 +1,354 @@
+//
+//Copyright (C) 2002-2004 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(), (unsigned char) (guardBlockBeginVal), "before");
+ checkGuardBlock(postGuard(), (unsigned char) (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
+
+ enum {
+ guardBlockBeginVal = 0xfb,
+ guardBlockEndVal = 0xfe,
+ userDataFill = 0xcd
+ };
+
+# ifdef GUARD_BLOCKS
+ enum {
+ guardBlockSize = 16
+ };
+ inline static size_t headerSize() { return sizeof(TAllocation); }
+# else
+ enum {
+ guardBlockSize = 0
+ };
+ 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();
+extern PoolAllocatorPointer& GetCompilerPoolAllocator();
+#define GlobalPoolAllocator GetGlobalPoolAllocator()
+#define CompilerPoolAllocator GetCompilerPoolAllocator()
+struct TThreadGlobalPools
+{
+ TPoolAllocator* globalPoolAllocator;
+ TPoolAllocator* compilerPoolAllocator;
+};
+
+//
+// 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 _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/src/mesa/shader/slang/Include/ResourceLimits.h b/src/mesa/shader/slang/Include/ResourceLimits.h
new file mode 100755
index 0000000000..ec7277d890
--- /dev/null
+++ b/src/mesa/shader/slang/Include/ResourceLimits.h
@@ -0,0 +1,52 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/Include/ShHandle.h b/src/mesa/shader/slang/Include/ShHandle.h
new file mode 100755
index 0000000000..e7cb53b9cd
--- /dev/null
+++ b/src/mesa/shader/slang/Include/ShHandle.h
@@ -0,0 +1,199 @@
+//
+//Copyright (C) 2002-2004 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/ShaderLangExt.h"
+#include "InfoSink.h"
+
+class TCompiler;
+class TLinker;
+class TUniformMap;
+namespace Lf {
+ class TBindingList;
+ class TLinker;
+ class TLibrary;
+};
+
+//
+// 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 Lf::TLinker* getAsNewLinker() { return 0; }
+ virtual TUniformMap* getAsUniformMap() { return 0; }
+ virtual Lf::TBindingList* getAsBindingList() { return 0; }
+ virtual Lf::TLibrary* getAsLibrary() { 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; }
+
+ // Initialize our private pool for a new compilation, and
+ // return it.
+ virtual TPoolAllocator& getNewCompilationAllocator()
+ {
+ // We do a pop and push on the compiler pool, because compile can
+ // be called repeatedly on the same compiler handle. Each time,
+ // we want to pop away the results of any previous compile. We
+ // could do that with popAll, but this is a somewhat smaller
+ // hammer.
+ compilerPool.pop();
+ compilerPool.push();
+
+ return compilerPool;
+ }
+
+ TPoolAllocator& getCompilerPoolAllocator() { return compilerPool; }
+
+ TInfoSink& infoSink;
+protected:
+ EShLanguage language;
+ bool haveValidObjectCode;
+
+ // This is a per-compiler-object pool allocator. Allocations
+ // who's lifetime need not extend beyond the lifetime of the
+ // compiler itself can use this private pool.
+ TPoolAllocator compilerPool;
+};
+
+//
+// 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);
+TShHandleBase* ConstructBindings();
+TShHandleBase* ConstructLibrary();
+void DeleteLinker(TShHandleBase*);
+
+TUniformMap* ConstructUniformMap();
+void DeleteCompiler(TCompiler*);
+
+void DeleteUniformMap(TUniformMap*);
+void freeTargetDependentData(void*);
+
+#endif // _SHHANDLE_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/Types.h b/src/mesa/shader/slang/Include/Types.h
new file mode 100755
index 0000000000..368b140342
--- /dev/null
+++ b/src/mesa/shader/slang/Include/Types.h
@@ -0,0 +1,223 @@
+//
+//Copyright (C) 2002-2004 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 the compiler thinks 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;
+ TType* userDef;
+ int line;
+};
+
+//
+// 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)
+ { }
+ explicit TType(TPublicType p) :
+ type(p.type), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(0),
+ structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0)
+ {
+ if (p.userDef) {
+ structure = p.userDef->getStruct();
+ structureSize = setStructSize(p.userDef->getStruct());
+ typeName = p.userDef->getTypeName();
+ }
+ }
+ explicit TType(TTypeList* userDef, TString n) :
+ type(EbtStruct), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
+ structure(userDef), typeName(n), maxArraySize(0), arrayInformationType(0) {
+ structureSize = setStructSize(userDef);
+ }
+
+ virtual ~TType() {}
+ TType (const TType& type) { *this = type; }
+
+ int setStructSize(TTypeList* userDef)
+ {
+ int stSize = 0;
+ for (TTypeList::iterator tl = userDef->begin(); tl != userDef->end(); tl++) {
+ if (((*tl).type)->isArray()) {
+ stSize += ((*tl).type)->getInstanceSize() * ((*tl).type)->getArraySize();
+ } else if (((*tl).type)->isMatrix() || ((*tl).type)->isVector()){
+ stSize += ((*tl).type)->getInstanceSize();
+ } else if (((*tl).type)->getStruct()) {
+ //?? We should actually be calling getStructSize() function and not setStructSize. This problem occurs in case
+ // of nested/embedded structs.
+ stSize += setStructSize(((*tl).type)->getStruct());
+ } else
+ stSize += 1;
+ }
+ structureSize = stSize;
+ return stSize;
+ }
+
+ 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 = n; }
+ virtual void setFieldName(const TString& n) { fieldName = n; }
+ virtual const TString& getTypeName() const { return typeName; }
+ virtual const TString& getFieldName() const { 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; }
+ virtual bool isArray() const { return array; }
+ 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 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 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 getStructSize() { return structureSize; }
+ TTypeList* getStruct() const { return structure; }
+ TString& getMangledName() {
+ if (mangled.size() == 0) {
+ buildMangledName(mangled);
+ mangled+=';';
+ }
+ return mangled;
+ }
+ bool operator==(const TType& right) const {
+ return type == right.type &&
+ size == right.size &&
+ matrix == right.matrix &&
+ array == right.array &&
+ 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:
+ TBasicType type;
+ TQualifier qualifier;
+ int size; // size of vector or matrix, not size of array
+ bool matrix;
+ bool array;
+ int arraySize;
+ TTypeList* structure; // 0 unless this is a struct
+ TString fieldName; // for structure field names
+ TString typeName; // for structure field type name
+ TString mangled;
+ int structureSize;
+ int maxArraySize;
+ TType* arrayInformationType;
+
+ void buildMangledName(TString&);
+};
+
+#endif // _TYPES_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/intermediate.h b/src/mesa/shader/slang/Include/intermediate.h
new file mode 100755
index 0000000000..ab87642690
--- /dev/null
+++ b/src/mesa/shader/slang/Include/intermediate.h
@@ -0,0 +1,505 @@
+//
+//Copyright (C) 2002-2004 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,
+};
+
+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&, bool);
+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) { }
+ TIntermAggregate(TOperator o) : TIntermOperator(o) { }
+ 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; }
+protected:
+ TIntermSequence sequence;
+ TQualifierList qualifier;
+ TString name;
+ bool userDefined; // used for user defined function names
+};
+
+//
+// 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, 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/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp b/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp
new file mode 100755
index 0000000000..8b57616d34
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp
@@ -0,0 +1,2822 @@
+#line 2 "Gen_glslang.cpp"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp,v 1.1 2005/01/17 16:01:49 michal Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 144
+#define YY_END_OF_BUFFER 145
+static yyconst short int yy_accept[410] =
+ { 0,
+ 0, 0, 0, 0, 145, 143, 142, 142, 127, 133,
+ 138, 122, 123, 131, 130, 119, 128, 126, 132, 90,
+ 90, 120, 116, 134, 121, 135, 139, 86, 124, 125,
+ 137, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 117, 136, 118, 129, 141, 144, 143, 140, 113,
+ 99, 118, 107, 102, 97, 105, 95, 106, 96, 93,
+ 94, 0, 98, 92, 88, 89, 0, 0, 90, 125,
+ 117, 124, 114, 110, 112, 111, 115, 86, 103, 109,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+
+ 8, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 11, 13, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 104,
+ 108, 140, 0, 0, 1, 92, 0, 0, 91, 87,
+ 100, 101, 43, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 9, 86, 86, 86, 86, 86, 86, 86, 17, 86,
+ 86, 86, 86, 86, 14, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+
+ 86, 86, 86, 86, 86, 86, 0, 93, 0, 92,
+ 86, 19, 86, 86, 83, 86, 86, 86, 86, 86,
+ 86, 86, 12, 46, 86, 86, 86, 86, 86, 51,
+ 65, 86, 86, 86, 86, 86, 86, 62, 24, 25,
+ 26, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 49, 20, 86, 86, 86, 86,
+ 86, 86, 27, 28, 29, 18, 86, 86, 86, 6,
+ 33, 34, 35, 44, 3, 86, 86, 86, 86, 76,
+ 77, 78, 86, 21, 66, 16, 73, 74, 75, 70,
+ 71, 72, 86, 15, 68, 86, 30, 31, 32, 86,
+
+ 86, 86, 86, 86, 86, 86, 63, 86, 86, 86,
+ 86, 86, 86, 86, 45, 86, 85, 86, 86, 10,
+ 86, 86, 86, 86, 64, 59, 54, 86, 86, 86,
+ 69, 50, 57, 23, 86, 82, 58, 42, 52, 86,
+ 86, 86, 86, 86, 86, 86, 86, 53, 22, 86,
+ 86, 86, 86, 86, 86, 47, 4, 86, 5, 86,
+ 86, 7, 60, 86, 86, 55, 86, 86, 86, 86,
+ 48, 67, 56, 2, 61, 84, 36, 37, 38, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 39,
+ 86, 86, 86, 86, 86, 79, 86, 80, 86, 86,
+
+ 86, 40, 86, 41, 86, 86, 86, 81, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 1, 1, 1, 5, 6, 1, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 20, 20, 21, 21, 22, 23, 24,
+ 25, 26, 27, 1, 28, 28, 29, 30, 31, 28,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 34, 32, 32, 32, 32, 35, 32, 32,
+ 36, 1, 37, 38, 32, 1, 39, 40, 41, 42,
+
+ 43, 44, 45, 46, 47, 32, 48, 49, 50, 51,
+ 52, 53, 32, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[67] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 1, 3, 3, 3, 3, 3, 3,
+ 3, 1, 1, 1, 1, 1, 1, 4, 4, 4,
+ 3, 5, 5, 5, 5, 1, 1, 1, 4, 4,
+ 4, 4, 3, 4, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 1, 1, 1, 1
+ } ;
+
+static yyconst short int yy_base[416] =
+ { 0,
+ 0, 0, 66, 0, 607, 608, 608, 608, 581, 108,
+ 129, 608, 608, 580, 126, 608, 125, 123, 138, 151,
+ 142, 578, 608, 152, 578, 120, 608, 0, 608, 608,
+ 123, 103, 126, 140, 144, 139, 154, 550, 117, 156,
+ 549, 561, 110, 542, 126, 555, 169, 175, 154, 174,
+ 551, 608, 156, 608, 608, 608, 608, 582, 0, 608,
+ 608, 608, 608, 608, 608, 608, 608, 608, 608, 222,
+ 608, 592, 608, 229, 162, 220, 258, 0, 221, 608,
+ 608, 608, 569, 608, 608, 608, 568, 0, 608, 608,
+ 542, 535, 538, 546, 545, 532, 547, 534, 540, 528,
+
+ 525, 538, 525, 522, 522, 528, 516, 523, 520, 530,
+ 516, 522, 527, 0, 205, 526, 517, 511, 516, 518,
+ 508, 522, 522, 505, 510, 507, 496, 156, 510, 506,
+ 508, 497, 500, 172, 505, 497, 509, 183, 502, 608,
+ 608, 0, 270, 545, 608, 277, 294, 306, 313, 0,
+ 608, 608, 0, 493, 497, 506, 503, 487, 487, 168,
+ 502, 499, 499, 497, 494, 486, 492, 479, 490, 493,
+ 0, 490, 478, 485, 487, 480, 469, 468, 481, 482,
+ 477, 282, 478, 469, 466, 470, 468, 459, 462, 460,
+ 470, 456, 454, 454, 456, 453, 464, 463, 215, 458,
+
+ 453, 442, 299, 460, 462, 451, 320, 327, 334, 341,
+ 452, 0, 450, 346, 0, 442, 440, 448, 437, 454,
+ 443, 349, 0, 0, 437, 447, 447, 432, 352, 0,
+ 0, 355, 436, 430, 429, 430, 358, 0, 0, 0,
+ 0, 428, 433, 424, 437, 432, 424, 428, 420, 423,
+ 427, 432, 431, 422, 0, 0, 428, 417, 417, 422,
+ 421, 418, 0, 0, 0, 0, 408, 420, 422, 0,
+ 0, 0, 0, 0, 0, 410, 411, 405, 415, 0,
+ 0, 0, 406, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 413, 0, 0, 411, 0, 0, 0, 401,
+
+ 406, 396, 409, 409, 398, 405, 0, 403, 405, 389,
+ 398, 404, 399, 387, 0, 389, 0, 388, 391, 0,
+ 380, 379, 379, 392, 0, 394, 0, 393, 392, 379,
+ 0, 0, 0, 0, 375, 0, 0, 0, 0, 372,
+ 383, 376, 382, 379, 374, 366, 378, 0, 0, 371,
+ 378, 377, 374, 362, 373, 0, 0, 373, 0, 371,
+ 370, 0, 0, 369, 368, 0, 380, 379, 360, 332,
+ 0, 0, 0, 0, 0, 0, 354, 222, 354, 346,
+ 339, 341, 337, 339, 338, 280, 266, 266, 262, 0,
+ 260, 228, 241, 225, 219, 235, 214, 0, 203, 189,
+
+ 172, 0, 165, 0, 156, 108, 94, 0, 608, 390,
+ 391, 394, 399, 403, 404
+ } ;
+
+static yyconst short int yy_def[416] =
+ { 0,
+ 409, 1, 409, 3, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 410, 409, 409, 409, 409, 409, 409, 411, 409, 409,
+ 409, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 409, 409, 409, 409, 409, 409, 409, 412, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 413, 409, 409, 20, 414, 409, 415, 410, 409,
+ 409, 409, 409, 409, 409, 409, 409, 411, 409, 409,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 409,
+ 409, 412, 409, 413, 409, 409, 409, 409, 409, 415,
+ 409, 409, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+
+ 411, 411, 411, 411, 411, 411, 409, 409, 409, 409,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+
+ 411, 411, 411, 411, 411, 411, 411, 411, 0, 409,
+ 409, 409, 409, 409, 409
+ } ;
+
+static yyconst short int yy_nxt[675] =
+ { 0,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 21, 21, 21, 21,
+ 21, 22, 23, 24, 25, 26, 27, 28, 28, 28,
+ 28, 28, 28, 28, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 28, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 28,
+ 28, 28, 52, 53, 54, 55, 6, 56, 57, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 58,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 59, 59, 59, 59, 59, 59, 59,
+
+ 59, 6, 6, 6, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 6, 6,
+ 6, 6, 61, 62, 63, 66, 68, 70, 70, 70,
+ 70, 70, 70, 70, 86, 87, 71, 89, 119, 69,
+ 67, 72, 408, 64, 74, 112, 81, 91, 92, 407,
+ 90, 120, 73, 74, 122, 75, 75, 75, 75, 75,
+ 75, 76, 77, 82, 113, 83, 84, 93, 96, 94,
+ 140, 77, 123, 95, 77, 78, 99, 103, 97, 104,
+ 100, 98, 106, 77, 192, 101, 409, 406, 105, 114,
+
+ 107, 102, 108, 405, 134, 109, 115, 125, 135, 193,
+ 78, 110, 136, 116, 126, 127, 137, 130, 199, 141,
+ 131, 409, 217, 218, 128, 138, 200, 129, 132, 204,
+ 404, 205, 74, 74, 403, 133, 70, 70, 70, 70,
+ 70, 70, 70, 146, 146, 146, 146, 146, 146, 146,
+ 77, 77, 143, 176, 382, 383, 177, 178, 258, 147,
+ 179, 402, 77, 77, 143, 401, 259, 148, 400, 148,
+ 399, 147, 149, 149, 149, 149, 149, 149, 149, 207,
+ 398, 207, 397, 396, 208, 208, 208, 208, 208, 208,
+ 208, 146, 146, 146, 146, 146, 146, 146, 239, 240,
+
+ 241, 395, 394, 209, 393, 209, 392, 147, 210, 210,
+ 210, 210, 210, 210, 210, 263, 264, 265, 391, 147,
+ 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 149, 149, 208, 208, 208, 208, 208, 208,
+ 208, 208, 208, 208, 208, 208, 208, 208, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 271, 272, 273, 280, 281, 282, 287, 288,
+ 289, 290, 291, 292, 297, 298, 299, 367, 368, 369,
+ 390, 389, 388, 387, 386, 385, 384, 381, 380, 379,
+ 370, 79, 79, 88, 88, 88, 142, 142, 142, 144,
+
+ 144, 144, 144, 144, 76, 76, 150, 150, 378, 377,
+ 376, 375, 374, 373, 372, 371, 366, 365, 364, 363,
+ 362, 361, 360, 359, 358, 357, 356, 355, 354, 353,
+ 352, 351, 350, 349, 348, 347, 346, 345, 344, 343,
+ 342, 341, 340, 339, 338, 337, 336, 335, 334, 333,
+ 332, 331, 330, 329, 328, 327, 326, 325, 324, 323,
+ 322, 321, 320, 319, 318, 317, 316, 315, 314, 313,
+ 312, 311, 310, 309, 308, 307, 306, 305, 304, 303,
+ 302, 301, 300, 296, 295, 294, 293, 286, 285, 284,
+ 283, 279, 278, 277, 276, 275, 274, 270, 269, 268,
+
+ 267, 266, 262, 261, 260, 257, 256, 255, 254, 253,
+ 252, 251, 250, 249, 248, 247, 246, 245, 244, 243,
+ 242, 238, 237, 236, 235, 234, 233, 232, 231, 230,
+ 229, 228, 227, 226, 225, 224, 223, 222, 221, 220,
+ 219, 216, 215, 214, 213, 212, 211, 145, 206, 203,
+ 202, 201, 198, 197, 196, 195, 194, 191, 190, 189,
+ 188, 187, 186, 185, 184, 183, 182, 181, 180, 175,
+ 174, 173, 172, 171, 170, 169, 168, 167, 166, 165,
+ 164, 163, 162, 161, 160, 159, 158, 157, 156, 155,
+ 154, 153, 152, 151, 145, 72, 139, 124, 121, 118,
+
+ 117, 111, 85, 80, 65, 60, 409, 5, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409
+ } ;
+
+static yyconst short int yy_chk[675] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 10, 10, 11, 15, 17, 18, 18, 18,
+ 18, 18, 18, 18, 26, 26, 19, 31, 43, 17,
+ 15, 19, 407, 11, 21, 39, 24, 32, 32, 406,
+ 31, 43, 19, 20, 45, 20, 20, 20, 20, 20,
+ 20, 20, 21, 24, 39, 24, 24, 33, 34, 33,
+ 53, 20, 45, 33, 21, 20, 35, 36, 34, 36,
+ 35, 34, 37, 20, 128, 35, 75, 405, 36, 40,
+
+ 37, 35, 37, 403, 49, 37, 40, 47, 49, 128,
+ 20, 37, 50, 40, 47, 47, 50, 48, 134, 53,
+ 48, 75, 160, 160, 47, 50, 134, 47, 48, 138,
+ 401, 138, 76, 79, 400, 48, 70, 70, 70, 70,
+ 70, 70, 70, 74, 74, 74, 74, 74, 74, 74,
+ 76, 79, 70, 115, 378, 378, 115, 115, 199, 74,
+ 115, 399, 76, 79, 70, 397, 199, 77, 396, 77,
+ 395, 74, 77, 77, 77, 77, 77, 77, 77, 143,
+ 394, 143, 393, 392, 143, 143, 143, 143, 143, 143,
+ 143, 146, 146, 146, 146, 146, 146, 146, 182, 182,
+
+ 182, 391, 389, 147, 388, 147, 387, 146, 147, 147,
+ 147, 147, 147, 147, 147, 203, 203, 203, 386, 146,
+ 148, 148, 148, 148, 148, 148, 148, 149, 149, 149,
+ 149, 149, 149, 149, 207, 207, 207, 207, 207, 207,
+ 207, 208, 208, 208, 208, 208, 208, 208, 209, 209,
+ 209, 209, 209, 209, 209, 210, 210, 210, 210, 210,
+ 210, 210, 214, 214, 214, 222, 222, 222, 229, 229,
+ 229, 232, 232, 232, 237, 237, 237, 354, 354, 354,
+ 385, 384, 383, 382, 381, 380, 379, 377, 370, 369,
+ 354, 410, 410, 411, 411, 411, 412, 412, 412, 413,
+
+ 413, 413, 413, 413, 414, 414, 415, 415, 368, 367,
+ 365, 364, 361, 360, 358, 355, 353, 352, 351, 350,
+ 347, 346, 345, 344, 343, 342, 341, 340, 335, 330,
+ 329, 328, 326, 324, 323, 322, 321, 319, 318, 316,
+ 314, 313, 312, 311, 310, 309, 308, 306, 305, 304,
+ 303, 302, 301, 300, 296, 293, 283, 279, 278, 277,
+ 276, 269, 268, 267, 262, 261, 260, 259, 258, 257,
+ 254, 253, 252, 251, 250, 249, 248, 247, 246, 245,
+ 244, 243, 242, 236, 235, 234, 233, 228, 227, 226,
+ 225, 221, 220, 219, 218, 217, 216, 213, 211, 206,
+
+ 205, 204, 202, 201, 200, 198, 197, 196, 195, 194,
+ 193, 192, 191, 190, 189, 188, 187, 186, 185, 184,
+ 183, 181, 180, 179, 178, 177, 176, 175, 174, 173,
+ 172, 170, 169, 168, 167, 166, 165, 164, 163, 162,
+ 161, 159, 158, 157, 156, 155, 154, 144, 139, 137,
+ 136, 135, 133, 132, 131, 130, 129, 127, 126, 125,
+ 124, 123, 122, 121, 120, 119, 118, 117, 116, 113,
+ 112, 111, 110, 109, 108, 107, 106, 105, 104, 103,
+ 102, 101, 100, 99, 98, 97, 96, 95, 94, 93,
+ 92, 91, 87, 83, 72, 58, 51, 46, 44, 42,
+
+ 41, 38, 25, 22, 14, 9, 5, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+char *yytext;
+#line 1 ".\\glslang\\MachineIndependent\\glslang.l"
+#define INITIAL 0
+/*
+//
+//Copyright (C) 2002-2004 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
+*/
+#define YY_NO_UNPUT 1
+#line 59 ".\\glslang\\MachineIndependent\\glslang.l"
+#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);
+
+#ifdef _WIN32
+ extern int yyparse(TParseContext&);
+ #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)
+ TSourceLoc yylineno;
+#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))
+
+#define YY_NEVER_INTERACTIVE 1
+#define FIELDS 1
+
+#line 729 "Gen_glslang.cpp"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 91 ".\\glslang\\MachineIndependent\\glslang.l"
+
+#line 878 "Gen_glslang.cpp"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 410 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 608 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 92 ".\\glslang\\MachineIndependent\\glslang.l"
+{ /* ?? carriage and/or line-feed? */ };
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 94 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(ATTRIBUTE); }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 95 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(CONST_QUAL); }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 96 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(UNIFORM); }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 97 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(VARYING); }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 99 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(BREAK); }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 100 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(CONTINUE); }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 101 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(DO); }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 102 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(FOR); }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 103 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(WHILE); }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 105 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(IF); }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 106 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(ELSE); }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 108 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(IN_QUAL); }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 109 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(OUT_QUAL); }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 110 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(INOUT_QUAL); }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 112 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 113 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 114 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 115 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 116 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.b = true; return(BOOLCONSTANT); }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 117 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 119 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(DISCARD); }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 120 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(RETURN); }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 122 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 123 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 124 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 126 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 127 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 128 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 129 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 130 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 131 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 132 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 133 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 134 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 136 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1D; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 137 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 138 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER3D; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 139 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 140 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DSHADOW; }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 141 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DSHADOW; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 143 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(STRUCT); }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 145 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 147 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 148 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 149 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 150 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 151 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 152 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 153 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 155 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 156 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 157 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 159 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 160 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 161 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 162 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 163 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 164 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 165 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 166 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 168 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 169 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 170 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 171 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 172 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 173 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 175 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 176 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 178 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 179 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 180 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 181 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 182 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 183 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 184 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 185 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 186 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 188 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 189 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 190 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 192 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 193 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 195 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 196 ".\\glslang\\MachineIndependent\\glslang.l"
+{ PaReservedWord(); return 0; }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 198 ".\\glslang\\MachineIndependent\\glslang.l"
+{
+ pyylval->lex.line = yylineno;
+ pyylval->lex.string = NewPoolTString(yytext);
+ return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol);
+}
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 204 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 205 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 206 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 207 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 209 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 210 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 211 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 213 ".\\glslang\\MachineIndependent\\glslang.l"
+{ int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 215 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(ADD_ASSIGN); }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 216 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(SUB_ASSIGN); }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 217 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(MUL_ASSIGN); }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 218 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(DIV_ASSIGN); }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 219 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(MOD_ASSIGN); }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 220 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(LEFT_ASSIGN); }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 221 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 222 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(AND_ASSIGN); }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 223 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(XOR_ASSIGN); }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 224 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(OR_ASSIGN); }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 226 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(INC_OP); }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 227 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(DEC_OP); }
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 228 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(AND_OP); }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 229 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(OR_OP); }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 230 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(XOR_OP); }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 231 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(LE_OP); }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 232 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(GE_OP); }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 233 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(EQ_OP); }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 234 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(NE_OP); }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 235 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(LEFT_OP); }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 236 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(RIGHT_OP); }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 237 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 238 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 239 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(RIGHT_BRACE); }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 240 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 241 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(COLON); }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 242 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 243 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 244 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 245 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(LEFT_BRACKET); }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 246 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(RIGHT_BRACKET); }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 247 ".\\glslang\\MachineIndependent\\glslang.l"
+{ BEGIN(FIELDS); return(DOT); }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 248 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(BANG); }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 249 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(DASH); }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 250 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(TILDE); }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 251 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(PLUS); }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 252 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(STAR); }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 253 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(SLASH); }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 254 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(PERCENT); }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 255 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(LEFT_ANGLE); }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 256 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(RIGHT_ANGLE); }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 257 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(VERTICAL_BAR); }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 258 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(CARET); }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 259 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(AMPERSAND); }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 260 ".\\glslang\\MachineIndependent\\glslang.l"
+{ pyylval->lex.line = yylineno; return(QUESTION); }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 262 ".\\glslang\\MachineIndependent\\glslang.l"
+{
+BEGIN(INITIAL);
+ pyylval->lex.line = yylineno;
+ pyylval->lex.string = NewPoolTString(yytext);
+ return FIELD_SELECTION; }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 267 ".\\glslang\\MachineIndependent\\glslang.l"
+{}
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 269 ".\\glslang\\MachineIndependent\\glslang.l"
+{ }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(FIELDS):
+#line 270 ".\\glslang\\MachineIndependent\\glslang.l"
+{ (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 271 ".\\glslang\\MachineIndependent\\glslang.l"
+{ parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";
+ return 0; }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 274 ".\\glslang\\MachineIndependent\\glslang.l"
+ECHO;
+ YY_BREAK
+#line 1695 "Gen_glslang.cpp"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a singled characater, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 410 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 410 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 409);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ yytext_ptr = yy_c_buf_p;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ {
+ yy_c_buf_p =
+ yytext_ptr + YY_MORE_ADJ;
+ return EOF;
+ }
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+ break;
+
+ case EOB_ACT_LAST_MATCH:
+#ifdef __cplusplus
+ YY_FATAL_ERROR(
+ "unexpected last match in yyinput()" );
+#else
+ YY_FATAL_ERROR(
+ "unexpected last match in input()" );
+#endif
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *str )
+#else
+YY_BUFFER_STATE yy_scan_string( str )
+yyconst char *str;
+#endif
+ {
+ int len;
+ for ( len = 0; str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n - YY_MORE_ADJ; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 274 ".\\glslang\\MachineIndependent\\glslang.l"
+
+
+
+//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 || !argv[0])
+ 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;
+ yylineno = 1;
+
+ if (*cpp->PaStrLen > 0) {
+ int ret;
+ #ifdef _WIN32
+ ret = yyparse(parseContextLocal);
+ #else
+ ret = yyparse((void*)(&parseContextLocal));
+ #endif
+ if (cpp->CompileError == 1)
+ return 1;
+ else
+ return ret;
+ }
+ else
+ return 0;
+}
+
+void yyerror(char *s)
+{
+ if (((TParseContext *)cpp->pC)->AfterEOF)
+ GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
+ 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 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 MapStrings(const char *string1, const char *string2)
+{
+ TString strSrc, strDest;
+ strSrc = TString(string1);
+ strDest = TString(string2);
+
+ ((TParseContext *)cpp->pC)->PragmaTable[strSrc] = strDest;
+}
+
+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;
+ }
+}
+
+}
+
+void setInitialState()
+{
+ yy_start = 1;
+}
diff --git a/src/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp b/src/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp
new file mode 100755
index 0000000000..ef38e26e9d
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp
@@ -0,0 +1,3666 @@
+
+/* A Bison parser, made from glslang.y with Bison version GNU Bison version 1.24
+ */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define ATTRIBUTE 258
+#define CONST_QUAL 259
+#define BOOL_TYPE 260
+#define FLOAT_TYPE 261
+#define INT_TYPE 262
+#define BREAK 263
+#define CONTINUE 264
+#define DO 265
+#define ELSE 266
+#define FOR 267
+#define IF 268
+#define DISCARD 269
+#define RETURN 270
+#define BVEC2 271
+#define BVEC3 272
+#define BVEC4 273
+#define IVEC2 274
+#define IVEC3 275
+#define IVEC4 276
+#define VEC2 277
+#define VEC3 278
+#define VEC4 279
+#define MATRIX2 280
+#define MATRIX3 281
+#define MATRIX4 282
+#define IN_QUAL 283
+#define OUT_QUAL 284
+#define INOUT_QUAL 285
+#define UNIFORM 286
+#define VARYING 287
+#define STRUCT 288
+#define VOID_TYPE 289
+#define WHILE 290
+#define SAMPLER1D 291
+#define SAMPLER2D 292
+#define SAMPLER3D 293
+#define SAMPLERCUBE 294
+#define SAMPLER1DSHADOW 295
+#define SAMPLER2DSHADOW 296
+#define IDENTIFIER 297
+#define TYPE_NAME 298
+#define FLOATCONSTANT 299
+#define INTCONSTANT 300
+#define BOOLCONSTANT 301
+#define FIELD_SELECTION 302
+#define LEFT_OP 303
+#define RIGHT_OP 304
+#define INC_OP 305
+#define DEC_OP 306
+#define LE_OP 307
+#define GE_OP 308
+#define EQ_OP 309
+#define NE_OP 310
+#define AND_OP 311
+#define OR_OP 312
+#define XOR_OP 313
+#define MUL_ASSIGN 314
+#define DIV_ASSIGN 315
+#define ADD_ASSIGN 316
+#define MOD_ASSIGN 317
+#define LEFT_ASSIGN 318
+#define RIGHT_ASSIGN 319
+#define AND_ASSIGN 320
+#define XOR_ASSIGN 321
+#define OR_ASSIGN 322
+#define SUB_ASSIGN 323
+#define LEFT_PAREN 324
+#define RIGHT_PAREN 325
+#define LEFT_BRACKET 326
+#define RIGHT_BRACKET 327
+#define LEFT_BRACE 328
+#define RIGHT_BRACE 329
+#define DOT 330
+#define COMMA 331
+#define COLON 332
+#define EQUAL 333
+#define SEMICOLON 334
+#define BANG 335
+#define DASH 336
+#define TILDE 337
+#define PLUS 338
+#define STAR 339
+#define SLASH 340
+#define PERCENT 341
+#define LEFT_ANGLE 342
+#define RIGHT_ANGLE 343
+#define VERTICAL_BAR 344
+#define CARET 345
+#define AMPERSAND 346
+#define QUESTION 347
+
+#line 39 "glslang.y"
+
+
+/* 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(); \
+ } \
+}
+
+#line 117 "glslang.y"
+typedef 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;
+} YYSTYPE;
+#line 148 "glslang.y"
+
+#ifndef _WIN32
+ extern int yylex(YYSTYPE*, void*);
+#endif
+
+#ifndef YYLTYPE
+typedef
+ struct yyltype
+ {
+ int timestamp;
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ char *text;
+ }
+ yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#ifndef YYDEBUG
+#define YYDEBUG 1
+#endif
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define YYFINAL 331
+#define YYFLAG -32768
+#define YYNTBASE 93
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 347 ? yytranslate[x] : 167)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = { 0,
+ 0, 2, 4, 6, 8, 10, 14, 16, 21, 23,
+ 27, 30, 33, 35, 37, 40, 43, 46, 48, 51,
+ 55, 58, 60, 62, 64, 66, 68, 70, 72, 74,
+ 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
+ 96, 99, 102, 105, 107, 109, 111, 113, 115, 119,
+ 123, 127, 129, 133, 137, 139, 143, 147, 149, 153,
+ 157, 161, 165, 167, 171, 175, 177, 181, 183, 187,
+ 189, 193, 195, 199, 201, 205, 207, 211, 213, 219,
+ 221, 225, 227, 229, 231, 233, 235, 237, 239, 241,
+ 243, 245, 247, 249, 253, 255, 258, 261, 264, 266,
+ 268, 271, 275, 279, 282, 288, 292, 295, 299, 302,
+ 303, 305, 307, 309, 311, 316, 318, 322, 328, 335,
+ 341, 343, 346, 351, 357, 362, 364, 367, 369, 371,
+ 373, 375, 377, 379, 381, 383, 385, 387, 389, 391,
+ 393, 395, 397, 399, 401, 403, 405, 407, 409, 411,
+ 413, 415, 417, 419, 421, 423, 429, 434, 436, 439,
+ 443, 445, 449, 451, 456, 458, 460, 462, 464, 466,
+ 468, 470, 472, 474, 477, 478, 479, 485, 487, 489,
+ 492, 496, 498, 501, 503, 506, 512, 516, 518, 520,
+ 525, 526, 533, 534, 543, 544, 552, 554, 556, 558,
+ 559, 562, 566, 569, 572, 575, 579, 582, 584, 587,
+ 589, 591, 592
+};
+
+static const short yyrhs[] = { 42,
+ 0, 93, 0, 45, 0, 44, 0, 46, 0, 69,
+ 120, 70, 0, 94, 0, 95, 71, 96, 72, 0,
+ 97, 0, 95, 75, 47, 0, 95, 50, 0, 95,
+ 51, 0, 120, 0, 98, 0, 100, 70, 0, 99,
+ 70, 0, 101, 34, 0, 101, 0, 101, 118, 0,
+ 100, 76, 118, 0, 102, 69, 0, 103, 0, 42,
+ 0, 6, 0, 7, 0, 5, 0, 22, 0, 23,
+ 0, 24, 0, 16, 0, 17, 0, 18, 0, 19,
+ 0, 20, 0, 21, 0, 25, 0, 26, 0, 27,
+ 0, 43, 0, 95, 0, 50, 104, 0, 51, 104,
+ 0, 105, 104, 0, 83, 0, 81, 0, 80, 0,
+ 82, 0, 104, 0, 106, 84, 104, 0, 106, 85,
+ 104, 0, 106, 86, 104, 0, 106, 0, 107, 83,
+ 106, 0, 107, 81, 106, 0, 107, 0, 108, 48,
+ 107, 0, 108, 49, 107, 0, 108, 0, 109, 87,
+ 108, 0, 109, 88, 108, 0, 109, 52, 108, 0,
+ 109, 53, 108, 0, 109, 0, 110, 54, 109, 0,
+ 110, 55, 109, 0, 110, 0, 111, 91, 110, 0,
+ 111, 0, 112, 90, 111, 0, 112, 0, 113, 89,
+ 112, 0, 113, 0, 114, 56, 113, 0, 114, 0,
+ 115, 58, 114, 0, 115, 0, 116, 57, 115, 0,
+ 116, 0, 116, 92, 120, 77, 117, 0, 117, 0,
+ 104, 119, 118, 0, 78, 0, 59, 0, 60, 0,
+ 62, 0, 61, 0, 68, 0, 63, 0, 64, 0,
+ 65, 0, 66, 0, 67, 0, 118, 0, 120, 76,
+ 118, 0, 117, 0, 123, 79, 0, 131, 79, 0,
+ 124, 70, 0, 126, 0, 125, 0, 126, 128, 0,
+ 125, 76, 128, 0, 133, 42, 69, 0, 135, 42,
+ 0, 135, 42, 71, 121, 72, 0, 134, 129, 127,
+ 0, 129, 127, 0, 134, 129, 130, 0, 129, 130,
+ 0, 0, 28, 0, 29, 0, 30, 0, 135, 0,
+ 135, 71, 121, 72, 0, 132, 0, 131, 76, 42,
+ 0, 131, 76, 42, 71, 72, 0, 131, 76, 42,
+ 71, 121, 72, 0, 131, 76, 42, 78, 141, 0,
+ 133, 0, 133, 42, 0, 133, 42, 71, 72, 0,
+ 133, 42, 71, 121, 72, 0, 133, 42, 78, 141,
+ 0, 135, 0, 134, 135, 0, 4, 0, 3, 0,
+ 32, 0, 31, 0, 34, 0, 6, 0, 7, 0,
+ 5, 0, 22, 0, 23, 0, 24, 0, 16, 0,
+ 17, 0, 18, 0, 19, 0, 20, 0, 21, 0,
+ 25, 0, 26, 0, 27, 0, 36, 0, 37, 0,
+ 38, 0, 39, 0, 40, 0, 41, 0, 136, 0,
+ 43, 0, 33, 42, 73, 137, 74, 0, 33, 73,
+ 137, 74, 0, 138, 0, 137, 138, 0, 135, 139,
+ 79, 0, 140, 0, 139, 76, 140, 0, 42, 0,
+ 42, 71, 121, 72, 0, 118, 0, 122, 0, 145,
+ 0, 144, 0, 142, 0, 151, 0, 152, 0, 155,
+ 0, 162, 0, 73, 74, 0, 0, 0, 73, 146,
+ 150, 147, 74, 0, 149, 0, 144, 0, 73, 74,
+ 0, 73, 150, 74, 0, 143, 0, 150, 143, 0,
+ 79, 0, 120, 79, 0, 13, 69, 120, 70, 153,
+ 0, 143, 11, 143, 0, 143, 0, 120, 0, 133,
+ 42, 78, 141, 0, 0, 35, 69, 156, 154, 70,
+ 148, 0, 0, 10, 157, 143, 35, 69, 120, 70,
+ 79, 0, 0, 12, 69, 158, 159, 161, 70, 148,
+ 0, 151, 0, 142, 0, 154, 0, 0, 160, 79,
+ 0, 160, 79, 120, 0, 9, 79, 0, 8, 79,
+ 0, 15, 79, 0, 15, 120, 79, 0, 14, 79,
+ 0, 164, 0, 163, 164, 0, 165, 0, 122, 0,
+ 0, 123, 166, 149, 0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+ 210, 244, 247, 260, 265, 270, 276, 279, 347, 350,
+ 459, 469, 482, 490, 585, 589, 596, 600, 607, 613,
+ 622, 628, 639, 654, 655, 656, 657, 658, 659, 660,
+ 661, 662, 663, 664, 665, 666, 667, 668, 669, 680,
+ 683, 693, 703, 725, 726, 727, 728, 734, 735, 744,
+ 753, 765, 766, 774, 785, 786, 795, 807, 808, 818,
+ 828, 838, 851, 852, 862, 875, 876, 888, 889, 901,
+ 902, 914, 915, 928, 929, 942, 943, 956, 957, 971,
+ 972, 985, 986, 987, 988, 989, 990, 991, 992, 993,
+ 994, 995, 999, 1002, 1010, 1018, 1019, 1027, 1063, 1066,
+ 1073, 1081, 1102, 1120, 1131, 1158, 1163, 1173, 1178, 1188,
+ 1191, 1194, 1197, 1203, 1208, 1226, 1229, 1237, 1245, 1253,
+ 1275, 1279, 1288, 1297, 1306, 1396, 1399, 1416, 1420, 1427,
+ 1435, 1444, 1449, 1454, 1459, 1470, 1475, 1480, 1485, 1490,
+ 1495, 1500, 1505, 1510, 1515, 1521, 1527, 1533, 1539, 1545,
+ 1551, 1557, 1563, 1569, 1574, 1587, 1597, 1605, 1608, 1623,
+ 1641, 1645, 1651, 1656, 1672, 1676, 1680, 1681, 1687, 1688,
+ 1689, 1690, 1691, 1695, 1696, 1696, 1696, 1704, 1705, 1710,
+ 1713, 1721, 1724, 1730, 1731, 1735, 1743, 1747, 1757, 1762,
+ 1779, 1779, 1784, 1784, 1791, 1791, 1804, 1807, 1813, 1816,
+ 1822, 1826, 1833, 1840, 1847, 1854, 1865, 1874, 1878, 1885,
+ 1888, 1894, 1979
+};
+
+static const char * const yytname[] = { "$","error","$undefined.","ATTRIBUTE",
+"CONST_QUAL","BOOL_TYPE","FLOAT_TYPE","INT_TYPE","BREAK","CONTINUE","DO","ELSE",
+"FOR","IF","DISCARD","RETURN","BVEC2","BVEC3","BVEC4","IVEC2","IVEC3","IVEC4",
+"VEC2","VEC3","VEC4","MATRIX2","MATRIX3","MATRIX4","IN_QUAL","OUT_QUAL","INOUT_QUAL",
+"UNIFORM","VARYING","STRUCT","VOID_TYPE","WHILE","SAMPLER1D","SAMPLER2D","SAMPLER3D",
+"SAMPLERCUBE","SAMPLER1DSHADOW","SAMPLER2DSHADOW","IDENTIFIER","TYPE_NAME","FLOATCONSTANT",
+"INTCONSTANT","BOOLCONSTANT","FIELD_SELECTION","LEFT_OP","RIGHT_OP","INC_OP",
+"DEC_OP","LE_OP","GE_OP","EQ_OP","NE_OP","AND_OP","OR_OP","XOR_OP","MUL_ASSIGN",
+"DIV_ASSIGN","ADD_ASSIGN","MOD_ASSIGN","LEFT_ASSIGN","RIGHT_ASSIGN","AND_ASSIGN",
+"XOR_ASSIGN","OR_ASSIGN","SUB_ASSIGN","LEFT_PAREN","RIGHT_PAREN","LEFT_BRACKET",
+"RIGHT_BRACKET","LEFT_BRACE","RIGHT_BRACE","DOT","COMMA","COLON","EQUAL","SEMICOLON",
+"BANG","DASH","TILDE","PLUS","STAR","SLASH","PERCENT","LEFT_ANGLE","RIGHT_ANGLE",
+"VERTICAL_BAR","CARET","AMPERSAND","QUESTION","variable_identifier","primary_expression",
+"postfix_expression","integer_expression","function_call","function_call_generic",
+"function_call_header_no_parameters","function_call_header_with_parameters",
+"function_call_header","function_identifier","constructor_identifier","unary_expression",
+"unary_operator","multiplicative_expression","additive_expression","shift_expression",
+"relational_expression","equality_expression","and_expression","exclusive_or_expression",
+"inclusive_or_expression","logical_and_expression","logical_xor_expression",
+"logical_or_expression","conditional_expression","assignment_expression","assignment_operator",
+"expression","constant_expression","declaration","function_prototype","function_declarator",
+"function_header_with_parameters","function_header","parameter_declarator","parameter_declaration",
+"parameter_qualifier","parameter_type_specifier","init_declarator_list","single_declaration",
+"fully_specified_type","type_qualifier","type_specifier","struct_specifier",
+"struct_declaration_list","struct_declaration","struct_declarator_list","struct_declarator",
+"initializer","declaration_statement","statement","simple_statement","compound_statement",
+"@1","@2","statement_no_new_scope","compound_statement_no_new_scope","statement_list",
+"expression_statement","selection_statement","selection_rest_statement","condition",
+"iteration_statement","@3","@4","@5","for_init_statement","conditionopt","for_rest_statement",
+"jump_statement","translation_unit","external_declaration","function_definition",
+"@6",""
+};
+#endif
+
+static const short yyr1[] = { 0,
+ 93, 94, 94, 94, 94, 94, 95, 95, 95, 95,
+ 95, 95, 96, 97, 98, 98, 99, 99, 100, 100,
+ 101, 102, 102, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 104,
+ 104, 104, 104, 105, 105, 105, 105, 106, 106, 106,
+ 106, 107, 107, 107, 108, 108, 108, 109, 109, 109,
+ 109, 109, 110, 110, 110, 111, 111, 112, 112, 113,
+ 113, 114, 114, 115, 115, 116, 116, 117, 117, 118,
+ 118, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 120, 120, 121, 122, 122, 123, 124, 124,
+ 125, 125, 126, 127, 127, 128, 128, 128, 128, 129,
+ 129, 129, 129, 130, 130, 131, 131, 131, 131, 131,
+ 132, 132, 132, 132, 132, 133, 133, 134, 134, 134,
+ 134, 135, 135, 135, 135, 135, 135, 135, 135, 135,
+ 135, 135, 135, 135, 135, 135, 135, 135, 135, 135,
+ 135, 135, 135, 135, 135, 136, 136, 137, 137, 138,
+ 139, 139, 140, 140, 141, 142, 143, 143, 144, 144,
+ 144, 144, 144, 145, 146, 147, 145, 148, 148, 149,
+ 149, 150, 150, 151, 151, 152, 153, 153, 154, 154,
+ 156, 155, 157, 155, 158, 155, 159, 159, 160, 160,
+ 161, 161, 162, 162, 162, 162, 162, 163, 163, 164,
+ 164, 166, 165
+};
+
+static const short yyr2[] = { 0,
+ 1, 1, 1, 1, 1, 3, 1, 4, 1, 3,
+ 2, 2, 1, 1, 2, 2, 2, 1, 2, 3,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 1, 1, 1, 1, 3, 3,
+ 3, 1, 3, 3, 1, 3, 3, 1, 3, 3,
+ 3, 3, 1, 3, 3, 1, 3, 1, 3, 1,
+ 3, 1, 3, 1, 3, 1, 3, 1, 5, 1,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 1, 2, 2, 2, 1, 1,
+ 2, 3, 3, 2, 5, 3, 2, 3, 2, 0,
+ 1, 1, 1, 1, 4, 1, 3, 5, 6, 5,
+ 1, 2, 4, 5, 4, 1, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 5, 4, 1, 2, 3,
+ 1, 3, 1, 4, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 0, 0, 5, 1, 1, 2,
+ 3, 1, 2, 1, 2, 5, 3, 1, 1, 4,
+ 0, 6, 0, 8, 0, 7, 1, 1, 1, 0,
+ 2, 3, 2, 2, 2, 3, 2, 1, 2, 1,
+ 1, 0, 3
+};
+
+static const short yydefact[] = { 0,
+ 129, 128, 135, 133, 134, 139, 140, 141, 142, 143,
+ 144, 136, 137, 138, 145, 146, 147, 131, 130, 0,
+ 132, 148, 149, 150, 151, 152, 153, 155, 211, 212,
+ 0, 100, 110, 0, 116, 121, 0, 126, 154, 0,
+ 208, 210, 0, 0, 96, 0, 98, 110, 111, 112,
+ 113, 101, 0, 110, 0, 97, 122, 127, 209, 0,
+ 0, 0, 158, 0, 213, 102, 107, 109, 114, 0,
+ 117, 103, 0, 0, 0, 163, 0, 161, 157, 159,
+ 135, 133, 134, 0, 0, 193, 0, 0, 0, 0,
+ 139, 140, 141, 142, 143, 144, 136, 137, 138, 145,
+ 146, 147, 0, 1, 155, 4, 3, 5, 0, 0,
+ 0, 175, 180, 184, 46, 45, 47, 44, 2, 7,
+ 40, 9, 14, 0, 0, 18, 0, 22, 48, 0,
+ 52, 55, 58, 63, 66, 68, 70, 72, 74, 76,
+ 78, 80, 93, 0, 166, 0, 169, 182, 168, 167,
+ 0, 170, 171, 172, 173, 104, 0, 106, 108, 0,
+ 0, 26, 24, 25, 30, 31, 32, 33, 34, 35,
+ 27, 28, 29, 36, 37, 38, 39, 123, 48, 95,
+ 0, 165, 125, 156, 0, 0, 160, 204, 203, 0,
+ 195, 0, 207, 205, 0, 191, 41, 42, 0, 174,
+ 0, 11, 12, 0, 0, 16, 15, 0, 17, 19,
+ 21, 83, 84, 86, 85, 88, 89, 90, 91, 92,
+ 87, 82, 0, 43, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 185, 181, 183, 0, 0,
+ 118, 0, 120, 124, 0, 162, 0, 0, 0, 206,
+ 0, 6, 176, 0, 13, 10, 20, 81, 49, 50,
+ 51, 54, 53, 56, 57, 61, 62, 59, 60, 64,
+ 65, 67, 69, 71, 73, 75, 77, 0, 94, 0,
+ 115, 119, 164, 0, 198, 197, 200, 0, 189, 0,
+ 0, 0, 8, 0, 105, 0, 199, 0, 0, 188,
+ 186, 0, 0, 177, 79, 0, 201, 0, 0, 0,
+ 179, 192, 178, 0, 202, 196, 187, 190, 194, 0,
+ 0
+};
+
+static const short yydefgoto[] = { 119,
+ 120, 121, 264, 122, 123, 124, 125, 126, 127, 128,
+ 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
+ 139, 140, 141, 142, 143, 223, 144, 181, 145, 146,
+ 31, 32, 33, 67, 52, 53, 68, 34, 35, 36,
+ 37, 38, 39, 62, 63, 77, 78, 183, 147, 148,
+ 149, 150, 201, 302, 322, 323, 151, 152, 153, 311,
+ 301, 154, 261, 190, 258, 297, 308, 309, 155, 40,
+ 41, 42, 46
+};
+
+static const short yypact[] = { 1130,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -31,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -36,
+ -43, 8, 4, -50,-32768, 38, 1169,-32768,-32768, 197,
+-32768,-32768, 21, 1169,-32768, 58,-32768, 35,-32768,-32768,
+-32768,-32768, 1169, 69, 93,-32768, -54,-32768,-32768, 1169,
+ 94, 1047,-32768, 257,-32768,-32768,-32768,-32768, -20, 1169,
+ -3,-32768, 707, 979, 1086, 66, -21,-32768,-32768,-32768,
+ 70, 71, 72, 59, 63,-32768, 75, 76, 67, 775,
+ 78, 81, 82, 83, 84, 85, 87, 88, 89, 90,
+ 91, 95, 96, 97, 98,-32768,-32768,-32768, 979, 979,
+ 979, 117,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 10,-32768,-32768, 92, 0, 843, 99,-32768, 55, 979,
+ 24, -12, 53, -40, 51, 79, 73, 104, 138, 140,
+ -39,-32768,-32768, 7,-32768, -36,-32768,-32768,-32768,-32768,
+ 338,-32768,-32768,-32768,-32768, 128, 979,-32768,-32768, 911,
+ 979,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 133,-32768,-32768,-32768, 979, 94,-32768,-32768,-32768, 419,
+-32768, 979,-32768,-32768, 17,-32768,-32768,-32768, 2,-32768,
+ 419,-32768,-32768, 979, 159,-32768,-32768, 979,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 979,-32768, 979, 979, 979, 979, 979, 979,
+ 979, 979, 979, 979, 979, 979, 979, 979, 979, 979,
+ 979, 979, 979, 979, 979,-32768,-32768,-32768, 979, 135,
+-32768, 136,-32768,-32768, 137,-32768, 175, 571, 3,-32768,
+ 639,-32768, 419, 139, 149,-32768,-32768,-32768,-32768,-32768,
+-32768, 24, 24, -12, -12, 53, 53, 53, 53, -40,
+ -40, 51, 79, 73, 104, 138, 140, 48,-32768, 154,
+-32768,-32768,-32768, 158,-32768,-32768, 639, 419, 149, 190,
+ 169, 167,-32768, 979,-32768, 979,-32768, 163, 173, 233,
+-32768, 171, 500,-32768,-32768, 12, 979, 500, 419, 979,
+-32768,-32768,-32768, 166, 149,-32768,-32768,-32768,-32768, 250,
+-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ -53,-32768, -117, -104, -143, -107, 14, 15, 13, 18,
+ 16, 42,-32768, -57, -74,-32768, -49, -154, 5, 9,
+-32768,-32768,-32768, 185, 208, 232, 217,-32768,-32768, -247,
+ -29, -16,-32768, 244, -52,-32768, 119, -159, 52, -150,
+ -288,-32768,-32768,-32768, -9, 260, 110, 54,-32768,-32768,
+ 19,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 273,-32768,-32768
+};
+
+
+#define YYLAST 1212
+
+
+static const short yytable[] = { 182,
+ 248, 253, 250, 54, 29, 252, 1, 2, 30, 80,
+ 43, 232, 233, 300, 72, 180, 73, 243, 54, 179,
+ 58, 156, 80, 74, 321, 55, 47, 61, 56, 321,
+ 255, 49, 50, 51, 18, 19, 69, 1, 2, 257,
+ 195, 44, 45, 61, 29, 61, 234, 235, 30, 300,
+ 157, 210, 244, 69, 186, 197, 198, 187, 61, 202,
+ 203, 199, 49, 50, 51, 18, 19, 160, 228, 207,
+ 229, 262, 298, -99, 161, 208, 224, 245, 245, 57,
+ 204, 324, 245, 48, 205, 246, 182, 245, 276, 277,
+ 278, 279, 245, 60, 290, 260, 49, 50, 51, 180,
+ 230, 231, 180, 179, 236, 237, 179, 225, 226, 227,
+ 272, 273, 248, 212, 213, 214, 215, 216, 217, 218,
+ 219, 220, 221, 245, 304, 274, 275, 180, 280, 281,
+ 64, 179, 222, 267, 71, 76, 185, 188, -26, -24,
+ -25, 189, 259, 191, 192, 193, -30, 310, 268, -31,
+ -32, -33, -34, -35, 265, -27, -28, -29, -36, -37,
+ 328, 206, 239, -38, 196, -23, -39, 211, 327, 238,
+ 289, 269, 270, 271, 179, 179, 179, 179, 179, 179,
+ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
+ 200, 180, 240, 241, 288, 179, 330, 242, 249, 1,
+ 2, 3, 4, 5, 254, 266, 291, 292, 293, 294,
+ 303, 299, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 245, 305, 306, 18, 19, 20,
+ 21, 312, 22, 23, 24, 25, 26, 27, 313, 28,
+ 314, 317, 318, 319, 329, 182, 315, 299, 320, 331,
+ 179, 282, 284, 283, 158, 66, 316, 286, 285, 1,
+ 2, 81, 82, 83, 84, 85, 86, 325, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
+ 99, 100, 101, 102, 287, 70, 159, 18, 19, 20,
+ 21, 103, 22, 23, 24, 25, 26, 27, 104, 105,
+ 106, 107, 108, 75, 256, 65, 109, 110, 326, 295,
+ 263, 296, 59, 0, 0, 307, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 111, 0, 0, 0, 112,
+ 113, 0, 0, 0, 0, 114, 115, 116, 117, 118,
+ 1, 2, 81, 82, 83, 84, 85, 86, 0, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 0, 0, 0, 18, 19,
+ 20, 21, 103, 22, 23, 24, 25, 26, 27, 104,
+ 105, 106, 107, 108, 0, 0, 0, 109, 110, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 111, 0, 0, 0,
+ 112, 247, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 1, 2, 81, 82, 83, 84, 85, 86, 0,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 0, 0, 0, 18,
+ 19, 20, 21, 103, 22, 23, 24, 25, 26, 27,
+ 104, 105, 106, 107, 108, 0, 0, 0, 109, 110,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 111, 0, 0,
+ 0, 112, 0, 0, 0, 0, 0, 114, 115, 116,
+ 117, 118, 1, 2, 81, 82, 83, 84, 85, 86,
+ 0, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 0, 0, 0,
+ 18, 19, 20, 21, 103, 22, 23, 24, 25, 26,
+ 27, 104, 105, 106, 107, 108, 0, 0, 0, 109,
+ 110, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 111, 0,
+ 0, 0, 64, 1, 2, 81, 82, 83, 114, 115,
+ 116, 117, 118, 0, 0, 0, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 0, 0,
+ 0, 18, 19, 20, 21, 0, 22, 23, 24, 25,
+ 26, 27, 104, 105, 106, 107, 108, 0, 0, 0,
+ 109, 110, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 111,
+ 0, 1, 2, 81, 82, 83, 0, 0, 0, 114,
+ 115, 116, 117, 118, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 0, 0, 0, 18,
+ 19, 20, 21, 0, 22, 23, 24, 25, 26, 27,
+ 104, 105, 106, 107, 108, 0, 0, 0, 109, 110,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 111, 0, 0,
+ 0, 162, 163, 164, 0, 0, 0, 0, 115, 116,
+ 117, 118, 165, 166, 167, 168, 169, 170, 171, 172,
+ 173, 174, 175, 176, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 104, 177,
+ 106, 107, 108, 0, 0, 0, 109, 110, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 111, 0, 0, 178, 162,
+ 163, 164, 0, 0, 0, 0, 115, 116, 117, 118,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 104, 177, 106, 107,
+ 108, 0, 0, 0, 109, 110, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 111, 0, 0, 0, 162, 163, 164,
+ 0, 0, 0, 194, 115, 116, 117, 118, 165, 166,
+ 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
+ 0, 0, 0, 0, 0, 0, 209, 0, 0, 0,
+ 0, 0, 0, 0, 104, 177, 106, 107, 108, 0,
+ 0, 0, 109, 110, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 111, 0, 0, 0, 162, 163, 164, 0, 0,
+ 0, 0, 115, 116, 117, 118, 165, 166, 167, 168,
+ 169, 170, 171, 172, 173, 174, 175, 176, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 104, 177, 106, 107, 108, 0, 0, 0,
+ 109, 110, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 111,
+ 0, 0, 251, 162, 163, 164, 0, 0, 0, 0,
+ 115, 116, 117, 118, 165, 166, 167, 168, 169, 170,
+ 171, 172, 173, 174, 175, 176, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 104, 177, 106, 107, 108, 0, 0, 0, 109, 110,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 111, 0, 0,
+ 0, 3, 4, 5, 0, 0, 0, 0, 115, 116,
+ 117, 118, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 0, 0, 0, 0, 0, 20,
+ 21, 0, 22, 23, 24, 25, 26, 27, 0, 28,
+ 3, 4, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 0, 0, 0, 0, 0, 20, 21,
+ 79, 22, 23, 24, 25, 26, 27, 0, 28, 0,
+ 0, 0, 1, 2, 3, 4, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 0, 0, 184,
+ 18, 19, 20, 21, 0, 22, 23, 24, 25, 26,
+ 27, 0, 28, 3, 4, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 0, 0, 0, 0,
+ 0, 20, 21, 0, 22, 23, 24, 25, 26, 27,
+ 0, 28
+};
+
+static const short yycheck[] = { 74,
+ 151, 161, 157, 33, 0, 160, 3, 4, 0, 62,
+ 42, 52, 53, 261, 69, 73, 71, 57, 48, 73,
+ 37, 42, 75, 78, 313, 76, 70, 44, 79, 318,
+ 185, 28, 29, 30, 31, 32, 53, 3, 4, 190,
+ 90, 73, 79, 60, 40, 62, 87, 88, 40, 297,
+ 71, 126, 92, 70, 76, 109, 110, 79, 75, 50,
+ 51, 111, 28, 29, 30, 31, 32, 71, 81, 70,
+ 83, 70, 70, 70, 78, 76, 130, 76, 76, 42,
+ 71, 70, 76, 76, 75, 79, 161, 76, 232, 233,
+ 234, 235, 76, 73, 249, 79, 28, 29, 30, 157,
+ 48, 49, 160, 157, 54, 55, 160, 84, 85, 86,
+ 228, 229, 263, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 76, 77, 230, 231, 185, 236, 237,
+ 73, 185, 78, 208, 42, 42, 71, 79, 69, 69,
+ 69, 79, 192, 69, 69, 79, 69, 298, 223, 69,
+ 69, 69, 69, 69, 204, 69, 69, 69, 69, 69,
+ 320, 70, 90, 69, 69, 69, 69, 69, 319, 91,
+ 245, 225, 226, 227, 228, 229, 230, 231, 232, 233,
+ 234, 235, 236, 237, 238, 239, 240, 241, 242, 243,
+ 74, 249, 89, 56, 244, 249, 0, 58, 71, 3,
+ 4, 5, 6, 7, 72, 47, 72, 72, 72, 35,
+ 72, 261, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 76, 72, 69, 31, 32, 33,
+ 34, 42, 36, 37, 38, 39, 40, 41, 70, 43,
+ 74, 79, 70, 11, 79, 320, 304, 297, 78, 0,
+ 304, 238, 240, 239, 70, 48, 306, 242, 241, 3,
+ 4, 5, 6, 7, 8, 9, 10, 317, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 243, 54, 70, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 60, 186, 46, 50, 51, 318, 258,
+ 201, 258, 40, -1, -1, 297, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 69, -1, -1, -1, 73,
+ 74, -1, -1, -1, -1, 79, 80, 81, 82, 83,
+ 3, 4, 5, 6, 7, 8, 9, 10, -1, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, -1, -1, -1, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, -1, -1, -1, 50, 51, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 69, -1, -1, -1,
+ 73, 74, -1, -1, -1, -1, 79, 80, 81, 82,
+ 83, 3, 4, 5, 6, 7, 8, 9, 10, -1,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, -1, -1, -1, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, -1, -1, -1, 50, 51,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 69, -1, -1,
+ -1, 73, -1, -1, -1, -1, -1, 79, 80, 81,
+ 82, 83, 3, 4, 5, 6, 7, 8, 9, 10,
+ -1, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, -1, -1, -1,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, -1, -1, -1, 50,
+ 51, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 69, -1,
+ -1, -1, 73, 3, 4, 5, 6, 7, 79, 80,
+ 81, 82, 83, -1, -1, -1, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, 31, 32, 33, 34, -1, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, -1, -1, -1,
+ 50, 51, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 69,
+ -1, 3, 4, 5, 6, 7, -1, -1, -1, 79,
+ 80, 81, 82, 83, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, -1, -1, -1, 31,
+ 32, 33, 34, -1, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, -1, -1, -1, 50, 51,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 69, -1, -1,
+ -1, 5, 6, 7, -1, -1, -1, -1, 80, 81,
+ 82, 83, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 42, 43,
+ 44, 45, 46, -1, -1, -1, 50, 51, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 69, -1, -1, 72, 5,
+ 6, 7, -1, -1, -1, -1, 80, 81, 82, 83,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 42, 43, 44, 45,
+ 46, -1, -1, -1, 50, 51, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 69, -1, -1, -1, 5, 6, 7,
+ -1, -1, -1, 79, 80, 81, 82, 83, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ -1, -1, -1, -1, -1, -1, 34, -1, -1, -1,
+ -1, -1, -1, -1, 42, 43, 44, 45, 46, -1,
+ -1, -1, 50, 51, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 69, -1, -1, -1, 5, 6, 7, -1, -1,
+ -1, -1, 80, 81, 82, 83, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 42, 43, 44, 45, 46, -1, -1, -1,
+ 50, 51, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 69,
+ -1, -1, 72, 5, 6, 7, -1, -1, -1, -1,
+ 80, 81, 82, 83, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 42, 43, 44, 45, 46, -1, -1, -1, 50, 51,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 69, -1, -1,
+ -1, 5, 6, 7, -1, -1, -1, -1, 80, 81,
+ 82, 83, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, -1, -1, -1, -1, -1, 33,
+ 34, -1, 36, 37, 38, 39, 40, 41, -1, 43,
+ 5, 6, 7, -1, -1, -1, -1, -1, -1, -1,
+ -1, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, 33, 34,
+ 74, 36, 37, 38, 39, 40, 41, -1, 43, -1,
+ -1, -1, 3, 4, 5, 6, 7, -1, -1, -1,
+ -1, -1, -1, -1, -1, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, -1, -1, 74,
+ 31, 32, 33, 34, -1, 36, 37, 38, 39, 40,
+ 41, -1, 43, 5, 6, 7, -1, -1, -1, -1,
+ -1, -1, -1, -1, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, -1, -1, -1, -1,
+ -1, 33, 34, -1, 36, 37, 38, 39, 40, 41,
+ -1, 43
+};
+#define YYPURE 1
+
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* not HAVE_ALLOCA_H */
+#ifdef _AIX
+ #pragma alloca
+#else /* not _AIX */
+char *alloca ();
+#endif /* not _AIX */
+#endif /* not HAVE_ALLOCA_H */
+#endif /* not __GNUC__ */
+
+extern void yyerror(char* s);
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+#if (defined (MSDOS) && !defined (__TURBOC__)) || defined (WIN32)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+#endif /* alloca not defined. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { yychar = (token), yylval = (value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+int yyparse (void);
+#endif
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (from, to, count)
+ char *from;
+ char *to;
+ size_t count;
+{
+ register char *f = from;
+ register char *t = to;
+ register size_t i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (char *from, char *to, size_t count)
+{
+ register char *f = from;
+ register char *t = to;
+ register size_t i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+#ifndef YYPARSE_PARAM_DECL
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif
+#else
+#define YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#endif
+
+extern YY_DECL;
+
+int
+yyparse(YYPARSE_PARAM_DECL YYPARSE_PARAM) {
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1 = 0; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ size_t yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ size_t size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YYLSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yyls1, size * sizeof (*yylsp),
+ &yystacksize);
+#else
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yystacksize);
+#endif
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("parser stack overflow");
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+
+ switch (yyn) {
+
+case 1:
+#line 210 "glslang.y"
+{
+ // The symbol table search was done in the lexical phase
+ const TSymbol* symbol = yyvsp[0].lex.symbol;
+ const TVariable* variable;
+ if (symbol == 0) {
+ parseContext.error(yyvsp[0].lex.line, "undeclared identifier", yyvsp[0].lex.string->c_str(), "");
+ parseContext.recover();
+ TVariable* fakeVariable = new TVariable(yyvsp[0].lex.string, TType(EbtFloat));
+ parseContext.symbolTable.insert(*fakeVariable);
+ variable = fakeVariable;
+ } else {
+ // This identifier can only be a variable type symbol
+ if (! symbol->isVariable()) {
+ parseContext.error(yyvsp[0].lex.line, "variable expected", yyvsp[0].lex.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 = TType(variable->getType());
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(constArray, t, yyvsp[0].lex.line);
+ } else
+ yyval.interm.intermTypedNode = parseContext.intermediate.addSymbol(variable->getUniqueId(),
+ variable->getName(),
+ variable->getType(), yyvsp[0].lex.line);
+ ;
+ break;}
+case 2:
+#line 244 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 3:
+#line 247 "glslang.y"
+{
+ //
+ // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
+ // check for overflow for constants
+ //
+ if (abs(yyvsp[0].lex.i) >= (1 << 16)) {
+ parseContext.error(yyvsp[0].lex.line, " integer constant overflow", "", "");
+ parseContext.recover();
+ }
+ constUnion *unionArray = new constUnion[1];
+ unionArray->iConst = yyvsp[0].lex.i;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line);
+ ;
+ break;}
+case 4:
+#line 260 "glslang.y"
+{
+ constUnion *unionArray = new constUnion[1];
+ unionArray->fConst = yyvsp[0].lex.f;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), yyvsp[0].lex.line);
+ ;
+ break;}
+case 5:
+#line 265 "glslang.y"
+{
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = yyvsp[0].lex.b;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[0].lex.line);
+ ;
+ break;}
+case 6:
+#line 270 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[-1].interm.intermTypedNode;
+ ;
+ break;}
+case 7:
+#line 276 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 8:
+#line 279 "glslang.y"
+{
+ if (!yyvsp[-3].interm.intermTypedNode->isArray() && !yyvsp[-3].interm.intermTypedNode->isMatrix() && !yyvsp[-3].interm.intermTypedNode->isVector()) {
+ if (yyvsp[-3].interm.intermTypedNode->getAsSymbolNode())
+ parseContext.error(yyvsp[-2].lex.line, " left of '[' is not of type array, matrix, or vector ", yyvsp[-3].interm.intermTypedNode->getAsSymbolNode()->getSymbol().c_str(), "");
+ else
+ parseContext.error(yyvsp[-2].lex.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
+ parseContext.recover();
+ }
+ if (yyvsp[-3].interm.intermTypedNode->getType().getQualifier() == EvqConst && !yyvsp[-3].interm.intermTypedNode->isArray() && yyvsp[-1].interm.intermTypedNode->getQualifier() == EvqConst) {
+ if (yyvsp[-3].interm.intermTypedNode->isVector()) { // constant folding for vectors
+ TVectorFields fields;
+ fields.num = 1;
+ fields.offsets[0] = yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst; // need to do it this way because v.xy sends fields integer array
+ yyval.interm.intermTypedNode = parseContext.addConstVectorNode(fields, yyvsp[-3].interm.intermTypedNode, yyvsp[-2].lex.line);
+ } else if (yyvsp[-3].interm.intermTypedNode->isMatrix()) { // constant folding for matrices
+ yyval.interm.intermTypedNode = parseContext.addConstMatrixNode(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst, yyvsp[-3].interm.intermTypedNode, yyvsp[-2].lex.line);
+ }
+ } else {
+ if (yyvsp[-1].interm.intermTypedNode->getQualifier() == EvqConst) {
+ if ((yyvsp[-3].interm.intermTypedNode->isVector() || yyvsp[-3].interm.intermTypedNode->isMatrix()) && yyvsp[-3].interm.intermTypedNode->getType().getNominalSize() <= yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst && !yyvsp[-3].interm.intermTypedNode->isArray() ) {
+ parseContext.error(yyvsp[-2].lex.line, "", "[", "field selection out of range '%d'", yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst);
+ parseContext.recover();
+ } else {
+ if (yyvsp[-3].interm.intermTypedNode->isArray()) {
+ if (yyvsp[-3].interm.intermTypedNode->getType().getArraySize() == 0) {
+ if (yyvsp[-3].interm.intermTypedNode->getType().getMaxArraySize() <= yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst) {
+ if (parseContext.arraySetMaxSize(yyvsp[-3].interm.intermTypedNode->getAsSymbolNode(), yyvsp[-3].interm.intermTypedNode->getTypePointer(), yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst, true, yyvsp[-2].lex.line))
+ parseContext.recover();
+ } else {
+ if (parseContext.arraySetMaxSize(yyvsp[-3].interm.intermTypedNode->getAsSymbolNode(), yyvsp[-3].interm.intermTypedNode->getTypePointer(), 0, false, yyvsp[-2].lex.line))
+ parseContext.recover();
+ }
+ } else if ( yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst >= yyvsp[-3].interm.intermTypedNode->getType().getArraySize()) {
+ parseContext.error(yyvsp[-2].lex.line, "", "[", "array index out of range '%d'", yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst);
+ parseContext.recover();
+ }
+ }
+ yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-3].interm.intermTypedNode, yyvsp[-1].interm.intermTypedNode, yyvsp[-2].lex.line);
+ }
+ } else {
+ if (yyvsp[-3].interm.intermTypedNode->isArray() && yyvsp[-3].interm.intermTypedNode->getType().getArraySize() == 0) {
+ parseContext.error(yyvsp[-2].lex.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
+ parseContext.recover();
+ }
+
+ yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexIndirect, yyvsp[-3].interm.intermTypedNode, yyvsp[-1].interm.intermTypedNode, yyvsp[-2].lex.line);
+ }
+ }
+ if (yyval.interm.intermTypedNode == 0) {
+ constUnion *unionArray = new constUnion[1];
+ unionArray->fConst = 0.0;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), yyvsp[-2].lex.line);
+ } else if (yyvsp[-3].interm.intermTypedNode->isArray()) {
+ if (yyvsp[-3].interm.intermTypedNode->getType().getStruct())
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getType().getStruct(), yyvsp[-3].interm.intermTypedNode->getType().getTypeName()));
+ else
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqTemporary, yyvsp[-3].interm.intermTypedNode->getNominalSize(), yyvsp[-3].interm.intermTypedNode->isMatrix()));
+ } else if (yyvsp[-3].interm.intermTypedNode->isMatrix() && yyvsp[-3].interm.intermTypedNode->getType().getQualifier() == EvqConst)
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqConst, yyvsp[-3].interm.intermTypedNode->getNominalSize()));
+ else if (yyvsp[-3].interm.intermTypedNode->isMatrix())
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqTemporary, yyvsp[-3].interm.intermTypedNode->getNominalSize()));
+ else if (yyvsp[-3].interm.intermTypedNode->isVector() && yyvsp[-3].interm.intermTypedNode->getType().getQualifier() == EvqConst)
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqConst));
+ else if (yyvsp[-3].interm.intermTypedNode->isVector())
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqTemporary));
+ else
+ yyval.interm.intermTypedNode->setType(yyvsp[-3].interm.intermTypedNode->getType());
+ ;
+ break;}
+case 9:
+#line 347 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 10:
+#line 350 "glslang.y"
+{
+ if (yyvsp[-2].interm.intermTypedNode->isArray()) {
+ parseContext.error(yyvsp[0].lex.line, "cannot apply dot operator to an array", ".", "");
+ parseContext.recover();
+ }
+
+ if (yyvsp[-2].interm.intermTypedNode->isVector()) {
+ TVectorFields fields;
+ if (! parseContext.parseVectorFields(*yyvsp[0].lex.string, yyvsp[-2].interm.intermTypedNode->getNominalSize(), fields, yyvsp[0].lex.line)) {
+ fields.num = 1;
+ fields.offsets[0] = 0;
+ parseContext.recover();
+ }
+
+ if (yyvsp[-2].interm.intermTypedNode->getType().getQualifier() == EvqConst) { // constant folding for vector fields
+ yyval.interm.intermTypedNode = parseContext.addConstVectorNode(fields, yyvsp[-2].interm.intermTypedNode, yyvsp[0].lex.line);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ else
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType(), EvqConst, (int) (*yyvsp[0].lex.string).size()));
+ } else {
+ if (fields.num == 1) {
+ constUnion *unionArray = new constUnion[1];
+ unionArray->iConst = fields.offsets[0];
+ TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType()));
+ } else {
+ TString vectorString = *yyvsp[0].lex.string;
+ TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, yyvsp[0].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpVectorSwizzle, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType(),EvqTemporary, (int) vectorString.size()));
+ }
+ }
+ } else if (yyvsp[-2].interm.intermTypedNode->isMatrix()) {
+ TMatrixFields fields;
+ if (! parseContext.parseMatrixFields(*yyvsp[0].lex.string, yyvsp[-2].interm.intermTypedNode->getNominalSize(), fields, yyvsp[0].lex.line)) {
+ fields.wholeRow = false;
+ fields.wholeCol = false;
+ fields.row = 0;
+ fields.col = 0;
+ parseContext.recover();
+ }
+
+ if (fields.wholeRow || fields.wholeCol) {
+ parseContext.error(yyvsp[-1].lex.line, " non-scalar fields not implemented yet", ".", "");
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->iConst = 0;
+ TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType(), EvqTemporary, yyvsp[-2].interm.intermTypedNode->getNominalSize()));
+ } else {
+ constUnion *unionArray = new constUnion[1];
+ unionArray->iConst = fields.col * yyvsp[-2].interm.intermTypedNode->getNominalSize() + fields.row;
+ TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType()));
+ }
+ } else if (yyvsp[-2].interm.intermTypedNode->getBasicType() == EbtStruct) {
+ bool fieldFound = false;
+ TTypeList* fields = yyvsp[-2].interm.intermTypedNode->getType().getStruct();
+ if (fields == 0) {
+ parseContext.error(yyvsp[-1].lex.line, "structure has no fields", "Internal Error", "");
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ } else {
+ unsigned int i;
+ for (i = 0; i < fields->size(); ++i) {
+ if ((*fields)[i].type->getFieldName() == *yyvsp[0].lex.string) {
+ fieldFound = true;
+ break;
+ }
+ }
+ if (fieldFound) {
+ if (yyvsp[-2].interm.intermTypedNode->getType().getQualifier() == EvqConst) {
+ yyval.interm.intermTypedNode = parseContext.addConstStruct(*yyvsp[0].lex.string, yyvsp[-2].interm.intermTypedNode, yyvsp[-1].lex.line);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ else {
+ yyval.interm.intermTypedNode->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.
+ yyval.interm.intermTypedNode->getTypePointer()->changeQualifier(EvqConst);
+ }
+ } else {
+ constUnion *unionArray = new constUnion[1];
+ unionArray->iConst = i;
+ TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirectStruct, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode->setType(*(*fields)[i].type);
+ }
+ } else {
+ parseContext.error(yyvsp[-1].lex.line, " no such field in structure", yyvsp[0].lex.string->c_str(), "");
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ }
+ } else {
+ parseContext.error(yyvsp[-1].lex.line, " field selection requires structure, vector, or matrix on left hand side", yyvsp[0].lex.string->c_str(), "");
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ // don't delete $3.string, it's from the pool
+ ;
+ break;}
+case 11:
+#line 459 "glslang.y"
+{
+ if (parseContext.lValueErrorCheck(yyvsp[0].lex.line, "++", yyvsp[-1].interm.intermTypedNode))
+ parseContext.recover();
+ yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPostIncrement, yyvsp[-1].interm.intermTypedNode, yyvsp[0].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.unaryOpError(yyvsp[0].lex.line, "++", yyvsp[-1].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-1].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 12:
+#line 469 "glslang.y"
+{
+ if (parseContext.lValueErrorCheck(yyvsp[0].lex.line, "--", yyvsp[-1].interm.intermTypedNode))
+ parseContext.recover();
+ yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPostDecrement, yyvsp[-1].interm.intermTypedNode, yyvsp[0].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.unaryOpError(yyvsp[0].lex.line, "--", yyvsp[-1].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-1].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 13:
+#line 482 "glslang.y"
+{
+ if (parseContext.integerErrorCheck(yyvsp[0].interm.intermTypedNode, "[]"))
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 14:
+#line 490 "glslang.y"
+{
+ TFunction* fnCall = yyvsp[0].interm.function;
+ TOperator op = fnCall->getBuiltInOp();
+
+ if (op != EOpNull) {
+ //
+ // Then this should be a constructor.
+ //
+ TType type(EbtVoid); // use this to get the type back
+ if (parseContext.constructorErrorCheck(yyvsp[0].interm.line, yyvsp[0].interm.intermNode, *fnCall, op, &type)) {
+ yyval.interm.intermTypedNode = 0;
+ } else {
+ //
+ // It's a constructor, of type 'type'.
+ //
+ yyval.interm.intermTypedNode = parseContext.addConstructor(yyvsp[0].interm.intermNode, &type, op, fnCall, yyvsp[0].interm.line);
+ }
+
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.recover();
+ yyval.interm.intermTypedNode = parseContext.intermediate.setAggregateOperator(0, op, yyvsp[0].interm.line);
+ }
+ yyval.interm.intermTypedNode->setType(type);
+ } else {
+ //
+ // Not a constructor. Find it in the symbol table.
+ //
+ const TFunction* fnCandidate;
+ bool builtIn;
+ fnCandidate = parseContext.findFunction(yyvsp[0].interm.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.
+ //
+ yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(op, yyvsp[0].interm.intermNode, 0, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.error(yyvsp[0].interm.intermNode->getLine(), " wrong operand type", "Internal Error",
+ "built in unary operator function. Type: %s",
+ static_cast<TIntermTyped*>(yyvsp[0].interm.intermNode)->getCompleteString().c_str());
+ YYERROR;
+ }
+ } else {
+ yyval.interm.intermTypedNode = parseContext.intermediate.setAggregateOperator(yyvsp[0].interm.intermAggregate, op, yyvsp[0].interm.line);
+ }
+ } else {
+ // This is a real function call
+
+ yyval.interm.intermTypedNode = parseContext.intermediate.setAggregateOperator(yyvsp[0].interm.intermAggregate, EOpFunctionCall, yyvsp[0].interm.line);
+ yyval.interm.intermTypedNode->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)
+ yyval.interm.intermTypedNode->getAsAggregate()->setUserDefined();
+ yyval.interm.intermTypedNode->getAsAggregate()->setName(fnCandidate->getMangledName());
+
+ TQualifier qual;
+ TQualifierList& qualifierList = yyval.interm.intermTypedNode->getAsAggregate()->getQualifier();
+ for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
+ qual = (*fnCandidate)[i].type->getQualifier();
+ if (qual == EvqOut || qual == EvqInOut) {
+ if (parseContext.lValueErrorCheck(yyval.interm.intermTypedNode->getLine(), "assign", yyval.interm.intermTypedNode->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+ parseContext.error(yyvsp[0].interm.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
+ parseContext.recover();
+ }
+ }
+ qualifierList.push_back(qual);
+ }
+ }
+ yyval.interm.intermTypedNode->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->fConst = 0.0;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), yyvsp[0].interm.line);
+ parseContext.recover();
+ }
+ }
+ delete fnCall;
+ ;
+ break;}
+case 15:
+#line 585 "glslang.y"
+{
+ yyval.interm = yyvsp[-1].interm;
+ yyval.interm.line = yyvsp[0].lex.line;
+ ;
+ break;}
+case 16:
+#line 589 "glslang.y"
+{
+ yyval.interm = yyvsp[-1].interm;
+ yyval.interm.line = yyvsp[0].lex.line;
+ ;
+ break;}
+case 17:
+#line 596 "glslang.y"
+{
+ yyval.interm.function = yyvsp[-1].interm.function;
+ yyval.interm.intermNode = 0;
+ ;
+ break;}
+case 18:
+#line 600 "glslang.y"
+{
+ yyval.interm.function = yyvsp[0].interm.function;
+ yyval.interm.intermNode = 0;
+ ;
+ break;}
+case 19:
+#line 607 "glslang.y"
+{
+ TParameter param = { 0, new TType(yyvsp[0].interm.intermTypedNode->getType()) };
+ yyvsp[-1].interm.function->addParameter(param);
+ yyval.interm.function = yyvsp[-1].interm.function;
+ yyval.interm.intermNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 20:
+#line 613 "glslang.y"
+{
+ TParameter param = { 0, new TType(yyvsp[0].interm.intermTypedNode->getType()) };
+ yyvsp[-2].interm.function->addParameter(param);
+ yyval.interm.function = yyvsp[-2].interm.function;
+ yyval.interm.intermNode = parseContext.intermediate.growAggregate(yyvsp[-2].interm.intermNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line);
+ ;
+ break;}
+case 21:
+#line 622 "glslang.y"
+{
+ yyval.interm.function = yyvsp[-1].interm.function;
+ ;
+ break;}
+case 22:
+#line 628 "glslang.y"
+{
+ if (yyvsp[0].interm.op == EOpConstructStruct) {
+ TString tempString = "";
+ TFunction *function = new TFunction(&tempString, *(yyvsp[0].interm.type.userDef), yyvsp[0].interm.op);
+ yyval.interm.function = function;
+ }
+ else {
+ TFunction *function = new TFunction(yyvsp[0].interm.op);
+ yyval.interm.function = function;
+ }
+ ;
+ break;}
+case 23:
+#line 639 "glslang.y"
+{
+ if (parseContext.reservedErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string))
+ parseContext.recover();
+ TFunction *function = new TFunction(yyvsp[0].lex.string, TType(EbtVoid));
+ yyval.interm.function = function;
+ ;
+ break;}
+case 24:
+#line 654 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructFloat; ;
+ break;}
+case 25:
+#line 655 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructInt; ;
+ break;}
+case 26:
+#line 656 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBool; ;
+ break;}
+case 27:
+#line 657 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructVec2; ;
+ break;}
+case 28:
+#line 658 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructVec3; ;
+ break;}
+case 29:
+#line 659 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructVec4; ;
+ break;}
+case 30:
+#line 660 "glslang.y"
+{ FRAG_VERT_ONLY("bvec2", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBVec2; ;
+ break;}
+case 31:
+#line 661 "glslang.y"
+{ FRAG_VERT_ONLY("bvec3", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBVec3; ;
+ break;}
+case 32:
+#line 662 "glslang.y"
+{ FRAG_VERT_ONLY("bvec4", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBVec4; ;
+ break;}
+case 33:
+#line 663 "glslang.y"
+{ FRAG_VERT_ONLY("ivec2", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructIVec2; ;
+ break;}
+case 34:
+#line 664 "glslang.y"
+{ FRAG_VERT_ONLY("ivec3", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructIVec3; ;
+ break;}
+case 35:
+#line 665 "glslang.y"
+{ FRAG_VERT_ONLY("ivec4", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructIVec4; ;
+ break;}
+case 36:
+#line 666 "glslang.y"
+{ FRAG_VERT_ONLY("mat2", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructMat2; ;
+ break;}
+case 37:
+#line 667 "glslang.y"
+{ FRAG_VERT_ONLY("mat3", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructMat3; ;
+ break;}
+case 38:
+#line 668 "glslang.y"
+{ FRAG_VERT_ONLY("mat4", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructMat4; ;
+ break;}
+case 39:
+#line 669 "glslang.y"
+{
+ TType& structure = static_cast<TVariable*>(yyvsp[0].lex.symbol)->getType();
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtStruct, qual, 1, false, false, &structure, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ yyval.interm.line = yyvsp[0].lex.line;
+ yyval.interm.op = EOpConstructStruct;
+ ;
+ break;}
+case 40:
+#line 680 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 41:
+#line 683 "glslang.y"
+{
+ if (parseContext.lValueErrorCheck(yyvsp[-1].lex.line, "++", yyvsp[0].interm.intermTypedNode))
+ parseContext.recover();
+ yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPreIncrement, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.unaryOpError(yyvsp[-1].lex.line, "++", yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 42:
+#line 693 "glslang.y"
+{
+ if (parseContext.lValueErrorCheck(yyvsp[-1].lex.line, "--", yyvsp[0].interm.intermTypedNode))
+ parseContext.recover();
+ yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPreDecrement, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.unaryOpError(yyvsp[-1].lex.line, "--", yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 43:
+#line 703 "glslang.y"
+{
+ if (yyvsp[-1].interm.op != EOpNull) {
+ yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(yyvsp[-1].interm.op, yyvsp[0].interm.intermTypedNode, yyvsp[-1].interm.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ char* errorOp = "";
+ switch(yyvsp[-1].interm.op) {
+ case EOpNegative: errorOp = "-"; break;
+ case EOpLogicalNot: errorOp = "!"; break;
+ case EOpBitwiseNot: errorOp = "~"; break;
+ default: break;
+ }
+ parseContext.unaryOpError(yyvsp[-1].interm.line, errorOp, yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ }
+ } else
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 44:
+#line 725 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpNull; ;
+ break;}
+case 45:
+#line 726 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpNegative; ;
+ break;}
+case 46:
+#line 727 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpLogicalNot; ;
+ break;}
+case 47:
+#line 728 "glslang.y"
+{ PACK_UNPACK_ONLY("~", yyvsp[0].lex.line);
+ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpBitwiseNot; ;
+ break;}
+case 48:
+#line 734 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 49:
+#line 735 "glslang.y"
+{
+ FRAG_VERT_ONLY("*", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpMul, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "*", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 50:
+#line 744 "glslang.y"
+{
+ FRAG_VERT_ONLY("/", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpDiv, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "/", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 51:
+#line 753 "glslang.y"
+{
+ PACK_UNPACK_ONLY("%", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpMod, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "%", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 52:
+#line 765 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 53:
+#line 766 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpAdd, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "+", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 54:
+#line 774 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpSub, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "-", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 55:
+#line 785 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 56:
+#line 786 "glslang.y"
+{
+ PACK_UNPACK_ONLY("<<", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLeftShift, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "<<", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 57:
+#line 795 "glslang.y"
+{
+ PACK_UNPACK_ONLY(">>", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpRightShift, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, ">>", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 58:
+#line 807 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 59:
+#line 808 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLessThan, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "<", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 60:
+#line 818 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpGreaterThan, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, ">", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 61:
+#line 828 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "<=", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 62:
+#line 838 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, ">=", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 63:
+#line 851 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 64:
+#line 852 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "==", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 65:
+#line 862 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpNotEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "!=", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 66:
+#line 875 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 67:
+#line 876 "glslang.y"
+{
+ PACK_UNPACK_ONLY("&", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpAnd, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "&", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 68:
+#line 888 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 69:
+#line 889 "glslang.y"
+{
+ PACK_UNPACK_ONLY("^", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "^", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 70:
+#line 901 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 71:
+#line 902 "glslang.y"
+{
+ PACK_UNPACK_ONLY("|", yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "|", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 72:
+#line 914 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 73:
+#line 915 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "&&", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 74:
+#line 928 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 75:
+#line 929 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLogicalXor, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "^^", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 76:
+#line 942 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 77:
+#line 943 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLogicalOr, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-1].lex.line, "||", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ constUnion *unionArray = new constUnion[1];
+ unionArray->bConst = false;
+ yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line);
+ }
+ ;
+ break;}
+case 78:
+#line 956 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 79:
+#line 957 "glslang.y"
+{
+ if (parseContext.boolErrorCheck(yyvsp[-3].lex.line, yyvsp[-4].interm.intermTypedNode))
+ parseContext.recover();
+
+ yyval.interm.intermTypedNode = parseContext.intermediate.addSelection(yyvsp[-4].interm.intermTypedNode, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-3].lex.line);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.binaryOpError(yyvsp[-3].lex.line, ":", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 80:
+#line 971 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 81:
+#line 972 "glslang.y"
+{
+ if (parseContext.lValueErrorCheck(yyvsp[-1].interm.line, "assign", yyvsp[-2].interm.intermTypedNode))
+ parseContext.recover();
+ yyval.interm.intermTypedNode = parseContext.intermediate.addAssign(yyvsp[-1].interm.op, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].interm.line);
+ if (yyval.interm.intermTypedNode == 0) {
+ parseContext.assignError(yyvsp[-1].interm.line, "assign", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString());
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode;
+ }
+ ;
+ break;}
+case 82:
+#line 985 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpAssign; ;
+ break;}
+case 83:
+#line 986 "glslang.y"
+{ FRAG_VERT_ONLY("*=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpMulAssign; ;
+ break;}
+case 84:
+#line 987 "glslang.y"
+{ FRAG_VERT_ONLY("/=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpDivAssign; ;
+ break;}
+case 85:
+#line 988 "glslang.y"
+{ PACK_UNPACK_ONLY("%=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpModAssign; ;
+ break;}
+case 86:
+#line 989 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpAddAssign; ;
+ break;}
+case 87:
+#line 990 "glslang.y"
+{ yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpSubAssign; ;
+ break;}
+case 88:
+#line 991 "glslang.y"
+{ PACK_UNPACK_ONLY("<<=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpLeftShiftAssign; ;
+ break;}
+case 89:
+#line 992 "glslang.y"
+{ PACK_UNPACK_ONLY("<<=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpRightShiftAssign; ;
+ break;}
+case 90:
+#line 993 "glslang.y"
+{ PACK_UNPACK_ONLY("&=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpAndAssign; ;
+ break;}
+case 91:
+#line 994 "glslang.y"
+{ PACK_UNPACK_ONLY("^=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpExclusiveOrAssign; ;
+ break;}
+case 92:
+#line 995 "glslang.y"
+{ PACK_UNPACK_ONLY("|=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpInclusiveOrAssign; ;
+ break;}
+case 93:
+#line 999 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 94:
+#line 1002 "glslang.y"
+{
+ yyval.interm.intermTypedNode = parseContext.intermediate.growAggregate(yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line);
+ yyval.interm.intermTypedNode->getAsAggregate()->setOperator(EOpComma);
+ yyval.interm.intermTypedNode->setType(yyvsp[0].interm.intermTypedNode->getType());
+ ;
+ break;}
+case 95:
+#line 1010 "glslang.y"
+{
+ if (parseContext.constErrorCheck(yyvsp[0].interm.intermTypedNode))
+ parseContext.recover();
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 96:
+#line 1018 "glslang.y"
+{ yyval.interm.intermNode = 0; ;
+ break;}
+case 97:
+#line 1019 "glslang.y"
+{
+ if (yyvsp[-1].interm.intermAggregate)
+ yyvsp[-1].interm.intermAggregate->setOperator(EOpSequence);
+ yyval.interm.intermNode = yyvsp[-1].interm.intermAggregate;
+ ;
+ break;}
+case 98:
+#line 1027 "glslang.y"
+{
+ //
+ // 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(yyvsp[-1].interm.function->getMangledName()));
+ if (prevDec) {
+ if (prevDec->getReturnType() != yyvsp[-1].interm.function->getReturnType()) {
+ parseContext.error(yyvsp[0].lex.line, "overloaded functions must have the same return type", yyvsp[-1].interm.function->getReturnType().getBasicString(), "");
+ parseContext.recover();
+ }
+ for (int i = 0; i < prevDec->getParamCount(); ++i) {
+ if ((*prevDec)[i].type->getQualifier() != (*yyvsp[-1].interm.function)[i].type->getQualifier()) {
+ parseContext.error(yyvsp[0].lex.line, "overloaded functions must have the same parameter qualifiers", (*yyvsp[-1].interm.function)[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.
+ //
+ yyval.interm.function = yyvsp[-1].interm.function;
+ yyval.interm.line = yyvsp[0].lex.line;
+
+ parseContext.symbolTable.insert(*yyval.interm.function);
+ ;
+ break;}
+case 99:
+#line 1063 "glslang.y"
+{
+ yyval.interm.function = yyvsp[0].interm.function;
+ ;
+ break;}
+case 100:
+#line 1066 "glslang.y"
+{
+ yyval.interm.function = yyvsp[0].interm.function;
+ ;
+ break;}
+case 101:
+#line 1073 "glslang.y"
+{
+ // Add the parameter
+ yyval.interm.function = yyvsp[-1].interm.function;
+ if (yyvsp[0].interm.param.type->getBasicType() != EbtVoid)
+ yyvsp[-1].interm.function->addParameter(yyvsp[0].interm.param);
+ else
+ delete yyvsp[0].interm.param.type;
+ ;
+ break;}
+case 102:
+#line 1081 "glslang.y"
+{
+ //
+ // Only first parameter of one-parameter functions can be void
+ // The check for named parameters not being void is done in parameter_declarator
+ //
+ if (yyvsp[0].interm.param.type->getBasicType() == EbtVoid) {
+ //
+ // This parameter > first is void
+ //
+ parseContext.error(yyvsp[-1].lex.line, "cannot be an argument type except for '(void)'", "void", "");
+ parseContext.recover();
+ delete yyvsp[0].interm.param.type;
+ } else {
+ // Add the parameter
+ yyval.interm.function = yyvsp[-2].interm.function;
+ yyvsp[-2].interm.function->addParameter(yyvsp[0].interm.param);
+ }
+ ;
+ break;}
+case 103:
+#line 1102 "glslang.y"
+{
+ if (yyvsp[-2].interm.type.qualifier != EvqGlobal && yyvsp[-2].interm.type.qualifier != EvqTemporary) {
+ parseContext.error(yyvsp[-1].lex.line, "no qualifiers allowed for function return", getQualifierString(yyvsp[-2].interm.type.qualifier), "");
+ parseContext.recover();
+ }
+ // make sure a sampler is not involved as well...
+ if (parseContext.structQualifierErrorCheck(yyvsp[-1].lex.line, yyvsp[-2].interm.type))
+ parseContext.recover();
+
+ // Add the function as a prototype after parsing it (we do not support recursion)
+ TFunction *function;
+ function = new TFunction(yyvsp[-1].lex.string, TType(yyvsp[-2].interm.type));
+ yyval.interm.function = function;
+ ;
+ break;}
+case 104:
+#line 1120 "glslang.y"
+{
+ if (yyvsp[-1].interm.type.type == EbtVoid) {
+ parseContext.error(yyvsp[0].lex.line, "illegal use of type 'void'", yyvsp[0].lex.string->c_str(), "");
+ parseContext.recover();
+ }
+ if (parseContext.reservedErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string))
+ parseContext.recover();
+ TParameter param = {yyvsp[0].lex.string, new TType(yyvsp[-1].interm.type)};
+ yyval.interm.line = yyvsp[0].lex.line;
+ yyval.interm.param = param;
+ ;
+ break;}
+case 105:
+#line 1131 "glslang.y"
+{
+ // Check that we can make an array out of this type
+ if (yyvsp[-4].interm.type.array) {
+ parseContext.error(yyvsp[-2].lex.line, "cannot declare arrays of this type", TType(yyvsp[-4].interm.type).getCompleteString().c_str(), "");
+ parseContext.recover();
+ }
+ if (parseContext.reservedErrorCheck(yyvsp[-3].lex.line, *yyvsp[-3].lex.string))
+ parseContext.recover();
+ yyvsp[-4].interm.type.array = true;
+ TType* type = new TType(yyvsp[-4].interm.type);
+ if (yyvsp[-1].interm.intermTypedNode->getAsConstantUnion())
+ type->setArraySize(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst);
+ TParameter param = { yyvsp[-3].lex.string, type };
+ yyval.interm.line = yyvsp[-3].lex.line;
+ yyval.interm.param = param;
+ ;
+ break;}
+case 106:
+#line 1158 "glslang.y"
+{
+ yyval.interm = yyvsp[0].interm;
+ if (parseContext.paramErrorCheck(yyvsp[0].interm.line, yyvsp[-2].interm.type.qualifier, yyvsp[-1].interm.qualifier, yyval.interm.param.type))
+ parseContext.recover();
+ ;
+ break;}
+case 107:
+#line 1163 "glslang.y"
+{
+ yyval.interm = yyvsp[0].interm;
+ if (parseContext.parameterSamplerErrorCheck(yyvsp[0].interm.line, yyvsp[-1].interm.qualifier, *yyvsp[0].interm.param.type))
+ parseContext.recover();
+ if (parseContext.paramErrorCheck(yyvsp[0].interm.line, EvqTemporary, yyvsp[-1].interm.qualifier, yyval.interm.param.type))
+ parseContext.recover();
+ ;
+ break;}
+case 108:
+#line 1173 "glslang.y"
+{
+ yyval.interm = yyvsp[0].interm;
+ if (parseContext.paramErrorCheck(yyvsp[0].interm.line, yyvsp[-2].interm.type.qualifier, yyvsp[-1].interm.qualifier, yyval.interm.param.type))
+ parseContext.recover();
+ ;
+ break;}
+case 109:
+#line 1178 "glslang.y"
+{
+ yyval.interm = yyvsp[0].interm;
+ if (parseContext.parameterSamplerErrorCheck(yyvsp[0].interm.line, yyvsp[-1].interm.qualifier, *yyvsp[0].interm.param.type))
+ parseContext.recover();
+ if (parseContext.paramErrorCheck(yyvsp[0].interm.line, EvqTemporary, yyvsp[-1].interm.qualifier, yyval.interm.param.type))
+ parseContext.recover();
+ ;
+ break;}
+case 110:
+#line 1188 "glslang.y"
+{
+ yyval.interm.qualifier = EvqIn;
+ ;
+ break;}
+case 111:
+#line 1191 "glslang.y"
+{
+ yyval.interm.qualifier = EvqIn;
+ ;
+ break;}
+case 112:
+#line 1194 "glslang.y"
+{
+ yyval.interm.qualifier = EvqOut;
+ ;
+ break;}
+case 113:
+#line 1197 "glslang.y"
+{
+ yyval.interm.qualifier = EvqInOut;
+ ;
+ break;}
+case 114:
+#line 1203 "glslang.y"
+{
+ TParameter param = { 0, new TType(yyvsp[0].interm.type) };
+ yyval.interm.param = param;
+
+ ;
+ break;}
+case 115:
+#line 1208 "glslang.y"
+{
+ // Check that we can make an array out of this type
+ if (yyvsp[-3].interm.type.array) {
+ parseContext.error(yyvsp[-2].lex.line, "cannot declare arrays of this type", TType(yyvsp[-3].interm.type).getCompleteString().c_str(), "");
+ parseContext.recover();
+ }
+ yyvsp[-3].interm.type.array = true;
+ TType* type = new TType(yyvsp[-3].interm.type);
+ if (yyvsp[-1].interm.intermTypedNode->getAsConstantUnion())
+ type->setArraySize(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst);
+
+ TParameter param = { 0, type };
+ yyval.interm.line = yyvsp[-2].lex.line;
+ yyval.interm.param = param;
+ ;
+ break;}
+case 116:
+#line 1226 "glslang.y"
+{
+ yyval.interm = yyvsp[0].interm;
+ ;
+ break;}
+case 117:
+#line 1229 "glslang.y"
+{
+ yyval.interm = yyvsp[-2].interm;
+ if (parseContext.structQualifierErrorCheck(yyvsp[0].lex.line, yyvsp[-2].interm.type))
+ parseContext.recover();
+
+ if (parseContext.nonInitErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string, yyval.interm.type))
+ parseContext.recover();
+ ;
+ break;}
+case 118:
+#line 1237 "glslang.y"
+{
+ yyval.interm = yyvsp[-4].interm;
+ if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-4].interm.type))
+ parseContext.recover();
+
+ if (parseContext.arrayErrorCheck(yyvsp[-1].lex.line, *yyvsp[-2].lex.string, yyval.interm.type, 0))
+ parseContext.recover();
+ ;
+ break;}
+case 119:
+#line 1245 "glslang.y"
+{
+ yyval.interm = yyvsp[-5].interm;
+ if (parseContext.structQualifierErrorCheck(yyvsp[-3].lex.line, yyvsp[-5].interm.type))
+ parseContext.recover();
+
+ if (parseContext.arrayErrorCheck(yyvsp[-2].lex.line, *yyvsp[-3].lex.string, yyval.interm.type, yyvsp[-1].interm.intermTypedNode))
+ parseContext.recover();
+ ;
+ break;}
+case 120:
+#line 1253 "glslang.y"
+{
+ yyval.interm = yyvsp[-4].interm;
+ if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-4].interm.type))
+ parseContext.recover();
+
+ TIntermNode* intermNode;
+ if (!parseContext.executeInitializer(yyvsp[-2].lex.line, *yyvsp[-2].lex.string, yyvsp[-4].interm.type, yyvsp[0].interm.intermTypedNode, intermNode)) {
+ //
+ // build the intermediate representation
+ //
+ if (intermNode)
+ yyval.interm.intermAggregate = parseContext.intermediate.growAggregate(yyvsp[-4].interm.intermNode, intermNode, yyvsp[-1].lex.line);
+ else
+ yyval.interm.intermAggregate = yyvsp[-4].interm.intermAggregate;
+ } else {
+ parseContext.recover();
+ yyval.interm.intermAggregate = 0;
+ }
+ ;
+ break;}
+case 121:
+#line 1275 "glslang.y"
+{
+ yyval.interm.type = yyvsp[0].interm.type;
+ yyval.interm.intermAggregate = 0;
+ ;
+ break;}
+case 122:
+#line 1279 "glslang.y"
+{
+ yyval.interm.intermAggregate = 0;
+ yyval.interm.type = yyvsp[-1].interm.type;
+ if (parseContext.structQualifierErrorCheck(yyvsp[0].lex.line, yyvsp[-1].interm.type))
+ parseContext.recover();
+
+ if (parseContext.nonInitErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string, yyval.interm.type))
+ parseContext.recover();
+ ;
+ break;}
+case 123:
+#line 1288 "glslang.y"
+{
+ yyval.interm.intermAggregate = 0;
+ yyval.interm.type = yyvsp[-3].interm.type;
+ if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type))
+ parseContext.recover();
+
+ if (parseContext.arrayErrorCheck(yyvsp[-1].lex.line, *yyvsp[-2].lex.string, yyval.interm.type, 0))
+ parseContext.recover();
+ ;
+ break;}
+case 124:
+#line 1297 "glslang.y"
+{
+ yyval.interm.intermAggregate = 0;
+ yyval.interm.type = yyvsp[-4].interm.type;
+ if (parseContext.structQualifierErrorCheck(yyvsp[-3].lex.line, yyvsp[-4].interm.type))
+ parseContext.recover();
+
+ if (parseContext.arrayErrorCheck(yyvsp[-2].lex.line, *yyvsp[-3].lex.string, yyval.interm.type, yyvsp[-1].interm.intermTypedNode))
+ parseContext.recover();
+ ;
+ break;}
+case 125:
+#line 1306 "glslang.y"
+{
+ yyval.interm.type = yyvsp[-3].interm.type;
+ if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type))
+ parseContext.recover();
+
+ TIntermNode* intermNode;
+ if (!parseContext.executeInitializer(yyvsp[-2].lex.line, *yyvsp[-2].lex.string, yyvsp[-3].interm.type, yyvsp[0].interm.intermTypedNode, intermNode)) {
+ //
+ // Build intermediate representation
+ //
+ if (intermNode)
+ yyval.interm.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, yyvsp[-1].lex.line);
+ else
+ yyval.interm.intermAggregate = 0;
+ } else {
+ parseContext.recover();
+ yyval.interm.intermAggregate = 0;
+ }
+ ;
+ break;}
+case 126:
+#line 1396 "glslang.y"
+{
+ yyval.interm.type = yyvsp[0].interm.type;
+ ;
+ break;}
+case 127:
+#line 1399 "glslang.y"
+{
+ TPublicType t = { yyvsp[0].interm.type.type, yyvsp[-1].interm.type.qualifier, yyvsp[0].interm.type.size, yyvsp[0].interm.type.matrix, false, yyvsp[0].interm.type.userDef, 0 };
+ if (yyvsp[-1].interm.type.qualifier == EvqAttribute &&
+ (yyvsp[0].interm.type.type == EbtBool || yyvsp[0].interm.type.type == EbtInt)) {
+ parseContext.error(yyvsp[0].interm.type.line, "cannot be bool or int", getQualifierString(yyvsp[-1].interm.type.qualifier), "");
+ parseContext.recover();
+ }
+ if ((yyvsp[-1].interm.type.qualifier == EvqVaryingIn || yyvsp[-1].interm.type.qualifier == EvqVaryingOut) &&
+ (yyvsp[0].interm.type.type == EbtBool || yyvsp[0].interm.type.type == EbtInt)) {
+ parseContext.error(yyvsp[0].interm.type.line, "cannot be bool or int", getQualifierString(yyvsp[-1].interm.type.qualifier), "");
+ parseContext.recover();
+ }
+ yyval.interm.type = t;
+ ;
+ break;}
+case 128:
+#line 1416 "glslang.y"
+{
+ TPublicType t = { EbtVoid, EvqConst, 1, false, false, 0 };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 129:
+#line 1420 "glslang.y"
+{
+ VERTEX_ONLY("attribute", yyvsp[0].lex.line);
+ if (parseContext.globalErrorCheck(yyvsp[0].lex.line, parseContext.symbolTable.atGlobalLevel(), "attribute"))
+ parseContext.recover();
+ TPublicType t = { EbtVoid, EvqAttribute, 1, false, false, 0 };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 130:
+#line 1427 "glslang.y"
+{
+ if (parseContext.globalErrorCheck(yyvsp[0].lex.line, parseContext.symbolTable.atGlobalLevel(), "varying"))
+ parseContext.recover();
+ TPublicType t = { EbtVoid, EvqVaryingIn, 1, false, false, 0 };
+ if (parseContext.language == EShLangVertex)
+ t.qualifier = EvqVaryingOut;
+ yyval.interm.type = t;
+ ;
+ break;}
+case 131:
+#line 1435 "glslang.y"
+{
+ if (parseContext.globalErrorCheck(yyvsp[0].lex.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
+ parseContext.recover();
+ TPublicType t = { EbtVoid, EvqUniform, 1, false, false, 0 };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 132:
+#line 1444 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtVoid, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 133:
+#line 1449 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtFloat, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 134:
+#line 1454 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtInt, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 135:
+#line 1459 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtBool, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 136:
+#line 1470 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtFloat, qual, 2, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 137:
+#line 1475 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtFloat, qual, 3, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 138:
+#line 1480 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtFloat, qual, 4, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 139:
+#line 1485 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtBool, qual, 2, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 140:
+#line 1490 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtBool, qual, 3, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 141:
+#line 1495 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtBool, qual, 4, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 142:
+#line 1500 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtInt, qual, 2, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 143:
+#line 1505 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtInt, qual, 3, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 144:
+#line 1510 "glslang.y"
+{
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtInt, qual, 4, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 145:
+#line 1515 "glslang.y"
+{
+ FRAG_VERT_ONLY("mat2", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtFloat, qual, 2, true, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 146:
+#line 1521 "glslang.y"
+{
+ FRAG_VERT_ONLY("mat3", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtFloat, qual, 3, true, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 147:
+#line 1527 "glslang.y"
+{
+ FRAG_VERT_ONLY("mat4", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtFloat, qual, 4, true, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 148:
+#line 1533 "glslang.y"
+{
+ FRAG_VERT_ONLY("sampler1D", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtSampler1D, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 149:
+#line 1539 "glslang.y"
+{
+ FRAG_VERT_ONLY("sampler2D", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtSampler2D, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 150:
+#line 1545 "glslang.y"
+{
+ FRAG_VERT_ONLY("sampler3D", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtSampler3D, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 151:
+#line 1551 "glslang.y"
+{
+ FRAG_VERT_ONLY("samplerCube", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtSamplerCube, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 152:
+#line 1557 "glslang.y"
+{
+ FRAG_VERT_ONLY("sampler1DShadow", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtSampler1DShadow, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 153:
+#line 1563 "glslang.y"
+{
+ FRAG_VERT_ONLY("sampler2DShadow", yyvsp[0].lex.line);
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtSampler2DShadow, qual, 1, false, false, 0, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 154:
+#line 1569 "glslang.y"
+{
+ FRAG_VERT_ONLY("struct", yyvsp[0].interm.type.line);
+ yyval.interm.type = yyvsp[0].interm.type;
+ yyval.interm.type.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ ;
+ break;}
+case 155:
+#line 1574 "glslang.y"
+{
+ //
+ // This is for user defined type names. The lexical phase looked up the
+ // type.
+ //
+ TType& structure = static_cast<TVariable*>(yyvsp[0].lex.symbol)->getType();
+ TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TPublicType t = { EbtStruct, qual, 1, false, false, &structure, yyvsp[0].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 156:
+#line 1587 "glslang.y"
+{
+ TType* structure = new TType(yyvsp[-1].interm.typeList, *yyvsp[-3].lex.string);
+ TVariable* userTypeDef = new TVariable(yyvsp[-3].lex.string, *structure, true);
+ if (! parseContext.symbolTable.insert(*userTypeDef)) {
+ parseContext.error(yyvsp[-3].lex.line, "redefinition", yyvsp[-3].lex.string->c_str(), "struct");
+ parseContext.recover();
+ }
+ TPublicType t = { EbtStruct, EvqTemporary, 1, false, false, structure, yyvsp[-4].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 157:
+#line 1597 "glslang.y"
+{
+ TType* structure = new TType(yyvsp[-1].interm.typeList, TString(""));
+ TPublicType t = { EbtStruct, EvqTemporary, 1, false, false, structure, yyvsp[-3].lex.line };
+ yyval.interm.type = t;
+ ;
+ break;}
+case 158:
+#line 1605 "glslang.y"
+{
+ yyval.interm.typeList = yyvsp[0].interm.typeList;
+ ;
+ break;}
+case 159:
+#line 1608 "glslang.y"
+{
+ yyval.interm.typeList = yyvsp[-1].interm.typeList;
+ for (unsigned int i = 0; i < yyvsp[0].interm.typeList->size(); ++i) {
+ for (unsigned int j = 0; j < yyval.interm.typeList->size(); ++j) {
+ if ((*yyval.interm.typeList)[j].type->getFieldName() == (*yyvsp[0].interm.typeList)[i].type->getFieldName()) {
+ parseContext.error((*yyvsp[0].interm.typeList)[i].line, "duplicate field name in structure:", "struct", (*yyvsp[0].interm.typeList)[i].type->getFieldName().c_str());
+ parseContext.recover();
+ }
+ }
+ yyval.interm.typeList->push_back((*yyvsp[0].interm.typeList)[i]);
+ }
+ ;
+ break;}
+case 160:
+#line 1623 "glslang.y"
+{
+ yyval.interm.typeList = yyvsp[-1].interm.typeList;
+
+ if (parseContext.voidErrorCheck(yyvsp[-2].interm.type.line, (*yyvsp[-1].interm.typeList)[0].type->getFieldName(), yyvsp[-2].interm.type)) {
+ parseContext.recover();
+ }
+ for (unsigned int i = 0; i < yyval.interm.typeList->size(); ++i) {
+ //
+ // Careful not to replace already know aspects of type, like array-ness
+ //
+ (*yyval.interm.typeList)[i].type->setType(yyvsp[-2].interm.type.type, yyvsp[-2].interm.type.size, yyvsp[-2].interm.type.matrix, yyvsp[-2].interm.type.userDef);
+ if (yyvsp[-2].interm.type.userDef)
+ (*yyval.interm.typeList)[i].type->setTypeName(yyvsp[-2].interm.type.userDef->getTypeName());
+ }
+ ;
+ break;}
+case 161:
+#line 1641 "glslang.y"
+{
+ yyval.interm.typeList = NewPoolTTypeList();
+ yyval.interm.typeList->push_back(yyvsp[0].interm.typeLine);
+ ;
+ break;}
+case 162:
+#line 1645 "glslang.y"
+{
+ yyval.interm.typeList->push_back(yyvsp[0].interm.typeLine);
+ ;
+ break;}
+case 163:
+#line 1651 "glslang.y"
+{
+ yyval.interm.typeLine.type = new TType(EbtVoid);
+ yyval.interm.typeLine.line = yyvsp[0].lex.line;
+ yyval.interm.typeLine.type->setFieldName(*yyvsp[0].lex.string);
+ ;
+ break;}
+case 164:
+#line 1656 "glslang.y"
+{
+ yyval.interm.typeLine.type = new TType(EbtVoid);
+ yyval.interm.typeLine.line = yyvsp[-3].lex.line;
+ yyval.interm.typeLine.type->setFieldName(*yyvsp[-3].lex.string);
+
+ if (yyvsp[-1].interm.intermTypedNode->getAsConstantUnion() == 0 || yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getBasicType() != EbtInt ||
+ yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst <= 0) {
+ parseContext.error(yyvsp[-2].lex.line, "structure field array size must be a positive integer", yyvsp[-3].lex.string->c_str(), "");
+ parseContext.recover();
+ } else {
+ yyval.interm.typeLine.type->setArraySize(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst);
+ }
+ ;
+ break;}
+case 165:
+#line 1672 "glslang.y"
+{ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;
+ break;}
+case 166:
+#line 1676 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 167:
+#line 1680 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermAggregate; ;
+ break;}
+case 168:
+#line 1681 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 169:
+#line 1687 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 170:
+#line 1688 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 171:
+#line 1689 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 172:
+#line 1690 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 173:
+#line 1691 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 174:
+#line 1695 "glslang.y"
+{ yyval.interm.intermAggregate = 0; ;
+ break;}
+case 175:
+#line 1696 "glslang.y"
+{ parseContext.symbolTable.push(); ;
+ break;}
+case 176:
+#line 1696 "glslang.y"
+{ parseContext.symbolTable.pop(); ;
+ break;}
+case 177:
+#line 1696 "glslang.y"
+{
+ if (yyvsp[-2].interm.intermAggregate != 0)
+ yyvsp[-2].interm.intermAggregate->setOperator(EOpSequence);
+ yyval.interm.intermAggregate = yyvsp[-2].interm.intermAggregate;
+ ;
+ break;}
+case 178:
+#line 1704 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 179:
+#line 1705 "glslang.y"
+{ yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;
+ break;}
+case 180:
+#line 1710 "glslang.y"
+{
+ yyval.interm.intermNode = 0;
+ ;
+ break;}
+case 181:
+#line 1713 "glslang.y"
+{
+ if (yyvsp[-1].interm.intermAggregate)
+ yyvsp[-1].interm.intermAggregate->setOperator(EOpSequence);
+ yyval.interm.intermNode = yyvsp[-1].interm.intermAggregate;
+ ;
+ break;}
+case 182:
+#line 1721 "glslang.y"
+{
+ yyval.interm.intermAggregate = parseContext.intermediate.makeAggregate(yyvsp[0].interm.intermNode, 0);
+ ;
+ break;}
+case 183:
+#line 1724 "glslang.y"
+{
+ yyval.interm.intermAggregate = parseContext.intermediate.growAggregate(yyvsp[-1].interm.intermAggregate, yyvsp[0].interm.intermNode, 0);
+ ;
+ break;}
+case 184:
+#line 1730 "glslang.y"
+{ yyval.interm.intermNode = 0; ;
+ break;}
+case 185:
+#line 1731 "glslang.y"
+{ yyval.interm.intermNode = static_cast<TIntermNode*>(yyvsp[-1].interm.intermTypedNode); ;
+ break;}
+case 186:
+#line 1735 "glslang.y"
+{
+ if (parseContext.boolErrorCheck(yyvsp[-4].lex.line, yyvsp[-2].interm.intermTypedNode))
+ parseContext.recover();
+ yyval.interm.intermNode = parseContext.intermediate.addSelection(yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.nodePair, yyvsp[-4].lex.line);
+ ;
+ break;}
+case 187:
+#line 1743 "glslang.y"
+{
+ yyval.interm.nodePair.node1 = yyvsp[-2].interm.intermNode;
+ yyval.interm.nodePair.node2 = yyvsp[0].interm.intermNode;
+ ;
+ break;}
+case 188:
+#line 1747 "glslang.y"
+{
+ yyval.interm.nodePair.node1 = yyvsp[0].interm.intermNode;
+ yyval.interm.nodePair.node2 = 0;
+ ;
+ break;}
+case 189:
+#line 1757 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ if (parseContext.boolErrorCheck(yyvsp[0].interm.intermTypedNode->getLine(), yyvsp[0].interm.intermTypedNode))
+ parseContext.recover();
+ ;
+ break;}
+case 190:
+#line 1762 "glslang.y"
+{
+ TIntermNode* intermNode;
+ if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type))
+ parseContext.recover();
+ if (parseContext.boolErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type))
+ parseContext.recover();
+
+ if (!parseContext.executeInitializer(yyvsp[-2].lex.line, *yyvsp[-2].lex.string, yyvsp[-3].interm.type, yyvsp[0].interm.intermTypedNode, intermNode))
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ else {
+ parseContext.recover();
+ yyval.interm.intermTypedNode = 0;
+ }
+ ;
+ break;}
+case 191:
+#line 1779 "glslang.y"
+{ parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ;
+ break;}
+case 192:
+#line 1779 "glslang.y"
+{
+ parseContext.symbolTable.pop();
+ yyval.interm.intermNode = parseContext.intermediate.addLoop(yyvsp[0].interm.intermNode, yyvsp[-2].interm.intermTypedNode, 0, true, yyvsp[-5].lex.line);
+ --parseContext.loopNestingLevel;
+ ;
+ break;}
+case 193:
+#line 1784 "glslang.y"
+{ ++parseContext.loopNestingLevel; ;
+ break;}
+case 194:
+#line 1784 "glslang.y"
+{
+ if (parseContext.boolErrorCheck(yyvsp[0].lex.line, yyvsp[-2].interm.intermTypedNode))
+ parseContext.recover();
+
+ yyval.interm.intermNode = parseContext.intermediate.addLoop(yyvsp[-5].interm.intermNode, yyvsp[-2].interm.intermTypedNode, 0, false, yyvsp[-4].lex.line);
+ --parseContext.loopNestingLevel;
+ ;
+ break;}
+case 195:
+#line 1791 "glslang.y"
+{ parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ;
+ break;}
+case 196:
+#line 1791 "glslang.y"
+{
+ parseContext.symbolTable.pop();
+ yyval.interm.intermNode = parseContext.intermediate.makeAggregate(yyvsp[-3].interm.intermNode, yyvsp[-5].lex.line);
+ yyval.interm.intermNode = parseContext.intermediate.growAggregate(
+ yyval.interm.intermNode,
+ parseContext.intermediate.addLoop(yyvsp[0].interm.intermNode, reinterpret_cast<TIntermTyped*>(yyvsp[-2].interm.nodePair.node1), reinterpret_cast<TIntermTyped*>(yyvsp[-2].interm.nodePair.node2), true, yyvsp[-6].lex.line),
+ yyvsp[-6].lex.line);
+ yyval.interm.intermNode->getAsAggregate()->setOperator(EOpSequence);
+ --parseContext.loopNestingLevel;
+ ;
+ break;}
+case 197:
+#line 1804 "glslang.y"
+{
+ yyval.interm.intermNode = yyvsp[0].interm.intermNode;
+ ;
+ break;}
+case 198:
+#line 1807 "glslang.y"
+{
+ yyval.interm.intermNode = yyvsp[0].interm.intermNode;
+ ;
+ break;}
+case 199:
+#line 1813 "glslang.y"
+{
+ yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 200:
+#line 1816 "glslang.y"
+{
+ yyval.interm.intermTypedNode = 0;
+ ;
+ break;}
+case 201:
+#line 1822 "glslang.y"
+{
+ yyval.interm.nodePair.node1 = yyvsp[-1].interm.intermTypedNode;
+ yyval.interm.nodePair.node2 = 0;
+ ;
+ break;}
+case 202:
+#line 1826 "glslang.y"
+{
+ yyval.interm.nodePair.node1 = yyvsp[-2].interm.intermTypedNode;
+ yyval.interm.nodePair.node2 = yyvsp[0].interm.intermTypedNode;
+ ;
+ break;}
+case 203:
+#line 1833 "glslang.y"
+{
+ if (parseContext.loopNestingLevel <= 0) {
+ parseContext.error(yyvsp[-1].lex.line, "continue statement only allowed in loops", "", "");
+ parseContext.recover();
+ }
+ yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpContinue, yyvsp[-1].lex.line);
+ ;
+ break;}
+case 204:
+#line 1840 "glslang.y"
+{
+ if (parseContext.loopNestingLevel <= 0) {
+ parseContext.error(yyvsp[-1].lex.line, "break statement only allowed in loops", "", "");
+ parseContext.recover();
+ }
+ yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpBreak, yyvsp[-1].lex.line);
+ ;
+ break;}
+case 205:
+#line 1847 "glslang.y"
+{
+ yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpReturn, yyvsp[-1].lex.line);
+ if (parseContext.currentFunctionType->getBasicType() != EbtVoid) {
+ parseContext.error(yyvsp[-1].lex.line, "non-void function must return a value", "return", "");
+ parseContext.recover();
+ }
+ ;
+ break;}
+case 206:
+#line 1854 "glslang.y"
+{
+ yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpReturn, yyvsp[-1].interm.intermTypedNode, yyvsp[-2].lex.line);
+ parseContext.functionReturnsValue = true;
+ if (parseContext.currentFunctionType->getBasicType() == EbtVoid) {
+ parseContext.error(yyvsp[-2].lex.line, "void function cannot return a value", "return", "");
+ parseContext.recover();
+ } else if (*(parseContext.currentFunctionType) != yyvsp[-1].interm.intermTypedNode->getType()) {
+ parseContext.error(yyvsp[-2].lex.line, "function return is not matching type:", "return", "");
+ parseContext.recover();
+ }
+ ;
+ break;}
+case 207:
+#line 1865 "glslang.y"
+{
+ FRAG_ONLY("discard", yyvsp[-1].lex.line);
+ yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpKill, yyvsp[-1].lex.line);
+ ;
+ break;}
+case 208:
+#line 1874 "glslang.y"
+{
+ yyval.interm.intermNode = yyvsp[0].interm.intermNode;
+ parseContext.treeRoot = yyval.interm.intermNode;
+ ;
+ break;}
+case 209:
+#line 1878 "glslang.y"
+{
+ yyval.interm.intermNode = parseContext.intermediate.growAggregate(yyvsp[-1].interm.intermNode, yyvsp[0].interm.intermNode, 0);
+ parseContext.treeRoot = yyval.interm.intermNode;
+ ;
+ break;}
+case 210:
+#line 1885 "glslang.y"
+{
+ yyval.interm.intermNode = yyvsp[0].interm.intermNode;
+ ;
+ break;}
+case 211:
+#line 1888 "glslang.y"
+{
+ yyval.interm.intermNode = yyvsp[0].interm.intermNode;
+ ;
+ break;}
+case 212:
+#line 1894 "glslang.y"
+{
+ TFunction& function = *(yyvsp[0].interm.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(yyvsp[0].interm.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(yyvsp[0].interm.line, "function cannot take any parameter(s)", function.getName().c_str(), "");
+ parseContext.recover();
+ }
+ if (function.getReturnType().getBasicType() != EbtVoid) {
+ parseContext.error(yyvsp[0].interm.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(yyvsp[0].interm.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(), yyvsp[0].interm.line),
+ yyvsp[0].interm.line);
+ } else {
+ paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, yyvsp[0].interm.line), yyvsp[0].interm.line);
+ }
+ }
+ parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, yyvsp[0].interm.line);
+ yyvsp[0].interm.intermAggregate = paramNodes;
+ parseContext.loopNestingLevel = 0;
+ ;
+ break;}
+case 213:
+#line 1979 "glslang.y"
+{
+ //?? 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(yyvsp[-2].interm.line, "function does not return a value:", "", yyvsp[-2].interm.function->getName().c_str());
+ parseContext.recover();
+ }
+ parseContext.symbolTable.pop();
+ yyval.interm.intermNode = parseContext.intermediate.growAggregate(yyvsp[-2].interm.intermAggregate, yyvsp[0].interm.intermNode, 0);
+ parseContext.intermediate.setAggregateOperator(yyval.interm.intermNode, EOpFunction, yyvsp[-2].interm.line);
+ yyval.interm.intermNode->getAsAggregate()->setName(yyvsp[-2].interm.function->getMangledName().c_str());
+ yyval.interm.intermNode->getAsAggregate()->setType(yyvsp[-2].interm.function->getReturnType());
+ ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("parse error");
+ }
+
+ goto yyerrlab1;
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+}
+#line 1994 "glslang.y"
+
diff --git a/src/mesa/shader/slang/MachineIndependent/InfoSink.cpp b/src/mesa/shader/slang/MachineIndependent/InfoSink.cpp
new file mode 100755
index 0000000000..6b1b59149f
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/InfoSink.cpp
@@ -0,0 +1,107 @@
+//
+//Copyright (C) 2002-2004 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(1);
+ 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/src/mesa/shader/slang/MachineIndependent/Initialize.cpp b/src/mesa/shader/slang/MachineIndependent/Initialize.cpp
new file mode 100755
index 0000000000..24b9f0055f
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/Initialize.cpp
@@ -0,0 +1,868 @@
+//
+//Copyright (C) 2002-2004 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"
+#include <assert.h>
+
+void TBuiltIns::initialize(TBuiltInResource &resources)
+{
+ //
+ // 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 texture1D(sampler1D sampler, float coord, float bias);"));
+ s.append(TString("vec4 texture1DProj(sampler1D sampler, vec2 coord);"));
+ s.append(TString("vec4 texture1DProj(sampler1D sampler, vec2 coord, float bias);"));
+ s.append(TString("vec4 texture1DProj(sampler1D sampler, vec4 coord);"));
+ s.append(TString("vec4 texture1DProj(sampler1D sampler, vec4 coord, float bias);"));
+ 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 texture2D(sampler2D sampler, vec2 coord);"));
+ s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
+ 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 texture3D(sampler3D sampler, vec3 coord);"));
+ s.append(TString("vec4 texture3D(sampler3D sampler, vec3 coord, float bias);"));
+ s.append(TString("vec4 texture3DProj(sampler3D sampler, vec4 coord);"));
+ s.append(TString("vec4 texture3DProj(sampler3D sampler, vec4 coord, float bias);"));
+ 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 textureCube(samplerCube sampler, vec3 coord);"));
+ s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
+ s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+
+ s.append(TString("vec4 shadow1D(sampler1DShadow sampler, vec3 coord);"));
+ s.append(TString("vec4 shadow1D(sampler1DShadow sampler, vec3 coord, float bias);"));
+
+ s.append(TString("vec4 shadow2D(sampler2DShadow sampler, vec3 coord);"));
+ s.append(TString("vec4 shadow2D(sampler2DShadow sampler, vec3 coord, float bias);"));
+
+ s.append(TString("vec4 shadow1DProj(sampler1DShadow sampler, vec4 coord);"));
+ s.append(TString("vec4 shadow1DProj(sampler1DShadow sampler, vec4 coord, float bias);"));
+
+ s.append(TString("vec4 shadow2DProj(sampler2DShadow sampler, vec4 coord);"));
+ s.append(TString("vec4 shadow2DProj(sampler2DShadow sampler, vec4 coord, float bias);"));
+
+ 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);"));
+
+ //
+ // 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();"));
+
+ s.append(TString("\n"));
+ }
+ {
+ //============================================================================
+ //
+ // Prototypes for built-in functions seen by fragment shaders only.
+ //
+ //============================================================================
+
+ TString& s = BuiltInFunctionsFragment;
+
+ 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;
+
+ //
+ // 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_ModelViewMatrix;"));
+ s.append(TString("uniform mat4 gl_ProjectionMatrix;"));
+ s.append(TString("uniform mat4 gl_ModelViewProjectionMatrix;"));
+ 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 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_TextureMatrixInverse[gl_MaxTextureCoords];"));
+
+ 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_TextureMatrixTranspose[gl_MaxTextureCoords];"));
+
+ s.append(TString("uniform mat4 gl_ModelViewMatrixInverseTranspose;"));
+ s.append(TString("uniform mat4 gl_ProjectionMatrixInverseTranspose;"));
+ s.append(TString("uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;"));
+ s.append(TString("uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];"));
+
+ //
+ // 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;"));
+
+ //
+ // Clip planes p. 42.
+ //
+ s.append(TString("uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];"));
+
+ //
+ // 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("uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];"));
+
+ 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("};"));
+
+ 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];"));
+
+ //
+ // 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 IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, TBuiltInResource &resources)
+{
+ //
+ // 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)));
+
+ // 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;
+
+ 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 (true && "Language not supported");
+ }
+}
diff --git a/src/mesa/shader/slang/MachineIndependent/Initialize.h b/src/mesa/shader/slang/MachineIndependent/Initialize.h
new file mode 100755
index 0000000000..d06a3e2d5d
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/Initialize.h
@@ -0,0 +1,56 @@
+//
+//Copyright (C) 2002-2004 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(TBuiltInResource &resources);
+ TBuiltInStrings* getBuiltInStrings() { return builtInStrings; }
+protected:
+ TBuiltInStrings builtInStrings[EShLangCount];
+};
+
+void IdentifyBuiltIns(EShLanguage, TSymbolTable&, TBuiltInResource &resources);
+
+#endif // _INITIALIZE_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp b/src/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp
new file mode 100755
index 0000000000..5f2a730d73
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp
@@ -0,0 +1,243 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp b/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp
new file mode 100755
index 0000000000..f21e7b470f
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp
@@ -0,0 +1,2057 @@
+//
+//Copyright (C) 2002-2004 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 "../Include/ShHandle.h"
+#include "localintermediate.h"
+#include "QualifierAlive.h"
+#include "RemoveTree.h"
+#include <assert.h>
+#include <float.h>
+
+////////////////////////////////////////////////////////////////////////////
+//
+// 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 = copyConstUnion(left->getAsConstantUnion())->getAsConstantUnion();
+
+ if (rightTempConstant)
+ rightTempConstant = copyConstUnion(right->getAsConstantUnion())->getAsConstantUnion();
+
+ if (right->getType().getQualifier() == EvqConst && left->getType().getQualifier() == EvqConst) {
+ if (right->getAsAggregate()) {
+ rightTempConstant = changeAggrToTempConst(right->getAsAggregate(), symbolTable, line);
+ if (rightTempConstant->getUnionArrayPointer() == 0)
+ return 0;
+ }
+
+ if (left->getAsAggregate()) {
+ leftTempConstant = changeAggrToTempConst(left->getAsAggregate(), symbolTable, line);
+ if (leftTempConstant->getUnionArrayPointer() == 0)
+ return 0;
+ }
+ }
+
+ //
+ // See if we can fold constants.
+ //
+
+ TIntermTyped* typedReturnNode = 0;
+ if ( leftTempConstant && rightTempConstant) {
+ if (leftTempConstant->getSize() == 1 && rightTempConstant->getSize() > 1)
+ typedReturnNode = rightTempConstant->fold(node->getOp(), leftTempConstant, infoSink, false);
+ else
+ typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink, true);
+
+ if (typedReturnNode)
+ return typedReturnNode;
+ else {
+ node->setLeft(leftTempConstant);
+ node->setRight(rightTempConstant);
+ }
+ } else if (leftTempConstant) {
+ node->setLeft(copyConstUnion(leftTempConstant));
+ } else if (rightTempConstant) {
+ node->setRight(rightTempConstant);
+ }
+
+ 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);
+
+ if (right->getAsConstantUnion()) { // if the right node of assignment is a TempConstant node, allocate its own new space and remove the pointer to the symbol table value
+ right = copyConstUnion(right->getAsConstantUnion()) ;
+ if (right == 0)
+ return 0;
+ }
+
+ 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)
+ 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;
+ }
+
+ if (child->getAsConstantUnion())
+ child = copyConstUnion(child->getAsConstantUnion());
+
+ if (child->getAsAggregate() && child->getType().getQualifier() == EvqConst) {
+ child = changeAggrToTempConst(child->getAsAggregate(), symbolTable, line);
+ if (child->getAsConstantUnion()->getUnionArrayPointer() == 0)
+ return 0;
+ }
+
+ TIntermConstantUnion *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, true);
+
+ 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:
+ 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;
+
+ 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;
+ }
+
+ //
+ // Do conversion.
+ //
+ bool allConstant = true;
+ // check to see if there is an aggregate node
+ if (node->getAsAggregate()) {
+ TIntermSequence &sequenceVector = node->getAsAggregate()->getSequence() ;
+ for (TIntermSequence::iterator p = sequenceVector.begin();
+ p != sequenceVector.end(); p++) {
+ if (!(*p)->getAsTyped()->getAsConstantUnion())
+ allConstant = false;
+ }
+ }
+ if (allConstant && node->getAsAggregate()) { // we can do the constant folding here as all the nodes of the aggregate are const
+ TIntermSequence &sequenceVector = node->getAsAggregate()->getSequence() ;
+ for (TIntermSequence::iterator p = sequenceVector.begin();
+ p != sequenceVector.end(); p++) {
+ TIntermTyped* newNode = 0;
+ constUnion *unionArray = new constUnion[1];
+
+ switch (promoteTo) {
+ case EbtFloat:
+ switch ((*p)->getAsTyped()->getType().getBasicType()) {
+
+ case EbtInt:
+ unionArray->fConst = static_cast<float>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst);
+ newNode = addConstantUnion(unionArray, TType(EbtFloat, EvqConst), node->getLine()); break;
+ case EbtBool:
+ unionArray->fConst = static_cast<float>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst);
+ newNode = newNode = addConstantUnion(unionArray, TType(EbtFloat, EvqConst), node->getLine()); break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+ return 0;
+ }
+ break;
+ case EbtInt:
+ switch ((*p)->getAsTyped()->getType().getBasicType()) {
+ case EbtFloat:
+ unionArray->iConst = static_cast<int>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->fConst);
+ newNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), node->getLine());
+ break;
+ case EbtBool:
+ unionArray->iConst = static_cast<int>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst);
+ newNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), node->getLine());
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+ return 0;
+ }
+ break;
+ case EbtBool:
+ switch ((*p)->getAsTyped()->getType().getBasicType()) {
+ case EbtFloat:
+ unionArray->bConst = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->fConst != 0.0 ;
+ newNode = addConstantUnion(unionArray, TType(EbtBool, EvqConst), node->getLine());
+ break;
+ case EbtInt:
+ unionArray->bConst = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst != 0 ;
+ newNode = addConstantUnion(unionArray, TType(EbtBool, EvqConst), node->getLine());
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+ return 0;
+ }
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+ return 0;
+ }
+ if (newNode) {
+ sequenceVector.erase(p);
+ sequenceVector.insert(p, newNode);
+ }
+ }
+ return node->getAsAggregate();
+ } else 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;
+ }
+
+ newNode = new TIntermUnary(newOp, TType(promoteTo, EvqTemporary,
+ node->getNominalSize(),
+ node->isMatrix(),
+ node->isArray()));
+ 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()->bConst)
+ return nodePair.node1;
+ else
+ return nodePair.node2;
+ }
+
+ TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
+ node->setLine(line);
+
+ return node;
+}
+
+//
+// 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 condition is constant, and select now.
+ //
+
+ if (cond->getAsConstantUnion()) {
+ if (cond->getAsConstantUnion()->getUnionArrayPointer()->bConst)
+ 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->iConst = 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);
+
+ //
+ // Other things...
+ //
+
+ if (language == EShLangVertex && !QualifierWritten(root, EvqPosition)) {
+ infoSink.info.message(EPrefixError, "gl_Position must be written by all paths through a vertex shader.");
+ return false;
+ }
+
+ 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();
+
+ //
+ // Don't operate on arrays.
+ //
+ if (left->isArray() || right->isArray())
+ 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()));
+
+ //
+ // 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 compareStructure(TType leftNodeType, constUnion* rightUnionArray, constUnion* leftUnionArray, int& index)
+{
+ TTypeList* fields = leftNodeType.getStruct();
+
+ size_t structSize = fields->size();
+
+ for (size_t j = 0; j < structSize; j++) {
+ int size = (*fields)[j].type->getInstanceSize();
+ for (int i = 0; i < size; i++) {
+ switch ((*fields)[j].type->getBasicType()) {
+ case EbtFloat:
+ if (leftUnionArray[index].fConst != rightUnionArray[index].fConst)
+ return false;
+ index++;
+ break;
+ case EbtInt:
+ if (leftUnionArray[index].iConst != rightUnionArray[index].iConst)
+ return false;
+ index++;
+ break;
+ case EbtBool:
+ if (leftUnionArray[index].bConst != rightUnionArray[index].bConst)
+ return false;
+ index++;
+ break;
+ case EbtStruct:
+ if (!compareStructure(*(*fields)[j].type, rightUnionArray, leftUnionArray, index))
+ return false;
+ break;
+ default:
+ assert(true && "Cannot compare");
+ break;
+ }
+
+ }
+ }
+ 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, bool leftOperand)
+{
+ constUnion *unionArray = this->getUnionArrayPointer();
+
+ if (constantNode) {
+ if (constantNode->getAsConstantUnion() && constantNode->getSize() == 1 && constantNode->getType().getBasicType() != EbtStruct
+ && this->getSize() > 1) {
+ TIntermConstantUnion *node = constantNode->getAsConstantUnion();
+ TIntermConstantUnion *newNode;
+ constUnion* tempConstArray;
+ int i;
+ switch(op) {
+ case EOpAdd:
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst + node->getUnionArrayPointer()->fConst; break;
+ case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst + node->getUnionArrayPointer()->iConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"+\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+ case EOpMatrixTimesScalar:
+ case EOpVectorTimesScalar:
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst * node->getUnionArrayPointer()->fConst; break;
+ case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst * node->getUnionArrayPointer()->iConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"*\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+ case EOpSub:
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat:
+ if (leftOperand)
+ tempConstArray[i].fConst = unionArray[i].fConst - node->getUnionArrayPointer()->fConst;
+ else
+ tempConstArray[i].fConst = node->getUnionArrayPointer()->fConst - unionArray[i].fConst;
+ break;
+
+ case EbtInt:
+ if (leftOperand)
+ tempConstArray[i].iConst = unionArray[i].iConst - node->getUnionArrayPointer()->iConst;
+ else
+ tempConstArray[i].iConst = node->getUnionArrayPointer()->iConst - unionArray[i].iConst;
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"-\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpDiv:
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat:
+ if (leftOperand) {
+ if (node->getUnionArrayPointer()->fConst == 0.0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].fConst = FLT_MAX;
+ } else
+ tempConstArray[i].fConst = unionArray[i].fConst / node->getUnionArrayPointer()->fConst;
+ } else {
+ if (unionArray[i].fConst == 0.0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].fConst = FLT_MAX;
+ } else
+ tempConstArray[i].fConst = node->getUnionArrayPointer()->fConst / unionArray[i].fConst;
+ }
+ break;
+
+ case EbtInt:
+ if (leftOperand) {
+ if (node->getUnionArrayPointer()->iConst == 0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].iConst = INT_MAX;
+ } else
+ tempConstArray[i].iConst = unionArray[i].iConst / node->getUnionArrayPointer()->iConst;
+ } else {
+ if (unionArray[i].iConst == 0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].iConst = INT_MAX;
+ } else
+ tempConstArray[i].iConst = node->getUnionArrayPointer()->iConst / unionArray[i].iConst;
+ }
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst && node->getUnionArrayPointer()->bConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"&&\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpLogicalXor: // this code is written for possible future use, will not get executed currently
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst ^ node->getUnionArrayPointer()->bConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"^^\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst || node->getUnionArrayPointer()->bConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"||\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ default:
+ infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", this->getLine());
+ return 0;
+ }
+ newNode = new TIntermConstantUnion(tempConstArray, this->getType());
+ newNode->setLine(this->getLine());
+
+ return newNode;
+ } else if (constantNode->getAsConstantUnion() && (this->getSize() > 1 || this->getType().getBasicType() == EbtStruct)) {
+ TIntermConstantUnion *node = constantNode->getAsConstantUnion();
+ constUnion *rightUnionArray = node->getUnionArrayPointer();
+ constUnion* tempConstArray = 0;
+ TIntermConstantUnion *tempNode;
+ int index = 0;
+ bool boolNodeFlag = false;
+ int i;
+ switch(op) {
+ case EOpAdd:
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst + rightUnionArray[i].fConst; break;
+ case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst + rightUnionArray[i].iConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"+\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+ case EOpSub:
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat:
+ if (leftOperand)
+ tempConstArray[i].fConst = unionArray[i].fConst - rightUnionArray[i].fConst;
+ else
+ tempConstArray[i].fConst = rightUnionArray[i].fConst - unionArray[i].fConst;
+ break;
+
+ case EbtInt:
+ if (leftOperand)
+ tempConstArray[i].iConst = unionArray[i].iConst - rightUnionArray[i].iConst;
+ else
+ tempConstArray[i].iConst = rightUnionArray[i].iConst - unionArray[i].iConst;
+ break;
+
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"-\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+ case EOpMul:
+ {
+ if (this->isVector()) { // two vectors multiplied together
+ int size = this->getSize();
+ tempConstArray = new constUnion[size];
+
+ for (int i = 0; i < size; i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst * rightUnionArray[i].fConst; break;
+ case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst * rightUnionArray[i].iConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for vector multiply", this->getLine());
+ return 0;
+ }
+ }
+ }
+ }
+ break;
+ case EOpMatrixTimesMatrix:
+ {
+ if (this->getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
+ infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", this->getLine());
+ return 0;
+ }
+ int size = this->getNominalSize();
+ tempConstArray = new constUnion[size*size];
+ for (int row = 0; row < size; row++) {
+ for (int column = 0; column < size; column++) {
+ tempConstArray[size * column + row].fConst = 0.0;
+ for (int i = 0; i < size; i++) {
+ tempConstArray[size * column + row].fConst += unionArray[i * size + row].fConst * (rightUnionArray[column * size + i].fConst);
+ }
+ }
+ }
+ }
+ break;
+ case EOpDiv:
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtFloat:
+ if (leftOperand) {
+ if (rightUnionArray[i].fConst == 0.0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].fConst = FLT_MAX;
+ } else
+ tempConstArray[i].fConst = unionArray[i].fConst / rightUnionArray[i].fConst;
+ } else {
+ if (unionArray[i].fConst == 0.0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].fConst = FLT_MAX;
+ } else
+ tempConstArray[i].fConst = rightUnionArray[i].fConst / unionArray[i].fConst;
+ }
+ break;
+
+ case EbtInt:
+ if (leftOperand) {
+ if (rightUnionArray[i].iConst == 0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].iConst = INT_MAX;
+ } else
+ tempConstArray[i].iConst = unionArray[i].iConst / rightUnionArray[i].iConst;
+ } else {
+ if (unionArray[i].iConst == 0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ tempConstArray[i].iConst = INT_MAX;
+ } else
+ tempConstArray[i].iConst = rightUnionArray[i].iConst / unionArray[i].iConst;
+ }
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpMatrixTimesVector:
+ if (node->getBasicType() != EbtFloat) {
+ infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", this->getLine());
+ return 0;
+ }
+ tempConstArray = new constUnion[this->getNominalSize()];
+ {
+ for (int size = this->getNominalSize(), i = 0; i < size; i++) {
+ tempConstArray[i].fConst = 0.0;
+ for (int j = 0; j < size; j++) {
+ tempConstArray[i].fConst += ((unionArray[j*size + i].fConst) * rightUnionArray[j].fConst);
+ }
+ }
+ }
+
+ tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
+ tempNode->setLine(this->getLine());
+
+ return tempNode;
+
+ case EOpVectorTimesMatrix:
+ if (this->getType().getBasicType() != EbtFloat) {
+ infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", this->getLine());
+ return 0;
+ }
+
+ tempConstArray = new constUnion[this->getNominalSize()];
+ {
+ for (int size = this->getNominalSize(), i = 0; i < size; i++) {
+ tempConstArray[i].fConst = 0.0;
+ for (int j = 0; j < size; j++) {
+ tempConstArray[i].fConst += ((unionArray[j].fConst) * rightUnionArray[i*size + j].fConst);
+ }
+ }
+ }
+ break;
+
+ case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst && rightUnionArray[i].bConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"&&\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpLogicalXor: // this code is written for possible future use, will not get executed currently
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst ^ rightUnionArray[i].bConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"^^\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
+ tempConstArray = new constUnion[this->getSize()];
+ for (i = 0; i < this->getSize(); i++) {
+ switch (this->getType().getBasicType()) {
+ case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst || rightUnionArray[i].bConst; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"||\"", this->getLine());
+ return 0;
+ }
+ }
+ break;
+
+ case EOpEqual:
+
+ switch (this->getType().getBasicType()) {
+ case EbtFloat:
+ for (i = 0; i < this->getSize(); i++) {
+ if (unionArray[i].fConst != rightUnionArray[i].fConst) {
+ boolNodeFlag = true;
+ break; // break out of for loop
+ }
+ }
+ break;
+
+ case EbtInt:
+ for (i = 0; i < this->getSize(); i++) {
+ if (unionArray[i].iConst != rightUnionArray[i].iConst) {
+ boolNodeFlag = true;
+ break; // break out of for loop
+ }
+ }
+ break;
+ case EbtBool:
+ for (i = 0; i < this->getSize(); i++) {
+ if (unionArray[i].bConst != rightUnionArray[i].bConst) {
+ boolNodeFlag = true;
+ break; // break out of for loop
+ }
+ }
+ break;
+ case EbtStruct:
+ if (!compareStructure(node->getType(), node->getUnionArrayPointer(), unionArray, index))
+ boolNodeFlag = true;
+ break;
+
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"==\"", this->getLine());
+ return 0;
+ }
+
+ tempConstArray = new constUnion[1];
+ if (!boolNodeFlag) {
+ tempConstArray->bConst = true;
+ }
+ else {
+ tempConstArray->bConst = false;
+ }
+
+ tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
+ tempNode->setLine(this->getLine());
+
+ return tempNode;
+
+ case EOpNotEqual:
+ switch (this->getType().getBasicType()) {
+ case EbtFloat:
+ for (i = 0; i < this->getSize(); i++) {
+ if (unionArray[i].fConst == rightUnionArray[i].fConst) {
+ boolNodeFlag = true;
+ break; // break out of for loop
+ }
+ }
+ break;
+
+ case EbtInt:
+ for (i = 0; i < this->getSize(); i++) {
+ if (unionArray[i].iConst == rightUnionArray[i].iConst) {
+ boolNodeFlag = true;
+ break; // break out of for loop
+ }
+ }
+ break;
+ case EbtBool:
+ for (i = 0; i < this->getSize(); i++) {
+ if (unionArray[i].bConst == rightUnionArray[i].bConst) {
+ boolNodeFlag = true;
+ break; // break out of for loop
+ }
+ }
+ break;
+ case EbtStruct:
+ if (compareStructure(node->getType(), node->getUnionArrayPointer(), unionArray, index))
+ boolNodeFlag = true;
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"!=\"", this->getLine());
+ return 0;
+ }
+
+ tempConstArray = new constUnion[1];
+ if (!boolNodeFlag) {
+ tempConstArray->bConst = true;
+ }
+ else {
+ tempConstArray->bConst = false;
+ }
+
+ tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
+ tempNode->setLine(this->getLine());
+
+ return tempNode;
+
+ default:
+ infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", this->getLine());
+ return 0;
+ }
+ tempNode = new TIntermConstantUnion(tempConstArray, this->getType());
+ tempNode->setLine(this->getLine());
+
+ return tempNode;
+ } else if (this->getSize() == 1 && this->getType().getBasicType() != EbtStruct
+ && constantNode->getSize() == 1 && constantNode->getType().getBasicType() != EbtStruct ) { // scalar constant folding
+ constUnion *unionArray = new constUnion[1];
+ TIntermConstantUnion* newNode = 0;
+
+ switch (this->getType().getBasicType()) {
+ case EbtInt:
+ {
+ //
+ // Dealing with two operands, us and constant.
+ //
+ // Do Binary operations.
+ //
+ int rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->iConst;
+ int leftValue = this->getUnionArrayPointer()->iConst;
+ int line = this->getLine();
+
+ switch(op) {
+ //?? add constant intrinsics
+ case EOpAdd: unionArray->iConst = leftValue + rightValue; break;
+ case EOpSub: unionArray->iConst = leftValue - rightValue; break;
+ case EOpMul: unionArray->iConst = leftValue * rightValue; break;
+ case EOpDiv:
+ if (rightValue == 0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ unionArray->iConst = INT_MAX;
+ } else
+ unionArray->iConst = leftValue / rightValue; break;
+
+ case EOpMod: unionArray->iConst = leftValue % rightValue; break;
+
+ case EOpRightShift: unionArray->iConst = leftValue >> rightValue; break;
+ case EOpLeftShift: unionArray->iConst = leftValue << rightValue; break;
+
+ case EOpAnd: unionArray->iConst = leftValue & rightValue; break;
+ case EOpInclusiveOr: unionArray->iConst = leftValue | rightValue; break;
+ case EOpExclusiveOr: unionArray->iConst = leftValue ^ rightValue; break;
+
+ // the following assume it's okay to have memory leaks
+ case EOpEqual:
+ unionArray->bConst = leftValue == rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpNotEqual:
+ unionArray->bConst = leftValue != rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpLessThan:
+ unionArray->bConst = leftValue < rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpGreaterThan:
+ unionArray->bConst = leftValue > rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpLessThanEqual:
+ unionArray->bConst = leftValue <= rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpGreaterThanEqual:
+ unionArray->bConst = leftValue >= rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+
+ default:
+ //infoSink.info.message(EPrefixInternalError, "Binary operation not folded into constant int", line);
+ return 0;
+ }
+ if (!newNode) {
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtInt, EvqConst));
+ }
+ newNode->setLine(constantNode->getLine());
+ return newNode;
+ }
+ case EbtFloat:
+ {
+ float rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->fConst;
+ float leftValue = this->getUnionArrayPointer()->fConst;
+
+ switch(op) {
+ //?? add constant intrinsics
+ case EOpAdd: unionArray->fConst = leftValue + rightValue; break;
+ case EOpSub: unionArray->fConst = leftValue - rightValue; break;
+ case EOpMul: unionArray->fConst = leftValue * rightValue; break;
+ case EOpDiv:
+ if (rightValue == 0.0) {
+ infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
+ unionArray->fConst = FLT_MAX;
+ } else
+ unionArray->fConst = leftValue / rightValue; break;
+
+ // the following assume it's okay to have memory leaks (cleaned up by pool allocator)
+ case EOpEqual:
+ unionArray->bConst = leftValue == rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpNotEqual:
+ unionArray->bConst = leftValue != rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpLessThan:
+ unionArray->bConst = leftValue < rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpGreaterThan:
+ unionArray->bConst = leftValue > rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpLessThanEqual:
+ unionArray->bConst = leftValue <= rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+ case EOpGreaterThanEqual:
+ unionArray->bConst = leftValue >= rightValue;
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ break;
+
+ default:
+ //infoSink.info.message(EPrefixInternalError, "Binary operation not folded into constant float", line);
+ return 0;
+ }
+ if (!newNode) {
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtFloat, EvqConst));
+ }
+ newNode->setLine(constantNode->getLine());
+ return newNode;
+ }
+ case EbtBool:
+ {
+ bool rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->bConst;
+ bool leftValue = this->getUnionArrayPointer()->bConst;
+
+ switch(op) {
+ //?? add constant intrinsics
+ case EOpLogicalAnd: unionArray->bConst = leftValue & rightValue; break;
+ case EOpLogicalXor: unionArray->bConst = leftValue ^ rightValue; break;
+ case EOpLogicalOr: unionArray->bConst = leftValue | rightValue; break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Binary operator cannot be folded into constant bool", line);
+ return 0;
+ }
+ newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
+ newNode->setLine(constantNode->getLine());
+ return newNode;
+ }
+ default:
+ infoSink.info.message(EPrefixInternalError, "Cannot fold constant", this->getLine());
+ return 0;
+ }
+ }
+ } else {
+ //
+ // Do unary operations
+ //
+ TIntermConstantUnion *newNode = 0;
+ constUnion* tempConstArray = new constUnion[this->getSize()];
+ if (this->getSize() > 1) {
+ for (int i = 0; i < this->getSize(); i++) {
+ switch(op) {
+ case EOpNegative:
+ switch (this->getType().getBasicType()) {
+ case EbtFloat: tempConstArray[i].fConst = -(unionArray[i].fConst); break;
+ case EbtInt: tempConstArray[i].iConst = -(unionArray[i].iConst); break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", this->getLine());
+ return 0;
+ }
+ break;
+ case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
+ switch (this->getType().getBasicType()) {
+ case EbtBool: tempConstArray[i].bConst = !(unionArray[i].bConst); break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", this->getLine());
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ }
+ newNode = new TIntermConstantUnion(tempConstArray, this->getType());
+ newNode->setLine(this->getLine());
+ return newNode;
+ } else {
+ switch(op) {
+ //?? add constant intrinsics
+ case EOpNegative:
+ switch (this->getType().getBasicType()) {
+ case EbtInt:
+ tempConstArray->iConst = -(this->getUnionArrayPointer()->iConst);
+ newNode = new TIntermConstantUnion(tempConstArray, TType(EbtInt, EvqConst));
+ break;
+ case EbtFloat:
+ tempConstArray->fConst = -(this->getUnionArrayPointer()->fConst);
+ newNode = new TIntermConstantUnion(tempConstArray, TType(EbtFloat, EvqConst));
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", line);
+ return 0;
+ }
+ break;
+ case EOpLogicalNot:
+ switch (this->getType().getBasicType()) {
+ case EbtBool:
+ tempConstArray->bConst = !this->getUnionArrayPointer()->bConst;
+ newNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", line);
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ newNode->setLine(this->getLine());
+ return newNode;
+
+ }
+ }
+
+ return this;
+}
+
+TIntermConstantUnion* TIntermediate::changeAggrToTempConst(TIntermAggregate* node, TSymbolTable& symbolTable, TSourceLoc line)
+{
+ constUnion* unionArray = new constUnion[node->getType().getInstanceSize()];
+ bool returnVal;
+
+ if (node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
+ returnVal = parseConstTree(line, node, unionArray, node->getOp(), symbolTable, node->getType(), true);
+ }
+ else {
+ returnVal = parseConstTree(line, node, unionArray, node->getOp(), symbolTable, node->getType());
+ }
+
+ if (returnVal)
+ unionArray = 0;
+
+ return (addConstantUnion(unionArray, node->getType(), node->getLine()));
+}
+
+TIntermTyped* TIntermediate::copyConstUnion(TIntermConstantUnion* node)
+{
+ constUnion *unionArray = node->getUnionArrayPointer();
+
+ if (!unionArray)
+ return 0;
+
+ int size;
+ if (node->getType().getBasicType() == EbtStruct)
+ //?? We should actually be calling getStructSize() function and not setStructSize. This problem occurs in case
+ // of nested/embedded structs.
+ size = node->getType().setStructSize(node->getType().getStruct());
+ //size = node->getType().getStructSize();
+ else
+ size = node->getType().getInstanceSize();
+
+ constUnion *newSpace = new constUnion[size];
+
+ for (int i = 0; i < size; i++)
+ newSpace[i] = unionArray[i];
+
+ node->setUnionArrayPointer(newSpace);
+ return node;
+}
+
+TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
+{
+ constUnion *rightUnionArray = node->getUnionArrayPointer();
+ int size = node->getType().getInstanceSize();
+
+ constUnion *leftUnionArray = new constUnion[size];
+
+ for (int i=0; i < size; i++) {
+
+ switch (promoteTo) {
+ case EbtFloat:
+ switch (node->getType().getBasicType()) {
+ case EbtInt:
+ (leftUnionArray[i]).fConst = static_cast<float>(rightUnionArray[i].iConst);
+ break;
+ case EbtBool:
+ (leftUnionArray[i]).fConst = static_cast<float>(rightUnionArray[i].bConst);
+ break;
+ case EbtFloat:
+ (leftUnionArray[i]).fConst = rightUnionArray[i].fConst;
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+ return 0;
+ }
+ break;
+ case EbtInt:
+ switch (node->getType().getBasicType()) {
+ case EbtInt:
+ (leftUnionArray[i]).iConst = rightUnionArray[i].iConst;
+ break;
+ case EbtBool:
+ (leftUnionArray[i]).iConst = static_cast<int>(rightUnionArray[i].bConst);
+ break;
+ case EbtFloat:
+ (leftUnionArray[i]).iConst = static_cast<int>(rightUnionArray[i].fConst);
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+ return 0;
+ }
+ break;
+ case EbtBool:
+ switch (node->getType().getBasicType()) {
+ case EbtInt:
+ (leftUnionArray[i]).bConst = rightUnionArray[i].iConst != 0;
+ break;
+ case EbtBool:
+ (leftUnionArray[i]).bConst = rightUnionArray[i].bConst;
+ break;
+ case EbtFloat:
+ (leftUnionArray[i]).bConst = rightUnionArray[i].fConst != 0.0;
+ 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;
+ }
+
+ }
+ TType t = node->getType();
+
+ return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
+}
+
+//
+// This method inserts the child nodes into the parent node at the given location specified
+// by parentNodeIter. offset tells the integer offset into the parent vector that points to
+// the child node. sequenceVector is the parent vector.
+// Returns reference to the last inserted child node
+// increments the offset based on the number of child nodes added
+//
+void TIntermediate::removeChildNode(TIntermSequence &parentSequence, TType& parentType, int& offset, TIntermSequence::iterator& parentNodeIter, TIntermAggregate* child)
+{
+ if (!child)
+ return;
+
+ parentNodeIter = parentSequence.begin() + offset;
+
+ TIntermSequence& childSequence = child->getSequence();
+ int oldSize = static_cast<int>(parentSequence.size());
+ if (childSequence.size() == 1) {
+ if (!removeMatrixConstNode(parentSequence, parentType, child, offset)) {
+ for (int i = 0; i < child->getType().getInstanceSize(); i++) {
+ constUnion* constantUnion = new constUnion[1];
+ *constantUnion = *(childSequence[0]->getAsConstantUnion()->getUnionArrayPointer());
+ TIntermConstantUnion *constant = new TIntermConstantUnion(constantUnion,
+ childSequence[0]->getAsConstantUnion()->getType());
+ constant->setLine(child->getLine());
+ parentNodeIter = parentSequence.begin() + offset;
+ parentSequence.insert(parentNodeIter, constant);
+ }
+ }
+ } else
+ parentSequence.insert(parentNodeIter, childSequence.begin(), childSequence.end());
+
+ int newSize = static_cast<int>(parentSequence.size());
+ offset = offset + newSize - oldSize;
+ parentNodeIter = parentSequence.begin() + offset;
+ parentNodeIter = parentSequence.erase(parentNodeIter);
+ offset--;
+ parentNodeIter--;
+}
+
+//
+// The parent has only one child node. This method is not implemented
+// for parent that is a structure
+//
+TIntermTyped* TIntermediate::removeChildNode(TIntermTyped* parent, TType* parentType, TIntermAggregate* child)
+{
+ TIntermTyped* resultNode = 0;
+
+ if (parentType->getInstanceSize() == 1) {
+ resultNode = child->getSequence()[0]->getAsTyped();
+ } else {
+ int size = parentType->getInstanceSize();
+ TIntermSequence& parentSequence = parent->getAsAggregate()->getSequence();
+ TIntermSequence& childSequence = child->getSequence();
+
+ if (childSequence.size() == 1) {
+ if (!removeMatrixConstNode(parentSequence, *parentType, child, 1))
+ parentSequence.push_back(child->getSequence()[0]);
+ } else {
+ for (int i = 0; i < size; i++) {
+ parentSequence.push_back(child->getSequence()[i]);
+ }
+ }
+ parentSequence.erase(parentSequence.begin());
+
+ return parent;
+ }
+
+ return resultNode;
+}
+
+bool TIntermediate::removeMatrixConstNode(TIntermSequence &parentSequence, TType& parentType, TIntermAggregate* child, int offset)
+{
+ if (!child)
+ return false;
+
+ TIntermSequence::iterator parentNodeIter;
+ TIntermSequence &childSequence = child->getSequence();
+ int i;
+
+ switch (child->getOp()) {
+ case EOpConstructMat2:
+ case EOpConstructMat3:
+ case EOpConstructMat4:
+ for (i = 0; i < child->getType().getInstanceSize(); i++) {
+ constUnion* constantUnion = new constUnion[1];
+ if (i % (child->getType().getNominalSize() + 1) == 0) {
+ *constantUnion = *(childSequence[0]->getAsConstantUnion()->getUnionArrayPointer());
+ } else {
+ switch (parentType.getBasicType()) {
+ case EbtInt: constantUnion->iConst = 0; break;
+ case EbtFloat: constantUnion->fConst = 0.0; break;
+ case EbtBool: constantUnion->bConst = false; break;
+ }
+ }
+ TIntermConstantUnion *constant = new TIntermConstantUnion(constantUnion,
+ childSequence[0]->getAsConstantUnion()->getType());
+ constant->setLine(child->getLine());
+ parentNodeIter = parentSequence.begin() + offset + i;
+ parentSequence.insert(parentNodeIter, constant);
+ }
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/src/mesa/shader/slang/MachineIndependent/MMap.h b/src/mesa/shader/slang/MachineIndependent/MMap.h
new file mode 100755
index 0000000000..bc904443a9
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/MMap.h
@@ -0,0 +1,84 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/ParseHelper.cpp b/src/mesa/shader/slang/MachineIndependent/ParseHelper.cpp
new file mode 100755
index 0000000000..d20aa2fa87
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/ParseHelper.cpp
@@ -0,0 +1,1406 @@
+//
+//Copyright (C) 2002-2004 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;
+ }
+
+ bool tooBig = false;
+
+ for (int i = 0; i < fields.num; ++i) {
+ switch (compString[i]) {
+ case 'x': case 'r': case 's': case '0':
+ fields.offsets[i] = 0;
+ break;
+ case 'y': case 'g': case 't': case '1':
+ fields.offsets[i] = 1;
+ break;
+ case 'z': case 'b': case 'p': case '2':
+ if (vecSize < 3)
+ tooBig = true;
+ fields.offsets[i] = 2;
+ break;
+ case 'w': case 'a': case 'q': case '3':
+ if (vecSize < 4)
+ tooBig = true;
+ fields.offsets[i] = 3;
+ break;
+ default:
+ error(line, "illegal vector field selection", compString.c_str(), "");
+ return false;
+ }
+ }
+
+ if (tooBig) {
+ error(line, "vector field selection out of range", 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()->iConst;
+ 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:
+ 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() ||
+ identifier.substr(0, 3) != TString("gl_"))
+ return false;
+
+ error(line, "reserved built-in name", "gl_", "");
+
+ return true;
+}
+
+//
+// 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)
+{
+ switch(op) {
+ case EOpConstructInt: *type = TType(EbtInt); break;
+ case EOpConstructBool: *type = TType(EbtBool); break;
+ case EOpConstructFloat: *type = TType(EbtFloat); break;
+ case EOpConstructVec2: *type = TType(EbtFloat, EvqTemporary, 2); break;
+ case EOpConstructVec3: *type = TType(EbtFloat, EvqTemporary, 3); break;
+ case EOpConstructVec4: *type = TType(EbtFloat, EvqTemporary, 4); break;
+ case EOpConstructBVec2: *type = TType(EbtBool, EvqTemporary, 2); break;
+ case EOpConstructBVec3: *type = TType(EbtBool, EvqTemporary, 3); break;
+ case EOpConstructBVec4: *type = TType(EbtBool, EvqTemporary, 4); break;
+ case EOpConstructIVec2: *type = TType(EbtInt, EvqTemporary, 2); break;
+ case EOpConstructIVec3: *type = TType(EbtInt, EvqTemporary, 3); break;
+ case EOpConstructIVec4: *type = TType(EbtInt, EvqTemporary, 4); break;
+ case EOpConstructMat2: *type = TType(EbtFloat, EvqTemporary, 2, true); break;
+ case EOpConstructMat3: *type = TType(EbtFloat, EvqTemporary, 3, true); break;
+ case EOpConstructMat4: *type = TType(EbtFloat, EvqTemporary, 4, true); break;
+ case EOpConstructStruct: *type = TType(function.getReturnType().getStruct(), function.getReturnType().getTypeName()); break;
+ default:
+ error(line, "expected constructor", "Internal Error", "");
+ return true;
+ }
+
+ 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;
+ for (int i = 0; i < function.getParamCount(); ++i) {
+ size += function[i].type->getInstanceSize();
+ if (constructingMatrix && function[i].type->isMatrix())
+ matrixInMatrix = true;
+ if (full)
+ overFull = true;
+ if (op != EOpConstructStruct && size >= type->getInstanceSize())
+ full = true;
+ if (function[i].type->getQualifier() != EvqConst)
+ constType = false;
+ }
+
+ if (constType)
+ type->changeQualifier(EvqConst);
+
+ if (matrixInMatrix) {
+ error(line, "constructing matrix from matrix", "constructor", "(reserved)");
+ return true;
+ }
+
+ if (overFull) {
+ error(line, "too many arguments", "constructor", "");
+ return true;
+ }
+
+ if (size != 1 && size < type->getInstanceSize() || (size < 1) && op == EOpConstructStruct) {
+ 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 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, TIntermTyped* size)
+{
+ //
+ // Don't check for reserved word use until after we know it's not in the symbol table,
+ // because reserved arrays can be redeclared.
+ //
+
+ //
+ // Can the type be an array?
+ //
+ if (type.array || type.qualifier == EvqAttribute || type.qualifier == EvqConst) {
+ error(line, "cannot declare arrays of this type", TType(type).getCompleteString().c_str(), "");
+ return true;
+ }
+ type.array = true;
+
+ //
+ // size will be 0 if there is no size declared, otherwise it contains the size
+ // declared.
+ //
+ TIntermConstantUnion* constant = 0;
+ if (size) {
+ constant = size->getAsConstantUnion();
+ if (constant == 0 || constant->getBasicType() != EbtInt || constant->getUnionArrayPointer()->iConst <= 0) {
+ error(line, "array size must be a positive integer", identifier.c_str(), "");
+ return true;
+ }
+ }
+
+ bool builtIn = false;
+ bool sameScope = false;
+ TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope);
+ if (symbol == 0 || !sameScope) {
+ if (reservedErrorCheck(line, identifier))
+ return true;
+
+ TVariable* variable = new TVariable(&identifier, TType(type));
+
+ if (size)
+ variable->getType().setArraySize(constant->getUnionArrayPointer()->iConst);
+
+ 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;
+ }
+
+ TVariable* 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() != 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() > constant->getUnionArrayPointer()->iConst) {
+ error(line, "higher index value already used for the array", identifier.c_str(), "");
+ return true;
+ }
+ t->setArraySize(constant->getUnionArrayPointer()->iConst);
+ t = t->getArrayInformationType();
+ }
+
+ if (size)
+ variable->getType().setArraySize(constant->getUnionArrayPointer()->iConst);
+ }
+
+ 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);
+
+ // 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;
+}
+
+//
+// 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();
+
+ //
+ // Make the qualifier make sense, error is issued in a little bit.
+ //
+ bool constError = false;
+ if (type.qualifier == EvqConst) {
+ type.qualifier = EvqTemporary;
+ constError = true;
+ }
+
+ TVariable* variable = new TVariable(&identifier, TType(type));
+
+ if (! symbolTable.insert(*variable)) {
+ error(line, "redefinition", variable->getName().c_str(), "");
+ delete variable;
+ return true;
+ }
+ if (constError) {
+ error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
+ 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;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+// 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)
+{
+ if (reservedErrorCheck(line, identifier))
+ return true;
+
+ if (voidErrorCheck(line, identifier, pType))
+ return true;
+
+ //
+ // add variable to symbol table
+ //
+ TVariable* variable = new TVariable(&identifier, TType(pType));
+ 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 (TType(pType) != 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 (pType.size == 1 && TType(pType).getBasicType() != EbtStruct) {
+ switch (pType.type ) {
+ case EbtInt:
+ unionArray->iConst = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0].iConst;
+ break;
+ case EbtFloat:
+ unionArray->fConst = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0].fConst;
+ break;
+ case EbtBool:
+ unionArray->bConst = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0].bConst;
+ break;
+ default:
+ error(line, " cannot initialize constant of this type", "", "");
+ return true;
+ }
+ } else {
+ variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
+ }
+ } else if (initializer->getAsAggregate()) {
+ bool returnVal = false;
+ constUnion* unionArray = variable->getConstPointer();
+ if (initializer->getAsAggregate()->getSequence().size() == 1 && initializer->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
+ returnVal = intermediate.parseConstTree(line, initializer, unionArray, initializer->getAsAggregate()->getOp(), symbolTable, variable->getType(), true);
+ }
+ else {
+ returnVal = intermediate.parseConstTree(line, initializer, unionArray, initializer->getAsAggregate()->getOp(), symbolTable, variable->getType());
+ }
+ intermNode = 0;
+ constUnion *arrayUnion = unionArray;
+ if (returnVal) {
+ arrayUnion = 0;
+ variable->getType().changeQualifier(EvqTemporary);
+ }
+ return returnVal;
+ } 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, " assigning non-constant 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;
+}
+
+//
+// This method checks to see if the given aggregate node has all its children nodes as constants
+// This method does not test if structure members are constant
+//
+bool TParseContext::canNodeBeRemoved(TIntermNode* childNode)
+{
+ TIntermAggregate *aggrNode = childNode->getAsAggregate();
+ if (!aggrNode)
+ return false;
+
+ if (!aggrNode->isConstructor() || aggrNode->getOp() == EOpConstructStruct)
+ 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, TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
+{
+ if (node == 0)
+ return 0;
+
+ TIntermAggregate* aggrNode = node->getAsAggregate();
+
+ TTypeList::iterator list;
+ TTypeList* structure = 0; // Store the information (vector) about the return type of the structure.
+ if (op == EOpConstructStruct) {
+ TType ttype = fnCall->getReturnType();
+ structure = ttype.getStruct();
+ list = (*structure).begin();
+ }
+
+ 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 (op == EOpConstructStruct) {
+ // If structure constructor is being called for only one parameter inside the structure,
+ // we need to call constructStruct function once.
+ if (structure->size() != 1) {
+ error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
+
+ return 0;
+ } else
+ return constructStruct(node, (*list).type, 1, node->getLine(), false);
+ } else {
+ newNode = constructBuiltIn(type, op, node, node->getLine(), false);
+ if (newNode && newNode->getAsAggregate()) {
+ if (canNodeBeRemoved(newNode->getAsAggregate()->getSequence()[0])) {
+ TIntermAggregate* returnAggNode = newNode->getAsAggregate()->getSequence()[0]->getAsAggregate();
+ newNode = intermediate.removeChildNode(newNode, type, returnAggNode);
+ }
+ }
+ 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
+ if (op == EOpConstructStruct) {
+ if (structure->size() != sequenceVector.size()) { // If the number of parameters to the constructor does not match the expected number of parameters
+ error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
+
+ return 0;
+ }
+ }
+
+ 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++) {
+ bool move = false;
+ if (op == EOpConstructStruct) {
+ newNode = constructStruct(*p, (list[paramCount]).type, paramCount+1, node->getLine(), true);
+ if (newNode)
+ move = true;
+ } else {
+ newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
+
+ if (newNode) {
+ if (canNodeBeRemoved(newNode))
+ intermediate.removeChildNode(sequenceVector, *type, paramCount, p, newNode->getAsAggregate());
+ else
+ move = true;
+ }
+ }
+ if (move) {
+ sequenceVector.erase(p);
+ sequenceVector.insert(p, newNode);
+ }
+ }
+
+ return intermediate.setAggregateOperator(aggrNode, op, line);
+}
+
+// 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(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();
+ TIntermAggregate* aggregateNode = node->getAsAggregate();
+
+ 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 if (aggregateNode) { // if an aggregate node is present, the value has to be taken from the parse tree
+ // for a case like vec(4).xz
+ unionArray = new constUnion[aggregateNode->getType().getInstanceSize()];
+
+ bool returnVal = false;
+ if (aggregateNode->getAsAggregate()->getSequence().size() == 1 && aggregateNode->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
+ returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType(), true);
+ }
+ else {
+ returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType());
+ }
+
+ if (returnVal)
+ return 0;
+
+ } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
+ error(line, "No aggregate or constant union node available", "Internal Error", "");
+ recover();
+
+ return 0;
+ }
+
+ constUnion* constArray = new constUnion[fields.num];
+
+ for (int i = 0; i < fields.num; i++) {
+ if (fields.offsets[i] >= node->getType().getInstanceSize()) {
+ 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();
+ TIntermAggregate* aggregateNode = node->getAsAggregate();
+
+ 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 if (aggregateNode) {
+ // for a case like mat4(5)[0]
+ constUnion* unionArray = new constUnion[aggregateNode->getType().getInstanceSize()];
+ int size = aggregateNode->getType().getNominalSize();
+
+ bool returnVal = false;
+ if (aggregateNode->getAsAggregate()->getSequence().size() == 1 && aggregateNode->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
+ returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType(), true);
+ }
+ else {
+ returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType());
+ }
+
+ if (!returnVal)
+ typedNode = intermediate.addConstantUnion(&unionArray[size*index], aggregateNode->getType(), line);
+ else
+ return 0;
+
+ } else {
+ error(line, "No Aggregate or Constant Union node available", "Internal 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();
+ TIntermAggregate* aggregateNode = node->getAsAggregate();
+
+ for ( index = 0; index < fields->size(); ++index) {
+ if ((*fields)[index].type->getFieldName() == identifier) {
+ break;
+ } else {
+ if ((*fields)[index].type->getStruct())
+ //?? We should actually be calling getStructSize() function and not setStructSize. This problem occurs in case
+ // of nested/embedded structs.
+ instanceSize += (*fields)[index].type->setStructSize((*fields)[index].type->getStruct());
+ else
+ instanceSize += (*fields)[index].type->getInstanceSize();
+ }
+ }
+
+ if (tempConstantNode) {
+ constUnion* constArray = tempConstantNode->getUnionArrayPointer();
+
+ typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
+ } else if (aggregateNode) {
+ // for a case like constStruct(1,v3).i where structure fields is int i and vec3 v3.
+
+ constUnion* unionArray = new constUnion[aggregateNode->getType().getStructSize()];
+
+ bool returnVal = false;
+ if (aggregateNode->getAsAggregate()->getSequence().size() == 1 && aggregateNode->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
+ returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType(), true);
+ }
+ else {
+ returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType());
+ }
+
+ if (!returnVal)
+ typedNode = intermediate.addConstantUnion(unionArray+instanceSize, aggregateNode->getType(), line);
+ else
+ return 0;
+
+ } else {
+ error(line, "No Aggregate or Constant Union node available", "Internal Error", "");
+ recover();
+
+ return 0;
+ }
+
+ return typedNode;
+}
+
+//
+// Initialize all supported extensions to disable
+//
+void TParseContext::initializeExtensionBehavior()
+{
+ //
+ // example code: extensionBehavior["test"] = EDisable; // where "test" is the name of
+ // supported extension
+ //
+}
+
+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/src/mesa/shader/slang/MachineIndependent/ParseHelper.h b/src/mesa/shader/slang/MachineIndependent/ParseHelper.h
new file mode 100755
index 0000000000..87f3d3bea9
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/ParseHelper.h
@@ -0,0 +1,137 @@
+//
+//Copyright (C) 2002-2004 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;
+
+//
+// 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) { }
+ 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 arrayErrorCheck(int line, TString& identifier, TPublicType type, TIntermTyped* size);
+ 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 nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
+ bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
+ const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
+ bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
+ TIntermTyped* initializer, TIntermNode*& intermNode);
+ bool TParseContext::canNodeBeRemoved(TIntermNode*);
+ TIntermTyped* addConstructor(TIntermNode*, TType*, TOperator, TFunction*, TSourceLoc);
+ TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
+ TIntermTyped* constructBuiltIn(TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
+ TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
+ TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
+ TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
+ bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
+ typedef std::map<TString, TString> PragmaStringMap;
+ PragmaStringMap PragmaTable;
+ 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/src/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp b/src/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp
new file mode 100755
index 0000000000..7cb83b9bd0
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp
@@ -0,0 +1,348 @@
+//
+//Copyright (C) 2002-2004 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 <assert.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;
+ threadData->compilerPoolAllocator = 0;
+
+ 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;
+}
+
+PoolAllocatorPointer& GetCompilerPoolAllocator()
+{
+ TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
+
+ return threadData->compilerPoolAllocator;
+}
+
+//
+// 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;
+ }
+
+ //
+ // Put a marker at the beginning of the stack. We won't
+ // pop() past this.
+ //
+ tAllocState start = { currentPageOffset, 0 };
+ stack.push_back(start);
+}
+
+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;
+ }
+}
+
+
+//
+// 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/src/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp b/src/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp
new file mode 100755
index 0000000000..d7846e0ddb
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp
@@ -0,0 +1,91 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/QualifierAlive.h b/src/mesa/shader/slang/MachineIndependent/QualifierAlive.h
new file mode 100755
index 0000000000..d1fd318ff4
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/QualifierAlive.h
@@ -0,0 +1,35 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/RemoveTree.cpp b/src/mesa/shader/slang/MachineIndependent/RemoveTree.cpp
new file mode 100755
index 0000000000..3c015a460b
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/RemoveTree.cpp
@@ -0,0 +1,98 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/RemoveTree.h b/src/mesa/shader/slang/MachineIndependent/RemoveTree.h
new file mode 100755
index 0000000000..4f171fdee6
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/RemoveTree.h
@@ -0,0 +1,35 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/ShaderLang.cpp b/src/mesa/shader/slang/MachineIndependent/ShaderLang.cpp
new file mode 100755
index 0000000000..c3b8050f06
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/ShaderLang.cpp
@@ -0,0 +1,590 @@
+//
+//Copyright (C) 2002-2004 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 "Initialisation.h"
+
+#define SH_EXPORTING
+#include "../Public/ShaderLangExt.h"
+
+#include "Include/ResourceLimits.h"
+#include "Initialize.h"
+
+extern "C" int InitPreprocessor(void);
+extern "C" int FinalizePreprocessor(void);
+extern void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator);
+
+bool generateBuiltInSymbolTable(TBuiltInResource& resources, TInfoSink&);
+bool initializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, TBuiltInResource &resources);
+void GenerateResources(TBuiltInResource& resources);
+
+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;
+ TBuiltInResource resources;
+ GenerateResources(resources);
+ 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) {
+ PerProcessGPA = new TPoolAllocator(true);
+ PerProcessGPA->push();
+
+ TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
+ SetGlobalPoolAllocatorPtr(PerProcessGPA);
+ ret = generateBuiltInSymbolTable(resources, infoSink);
+ SetGlobalPoolAllocatorPtr(gPoolAllocator);
+ }
+
+ 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());
+}
+
+//
+// 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];
+
+//
+// Cleanup symbol tables
+//
+int __fastcall ShFinalize()
+{
+ if (PerProcessGPA) {
+ PerProcessGPA->popAll();
+ delete PerProcessGPA;
+ }
+ return 1;
+}
+
+//
+// This method is required only for Sh interface, not for OGLC interface
+//
+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;
+}
+
+//
+// This function should be called only once by the Master Dll. Currently, this is being called for each thread
+// which is incorrect. This is required to keep the Sh interface working for now and will eventually be called
+// from master dll once.
+//
+bool generateBuiltInSymbolTable(TBuiltInResource& resources, TInfoSink& infoSink)
+{
+ TBuiltIns builtIns;
+ builtIns.initialize(resources);
+ initializeSymbolTable(builtIns.getBuiltInStrings(), EShLangVertex, infoSink, resources);
+ initializeSymbolTable(builtIns.getBuiltInStrings(), EShLangFragment, infoSink, resources);
+ return true;
+}
+
+bool initializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, TBuiltInResource &resources)
+{
+ TIntermediate intermediate(infoSink);
+ TSymbolTable& symbolTable = SymbolTables[language];
+ TParseContext parseContext(symbolTable, intermediate, language, infoSink);
+
+ GlobalParseContext = &parseContext;
+
+ setInitialState();
+
+ if (symbolTable.isEmpty()) {
+
+ //
+ // 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;
+ }
+ }
+
+ IdentifyBuiltIns(parseContext.language, symbolTable, resources);
+ 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,
+ 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;
+
+ compiler->infoSink.info.erase();
+ compiler->infoSink.debug.erase();
+
+ if (numStrings == 0)
+ return 1;
+
+ TIntermediate intermediate(compiler->infoSink);
+ TSymbolTable symbolTable(SymbolTables[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;
+ GlobalPoolAllocator.push();
+ 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 (! ret && parseContext.treeRoot) {
+ if (parseContext.recoveredFromError) {
+ 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);
+ } else {
+ 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;
+ }
+ }
+ }
+ }
+
+ intermediate.remove(parseContext.treeRoot);
+
+ //
+ // Ensure symbol table is returned to the built-in level,
+ // throwing away all but the built-ins.
+ //
+ while (! symbolTable.atBuiltInLevel())
+ 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;
+ int i;
+
+ for (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();
+
+ for (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.
+//
+// This is to preserve the old linker API, P20 code can use the generic
+// ShConstructBinding() and ShAddBinding() APIs
+//
+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.
+// This is to preserve the old linker API, P20 code can use the generic
+// ShConstructBinding() and ShAddBinding() APIs
+//
+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.
+//
+// We dont have to change this code for now since the TUniformMap being
+// passed back to ICD by the linker is the same as being used for the old P10 linker
+//
+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/src/mesa/shader/slang/MachineIndependent/SymbolTable.cpp b/src/mesa/shader/slang/MachineIndependent/SymbolTable.cpp
new file mode 100755
index 0000000000..de9dfc1e8e
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/SymbolTable.cpp
@@ -0,0 +1,156 @@
+//
+//Copyright (C) 2002-2004 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';
+
+ unsigned int i;
+
+ 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 EbtStruct:
+ mangledName += "struct-";
+ mangledName += typeName;
+ for (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 += ']';
+ }
+}
+
+//
+// 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);
+ }
+ }
+}
diff --git a/src/mesa/shader/slang/MachineIndependent/SymbolTable.h b/src/mesa/shader/slang/MachineIndependent/SymbolTable.h
new file mode 100755
index 0000000000..fc1f3d1c6b
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/SymbolTable.h
@@ -0,0 +1,305 @@
+//
+//Copyright (C) 2002-2004 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;
+
+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, 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) {
+ if (!type.getStruct())
+ unionArray = new constUnion[type.getInstanceSize()];
+ else
+ unionArray = new constUnion[type.getStructSize()];
+ }
+ return unionArray;
+ }
+
+ constUnion* getConstPointer() const { return unionArray; }
+
+ void shareConstPointer( constUnion *constArray)
+ {
+ delete unionArray;
+ unionArray = constArray;
+ }
+
+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;
+};
+
+//
+// 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;
+
+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;
+
+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 table.size() == 1; }
+ bool atGlobalLevel() { return table.size() <= 2; }
+ 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;
+ }
+
+ void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
+ int getMaxSymbolId() { return uniqueId; }
+ void dump(TInfoSink &infoSink) const;
+
+protected:
+ int currentLevel() const { return static_cast<int>(table.size()) - 1; }
+
+ std::vector<TSymbolTableLevel*> table;
+ int uniqueId; // for unique identification in code generation
+};
+
+#endif // _SYMBOL_TABLE_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/glslang_tab.h b/src/mesa/shader/slang/MachineIndependent/glslang_tab.h
new file mode 100755
index 0000000000..6847735086
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/glslang_tab.h
@@ -0,0 +1,121 @@
+typedef 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;
+} YYSTYPE;
+#define ATTRIBUTE 258
+#define CONST_QUAL 259
+#define BOOL_TYPE 260
+#define FLOAT_TYPE 261
+#define INT_TYPE 262
+#define BREAK 263
+#define CONTINUE 264
+#define DO 265
+#define ELSE 266
+#define FOR 267
+#define IF 268
+#define DISCARD 269
+#define RETURN 270
+#define BVEC2 271
+#define BVEC3 272
+#define BVEC4 273
+#define IVEC2 274
+#define IVEC3 275
+#define IVEC4 276
+#define VEC2 277
+#define VEC3 278
+#define VEC4 279
+#define MATRIX2 280
+#define MATRIX3 281
+#define MATRIX4 282
+#define IN_QUAL 283
+#define OUT_QUAL 284
+#define INOUT_QUAL 285
+#define UNIFORM 286
+#define VARYING 287
+#define STRUCT 288
+#define VOID_TYPE 289
+#define WHILE 290
+#define SAMPLER1D 291
+#define SAMPLER2D 292
+#define SAMPLER3D 293
+#define SAMPLERCUBE 294
+#define SAMPLER1DSHADOW 295
+#define SAMPLER2DSHADOW 296
+#define IDENTIFIER 297
+#define TYPE_NAME 298
+#define FLOATCONSTANT 299
+#define INTCONSTANT 300
+#define BOOLCONSTANT 301
+#define FIELD_SELECTION 302
+#define LEFT_OP 303
+#define RIGHT_OP 304
+#define INC_OP 305
+#define DEC_OP 306
+#define LE_OP 307
+#define GE_OP 308
+#define EQ_OP 309
+#define NE_OP 310
+#define AND_OP 311
+#define OR_OP 312
+#define XOR_OP 313
+#define MUL_ASSIGN 314
+#define DIV_ASSIGN 315
+#define ADD_ASSIGN 316
+#define MOD_ASSIGN 317
+#define LEFT_ASSIGN 318
+#define RIGHT_ASSIGN 319
+#define AND_ASSIGN 320
+#define XOR_ASSIGN 321
+#define OR_ASSIGN 322
+#define SUB_ASSIGN 323
+#define LEFT_PAREN 324
+#define RIGHT_PAREN 325
+#define LEFT_BRACKET 326
+#define RIGHT_BRACKET 327
+#define LEFT_BRACE 328
+#define RIGHT_BRACE 329
+#define DOT 330
+#define COMMA 331
+#define COLON 332
+#define EQUAL 333
+#define SEMICOLON 334
+#define BANG 335
+#define DASH 336
+#define TILDE 337
+#define PLUS 338
+#define STAR 339
+#define SLASH 340
+#define PERCENT 341
+#define LEFT_ANGLE 342
+#define RIGHT_ANGLE 343
+#define VERTICAL_BAR 344
+#define CARET 345
+#define AMPERSAND 346
+#define QUESTION 347
+
diff --git a/src/mesa/shader/slang/MachineIndependent/intermOut.cpp b/src/mesa/shader/slang/MachineIndependent/intermOut.cpp
new file mode 100755
index 0000000000..c34b599994
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/intermOut.cpp
@@ -0,0 +1,496 @@
+//
+//Copyright (C) 2002-2004 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"
+#include "../Include/ShHandle.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 = 0;
+ if (node->getType().getBasicType() == EbtStruct)
+ size = node->getType().getStructSize();
+ else
+ size = node->getType().getInstanceSize();
+
+ for (int i = 0; i < size; i++) {
+ OutputTreeText(out, node, oit->depth);
+ switch (node->getType().getBasicType()) {
+ case EbtBool:
+ if (node->getUnionArrayPointer()[i].bConst)
+ 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].fConst, "const float");
+
+ out.debug << buf << "\n";
+ }
+ break;
+ case EbtInt:
+ {
+ char buf[300];
+ sprintf(buf, "%d (%s)", node->getUnionArrayPointer()[i].iConst, "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/src/mesa/shader/slang/MachineIndependent/localintermediate.h b/src/mesa/shader/slang/MachineIndependent/localintermediate.h
new file mode 100755
index 0000000000..3cf3ca5bb8
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/localintermediate.h
@@ -0,0 +1,90 @@
+//
+//Copyright (C) 2002-2004 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);
+ TIntermConstantUnion* addConstantUnion(constUnion*, const TType&, TSourceLoc);
+ TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
+ TIntermTyped* copyConstUnion(TIntermConstantUnion*) ;
+ TIntermConstantUnion* changeAggrToTempConst(TIntermAggregate*, TSymbolTable&, TSourceLoc );
+ 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*);
+ void removeChildNode(TIntermSequence&, TType&, int&, TIntermSequence::iterator&, TIntermAggregate*);
+ TIntermTyped* removeChildNode(TIntermTyped*, TType*, TIntermAggregate*);
+ bool removeMatrixConstNode(TIntermSequence&, TType&, TIntermAggregate*, int);
+
+protected:
+ TInfoSink& infoSink;
+
+private:
+ void operator=(TIntermediate&); // prevent assignments
+};
+
+#endif // _LOCAL_INTERMEDIATE_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/parseConst.cpp b/src/mesa/shader/slang/MachineIndependent/parseConst.cpp
new file mode 100755
index 0000000000..6900ef7590
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/parseConst.cpp
@@ -0,0 +1,345 @@
+//
+//Copyright (C) 2002-2004 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);
+ TQualifier qualifier = node->getType().getQualifier();
+ constUnion* unionArray = oit->unionArray;
+ int instanceSize;
+ if (oit->type.getBasicType() == EbtStruct)
+ instanceSize = oit->type.getStructSize();
+ else
+ instanceSize = oit->type.getInstanceSize();
+
+ if (oit->index >= instanceSize)
+ return;
+
+ 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 ;
+ }
+ TSymbol* symbol = oit->symbolTable.find(node->getSymbol());
+ TVariable* tVar = static_cast<TVariable*>(symbol);
+
+ constUnion* constArray = tVar->getConstPointer();
+ if (!constArray) {
+ char buf[200];
+ sprintf(buf, "'constructor' : constant '%s' has not been initialized correctly", node->getSymbol().c_str());
+ oit->infoSink.info.message(EPrefixError, buf, node->getLine());
+ oit->error = true;
+ return;
+ }
+ int symbolSize;
+
+ if (tVar->getType().getBasicType() == EbtStruct)
+ symbolSize = tVar->getType().getStructSize();
+ else
+ symbolSize = tVar->getType().getInstanceSize();
+
+ // for constructors such as ivec4(vec4), if vec4 is a symbol node, then the appropriate conversion is required as the
+ // types do not match
+ for (int i = 0; i < symbolSize; i++) {
+ if (oit->index >= instanceSize)
+ return;
+ if (tVar->getType().getBasicType() == oit->type.getBasicType() || oit->type.getBasicType() == EbtStruct)
+ (unionArray[oit->index]) = constArray[i];
+ else {
+ switch (tVar->getType().getBasicType()) {
+ case EbtFloat:
+ switch (oit->type.getBasicType()) {
+ case EbtInt: unionArray[oit->index].iConst = static_cast<int> (constArray[i].fConst); break;
+ case EbtBool: unionArray[oit->index].bConst = constArray[i].fConst != 0.0; break;
+ default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
+ }
+ break;
+ case EbtInt:
+ switch (oit->type.getBasicType()) {
+ case EbtFloat: unionArray[oit->index].fConst = static_cast<float>(constArray[i].iConst); break;
+ case EbtBool: unionArray[oit->index].bConst = constArray[i].iConst != 0 ; break;
+ default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
+ }
+ break;
+ case EbtBool:
+ switch (oit->type.getBasicType()) {
+ case EbtFloat: unionArray[oit->index].fConst = static_cast<float>(constArray[i].bConst); break;
+ case EbtInt: unionArray[oit->index].iConst = static_cast<int> (constArray[i].bConst); break;
+ default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
+ }
+ break;
+ default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
+ }
+ }
+ (oit->index)++;
+ }
+}
+
+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);
+ TType tt = node->getType();
+
+ 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();
+ if (node->getType().getBasicType() == EbtStruct)
+ oit->size = node->getType().getStructSize();
+ else
+ oit->size = node->getType().getInstanceSize();
+ 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;
+ if (oit->type.getBasicType() == EbtStruct)
+ instanceSize = oit->type.getStructSize();
+ else
+ instanceSize = oit->type.getInstanceSize();
+
+ if (oit->index >= instanceSize)
+ return;
+
+ if (!oit->singleConstantParam) {
+ int size;
+ if (node->getType().getBasicType() == EbtStruct)
+ size = node->getType().getStructSize();
+ else
+ size = node->getType().getInstanceSize();
+
+ 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().getBasicType() == EbtStruct && node->getType().getStructSize() > 1 ||
+ node->getType().getBasicType() != EbtStruct && node->getType().getInstanceSize() > 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].fConst = 0.0;
+
+ (oit->index)++;
+ if (node->getType().getBasicType() == EbtStruct && node->getType().getStructSize() > 1 ||
+ node->getType().getBasicType() != EbtStruct && node->getType().getInstanceSize() > 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/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.c
new file mode 100755
index 0000000000..386ad99171
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.c
@@ -0,0 +1,768 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.h
new file mode 100755
index 0000000000..3834eeb12c
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.h
@@ -0,0 +1,96 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/compile.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/compile.h
new file mode 100755
index 0000000000..9883994977
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/compile.h
@@ -0,0 +1,131 @@
+//
+//Copyright (C) 2002-2004 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
+};
+
+#endif // !defined(__COMPILE_H)
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c
new file mode 100755
index 0000000000..3787f5ac62
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c
@@ -0,0 +1,978 @@
+//
+//Copyright (C) 2002-2004 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"
+
+#include "slang_mesa.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 ((_mesa_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));
+ 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) {
+ while (token != '\n')
+ token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+ if ((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 ){
+ 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("#if");;
+ *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') {
+ CPPErrorToInfoLog("#if");
+ } else 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);
+ 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)
+{
+ const char *SrcStr;
+ const char *DestStr;
+ int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+
+ if(token=='\n'){
+ DecLineNumber();
+ CPPErrorToInfoLog("#pragma");
+ IncLineNumber();
+ return token;
+ }
+ if (token != CPP_IDENTIFIER)goto error;
+ SrcStr = GetAtomString(atable, yylvalpp->sc_ident);
+ token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+ if (token == '(') {
+ token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+ if (token != CPP_IDENTIFIER) goto error;
+ DestStr = GetAtomString(atable, yylvalpp->sc_ident);
+ token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+ if (token != ')') goto error;
+ token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+ if(token!='\n')goto error;
+ //make a call to CPP function MapStrings with SrcStr and DestStr.
+ MapStrings(SrcStr,DestStr);
+ }else{
+error:
+ CPPErrorToInfoLog("#pragma");
+ return token;
+ }
+
+ 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 = 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;
+ }
+ 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");
+ 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");
+ 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/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h
new file mode 100755
index 0000000000..8692d9bfd4
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h
@@ -0,0 +1,118 @@
+//
+//Copyright (C) 2002-2004 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 MapStrings(const char*,const char*); // #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/src/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c
new file mode 100755
index 0000000000..155eba2fd5
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c
@@ -0,0 +1,184 @@
+//
+//Copyright (C) 2002-2004 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;
+ 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/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.c
new file mode 100755
index 0000000000..ee6b65f8c3
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.c
@@ -0,0 +1,191 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.h
new file mode 100755
index 0000000000..544be6f5b5
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.h
@@ -0,0 +1,89 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/parser.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/parser.h
new file mode 100755
index 0000000000..6d8a3331e4
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/parser.h
@@ -0,0 +1,126 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h
new file mode 100755
index 0000000000..a3cd2e9c3b
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h
@@ -0,0 +1,84 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c
new file mode 100755
index 0000000000..74abe03dc6
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c
@@ -0,0 +1,787 @@
+//
+//Copyright (C) 2002-2004 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) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
+ ((*(long *)&(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 == '#' && (cpp->previous_token == '\n'||cpp->previous_token==0)) {
+ token = readCPPline(&yylvalpp);
+ if(check_EOF(token))
+ return 0;
+ continue;
+ }
+ 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) {
+ return maxSize;
+ } else if (strlen(tokenString) > 0) {
+ strcpy(buf, tokenString);
+ 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/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h
new file mode 100755
index 0000000000..225d20aead
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h
@@ -0,0 +1,118 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h
new file mode 100755
index 0000000000..c86354fe8a
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h
@@ -0,0 +1,115 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c
new file mode 100755
index 0000000000..f7ef690680
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c
@@ -0,0 +1,318 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h
new file mode 100755
index 0000000000..9be86d4208
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h
@@ -0,0 +1,145 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c
new file mode 100755
index 0000000000..4a9f2a1a02
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c
@@ -0,0 +1,464 @@
+//
+//Copyright (C) 2002-2004 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"
+
+#include "slang_mesa.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)
+{
+ size_t len;
+ char *str, *t;
+ const char *f;
+
+ len = strlen(fstr);
+ str = (char *) malloc(len + 1);
+ for (f=fstr, t=str; *f; f++) {
+ if (_mesa_isalnum(*f)) *t++ = *f;
+ else if (*f == '.' || *f == '/') *t++ = '_';
+ }
+ *t = 0;
+ return str;
+} // idstr
+
+
+/*
+ * lNewBlock()
+ *
+ */
+
+static TokenBlock *lNewBlock(TokenStream *fTok)
+{
+ TokenBlock *lBlock;
+
+ lBlock = (TokenBlock *) malloc(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);
+ 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)
+{
+ TokenStream *pTok;
+
+ pTok = (TokenStream *) malloc(sizeof(TokenStream));
+ pTok->next = NULL;
+ pTok->name = idstr(name);
+ pTok->head = NULL;
+ pTok->current = NULL;
+ lNewBlock(pTok);
+ 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/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h
new file mode 100755
index 0000000000..54b12fb0d6
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h
@@ -0,0 +1,122 @@
+//
+//Copyright (C) 2002-2004 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);
+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/src/mesa/shader/slang/MachineIndependent/unistd.h b/src/mesa/shader/slang/MachineIndependent/unistd.h
new file mode 100755
index 0000000000..efadd63fd9
--- /dev/null
+++ b/src/mesa/shader/slang/MachineIndependent/unistd.h
@@ -0,0 +1 @@
+// This is a NULL file and is meant to be empty
diff --git a/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp b/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp
new file mode 100755
index 0000000000..02e392f18b
--- /dev/null
+++ b/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp
@@ -0,0 +1,151 @@
+//
+//Copyright (C) 2002-2004 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 "Initialisation.h"
+#include "Include/InitializeGlobals.h"
+#include "Include/InitializeParseContext.h"
+#include "Public/ShaderLang.h"
+
+OS_TLSIndex GlobalProcessFlag = OS_INVALID_TLS_INDEX;
+
+bool InitProcess()
+{
+ if (GlobalProcessFlag != OS_INVALID_TLS_INDEX) {
+ //
+ // Function is re-entrant.
+ //
+ return true;
+ }
+
+ GlobalProcessFlag = OS_AllocTLSIndex();
+
+ if (GlobalProcessFlag == 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 (GlobalProcessFlag == OS_INVALID_TLS_INDEX) {
+ assert(0 && "InitThread(): Process hasn't been initalised.");
+ return false;
+ }
+
+ if (OS_GetTLSValue(GlobalProcessFlag) != 0) {
+ return true;
+ }
+
+ InitializeGlobalPools();
+
+ if(!InitializeGlobalParseContext())
+ return false;
+
+ if(!OS_SetTLSValue(GlobalProcessFlag, (void *)1)) {
+ assert(0 && "InitThread(): Unable to set init flag.");
+ return false;
+ }
+
+ return true;
+}
+
+
+bool DetachThread()
+{
+ bool retFlag = true;
+
+ if (GlobalProcessFlag == OS_INVALID_TLS_INDEX) {
+ assert(0 && "DetachThread(): Process hasn't been initalised.");
+ return false;
+ }
+
+ //
+ // Function is re-entrant and this thread may not have been initalised.
+ //
+ if (OS_GetTLSValue(GlobalProcessFlag) != 0)
+ {
+ if(!OS_SetTLSValue(GlobalProcessFlag, (void *)0)) {
+ assert(0 && "DetachThread(): Unable to clear init flag.");
+ retFlag = false;
+ }
+
+ FreeGlobalPools();
+
+ if (!FreeParseContext())
+ retFlag = false;
+ }
+
+ return retFlag;
+}
+
+bool DetachProcess()
+{
+ bool retFlag = true;
+
+ if (GlobalProcessFlag == OS_INVALID_TLS_INDEX)
+ return true;
+
+ ShFinalize();
+
+ retFlag = DetachThread();
+
+ FreePoolIndex();
+
+ if(!FreeParseContextIndex())
+ retFlag = false;
+
+ OS_FreeTLSIndex(GlobalProcessFlag);
+ GlobalProcessFlag = OS_INVALID_TLS_INDEX;
+
+ return retFlag;
+}
+
diff --git a/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.h b/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.h
new file mode 100755
index 0000000000..beaabbaa98
--- /dev/null
+++ b/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.h
@@ -0,0 +1,47 @@
+//
+//Copyright (C) 2002-2004 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 __INITIALISATION_H
+#define __INITIALISATION_H
+
+
+#include "osinclude.h"
+
+
+bool InitProcess();
+bool InitThread();
+bool DetachThread();
+bool DetachProcess();
+
+#endif // __INITIALISATION_H
+
diff --git a/src/mesa/shader/slang/OSDependent/Linux/osinclude.h b/src/mesa/shader/slang/OSDependent/Linux/osinclude.h
new file mode 100755
index 0000000000..df45958fbd
--- /dev/null
+++ b/src/mesa/shader/slang/OSDependent/Linux/osinclude.h
@@ -0,0 +1,77 @@
+//
+//Copyright (C) 2002-2004 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/src/mesa/shader/slang/OSDependent/Linux/ossource.cpp b/src/mesa/shader/slang/OSDependent/Linux/ossource.cpp
new file mode 100755
index 0000000000..a54cf83014
--- /dev/null
+++ b/src/mesa/shader/slang/OSDependent/Linux/ossource.cpp
@@ -0,0 +1,140 @@
+//
+//Copyright (C) 2002-2004 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 "Initialisation.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/src/mesa/shader/slang/OSDependent/Windows/osinclude.h b/src/mesa/shader/slang/OSDependent/Windows/osinclude.h
new file mode 100755
index 0000000000..c74a46b8fa
--- /dev/null
+++ b/src/mesa/shader/slang/OSDependent/Windows/osinclude.h
@@ -0,0 +1,68 @@
+//
+//Copyright (C) 2002-2004 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 1
+#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/src/mesa/shader/slang/OSDependent/Windows/ossource.cpp b/src/mesa/shader/slang/OSDependent/Windows/ossource.cpp
new file mode 100755
index 0000000000..81af9688b2
--- /dev/null
+++ b/src/mesa/shader/slang/OSDependent/Windows/ossource.cpp
@@ -0,0 +1,123 @@
+//
+//Copyright (C) 2002-2004 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 "Initialisation.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
+
+//
+// disable DllMain on Mesa-3D builds, call appropriate Init* and Detach*
+// routines manually in context initialization
+//
+/*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;
+}*/
+
+//
+// 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/src/mesa/shader/slang/Public/ShaderLang.h b/src/mesa/shader/slang/Public/ShaderLang.h
new file mode 100755
index 0000000000..44285e7bd8
--- /dev/null
+++ b/src/mesa/shader/slang/Public/ShaderLang.h
@@ -0,0 +1,232 @@
+/*
+//Copyright (C) 2002-2004 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_
+
+
+#ifdef _WIN32
+#define C_DECL __cdecl
+#define SH_IMPORT_EXPORT
+#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();
+/*
+// to be used for hardwareDataType and userDataType by ICD
+*/
+typedef enum {
+ EFloat,
+ EInt,
+ EBool,
+ EFloat_Vec2,
+ EFloat_Vec3,
+ EFloat_Vec4,
+ EInt_Vec2,
+ EInt_Vec3,
+ EInt_Vec4,
+ EBool_Vec2,
+ EBool_Vec3,
+ EBool_Vec4,
+ EFloat_Mat2,
+ EFloat_Mat3,
+ EFloat_Mat4,
+ ESampler_1D,
+ ESampler_2D,
+ ESampler_3D,
+ ESampler_Cube,
+ ESampler_1D_Shadow,
+ ESampler_2D_Shadow,
+ EStruct
+} ShBasicType;
+
+/*
+// 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,
+ 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);
+
+/*
+// 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);
+SH_IMPORT_EXPORT char* ShGetUniformName(const ShHandle linker, int virtualLocation);
+
+enum TDebugOptions {
+ EDebugOpNone = 0x000,
+ EDebugOpIntermediate = 0x001,
+ EDebugOpAssembly = 0x002,
+ EDebugOpObjectCode = 0x004,
+ EDebugOpLinkMaps = 0x008
+};
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _COMPILER_INTERFACE_INCLUDED_ */
diff --git a/src/mesa/shader/slang/Public/ShaderLangExt.h b/src/mesa/shader/slang/Public/ShaderLangExt.h
new file mode 100755
index 0000000000..bb669f327e
--- /dev/null
+++ b/src/mesa/shader/slang/Public/ShaderLangExt.h
@@ -0,0 +1,189 @@
+//
+//Copyright (C) 2002-2004 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 _SHADERLANG_EXTENSION_INCLUDED_
+#define _SHADERLANG_EXTENSION_INCLUDED_
+
+#include "ShaderLang.h"
+
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler/linker.
+//
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef enum {
+ EReserved = 0,
+ EFixed,
+ ERecommended,
+ EFloating
+} ShPriority;
+
+typedef enum {
+ ESymbol = 0,
+ EFloatConst,
+ EFloatConstPtr,
+ EIntConst,
+ EIntConstPtr,
+ EBoolConst,
+ EBoolConstPtr
+} ShDataType;
+
+// this definition will eventually go once we move to the new linker interface in the driver
+typedef enum {
+ EVirtualBinding,
+ EPhysicalBinding
+} ShVirtualPhysicalBinding;
+
+typedef struct {
+ int size; // out - total physical size for the binding in floats - P10
+ int location; // in-out - virtualLocation for all cases
+ int functionPriority; // out - used for giving priorities to function bindings
+ int proEpilogue; // out - essentially a bool defining whether its a prologue/epilogue or not, 1 means it is
+ int builtInName; // out - basically a bool value, 0 means not a builtInName, 1 means its a builtInName
+ int arraySize; // out - size of the array in units of its type - if the binding is for an array
+ ShPriority bindingPriority; // in-out - EFixed, ERecommended, EFloating
+ ShDataType bindingDataType; // in-out - whether its a symbol name or a constant value
+ ShBasicType hardwareDataType; // out - bool are loaded as floats on the hardware
+ ShBasicType userDataType; // out - mat3 -> mat3, ivec2 -> ivec2, vec2 -> vec2
+ ShBasicType basicUserType; // out - mat3 -> float, ivec2 ->int, vec2 -> float
+ int sizeOfType; // out - for vec3 -> 3, for float -> 1, for mat3 -> 3, mat3[10] -> 3
+ int matrix; // out - essentially a boolean, 0 means vector, 1 means matrix
+ union { // in-out
+ char* name;
+ float floatVal;
+ float* floatValPtr;
+ int intVal;
+ int* intValPtr;
+ };
+ // A pointer to ShP10PhysicalBinding or ShP20PhysicalBinding
+ void* targetDependentData; // in-out
+} ShBindingExt;
+
+//
+// to specify the type of binding
+//
+typedef enum {
+ EAttribute,
+ EUniform,
+ EVarying,
+ EFunction,
+ EConstant,
+ EFunctionRelocation,
+ EArbVertexLocal,
+ EArbVertexEnv,
+ EArbFragmentLocal,
+ EArbFragmentEnv,
+ EState,
+ ENoBindingType } ShBindingType;
+
+typedef struct {
+ // a pointer to ShBindingExt
+ ShBindingExt* pBinding;
+ int numOfBindings;
+ ShBindingType type;
+} ShBindingTableExt;
+
+typedef struct {
+ ShBindingTableExt *bindingTable;
+ int numOfBindingTables;
+} ShBindingList;
+
+SH_IMPORT_EXPORT ShHandle ShConstructBindings();
+SH_IMPORT_EXPORT ShHandle ShConstructLibrary();
+
+SH_IMPORT_EXPORT ShHandle ShAddBinding(ShHandle bindingHandle,
+ ShBindingExt* binding,
+ ShBindingType type);
+SH_IMPORT_EXPORT ShHandle ShAddBindingTable(ShHandle bindingHandle,
+ ShBindingTableExt *bindingTable,
+ ShBindingType type);
+
+SH_IMPORT_EXPORT int ShLinkExt(
+ const ShHandle, // linker object
+ const ShHandle h[], // compiler objects to link together
+ const int numHandles);
+
+SH_IMPORT_EXPORT ShBindingList* ShGetBindingList(const ShHandle linkerHandle);
+SH_IMPORT_EXPORT ShBindingTableExt* ShGetBindingTable(const ShHandle linkerHandle, ShBindingType type);
+SH_IMPORT_EXPORT int ShGetUniformLocationExt(const ShHandle linkerHandle, const char* name);
+SH_IMPORT_EXPORT int ShSetFixedAttributeBindingsExt(const ShHandle, const ShBindingTableExt*);
+SH_IMPORT_EXPORT int ShGetUniformLocationExt2(const ShHandle handle, const char* name, int* location, int* offset);
+SH_IMPORT_EXPORT int ShSetVirtualLocation(const ShHandle handle, ShBindingType type, int bindingIndex, int virtualLocation);
+SH_IMPORT_EXPORT int ShGetVirtualLocation(const ShHandle handle, ShBindingType type, int bindingIndex, int *virtualLocation);
+//
+// To get the bindings object from the linker object (after the link is done so that
+// bindings can be added to the list)
+//
+SH_IMPORT_EXPORT ShHandle ShGetBindings(const ShHandle linkerHandle);
+SH_IMPORT_EXPORT int ShAddLibraryCode(ShHandle library, const char* name, const ShHandle objectCodes[], const int numHandles);
+
+/*****************************************************************************
+ This code is used by the new shared linker
+ *****************************************************************************/
+//
+// Each programmable unit has a UnitExecutable. Targets may subclass
+// and append to this as desired.
+//
+typedef struct {
+ int name; // name of unit to which executable is targeted
+ int entry; // a target specific entry point
+ int count; // size of executable
+ const void* code; // read-only code
+} ShUnitExecutable;
+
+//
+// The "void*" returned from ShGetExecutable() will be an ShExecutable
+//
+typedef struct {
+ int count; // count of unit executables
+ ShUnitExecutable* executables;
+} ShExecutable;
+
+SH_IMPORT_EXPORT ShExecutable* ShGetExecutableExt(const ShHandle linkerHandle);
+
+typedef struct {
+ int numThread;
+ int stackSpacePerThread;
+ int visBufferValidity; // essenatially a boolean
+ int shaderFragTerminationStatus; // essentially a boolean
+} ShDeviceInfo;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // _SHADERLANG_EXTENSION_INCLUDED_