1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include <cctype>
8 #include <cstring>
9 #include <limits>
10 #include <unordered_map>
11 #include <unordered_set>
12
13 #include "compiler/translator/TranslatorMetalDirect/RewriteKeywords.h"
14
15 using namespace sh;
16
17 ////////////////////////////////////////////////////////////////////////////////
18
IdGen()19 IdGen::IdGen() {}
20
21 template <typename String, typename StringToImmutable>
createNewName(size_t count,const String * baseNames,const StringToImmutable & toImmutable)22 Name IdGen::createNewName(size_t count,
23 const String *baseNames,
24 const StringToImmutable &toImmutable)
25 {
26 const unsigned id = mNext++;
27 char idBuffer[std::numeric_limits<unsigned>::digits10 + 1];
28 sprintf(idBuffer, "%u", id);
29
30 mNewNameBuffer.clear();
31 mNewNameBuffer += '_';
32 mNewNameBuffer += idBuffer;
33
34 // Note:
35 // Double underscores are only allowed in C++ (and thus Metal) vendor identifiers, so here we
36 // take care not to introduce any.
37
38 for (size_t i = 0; i < count; ++i)
39 {
40 const ImmutableString baseName = toImmutable(baseNames[i]);
41 if (!baseName.empty())
42 {
43 const char *base = baseName.data();
44 if (baseName.beginsWith(kAngleInternalPrefix))
45 {
46 base += sizeof(kAngleInternalPrefix) - 1;
47 }
48 if (*base == '_')
49 {
50 ++base;
51 }
52 ASSERT(*base != '_');
53
54 if (mNewNameBuffer.back() != '_')
55 {
56 mNewNameBuffer += '_';
57 }
58
59 mNewNameBuffer += base;
60 }
61 }
62
63 return Name(ImmutableString(mNewNameBuffer), SymbolType::AngleInternal);
64 }
65
createNewName(const ImmutableString & baseName)66 Name IdGen::createNewName(const ImmutableString &baseName)
67 {
68 return createNewName({baseName});
69 }
70
createNewName(const Name & baseName)71 Name IdGen::createNewName(const Name &baseName)
72 {
73 return createNewName(baseName.rawName());
74 }
75
createNewName(const char * baseName)76 Name IdGen::createNewName(const char *baseName)
77 {
78 return createNewName(ImmutableString(baseName));
79 }
80
createNewName(std::initializer_list<ImmutableString> baseNames)81 Name IdGen::createNewName(std::initializer_list<ImmutableString> baseNames)
82 {
83 return createNewName(baseNames.size(), baseNames.begin(),
84 [](const ImmutableString &s) { return s; });
85 }
86
createNewName(std::initializer_list<Name> baseNames)87 Name IdGen::createNewName(std::initializer_list<Name> baseNames)
88 {
89 return createNewName(baseNames.size(), baseNames.begin(),
90 [](const Name &s) { return s.rawName(); });
91 }
92
createNewName(std::initializer_list<const char * > baseNames)93 Name IdGen::createNewName(std::initializer_list<const char *> baseNames)
94 {
95 return createNewName(baseNames.size(), baseNames.begin(),
96 [](const char *s) { return ImmutableString(s); });
97 }
98