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