Path: blob/main_old/src/compiler/translator/Common.h
1693 views
//1// Copyright 2002 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#ifndef COMPILER_TRANSLATOR_COMMON_H_7#define COMPILER_TRANSLATOR_COMMON_H_89#include <stdio.h>10#include <limits>11#include <map>12#include <sstream>13#include <string>14#include <unordered_map>15#include <vector>1617#include "common/angleutils.h"18#include "common/debug.h"19#include "common/third_party/smhasher/src/PMurHash.h"20#include "compiler/translator/PoolAlloc.h"2122namespace sh23{2425struct TSourceLoc26{27int first_file;28int first_line;29int last_file;30int last_line;31};3233constexpr TSourceLoc kNoSourceLoc{-1, -1, -1, -1};3435//36// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.37//38#define POOL_ALLOCATOR_NEW_DELETE \39void *operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \40void *operator new(size_t, void *_Where) { return (_Where); } \41void operator delete(void *) {} \42void operator delete(void *, void *) {} \43void *operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \44void *operator new[](size_t, void *_Where) { return (_Where); } \45void operator delete[](void *) {} \46void operator delete[](void *, void *) {}4748//49// Pool version of string.50//51typedef pool_allocator<char> TStringAllocator;52typedef std::basic_string<char, std::char_traits<char>, TStringAllocator> TString;53typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;5455//56// Persistent memory. Should only be used for strings that survive across compiles.57//58using TPersistString = std::string;59using TPersistStringStream = std::ostringstream;6061//62// Pool allocator versions of vectors, lists, and maps63//64template <class T>65class TVector : public std::vector<T, pool_allocator<T>>66{67public:68POOL_ALLOCATOR_NEW_DELETE6970typedef typename std::vector<T, pool_allocator<T>>::size_type size_type;71TVector() : std::vector<T, pool_allocator<T>>() {}72TVector(const pool_allocator<T> &a) : std::vector<T, pool_allocator<T>>(a) {}73TVector(size_type i) : std::vector<T, pool_allocator<T>>(i) {}74TVector(size_type i, const T &value) : std::vector<T, pool_allocator<T>>(i, value) {}75template <typename InputIt>76TVector(InputIt first, InputIt last) : std::vector<T, pool_allocator<T>>(first, last)77{}78TVector(std::initializer_list<T> init) : std::vector<T, pool_allocator<T>>(init) {}79};8081template <class K, class D, class H = std::hash<K>, class CMP = std::equal_to<K>>82class TUnorderedMap : public std::unordered_map<K, D, H, CMP, pool_allocator<std::pair<const K, D>>>83{84public:85POOL_ALLOCATOR_NEW_DELETE86typedef pool_allocator<std::pair<const K, D>> tAllocator;8788TUnorderedMap() : std::unordered_map<K, D, H, CMP, tAllocator>() {}89// use correct two-stage name lookup supported in gcc 3.4 and above90TUnorderedMap(const tAllocator &a)91: std::unordered_map<K, D, H, CMP, tAllocator>(92std::unordered_map<K, D, H, CMP, tAllocator>::key_compare(),93a)94{}95};9697template <class K, class D, class CMP = std::less<K>>98class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D>>>99{100public:101POOL_ALLOCATOR_NEW_DELETE102typedef pool_allocator<std::pair<const K, D>> tAllocator;103104TMap() : std::map<K, D, CMP, tAllocator>() {}105// use correct two-stage name lookup supported in gcc 3.4 and above106TMap(const tAllocator &a)107: std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a)108{}109};110111// Basic implementation of C++20's span for use with pool-allocated containers (TVector) or static112// arrays. This is used by the array sizes member of TType to allow arrayed types to be113// constexpr-constructed.114// See the reference for std::span here: https://en.cppreference.com/w/cpp/container/span115template <typename T>116class TSpan117{118public:119typedef size_t size_type;120121constexpr TSpan() {}122constexpr TSpan(T *ptr, size_type size) : mData(ptr), mSize(size) {}123124constexpr TSpan(const TSpan &that) : mData(that.mData), mSize(that.mSize) {}125constexpr TSpan &operator=(const TSpan &that)126{127mData = that.mData;128mSize = that.mSize;129return *this;130}131132// Note: the pointer is taken out of the TVector because TVector's memory is pool allocated,133// so the memory will live on even if the TVector is destroyed.134template <typename S>135TSpan(const TVector<S> &vec) : mData(vec.data()), mSize(vec.size())136{}137template <typename S>138TSpan &operator=(const TVector<S> &vec)139{140mData = vec.data();141mSize = vec.size();142return *this;143}144145constexpr bool operator==(const TSpan &that) const146{147if (mSize != that.mSize)148{149return false;150}151152if (mData == that.mData)153{154return true;155}156157for (size_type index = 0; index < mSize; ++index)158{159if (mData[index] != that.mData[index])160{161return false;162}163}164165return true;166}167constexpr bool operator!=(const TSpan &that) const { return !(*this == that); }168169constexpr T *data() const { return mData; }170constexpr size_type size() const { return mSize; }171constexpr bool empty() const { return mSize == 0; }172173constexpr T &operator[](size_type index) const { return mData[index]; }174constexpr T &front() const { return mData[0]; }175constexpr T &back() const { return mData[mSize - 1]; }176177constexpr T *begin() const { return mData; }178constexpr T *end() const { return mData + mSize; }179180constexpr std::reverse_iterator<T *> rbegin() const181{182return std::make_reverse_iterator(end());183}184constexpr std::reverse_iterator<T *> rend() const185{186return std::make_reverse_iterator(begin());187}188189constexpr TSpan first(size_type count) const190{191ASSERT(count <= mSize);192return count == 0 ? TSpan() : TSpan(mData, count);193}194constexpr TSpan last(size_type count) const195{196ASSERT(count <= mSize);197return count == 0 ? TSpan() : TSpan(mData + mSize - count, count);198}199constexpr TSpan subspan(size_type offset, size_type count) const200{201ASSERT(offset + count <= mSize);202return count == 0 ? TSpan() : TSpan(mData + offset, count);203}204205private:206T *mData = nullptr;207size_t mSize = 0;208};209210// Integer to TString conversion211template <typename T>212inline TString str(T i)213{214ASSERT(std::numeric_limits<T>::is_integer);215char buffer[((8 * sizeof(T)) / 3) + 3];216const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";217snprintf(buffer, sizeof(buffer), formatStr, i);218return buffer;219}220221// Allocate a char array in the global memory pool. str must be a null terminated string. strLength222// is the length without the null terminator.223inline const char *AllocatePoolCharArray(const char *str, size_t strLength)224{225size_t requiredSize = strLength + 1;226char *buffer = static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));227memcpy(buffer, str, requiredSize);228ASSERT(buffer[strLength] == '\0');229return buffer;230}231232// Initialize a new stream which must be imbued with the classic locale233template <typename T>234T InitializeStream()235{236T stream;237stream.imbue(std::locale::classic());238return stream;239}240241} // namespace sh242243namespace std244{245template <>246struct hash<sh::TString>247{248size_t operator()(const sh::TString &s) const249{250return angle::PMurHash32(0, s.data(), static_cast<int>(s.length()));251}252};253} // namespace std254255#endif // COMPILER_TRANSLATOR_COMMON_H_256257258