From 7d079fd7802763efd8c2d8856117b5df0b3a14e4 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 17 Jan 2005 16:01:49 +0000 Subject: 2005-oct-19 3dlabs slang compiler, tweaked a little bit --- src/mesa/shader/slang/Include/BaseTypes.h | 133 + src/mesa/shader/slang/Include/Common.h | 285 ++ src/mesa/shader/slang/Include/ConstantUnion.h | 50 + src/mesa/shader/slang/Include/InfoSink.h | 135 + src/mesa/shader/slang/Include/InitializeGlobals.h | 43 + .../shader/slang/Include/InitializeParseContext.h | 44 + src/mesa/shader/slang/Include/PoolAlloc.h | 354 ++ src/mesa/shader/slang/Include/ResourceLimits.h | 52 + src/mesa/shader/slang/Include/ShHandle.h | 199 ++ src/mesa/shader/slang/Include/Types.h | 223 ++ src/mesa/shader/slang/Include/intermediate.h | 505 +++ .../slang/MachineIndependent/Gen_glslang.cpp | 2822 +++++++++++++++ .../slang/MachineIndependent/Gen_glslang_tab.cpp | 3666 ++++++++++++++++++++ .../shader/slang/MachineIndependent/InfoSink.cpp | 107 + .../shader/slang/MachineIndependent/Initialize.cpp | 868 +++++ .../shader/slang/MachineIndependent/Initialize.h | 56 + .../slang/MachineIndependent/IntermTraverse.cpp | 243 ++ .../slang/MachineIndependent/Intermediate.cpp | 2057 +++++++++++ src/mesa/shader/slang/MachineIndependent/MMap.h | 84 + .../slang/MachineIndependent/ParseHelper.cpp | 1406 ++++++++ .../shader/slang/MachineIndependent/ParseHelper.h | 137 + .../shader/slang/MachineIndependent/PoolAlloc.cpp | 348 ++ .../slang/MachineIndependent/QualifierAlive.cpp | 91 + .../slang/MachineIndependent/QualifierAlive.h | 35 + .../shader/slang/MachineIndependent/RemoveTree.cpp | 98 + .../shader/slang/MachineIndependent/RemoveTree.h | 35 + .../shader/slang/MachineIndependent/ShaderLang.cpp | 590 ++++ .../slang/MachineIndependent/SymbolTable.cpp | 156 + .../shader/slang/MachineIndependent/SymbolTable.h | 305 ++ .../shader/slang/MachineIndependent/glslang_tab.h | 121 + .../shader/slang/MachineIndependent/intermOut.cpp | 496 +++ .../slang/MachineIndependent/localintermediate.h | 90 + .../shader/slang/MachineIndependent/parseConst.cpp | 345 ++ .../slang/MachineIndependent/preprocessor/atom.c | 768 ++++ .../slang/MachineIndependent/preprocessor/atom.h | 96 + .../MachineIndependent/preprocessor/compile.h | 131 + .../slang/MachineIndependent/preprocessor/cpp.c | 978 ++++++ .../slang/MachineIndependent/preprocessor/cpp.h | 118 + .../MachineIndependent/preprocessor/cppstruct.c | 184 + .../slang/MachineIndependent/preprocessor/memory.c | 191 + .../slang/MachineIndependent/preprocessor/memory.h | 89 + .../slang/MachineIndependent/preprocessor/parser.h | 126 + .../MachineIndependent/preprocessor/preprocess.h | 84 + .../MachineIndependent/preprocessor/scanner.c | 787 +++++ .../MachineIndependent/preprocessor/scanner.h | 118 + .../MachineIndependent/preprocessor/slglobals.h | 115 + .../MachineIndependent/preprocessor/symbols.c | 318 ++ .../MachineIndependent/preprocessor/symbols.h | 145 + .../slang/MachineIndependent/preprocessor/tokens.c | 464 +++ .../slang/MachineIndependent/preprocessor/tokens.h | 122 + src/mesa/shader/slang/MachineIndependent/unistd.h | 1 + .../slang/OGLCompilersDLL/Initialisation.cpp | 151 + .../shader/slang/OGLCompilersDLL/Initialisation.h | 47 + .../shader/slang/OSDependent/Linux/osinclude.h | 77 + .../shader/slang/OSDependent/Linux/ossource.cpp | 140 + .../shader/slang/OSDependent/Windows/osinclude.h | 68 + .../shader/slang/OSDependent/Windows/ossource.cpp | 123 + src/mesa/shader/slang/Public/ShaderLang.h | 232 ++ src/mesa/shader/slang/Public/ShaderLangExt.h | 189 + 59 files changed, 22041 insertions(+) create mode 100755 src/mesa/shader/slang/Include/BaseTypes.h create mode 100755 src/mesa/shader/slang/Include/Common.h create mode 100755 src/mesa/shader/slang/Include/ConstantUnion.h create mode 100755 src/mesa/shader/slang/Include/InfoSink.h create mode 100755 src/mesa/shader/slang/Include/InitializeGlobals.h create mode 100755 src/mesa/shader/slang/Include/InitializeParseContext.h create mode 100755 src/mesa/shader/slang/Include/PoolAlloc.h create mode 100755 src/mesa/shader/slang/Include/ResourceLimits.h create mode 100755 src/mesa/shader/slang/Include/ShHandle.h create mode 100755 src/mesa/shader/slang/Include/Types.h create mode 100755 src/mesa/shader/slang/Include/intermediate.h create mode 100755 src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/InfoSink.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/Initialize.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/Initialize.h create mode 100755 src/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/Intermediate.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/MMap.h create mode 100755 src/mesa/shader/slang/MachineIndependent/ParseHelper.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/ParseHelper.h create mode 100755 src/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/QualifierAlive.h create mode 100755 src/mesa/shader/slang/MachineIndependent/RemoveTree.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/RemoveTree.h create mode 100755 src/mesa/shader/slang/MachineIndependent/ShaderLang.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/SymbolTable.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/SymbolTable.h create mode 100755 src/mesa/shader/slang/MachineIndependent/glslang_tab.h create mode 100755 src/mesa/shader/slang/MachineIndependent/intermOut.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/localintermediate.h create mode 100755 src/mesa/shader/slang/MachineIndependent/parseConst.cpp create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/atom.c create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/atom.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/compile.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/memory.c create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/memory.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/parser.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c create mode 100755 src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h create mode 100755 src/mesa/shader/slang/MachineIndependent/unistd.h create mode 100755 src/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp create mode 100755 src/mesa/shader/slang/OGLCompilersDLL/Initialisation.h create mode 100755 src/mesa/shader/slang/OSDependent/Linux/osinclude.h create mode 100755 src/mesa/shader/slang/OSDependent/Linux/ossource.cpp create mode 100755 src/mesa/shader/slang/OSDependent/Windows/osinclude.h create mode 100755 src/mesa/shader/slang/OSDependent/Windows/ossource.cpp create mode 100755 src/mesa/shader/slang/Public/ShaderLang.h create mode 100755 src/mesa/shader/slang/Public/ShaderLangExt.h 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 +#elif defined (solaris) + #include + #define UINT_PTR uintptr_t +#else + #include + #define UINT_PTR uintptr_t +#endif + +#include + +/* 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 + #include + #include + #include + #include + #include + +//??#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 _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 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 _A = std::allocator<_K> > +class TBaseSet : public std::set <_K, _Pr, _A> +{ +public : + + // + // This method wasn't defined + // + template + 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 TStringAllocator; +typedef std::basic_string , 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 TVector : public std::vector > { +public: + typedef typename std::vector >::size_type size_type; + TVector() : std::vector >() {} + TVector(const pool_allocator& a) : std::vector >(a) {} + TVector(size_type i): std::vector >(i) {} +}; + +template class TList : public TBaseList > { +public: + typedef typename TBaseList >::size_type size_type; + TList() : TBaseList >() {} + TList(const pool_allocator& a) : TBaseList >(a) {} + TList(size_type i): TBaseList >(i) {} +}; + +// This is called TStlSet, because TSet is taken by an existing compiler class. +template class TStlSet : public std::set > { + // No pool allocator versions of constructors in std::set. +}; + + +template > class TMap : + public TBaseMap > > { +public: + typedef pool_allocator > tAllocator; + + TMap() : TBaseMap() {} + TMap(const tAllocator& a) : TBaseMap(key_compare(), a) {} +}; + +// +// Persistent string memory. Should only be used for strings that survive +// across compiles/links. +// +typedef std::basic_string TPersistString; + +// +// templatized min and max functions. +// +template T Min(const T a, const T b) { return a < b ? a : b; } +template 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 + +// +// 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 +#include + +// 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 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(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 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 + struct rebind { + typedef pool_allocator 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& p) : allocator(p.allocator) { } +#endif + +#if _MSC_VER >= 1300 + template +#ifdef USING_SGI_STL + pool_allocator(const pool_allocator& p) /*: allocator(p.getAllocator())*/ { } +#else + pool_allocator(const pool_allocator& p) : allocator(p.getAllocator()) { } +#endif +#endif + +#ifndef _WIN32 + template + pool_allocator(const pool_allocator& p) : allocator(p.getAllocator()) { } +#endif + +#ifdef USING_SGI_STL + static pointer allocate(size_type n) { + return reinterpret_cast(getAllocator().allocate(n)); } + pointer allocate(size_type n, const void*) { + return reinterpret_cast(getAllocator().allocate(n)); } + + static void deallocate(void*, size_type) { } + static void deallocate(pointer, size_type) { } +#else + pointer allocate(size_type n) { + return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } + pointer allocate(size_type n, const void*) { + return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } + + void deallocate(void*, size_type) { } + void deallocate(pointer, size_type) { } +#endif + + pointer _Charalloc(size_t n) { + return reinterpret_cast(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(-1) / sizeof(T); } + size_type max_size(int size) const { return static_cast(-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 TCompilerList; +typedef TVector 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 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 TIntermSequence; +typedef TVector 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 + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* 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 +#include +#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 +#include +#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 +#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(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(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(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(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:: 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 + +#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 +#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 +#else /* not sparc */ +#if (defined (MSDOS) && !defined (__TURBOC__)) || defined (WIN32) +#include +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include + #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(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(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(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(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(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(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(yyvsp[-2].interm.nodePair.node1), reinterpret_cast(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(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 +#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 + +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 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 +#include + +//////////////////////////////////////////////////////////////////////////// +// +// 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((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst); + newNode = addConstantUnion(unionArray, TType(EbtFloat, EvqConst), node->getLine()); break; + case EbtBool: + unionArray->fConst = static_cast((*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((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->fConst); + newNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), node->getLine()); + break; + case EbtBool: + unionArray->iConst = static_cast((*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(rightUnionArray[i].iConst); + break; + case EbtBool: + (leftUnionArray[i]).fConst = static_cast(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(rightUnionArray[i].bConst); + break; + case EbtFloat: + (leftUnionArray[i]).iConst = static_cast(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(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(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 +/////////////////////////////////////////////////////////////////////// +// +// 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(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(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(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(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(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(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(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(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 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 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 + +#include "Include/InitializeGlobals.h" +#include "osinclude.h" + +OS_TLSIndex PoolIndex; + +void InitializeGlobalPools() +{ + TThreadGlobalPools* globalPools= static_cast(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(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(OS_GetTLSValue(PoolIndex)); + + return *threadData->globalPoolAllocator; +} + +void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator) +{ + TThreadGlobalPools* threadData = static_cast(OS_GetTLSValue(PoolIndex)); + + threadData->globalPoolAllocator = poolAllocator; +} + +PoolAllocatorPointer& GetCompilerPoolAllocator() +{ + TThreadGlobalPools* threadData = static_cast(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(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(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(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(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(::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(reinterpret_cast(memory) + headerSkip); + } + + // + // Need a simple page to allocate from. + // + tHeader* memory; + if (freeList) { + memory = freeList; + freeList = freeList->nextPage; + } else { + memory = reinterpret_cast(::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(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(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(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(ConstructCompiler(language, debugOptions)); + + return reinterpret_cast(base); +} + +ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions) +{ + if (!InitThread()) + return 0; + + TShHandleBase* base = static_cast(ConstructLinker(executable, debugOptions)); + + return reinterpret_cast(base); +} + +ShHandle ShConstructUniformMap() +{ + if (!InitThread()) + return 0; + + TShHandleBase* base = static_cast(ConstructUniformMap()); + + return reinterpret_cast(base); +} + +void ShDestruct(ShHandle handle) +{ + if (handle == 0) + return; + + TShHandleBase* base = static_cast(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(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(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(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(linkHandle); + TLinker* linker = static_cast(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(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(linkHandle); + TLinker* linker = static_cast(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(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(handle); + + TLinker* linker = static_cast(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(handle); + TLinker* linker = static_cast(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(handle); + TLinker* linker = static_cast(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(handle); + TLinker* linker = static_cast(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(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('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((*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(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 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, pool_allocator > > tLevel; + typedef const tLevel::value_type tLevelPair; + typedef std::pair 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(table.size()) - 1; } + + std::vector 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(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(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 << ""; + } + + out.debug << " (" << node->getCompleteString() << ")"; + + out.debug << "\n"; + + return true; +} + +bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it) +{ + TOutputTraverser* oit = static_cast(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(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(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(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(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(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(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(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 (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(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(constArray[i].bConst); break; + case EbtInt: unionArray[oit->index].iConst = static_cast (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(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(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(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(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(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(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(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 +#include +#include +#include + +#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, "" }, + { CPP_GE_OP, ">=" }, + { CPP_RIGHT_OP, ">>" }, + { CPP_RIGHT_ASSIGN, ">>=" }, + { CPP_IDENTIFIER, "" }, + { CPP_INTCONSTANT, "" }, + { 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, "" }, + { CPP_TYPEIDENTIFIER, "" }, +}; + +/////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////// 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 "". 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 ""; + } + } else { + if (atom == 0) { + return ""; + } else { + if (atom == EOF) { + return ""; + } else { + return ""; + } + } + } +} // 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 "" atom: + + AddAtomFixed(atable, "", 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 +#include +#include +#include +#include + +#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; imac->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; imac->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; imac->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 +#include + +#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 +#include +#include + +#ifdef __STDC99__ +#include +#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 +#include +#include +#include + +#if 0 + #include + #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 +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#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 +#include + +// +// 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_ -- cgit v1.2.3