| // |
| // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| #ifndef COMPILER_TRANSLATOR_COMMON_H_ |
| #define COMPILER_TRANSLATOR_COMMON_H_ |
| |
| #include <stdio.h> |
| #include <limits> |
| #include <map> |
| #include <sstream> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| #include "common/angleutils.h" |
| #include "common/debug.h" |
| #include "common/third_party/smhasher/src/PMurHash.h" |
| #include "compiler/translator/PoolAlloc.h" |
| |
| namespace sh |
| { |
| |
| struct TSourceLoc |
| { |
| int first_file; |
| int first_line; |
| int last_file; |
| int last_line; |
| }; |
| |
| // |
| // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme. |
| // |
| #define POOL_ALLOCATOR_NEW_DELETE \ |
| void *operator new(size_t s) { return GetGlobalPoolAllocator()->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 GetGlobalPoolAllocator()->allocate(s); } \ |
| void *operator new[](size_t, void *_Where) { return (_Where); } \ |
| void operator delete[](void *) {} \ |
| void operator delete[](void *, void *) {} |
| |
| // |
| // Pool version of string. |
| // |
| typedef pool_allocator<char> TStringAllocator; |
| typedef std::basic_string<char, std::char_traits<char>, TStringAllocator> TString; |
| typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream; |
| |
| // |
| // Persistent string memory. Should only be used for strings that survive |
| // across compiles. |
| // |
| #define TPersistString std::string |
| #define TPersistStringStream std::ostringstream |
| |
| // |
| // Pool allocator versions of vectors, lists, and maps |
| // |
| template <class T> |
| class TVector : public std::vector<T, pool_allocator<T>> |
| { |
| public: |
| POOL_ALLOCATOR_NEW_DELETE |
| |
| typedef typename std::vector<T, pool_allocator<T>>::size_type size_type; |
| TVector() : std::vector<T, pool_allocator<T>>() {} |
| TVector(const pool_allocator<T> &a) : std::vector<T, pool_allocator<T>>(a) {} |
| TVector(size_type i) : std::vector<T, pool_allocator<T>>(i) {} |
| }; |
| |
| template <class K, class D, class H = std::hash<K>, class CMP = std::equal_to<K>> |
| class TUnorderedMap : public std::unordered_map<K, D, H, CMP, pool_allocator<std::pair<const K, D>>> |
| { |
| public: |
| POOL_ALLOCATOR_NEW_DELETE |
| typedef pool_allocator<std::pair<const K, D>> tAllocator; |
| |
| TUnorderedMap() : std::unordered_map<K, D, H, CMP, tAllocator>() {} |
| // use correct two-stage name lookup supported in gcc 3.4 and above |
| TUnorderedMap(const tAllocator &a) |
| : std::unordered_map<K, D, H, CMP, tAllocator>( |
| std::unordered_map<K, D, H, CMP, tAllocator>::key_compare(), |
| a) |
| {} |
| }; |
| |
| template <class K, class D, class CMP = std::less<K>> |
| class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D>>> |
| { |
| public: |
| POOL_ALLOCATOR_NEW_DELETE |
| typedef pool_allocator<std::pair<const K, D>> tAllocator; |
| |
| TMap() : std::map<K, D, CMP, tAllocator>() {} |
| // use correct two-stage name lookup supported in gcc 3.4 and above |
| TMap(const tAllocator &a) |
| : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) |
| {} |
| }; |
| |
| // Integer to TString conversion |
| template <typename T> |
| inline TString str(T i) |
| { |
| ASSERT(std::numeric_limits<T>::is_integer); |
| char buffer[((8 * sizeof(T)) / 3) + 3]; |
| const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u"; |
| snprintf(buffer, sizeof(buffer), formatStr, i); |
| return buffer; |
| } |
| |
| // Allocate a char array in the global memory pool. str must be a null terminated string. strLength |
| // is the length without the null terminator. |
| inline const char *AllocatePoolCharArray(const char *str, size_t strLength) |
| { |
| size_t requiredSize = strLength + 1; |
| char *buffer = static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize)); |
| memcpy(buffer, str, requiredSize); |
| ASSERT(buffer[strLength] == '\0'); |
| return buffer; |
| } |
| |
| // Initialize a new stream which must be imbued with the classic locale |
| template <typename T> |
| T InitializeStream() |
| { |
| T stream; |
| stream.imbue(std::locale::classic()); |
| return stream; |
| } |
| |
| } // namespace sh |
| |
| namespace std |
| { |
| template <> |
| struct hash<sh::TString> |
| { |
| size_t operator()(const sh::TString &s) const |
| { |
| return angle::PMurHash32(0, s.data(), static_cast<int>(s.length())); |
| } |
| }; |
| } // namespace std |
| |
| #endif // COMPILER_TRANSLATOR_COMMON_H_ |