xref: /aosp_15_r20/external/angle/src/compiler/translator/Name.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 "compiler/translator/Name.h"
8 #include "common/debug.h"
9 #include "compiler/translator/tree_util/IntermTraverse.h"
10 
11 namespace sh
12 {
13 ////////////////////////////////////////////////////////////////////////////////
14 
15 template <typename T>
GetName(T const & object)16 static ImmutableString GetName(T const &object)
17 {
18     if (object.symbolType() == SymbolType::Empty)
19     {
20         return kEmptyImmutableString;
21     }
22     return object.name();
23 }
24 
Name(const TField & field)25 Name::Name(const TField &field) : Name(GetName(field), field.symbolType()) {}
26 
Name(const TSymbol & symbol)27 Name::Name(const TSymbol &symbol) : Name(GetName(symbol), symbol.symbolType()) {}
28 
operator ==(const Name & other) const29 bool Name::operator==(const Name &other) const
30 {
31     return mRawName == other.mRawName && mSymbolType == other.mSymbolType;
32 }
33 
operator !=(const Name & other) const34 bool Name::operator!=(const Name &other) const
35 {
36     return !(*this == other);
37 }
38 
operator <(const Name & other) const39 bool Name::operator<(const Name &other) const
40 {
41     if (mRawName < other.mRawName)
42     {
43         return true;
44     }
45     if (other.mRawName < mRawName)
46     {
47         return false;
48     }
49     return mSymbolType < other.mSymbolType;
50 }
51 
empty() const52 bool Name::empty() const
53 {
54     return mSymbolType == SymbolType::Empty;
55 }
56 
beginsWith(const Name & prefix) const57 bool Name::beginsWith(const Name &prefix) const
58 {
59     if (mSymbolType != prefix.mSymbolType)
60     {
61         return false;
62     }
63     return mRawName.beginsWith(prefix.mRawName);
64 }
65 
emit(TInfoSinkBase & out) const66 void Name::emit(TInfoSinkBase &out) const
67 {
68     emitImpl(out);
69 }
70 
71 template <typename T>
emitImpl(T & out) const72 void Name::emitImpl(T &out) const
73 {
74     switch (mSymbolType)
75     {
76         case SymbolType::BuiltIn:
77             ASSERT(!mRawName.empty());
78             out << mRawName;
79             break;
80 
81         case SymbolType::UserDefined:
82             ASSERT(!mRawName.empty());
83             if (mRawName != "main")
84             {
85                 out << kUserDefinedNamePrefix << mRawName;
86             }
87             else
88             {
89                 out << mRawName;
90             }
91             break;
92 
93         case SymbolType::AngleInternal:
94             ASSERT(!mRawName.empty());
95             if (mRawName.beginsWith(kAngleInternalPrefix))
96             {
97                 out << mRawName;
98             }
99             else
100             {
101                 out << kAngleInternalPrefix << '_' << mRawName;
102             }
103             break;
104 
105         case SymbolType::Empty:
106             UNREACHABLE();
107             break;
108     }
109 }
110 
operator <<(std::ostream & out,const Name & name)111 std::ostream &operator<<(std::ostream &out, const Name &name)
112 {
113     name.emitImpl(out);
114     return out;
115 }
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 
119 namespace
120 {
121 
122 // NOTE: This matches more things than FindSymbolNode.
123 class ExpressionContainsNameVisitor : public TIntermTraverser
124 {
125     Name mName;
126     bool mFoundName = false;
127 
128   public:
ExpressionContainsNameVisitor(const Name & name)129     ExpressionContainsNameVisitor(const Name &name)
130         : TIntermTraverser(true, false, false), mName(name)
131     {}
132 
foundName() const133     bool foundName() const { return mFoundName; }
134 
visitSymbol(TIntermSymbol * node)135     void visitSymbol(TIntermSymbol *node) override
136     {
137         if (Name(node->variable()) == mName)
138         {
139             mFoundName = true;
140         }
141     }
142 
visitSwizzle(Visit,TIntermSwizzle *)143     bool visitSwizzle(Visit, TIntermSwizzle *) override { return !mFoundName; }
144 
visitBinary(Visit visit,TIntermBinary * node)145     bool visitBinary(Visit visit, TIntermBinary *node) override { return !mFoundName; }
146 
visitUnary(Visit visit,TIntermUnary * node)147     bool visitUnary(Visit visit, TIntermUnary *node) override { return !mFoundName; }
148 
visitTernary(Visit visit,TIntermTernary * node)149     bool visitTernary(Visit visit, TIntermTernary *node) override { return !mFoundName; }
150 
visitAggregate(Visit visit,TIntermAggregate * node)151     bool visitAggregate(Visit visit, TIntermAggregate *node) override
152     {
153         if (node->isConstructor())
154         {
155             const TType &type           = node->getType();
156             const TStructure *structure = type.getStruct();
157             if (structure && Name(*structure) == mName)
158             {
159                 mFoundName = true;
160             }
161         }
162         else
163         {
164             const TFunction *func = node->getFunction();
165             if (func && Name(*func) == mName)
166             {
167                 mFoundName = true;
168             }
169         }
170         return !mFoundName;
171     }
172 
visitIfElse(Visit visit,TIntermIfElse * node)173     bool visitIfElse(Visit visit, TIntermIfElse *node) override
174     {
175         UNREACHABLE();
176         return false;
177     }
178 
visitSwitch(Visit,TIntermSwitch *)179     bool visitSwitch(Visit, TIntermSwitch *) override
180     {
181         UNREACHABLE();
182         return false;
183     }
visitCase(Visit,TIntermCase *)184     bool visitCase(Visit, TIntermCase *) override
185     {
186         UNREACHABLE();
187         return false;
188     }
189 
visitFunctionPrototype(TIntermFunctionPrototype *)190     void visitFunctionPrototype(TIntermFunctionPrototype *) override { UNREACHABLE(); }
191 
visitFunctionDefinition(Visit,TIntermFunctionDefinition *)192     bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *) override
193     {
194         UNREACHABLE();
195         return false;
196     }
197 
visitBlock(Visit,TIntermBlock *)198     bool visitBlock(Visit, TIntermBlock *) override
199     {
200         UNREACHABLE();
201         return false;
202     }
203 
visitGlobalQualifierDeclaration(Visit,TIntermGlobalQualifierDeclaration *)204     bool visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *) override
205     {
206         UNREACHABLE();
207         return false;
208     }
209 
visitDeclaration(Visit,TIntermDeclaration *)210     bool visitDeclaration(Visit, TIntermDeclaration *) override
211     {
212         UNREACHABLE();
213         return false;
214     }
215 
visitLoop(Visit,TIntermLoop *)216     bool visitLoop(Visit, TIntermLoop *) override
217     {
218         UNREACHABLE();
219         return false;
220     }
221 
visitBranch(Visit,TIntermBranch *)222     bool visitBranch(Visit, TIntermBranch *) override
223     {
224         UNREACHABLE();
225         return false;
226     }
227 
visitPreprocessorDirective(TIntermPreprocessorDirective *)228     void visitPreprocessorDirective(TIntermPreprocessorDirective *) override { UNREACHABLE(); }
229 };
230 
231 }  // anonymous namespace
232 
ExpressionContainsName(const Name & name,TIntermTyped & node)233 bool ExpressionContainsName(const Name &name, TIntermTyped &node)
234 {
235     ExpressionContainsNameVisitor visitor(name);
236     node.traverse(&visitor);
237     return visitor.foundName();
238 }
239 
240 }  // namespace sh
241