// // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // // Neither the name of 3Dlabs Inc. Ltd. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // #ifndef _COMMON_INCLUDED_ #define _COMMON_INCLUDED_ #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API #include #define snprintf sprintf_s #define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args)) #elif defined (solaris) #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args)) #include #define UINT_PTR uintptr_t #else #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args)) #include #define UINT_PTR uintptr_t #endif #if defined(__ANDROID__) || _MSC_VER < 1700 #include namespace std { template std::string to_string(const T& val) { std::ostringstream os; os << val; return os.str(); } } #endif #if defined(_MSC_VER) && _MSC_VER < 1800 inline long long int strtoll (const char* str, char** endptr, int base) { return _strtoi64(str, endptr, base); } inline unsigned long long int strtoull (const char* str, char** endptr, int base) { return _strtoui64(str, endptr, base); } inline long long int atoll (const char* str) { return strtoll(str, NULL, 10); } #endif #if defined(_MSC_VER) #define strdup _strdup #endif /* windows only pragma */ #ifdef _MSC_VER #pragma warning(disable : 4786) // Don't warn about too long identifiers #pragma warning(disable : 4514) // unused inline method #pragma warning(disable : 4201) // nameless union #endif #include #include #include #include #include #include #include #include #include #include #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 *) { } namespace glslang { // // Pool version of string. // typedef pool_allocator TStringAllocator; typedef std::basic_string , TStringAllocator> TString; } // end namespace glslang // Repackage the std::hash for use by unordered map/set with a TString key. namespace std { template<> struct hash { std::size_t operator()(const glslang::TString& s) const { const unsigned _FNV_offset_basis = 2166136261U; const unsigned _FNV_prime = 16777619U; unsigned _Val = _FNV_offset_basis; size_t _Count = s.size(); const char* _First = s.c_str(); for (size_t _Next = 0; _Next < _Count; ++_Next) { _Val ^= (unsigned)_First[_Next]; _Val *= _FNV_prime; } return _Val; } }; } namespace glslang { inline TString* NewPoolTString(const char* s) { void* memory = GetThreadPoolAllocator().allocate(sizeof(TString)); return new(memory) TString(s); } template inline T* NewPoolObject(T*) { return new(GetThreadPoolAllocator().allocate(sizeof(T))) T; } template inline T* NewPoolObject(T, int instances) { return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances]; } // // Pool allocator versions of vectors, lists, and maps // template class TVector : public std::vector > { public: POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) 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) {} TVector(size_type i, const T& val) : std::vector >(i, val) {} }; template class TList : public std::list > { }; template > class TMap : public std::map > > { }; template , class PRED = std::equal_to > class TUnorderedMap : public std::unordered_map > > { }; // // 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. // #if defined _MSC_VER || defined MINGW_HAS_SECURE_API 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 _itoa_s(i, text, sizeof(text), base); return text; } #else 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 for all cases snprintf(text, sizeof(text), "%d", i); return text; } #endif struct TSourceLoc { void init() { name = nullptr; string = 0; line = 0; column = 0; } void init(int stringNum) { init(); string = stringNum; } // Returns the name if it exists. Otherwise, returns the string number. std::string getStringNameOrNum(bool quoteStringName = true) const { if (name != nullptr) return quoteStringName ? ("\"" + std::string(name) + "\"") : name; return std::to_string((long long)string); } const char* name; // descriptive name for this string int string; int line; int column; }; class TPragmaTable : public TMap { public: POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) }; const int MaxTokenLength = 1024; template bool IsPow2(T powerOf2) { if (powerOf2 <= 0) return false; return (powerOf2 & (powerOf2 - 1)) == 0; } // Round number up to a multiple of the given powerOf2, which is not // a power, just a number that must be a power of 2. template void RoundToPow2(T& number, int powerOf2) { assert(IsPow2(powerOf2)); number = (number + powerOf2 - 1) & ~(powerOf2 - 1); } template bool IsMultipleOfPow2(T number, int powerOf2) { assert(IsPow2(powerOf2)); return ! (number & (powerOf2 - 1)); } } // end namespace glslang #endif // _COMMON_INCLUDED_