xref: /aosp_15_r20/external/angle/src/compiler/translator/Common.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #ifndef COMPILER_TRANSLATOR_COMMON_H_
8*8975f5c5SAndroid Build Coastguard Worker #define COMPILER_TRANSLATOR_COMMON_H_
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include <stdio.h>
11*8975f5c5SAndroid Build Coastguard Worker #include <limits>
12*8975f5c5SAndroid Build Coastguard Worker #include <map>
13*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
14*8975f5c5SAndroid Build Coastguard Worker #include <string>
15*8975f5c5SAndroid Build Coastguard Worker #include <string_view>
16*8975f5c5SAndroid Build Coastguard Worker #include <unordered_map>
17*8975f5c5SAndroid Build Coastguard Worker #include <unordered_set>
18*8975f5c5SAndroid Build Coastguard Worker #include <vector>
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/PoolAlloc.h"
23*8975f5c5SAndroid Build Coastguard Worker 
24*8975f5c5SAndroid Build Coastguard Worker namespace sh
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker 
27*8975f5c5SAndroid Build Coastguard Worker struct TSourceLoc
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker     int first_file;
30*8975f5c5SAndroid Build Coastguard Worker     int first_line;
31*8975f5c5SAndroid Build Coastguard Worker     int last_file;
32*8975f5c5SAndroid Build Coastguard Worker     int last_line;
33*8975f5c5SAndroid Build Coastguard Worker };
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker constexpr TSourceLoc kNoSourceLoc{-1, -1, -1, -1};
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker //
38*8975f5c5SAndroid Build Coastguard Worker // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
39*8975f5c5SAndroid Build Coastguard Worker //
40*8975f5c5SAndroid Build Coastguard Worker #define POOL_ALLOCATOR_NEW_DELETE                     \
41*8975f5c5SAndroid Build Coastguard Worker     void *operator new(size_t s)                      \
42*8975f5c5SAndroid Build Coastguard Worker     {                                                 \
43*8975f5c5SAndroid Build Coastguard Worker         return GetGlobalPoolAllocator()->allocate(s); \
44*8975f5c5SAndroid Build Coastguard Worker     }                                                 \
45*8975f5c5SAndroid Build Coastguard Worker     void *operator new(size_t, void *_Where)          \
46*8975f5c5SAndroid Build Coastguard Worker     {                                                 \
47*8975f5c5SAndroid Build Coastguard Worker         return (_Where);                              \
48*8975f5c5SAndroid Build Coastguard Worker     }                                                 \
49*8975f5c5SAndroid Build Coastguard Worker     void operator delete(void *)                      \
50*8975f5c5SAndroid Build Coastguard Worker     {}                                                \
51*8975f5c5SAndroid Build Coastguard Worker     void operator delete(void *, void *)              \
52*8975f5c5SAndroid Build Coastguard Worker     {}                                                \
53*8975f5c5SAndroid Build Coastguard Worker     void *operator new[](size_t s)                    \
54*8975f5c5SAndroid Build Coastguard Worker     {                                                 \
55*8975f5c5SAndroid Build Coastguard Worker         return GetGlobalPoolAllocator()->allocate(s); \
56*8975f5c5SAndroid Build Coastguard Worker     }                                                 \
57*8975f5c5SAndroid Build Coastguard Worker     void *operator new[](size_t, void *_Where)        \
58*8975f5c5SAndroid Build Coastguard Worker     {                                                 \
59*8975f5c5SAndroid Build Coastguard Worker         return (_Where);                              \
60*8975f5c5SAndroid Build Coastguard Worker     }                                                 \
61*8975f5c5SAndroid Build Coastguard Worker     void operator delete[](void *)                    \
62*8975f5c5SAndroid Build Coastguard Worker     {}                                                \
63*8975f5c5SAndroid Build Coastguard Worker     void operator delete[](void *, void *)            \
64*8975f5c5SAndroid Build Coastguard Worker     {}
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker //
67*8975f5c5SAndroid Build Coastguard Worker // Pool version of string.
68*8975f5c5SAndroid Build Coastguard Worker //
69*8975f5c5SAndroid Build Coastguard Worker typedef pool_allocator<char> TStringAllocator;
70*8975f5c5SAndroid Build Coastguard Worker typedef std::basic_string<char, std::char_traits<char>, TStringAllocator> TString;
71*8975f5c5SAndroid Build Coastguard Worker typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
72*8975f5c5SAndroid Build Coastguard Worker 
73*8975f5c5SAndroid Build Coastguard Worker //
74*8975f5c5SAndroid Build Coastguard Worker // Persistent memory.  Should only be used for strings that survive across compiles.
75*8975f5c5SAndroid Build Coastguard Worker //
76*8975f5c5SAndroid Build Coastguard Worker using TPersistString       = std::string;
77*8975f5c5SAndroid Build Coastguard Worker using TPersistStringStream = std::ostringstream;
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker //
80*8975f5c5SAndroid Build Coastguard Worker // Pool allocator versions of vectors, lists, and maps
81*8975f5c5SAndroid Build Coastguard Worker //
82*8975f5c5SAndroid Build Coastguard Worker template <class T>
83*8975f5c5SAndroid Build Coastguard Worker class TVector : public std::vector<T, pool_allocator<T>>
84*8975f5c5SAndroid Build Coastguard Worker {
85*8975f5c5SAndroid Build Coastguard Worker   public:
86*8975f5c5SAndroid Build Coastguard Worker     POOL_ALLOCATOR_NEW_DELETE
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker     typedef typename std::vector<T, pool_allocator<T>>::size_type size_type;
TVector()89*8975f5c5SAndroid Build Coastguard Worker     TVector() : std::vector<T, pool_allocator<T>>() {}
TVector(const pool_allocator<T> & a)90*8975f5c5SAndroid Build Coastguard Worker     TVector(const pool_allocator<T> &a) : std::vector<T, pool_allocator<T>>(a) {}
TVector(size_type i)91*8975f5c5SAndroid Build Coastguard Worker     TVector(size_type i) : std::vector<T, pool_allocator<T>>(i) {}
TVector(size_type i,const T & value)92*8975f5c5SAndroid Build Coastguard Worker     TVector(size_type i, const T &value) : std::vector<T, pool_allocator<T>>(i, value) {}
93*8975f5c5SAndroid Build Coastguard Worker     template <typename InputIt>
TVector(InputIt first,InputIt last)94*8975f5c5SAndroid Build Coastguard Worker     TVector(InputIt first, InputIt last) : std::vector<T, pool_allocator<T>>(first, last)
95*8975f5c5SAndroid Build Coastguard Worker     {}
TVector(std::initializer_list<T> init)96*8975f5c5SAndroid Build Coastguard Worker     TVector(std::initializer_list<T> init) : std::vector<T, pool_allocator<T>>(init) {}
97*8975f5c5SAndroid Build Coastguard Worker };
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker template <class K, class D, class H = std::hash<K>, class CMP = std::equal_to<K>>
100*8975f5c5SAndroid Build Coastguard Worker class TUnorderedMap : public std::unordered_map<K, D, H, CMP, pool_allocator<std::pair<const K, D>>>
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker   public:
103*8975f5c5SAndroid Build Coastguard Worker     POOL_ALLOCATOR_NEW_DELETE
104*8975f5c5SAndroid Build Coastguard Worker     typedef pool_allocator<std::pair<const K, D>> tAllocator;
105*8975f5c5SAndroid Build Coastguard Worker 
TUnorderedMap()106*8975f5c5SAndroid Build Coastguard Worker     TUnorderedMap() : std::unordered_map<K, D, H, CMP, tAllocator>() {}
107*8975f5c5SAndroid Build Coastguard Worker     // use correct two-stage name lookup supported in gcc 3.4 and above
TUnorderedMap(const tAllocator & a)108*8975f5c5SAndroid Build Coastguard Worker     TUnorderedMap(const tAllocator &a)
109*8975f5c5SAndroid Build Coastguard Worker         : std::unordered_map<K, D, H, CMP, tAllocator>(
110*8975f5c5SAndroid Build Coastguard Worker               std::unordered_map<K, D, H, CMP, tAllocator>::key_compare(),
111*8975f5c5SAndroid Build Coastguard Worker               a)
112*8975f5c5SAndroid Build Coastguard Worker     {}
113*8975f5c5SAndroid Build Coastguard Worker };
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker template <class K, class H = std::hash<K>, class CMP = std::equal_to<K>>
116*8975f5c5SAndroid Build Coastguard Worker class TUnorderedSet : public std::unordered_set<K, H, CMP, pool_allocator<K>>
117*8975f5c5SAndroid Build Coastguard Worker {
118*8975f5c5SAndroid Build Coastguard Worker   public:
119*8975f5c5SAndroid Build Coastguard Worker     POOL_ALLOCATOR_NEW_DELETE
120*8975f5c5SAndroid Build Coastguard Worker     typedef pool_allocator<K> tAllocator;
121*8975f5c5SAndroid Build Coastguard Worker 
TUnorderedSet()122*8975f5c5SAndroid Build Coastguard Worker     TUnorderedSet() : std::unordered_set<K, H, CMP, tAllocator>() {}
123*8975f5c5SAndroid Build Coastguard Worker     // use correct two-stage name lookup supported in gcc 3.4 and above
TUnorderedSet(const tAllocator & a)124*8975f5c5SAndroid Build Coastguard Worker     TUnorderedSet(const tAllocator &a)
125*8975f5c5SAndroid Build Coastguard Worker         : std::unordered_set<K, H, CMP, tAllocator>(
126*8975f5c5SAndroid Build Coastguard Worker               std::unordered_set<K, H, CMP, tAllocator>::key_compare(),
127*8975f5c5SAndroid Build Coastguard Worker               a)
128*8975f5c5SAndroid Build Coastguard Worker     {}
129*8975f5c5SAndroid Build Coastguard Worker };
130*8975f5c5SAndroid Build Coastguard Worker 
131*8975f5c5SAndroid Build Coastguard Worker template <class K, class D, class CMP = std::less<K>>
132*8975f5c5SAndroid Build Coastguard Worker class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D>>>
133*8975f5c5SAndroid Build Coastguard Worker {
134*8975f5c5SAndroid Build Coastguard Worker   public:
135*8975f5c5SAndroid Build Coastguard Worker     POOL_ALLOCATOR_NEW_DELETE
136*8975f5c5SAndroid Build Coastguard Worker     typedef pool_allocator<std::pair<const K, D>> tAllocator;
137*8975f5c5SAndroid Build Coastguard Worker 
TMap()138*8975f5c5SAndroid Build Coastguard Worker     TMap() : std::map<K, D, CMP, tAllocator>() {}
139*8975f5c5SAndroid Build Coastguard Worker     // use correct two-stage name lookup supported in gcc 3.4 and above
TMap(const tAllocator & a)140*8975f5c5SAndroid Build Coastguard Worker     TMap(const tAllocator &a)
141*8975f5c5SAndroid Build Coastguard Worker         : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a)
142*8975f5c5SAndroid Build Coastguard Worker     {}
143*8975f5c5SAndroid Build Coastguard Worker };
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker // Basic implementation of C++20's span for use with pool-allocated containers (TVector) or static
146*8975f5c5SAndroid Build Coastguard Worker // arrays.  This is used by the array sizes member of TType to allow arrayed types to be
147*8975f5c5SAndroid Build Coastguard Worker // constexpr-constructed.
148*8975f5c5SAndroid Build Coastguard Worker // See the reference for std::span here: https://en.cppreference.com/w/cpp/container/span
149*8975f5c5SAndroid Build Coastguard Worker template <typename T>
150*8975f5c5SAndroid Build Coastguard Worker class TSpan
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker   public:
153*8975f5c5SAndroid Build Coastguard Worker     typedef size_t size_type;
154*8975f5c5SAndroid Build Coastguard Worker 
TSpan()155*8975f5c5SAndroid Build Coastguard Worker     constexpr TSpan() {}
TSpan(T * ptr,size_type size)156*8975f5c5SAndroid Build Coastguard Worker     constexpr TSpan(T *ptr, size_type size) : mData(ptr), mSize(size) {}
157*8975f5c5SAndroid Build Coastguard Worker 
TSpan(const TSpan & that)158*8975f5c5SAndroid Build Coastguard Worker     constexpr TSpan(const TSpan &that) : mData(that.mData), mSize(that.mSize) {}
159*8975f5c5SAndroid Build Coastguard Worker     constexpr TSpan &operator=(const TSpan &that)
160*8975f5c5SAndroid Build Coastguard Worker     {
161*8975f5c5SAndroid Build Coastguard Worker         mData = that.mData;
162*8975f5c5SAndroid Build Coastguard Worker         mSize = that.mSize;
163*8975f5c5SAndroid Build Coastguard Worker         return *this;
164*8975f5c5SAndroid Build Coastguard Worker     }
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker     // Note: the pointer is taken out of the TVector because TVector's memory is pool allocated,
167*8975f5c5SAndroid Build Coastguard Worker     // so the memory will live on even if the TVector is destroyed.
168*8975f5c5SAndroid Build Coastguard Worker     template <typename S>
TSpan(const TVector<S> & vec)169*8975f5c5SAndroid Build Coastguard Worker     TSpan(const TVector<S> &vec) : mData(vec.data()), mSize(vec.size())
170*8975f5c5SAndroid Build Coastguard Worker     {}
171*8975f5c5SAndroid Build Coastguard Worker     template <typename S>
172*8975f5c5SAndroid Build Coastguard Worker     TSpan &operator=(const TVector<S> &vec)
173*8975f5c5SAndroid Build Coastguard Worker     {
174*8975f5c5SAndroid Build Coastguard Worker         mData = vec.data();
175*8975f5c5SAndroid Build Coastguard Worker         mSize = vec.size();
176*8975f5c5SAndroid Build Coastguard Worker         return *this;
177*8975f5c5SAndroid Build Coastguard Worker     }
178*8975f5c5SAndroid Build Coastguard Worker 
179*8975f5c5SAndroid Build Coastguard Worker     constexpr bool operator==(const TSpan &that) const
180*8975f5c5SAndroid Build Coastguard Worker     {
181*8975f5c5SAndroid Build Coastguard Worker         if (mSize != that.mSize)
182*8975f5c5SAndroid Build Coastguard Worker         {
183*8975f5c5SAndroid Build Coastguard Worker             return false;
184*8975f5c5SAndroid Build Coastguard Worker         }
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker         if (mData == that.mData)
187*8975f5c5SAndroid Build Coastguard Worker         {
188*8975f5c5SAndroid Build Coastguard Worker             return true;
189*8975f5c5SAndroid Build Coastguard Worker         }
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker         for (size_type index = 0; index < mSize; ++index)
192*8975f5c5SAndroid Build Coastguard Worker         {
193*8975f5c5SAndroid Build Coastguard Worker             if (mData[index] != that.mData[index])
194*8975f5c5SAndroid Build Coastguard Worker             {
195*8975f5c5SAndroid Build Coastguard Worker                 return false;
196*8975f5c5SAndroid Build Coastguard Worker             }
197*8975f5c5SAndroid Build Coastguard Worker         }
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker         return true;
200*8975f5c5SAndroid Build Coastguard Worker     }
201*8975f5c5SAndroid Build Coastguard Worker     constexpr bool operator!=(const TSpan &that) const { return !(*this == that); }
202*8975f5c5SAndroid Build Coastguard Worker 
data()203*8975f5c5SAndroid Build Coastguard Worker     constexpr T *data() const { return mData; }
size()204*8975f5c5SAndroid Build Coastguard Worker     constexpr size_type size() const { return mSize; }
empty()205*8975f5c5SAndroid Build Coastguard Worker     constexpr bool empty() const { return mSize == 0; }
206*8975f5c5SAndroid Build Coastguard Worker 
207*8975f5c5SAndroid Build Coastguard Worker     constexpr T &operator[](size_type index) const { return mData[index]; }
front()208*8975f5c5SAndroid Build Coastguard Worker     constexpr T &front() const { return mData[0]; }
back()209*8975f5c5SAndroid Build Coastguard Worker     constexpr T &back() const { return mData[mSize - 1]; }
210*8975f5c5SAndroid Build Coastguard Worker 
begin()211*8975f5c5SAndroid Build Coastguard Worker     constexpr T *begin() const { return mData; }
end()212*8975f5c5SAndroid Build Coastguard Worker     constexpr T *end() const { return mData + mSize; }
213*8975f5c5SAndroid Build Coastguard Worker 
rbegin()214*8975f5c5SAndroid Build Coastguard Worker     constexpr std::reverse_iterator<T *> rbegin() const
215*8975f5c5SAndroid Build Coastguard Worker     {
216*8975f5c5SAndroid Build Coastguard Worker         return std::make_reverse_iterator(end());
217*8975f5c5SAndroid Build Coastguard Worker     }
rend()218*8975f5c5SAndroid Build Coastguard Worker     constexpr std::reverse_iterator<T *> rend() const
219*8975f5c5SAndroid Build Coastguard Worker     {
220*8975f5c5SAndroid Build Coastguard Worker         return std::make_reverse_iterator(begin());
221*8975f5c5SAndroid Build Coastguard Worker     }
222*8975f5c5SAndroid Build Coastguard Worker 
first(size_type count)223*8975f5c5SAndroid Build Coastguard Worker     constexpr TSpan first(size_type count) const
224*8975f5c5SAndroid Build Coastguard Worker     {
225*8975f5c5SAndroid Build Coastguard Worker         ASSERT(count <= mSize);
226*8975f5c5SAndroid Build Coastguard Worker         return count == 0 ? TSpan() : TSpan(mData, count);
227*8975f5c5SAndroid Build Coastguard Worker     }
last(size_type count)228*8975f5c5SAndroid Build Coastguard Worker     constexpr TSpan last(size_type count) const
229*8975f5c5SAndroid Build Coastguard Worker     {
230*8975f5c5SAndroid Build Coastguard Worker         ASSERT(count <= mSize);
231*8975f5c5SAndroid Build Coastguard Worker         return count == 0 ? TSpan() : TSpan(mData + mSize - count, count);
232*8975f5c5SAndroid Build Coastguard Worker     }
subspan(size_type offset,size_type count)233*8975f5c5SAndroid Build Coastguard Worker     constexpr TSpan subspan(size_type offset, size_type count) const
234*8975f5c5SAndroid Build Coastguard Worker     {
235*8975f5c5SAndroid Build Coastguard Worker         ASSERT(offset + count <= mSize);
236*8975f5c5SAndroid Build Coastguard Worker         return count == 0 ? TSpan() : TSpan(mData + offset, count);
237*8975f5c5SAndroid Build Coastguard Worker     }
238*8975f5c5SAndroid Build Coastguard Worker 
239*8975f5c5SAndroid Build Coastguard Worker   private:
240*8975f5c5SAndroid Build Coastguard Worker     T *mData     = nullptr;
241*8975f5c5SAndroid Build Coastguard Worker     size_t mSize = 0;
242*8975f5c5SAndroid Build Coastguard Worker };
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker // Integer to TString conversion
245*8975f5c5SAndroid Build Coastguard Worker template <typename T>
str(T i)246*8975f5c5SAndroid Build Coastguard Worker inline TString str(T i)
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker     ASSERT(std::numeric_limits<T>::is_integer);
249*8975f5c5SAndroid Build Coastguard Worker     char buffer[((8 * sizeof(T)) / 3) + 3];
250*8975f5c5SAndroid Build Coastguard Worker     const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";
251*8975f5c5SAndroid Build Coastguard Worker     snprintf(buffer, sizeof(buffer), formatStr, i);
252*8975f5c5SAndroid Build Coastguard Worker     return buffer;
253*8975f5c5SAndroid Build Coastguard Worker }
254*8975f5c5SAndroid Build Coastguard Worker 
255*8975f5c5SAndroid Build Coastguard Worker // Allocate a char array in the global memory pool. str must be a null terminated string. strLength
256*8975f5c5SAndroid Build Coastguard Worker // is the length without the null terminator.
AllocatePoolCharArray(const char * str,size_t strLength)257*8975f5c5SAndroid Build Coastguard Worker inline const char *AllocatePoolCharArray(const char *str, size_t strLength)
258*8975f5c5SAndroid Build Coastguard Worker {
259*8975f5c5SAndroid Build Coastguard Worker     size_t requiredSize = strLength + 1;
260*8975f5c5SAndroid Build Coastguard Worker     char *buffer        = static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
261*8975f5c5SAndroid Build Coastguard Worker     memcpy(buffer, str, requiredSize);
262*8975f5c5SAndroid Build Coastguard Worker     ASSERT(buffer[strLength] == '\0');
263*8975f5c5SAndroid Build Coastguard Worker     return buffer;
264*8975f5c5SAndroid Build Coastguard Worker }
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker // Initialize a new stream which must be imbued with the classic locale
267*8975f5c5SAndroid Build Coastguard Worker template <typename T>
InitializeStream()268*8975f5c5SAndroid Build Coastguard Worker T InitializeStream()
269*8975f5c5SAndroid Build Coastguard Worker {
270*8975f5c5SAndroid Build Coastguard Worker     T stream;
271*8975f5c5SAndroid Build Coastguard Worker     stream.imbue(std::locale::classic());
272*8975f5c5SAndroid Build Coastguard Worker     return stream;
273*8975f5c5SAndroid Build Coastguard Worker }
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker }  // namespace sh
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker namespace std
278*8975f5c5SAndroid Build Coastguard Worker {
279*8975f5c5SAndroid Build Coastguard Worker template <>
280*8975f5c5SAndroid Build Coastguard Worker struct hash<sh::TString>
281*8975f5c5SAndroid Build Coastguard Worker {
282*8975f5c5SAndroid Build Coastguard Worker     size_t operator()(const sh::TString &s) const
283*8975f5c5SAndroid Build Coastguard Worker     {
284*8975f5c5SAndroid Build Coastguard Worker         auto v = std::string_view(s.data(), static_cast<int>(s.length()));
285*8975f5c5SAndroid Build Coastguard Worker         return std::hash<std::string_view>{}(v);
286*8975f5c5SAndroid Build Coastguard Worker     }
287*8975f5c5SAndroid Build Coastguard Worker };
288*8975f5c5SAndroid Build Coastguard Worker }  // namespace std
289*8975f5c5SAndroid Build Coastguard Worker 
290*8975f5c5SAndroid Build Coastguard Worker #endif  // COMPILER_TRANSLATOR_COMMON_H_
291