xref: /aosp_15_r20/external/angle/src/compiler/translator/IntermRebuild.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 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_INTERMREBUILD_H_
8*8975f5c5SAndroid Build Coastguard Worker #define COMPILER_TRANSLATOR_INTERMREBUILD_H_
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/NodeType.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_util/IntermTraverse.h"
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker namespace sh
14*8975f5c5SAndroid Build Coastguard Worker {
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker // Walks the tree to rebuild nodes.
17*8975f5c5SAndroid Build Coastguard Worker // This class is intended to be derived with overridden visitXXX functions.
18*8975f5c5SAndroid Build Coastguard Worker //
19*8975f5c5SAndroid Build Coastguard Worker // Each visitXXX function that does not have a Visit parameter simply has the visitor called
20*8975f5c5SAndroid Build Coastguard Worker // exactly once, regardless of (preVisit) or (postVisit) values.
21*8975f5c5SAndroid Build Coastguard Worker 
22*8975f5c5SAndroid Build Coastguard Worker // Each visitXXX function that has a Visit parameter behaves as follows:
23*8975f5c5SAndroid Build Coastguard Worker //    * If (preVisit):
24*8975f5c5SAndroid Build Coastguard Worker //      - The node is visited before children are traversed.
25*8975f5c5SAndroid Build Coastguard Worker //      - The returned value is used to replace the visited node. The returned value may be the same
26*8975f5c5SAndroid Build Coastguard Worker //        as the original node.
27*8975f5c5SAndroid Build Coastguard Worker //      - If multiple nodes are returned, children and post visits of the returned nodes are not
28*8975f5c5SAndroid Build Coastguard Worker //        preformed, even if it is a singleton collection.
29*8975f5c5SAndroid Build Coastguard Worker //    * If (childVisit)
30*8975f5c5SAndroid Build Coastguard Worker //      - If any new children are returned, the node is automatically rebuilt with the new children
31*8975f5c5SAndroid Build Coastguard Worker //        before post visit.
32*8975f5c5SAndroid Build Coastguard Worker //      - Depending on the type of the node, null children may be discarded.
33*8975f5c5SAndroid Build Coastguard Worker //      - Ill-typed children cause rebuild errors. Ill-typed means the node to automatically rebuild
34*8975f5c5SAndroid Build Coastguard Worker //        cannot accept a child of a certain type as input to its constructor.
35*8975f5c5SAndroid Build Coastguard Worker //      - Only instances of TIntermAggregateBase can accept Multi results for any of its children.
36*8975f5c5SAndroid Build Coastguard Worker //        If supplied, the nodes are spliced children at the spot of the original child.
37*8975f5c5SAndroid Build Coastguard Worker //    * If (postVisit)
38*8975f5c5SAndroid Build Coastguard Worker //      - The node is visited after any children are traversed.
39*8975f5c5SAndroid Build Coastguard Worker //      - Only after such a rebuild (or lack thereof), the post-visit is performed.
40*8975f5c5SAndroid Build Coastguard Worker //
41*8975f5c5SAndroid Build Coastguard Worker // Nodes in visit functions are allowed to be modified in place, including TIntermAggregateBase
42*8975f5c5SAndroid Build Coastguard Worker // child sequences.
43*8975f5c5SAndroid Build Coastguard Worker //
44*8975f5c5SAndroid Build Coastguard Worker // The default implementations of all the visitXXX functions support full pre and post traversal
45*8975f5c5SAndroid Build Coastguard Worker // without modifying the visited nodes.
46*8975f5c5SAndroid Build Coastguard Worker //
47*8975f5c5SAndroid Build Coastguard Worker class TIntermRebuild : angle::NonCopyable
48*8975f5c5SAndroid Build Coastguard Worker {
49*8975f5c5SAndroid Build Coastguard Worker 
50*8975f5c5SAndroid Build Coastguard Worker     enum class Action
51*8975f5c5SAndroid Build Coastguard Worker     {
52*8975f5c5SAndroid Build Coastguard Worker         ReplaceSingle,
53*8975f5c5SAndroid Build Coastguard Worker         ReplaceMulti,
54*8975f5c5SAndroid Build Coastguard Worker         Drop,
55*8975f5c5SAndroid Build Coastguard Worker         Fail,
56*8975f5c5SAndroid Build Coastguard Worker     };
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker   public:
59*8975f5c5SAndroid Build Coastguard Worker     struct Fail
60*8975f5c5SAndroid Build Coastguard Worker     {};
61*8975f5c5SAndroid Build Coastguard Worker 
62*8975f5c5SAndroid Build Coastguard Worker     enum VisitBits : size_t
63*8975f5c5SAndroid Build Coastguard Worker     {
64*8975f5c5SAndroid Build Coastguard Worker         // No bits are set.
65*8975f5c5SAndroid Build Coastguard Worker         Empty = 0u,
66*8975f5c5SAndroid Build Coastguard Worker 
67*8975f5c5SAndroid Build Coastguard Worker         // Allow visit of returned node's children.
68*8975f5c5SAndroid Build Coastguard Worker         Children = 1u << 0u,
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker         // Allow post visit of returned node.
71*8975f5c5SAndroid Build Coastguard Worker         Post = 1u << 1u,
72*8975f5c5SAndroid Build Coastguard Worker 
73*8975f5c5SAndroid Build Coastguard Worker         // If (Children) bit, only visit if the returned node is the same as the original node.
74*8975f5c5SAndroid Build Coastguard Worker         ChildrenRequiresSame = 1u << 2u,
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker         // If (Post) bit, only visit if the returned node is the same as the original node.
77*8975f5c5SAndroid Build Coastguard Worker         PostRequiresSame = 1u << 3u,
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker         RequireSame  = ChildrenRequiresSame | PostRequiresSame,
80*8975f5c5SAndroid Build Coastguard Worker         Neither      = Empty,
81*8975f5c5SAndroid Build Coastguard Worker         Both         = Children | Post,
82*8975f5c5SAndroid Build Coastguard Worker         BothWhenSame = Both | RequireSame,
83*8975f5c5SAndroid Build Coastguard Worker     };
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker   private:
86*8975f5c5SAndroid Build Coastguard Worker     struct NodeStackGuard;
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker     template <typename T>
89*8975f5c5SAndroid Build Coastguard Worker     struct ConsList
90*8975f5c5SAndroid Build Coastguard Worker     {
91*8975f5c5SAndroid Build Coastguard Worker         T value;
92*8975f5c5SAndroid Build Coastguard Worker         ConsList<T> *tail;
93*8975f5c5SAndroid Build Coastguard Worker     };
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     class BaseResult
96*8975f5c5SAndroid Build Coastguard Worker     {
97*8975f5c5SAndroid Build Coastguard Worker         BaseResult(const BaseResult &)            = delete;
98*8975f5c5SAndroid Build Coastguard Worker         BaseResult &operator=(const BaseResult &) = delete;
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker       public:
101*8975f5c5SAndroid Build Coastguard Worker         BaseResult(BaseResult &&other) = default;
102*8975f5c5SAndroid Build Coastguard Worker         BaseResult(BaseResult &other);  // For subclass move constructor impls
103*8975f5c5SAndroid Build Coastguard Worker         BaseResult(TIntermNode &node, VisitBits visit);
104*8975f5c5SAndroid Build Coastguard Worker         BaseResult(TIntermNode *node, VisitBits visit);
105*8975f5c5SAndroid Build Coastguard Worker         BaseResult(std::nullptr_t);
106*8975f5c5SAndroid Build Coastguard Worker         BaseResult(Fail);
107*8975f5c5SAndroid Build Coastguard Worker         BaseResult(std::vector<TIntermNode *> &&nodes);
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         void moveAssignImpl(BaseResult &other);  // For subclass move assign impls
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker         static BaseResult Multi(std::vector<TIntermNode *> &&nodes);
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker         template <typename Iter>
Multi(Iter nodesBegin,Iter nodesEnd)114*8975f5c5SAndroid Build Coastguard Worker         static BaseResult Multi(Iter nodesBegin, Iter nodesEnd)
115*8975f5c5SAndroid Build Coastguard Worker         {
116*8975f5c5SAndroid Build Coastguard Worker             std::vector<TIntermNode *> nodes;
117*8975f5c5SAndroid Build Coastguard Worker             for (Iter nodesCurr = nodesBegin; nodesCurr != nodesEnd; ++nodesCurr)
118*8975f5c5SAndroid Build Coastguard Worker             {
119*8975f5c5SAndroid Build Coastguard Worker                 nodes.push_back(*nodesCurr);
120*8975f5c5SAndroid Build Coastguard Worker             }
121*8975f5c5SAndroid Build Coastguard Worker             return std::move(nodes);
122*8975f5c5SAndroid Build Coastguard Worker         }
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker         bool isFail() const;
125*8975f5c5SAndroid Build Coastguard Worker         bool isDrop() const;
126*8975f5c5SAndroid Build Coastguard Worker         TIntermNode *single() const;
127*8975f5c5SAndroid Build Coastguard Worker         const std::vector<TIntermNode *> *multi() const;
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker       public:
130*8975f5c5SAndroid Build Coastguard Worker         Action mAction;
131*8975f5c5SAndroid Build Coastguard Worker         VisitBits mVisit;
132*8975f5c5SAndroid Build Coastguard Worker         TIntermNode *mSingle;
133*8975f5c5SAndroid Build Coastguard Worker         std::vector<TIntermNode *> mMulti;
134*8975f5c5SAndroid Build Coastguard Worker     };
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker   public:
137*8975f5c5SAndroid Build Coastguard Worker     class PreResult : private BaseResult
138*8975f5c5SAndroid Build Coastguard Worker     {
139*8975f5c5SAndroid Build Coastguard Worker         friend class TIntermRebuild;
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker       public:
142*8975f5c5SAndroid Build Coastguard Worker         PreResult(PreResult &&other);
143*8975f5c5SAndroid Build Coastguard Worker         PreResult(TIntermNode &node, VisitBits visit = VisitBits::BothWhenSame);
144*8975f5c5SAndroid Build Coastguard Worker         PreResult(TIntermNode *node, VisitBits visit = VisitBits::BothWhenSame);
145*8975f5c5SAndroid Build Coastguard Worker         PreResult(std::nullptr_t);  // Used to drop a node.
146*8975f5c5SAndroid Build Coastguard Worker         PreResult(Fail);            // Used to signal failure.
147*8975f5c5SAndroid Build Coastguard Worker 
148*8975f5c5SAndroid Build Coastguard Worker         void operator=(PreResult &&other);
149*8975f5c5SAndroid Build Coastguard Worker 
Multi(std::vector<TIntermNode * > && nodes)150*8975f5c5SAndroid Build Coastguard Worker         static PreResult Multi(std::vector<TIntermNode *> &&nodes)
151*8975f5c5SAndroid Build Coastguard Worker         {
152*8975f5c5SAndroid Build Coastguard Worker             return BaseResult::Multi(std::move(nodes));
153*8975f5c5SAndroid Build Coastguard Worker         }
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker         template <typename Iter>
Multi(Iter nodesBegin,Iter nodesEnd)156*8975f5c5SAndroid Build Coastguard Worker         static PreResult Multi(Iter nodesBegin, Iter nodesEnd)
157*8975f5c5SAndroid Build Coastguard Worker         {
158*8975f5c5SAndroid Build Coastguard Worker             return BaseResult::Multi(nodesBegin, nodesEnd);
159*8975f5c5SAndroid Build Coastguard Worker         }
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::isDrop;
162*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::isFail;
163*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::multi;
164*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::single;
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker       private:
167*8975f5c5SAndroid Build Coastguard Worker         PreResult(BaseResult &&other);
168*8975f5c5SAndroid Build Coastguard Worker     };
169*8975f5c5SAndroid Build Coastguard Worker 
170*8975f5c5SAndroid Build Coastguard Worker     class PostResult : private BaseResult
171*8975f5c5SAndroid Build Coastguard Worker     {
172*8975f5c5SAndroid Build Coastguard Worker         friend class TIntermRebuild;
173*8975f5c5SAndroid Build Coastguard Worker 
174*8975f5c5SAndroid Build Coastguard Worker       public:
175*8975f5c5SAndroid Build Coastguard Worker         PostResult(PostResult &&other);
176*8975f5c5SAndroid Build Coastguard Worker         PostResult(TIntermNode &node);
177*8975f5c5SAndroid Build Coastguard Worker         PostResult(TIntermNode *node);
178*8975f5c5SAndroid Build Coastguard Worker         PostResult(std::nullptr_t);  // Used to drop a node
179*8975f5c5SAndroid Build Coastguard Worker         PostResult(Fail);            // Used to signal failure.
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker         void operator=(PostResult &&other);
182*8975f5c5SAndroid Build Coastguard Worker 
Multi(std::vector<TIntermNode * > && nodes)183*8975f5c5SAndroid Build Coastguard Worker         static PostResult Multi(std::vector<TIntermNode *> &&nodes)
184*8975f5c5SAndroid Build Coastguard Worker         {
185*8975f5c5SAndroid Build Coastguard Worker             return BaseResult::Multi(std::move(nodes));
186*8975f5c5SAndroid Build Coastguard Worker         }
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker         template <typename Iter>
Multi(Iter nodesBegin,Iter nodesEnd)189*8975f5c5SAndroid Build Coastguard Worker         static PostResult Multi(Iter nodesBegin, Iter nodesEnd)
190*8975f5c5SAndroid Build Coastguard Worker         {
191*8975f5c5SAndroid Build Coastguard Worker             return BaseResult::Multi(nodesBegin, nodesEnd);
192*8975f5c5SAndroid Build Coastguard Worker         }
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::isDrop;
195*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::isFail;
196*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::multi;
197*8975f5c5SAndroid Build Coastguard Worker         using BaseResult::single;
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker       private:
200*8975f5c5SAndroid Build Coastguard Worker         PostResult(BaseResult &&other);
201*8975f5c5SAndroid Build Coastguard Worker     };
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker   public:
204*8975f5c5SAndroid Build Coastguard Worker     TIntermRebuild(TCompiler &compiler, bool preVisit, bool postVisit);
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker     virtual ~TIntermRebuild();
207*8975f5c5SAndroid Build Coastguard Worker 
208*8975f5c5SAndroid Build Coastguard Worker     // Rebuilds the tree starting at the provided root. If a new node would be returned for the
209*8975f5c5SAndroid Build Coastguard Worker     // root, the root node's children become that of the new node instead. Returns false if failure
210*8975f5c5SAndroid Build Coastguard Worker     // occurred.
211*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] bool rebuildRoot(TIntermBlock &root);
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker   protected:
214*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitSymbolPre(TIntermSymbol &node);
215*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitConstantUnionPre(TIntermConstantUnion &node);
216*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitFunctionPrototypePre(TIntermFunctionPrototype &node);
217*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitPreprocessorDirectivePre(TIntermPreprocessorDirective &node);
218*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitUnaryPre(TIntermUnary &node);
219*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitBinaryPre(TIntermBinary &node);
220*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitTernaryPre(TIntermTernary &node);
221*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitSwizzlePre(TIntermSwizzle &node);
222*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitIfElsePre(TIntermIfElse &node);
223*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitSwitchPre(TIntermSwitch &node);
224*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitCasePre(TIntermCase &node);
225*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitLoopPre(TIntermLoop &node);
226*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitBranchPre(TIntermBranch &node);
227*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitDeclarationPre(TIntermDeclaration &node);
228*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitBlockPre(TIntermBlock &node);
229*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitAggregatePre(TIntermAggregate &node);
230*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitFunctionDefinitionPre(TIntermFunctionDefinition &node);
231*8975f5c5SAndroid Build Coastguard Worker     virtual PreResult visitGlobalQualifierDeclarationPre(TIntermGlobalQualifierDeclaration &node);
232*8975f5c5SAndroid Build Coastguard Worker 
233*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitSymbolPost(TIntermSymbol &node);
234*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitConstantUnionPost(TIntermConstantUnion &node);
235*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitFunctionPrototypePost(TIntermFunctionPrototype &node);
236*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitPreprocessorDirectivePost(TIntermPreprocessorDirective &node);
237*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitUnaryPost(TIntermUnary &node);
238*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitBinaryPost(TIntermBinary &node);
239*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitTernaryPost(TIntermTernary &node);
240*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitSwizzlePost(TIntermSwizzle &node);
241*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitIfElsePost(TIntermIfElse &node);
242*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitSwitchPost(TIntermSwitch &node);
243*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitCasePost(TIntermCase &node);
244*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitLoopPost(TIntermLoop &node);
245*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitBranchPost(TIntermBranch &node);
246*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitDeclarationPost(TIntermDeclaration &node);
247*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitBlockPost(TIntermBlock &node);
248*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitAggregatePost(TIntermAggregate &node);
249*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitFunctionDefinitionPost(TIntermFunctionDefinition &node);
250*8975f5c5SAndroid Build Coastguard Worker     virtual PostResult visitGlobalQualifierDeclarationPost(TIntermGlobalQualifierDeclaration &node);
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     // Can be used to rebuild a specific node during a traversal. Useful for fine control of
253*8975f5c5SAndroid Build Coastguard Worker     // rebuilding a node's children.
254*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] PostResult rebuild(TIntermNode &node);
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker     // Rebuilds the provided node in place. If a new node would be returned, the old node's children
257*8975f5c5SAndroid Build Coastguard Worker     // become that of the new node instead. Returns false if failure occurred.
258*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] bool rebuildInPlace(TIntermAggregate &node);
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker     // Rebuilds the provided node in place. If a new node would be returned, the old node's children
261*8975f5c5SAndroid Build Coastguard Worker     // become that of the new node instead. Returns false if failure occurred.
262*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] bool rebuildInPlace(TIntermBlock &node);
263*8975f5c5SAndroid Build Coastguard Worker 
264*8975f5c5SAndroid Build Coastguard Worker     // Rebuilds the provided node in place. If a new node would be returned, the old node's children
265*8975f5c5SAndroid Build Coastguard Worker     // become that of the new node instead. Returns false if failure occurred.
266*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] bool rebuildInPlace(TIntermDeclaration &node);
267*8975f5c5SAndroid Build Coastguard Worker 
268*8975f5c5SAndroid Build Coastguard Worker     // If currently at or below a function declaration body, this returns the function that encloses
269*8975f5c5SAndroid Build Coastguard Worker     // the currently visited node. (This returns null if at a function declaration node.)
270*8975f5c5SAndroid Build Coastguard Worker     const TFunction *getParentFunction() const;
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *getParentNode(size_t offset = 0) const;
273*8975f5c5SAndroid Build Coastguard Worker 
274*8975f5c5SAndroid Build Coastguard Worker   private:
275*8975f5c5SAndroid Build Coastguard Worker     template <typename Node>
276*8975f5c5SAndroid Build Coastguard Worker     [[nodiscard]] bool rebuildInPlaceImpl(Node &node);
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker     PostResult traverseAny(TIntermNode &node);
279*8975f5c5SAndroid Build Coastguard Worker 
280*8975f5c5SAndroid Build Coastguard Worker     template <typename Node>
281*8975f5c5SAndroid Build Coastguard Worker     Node *traverseAnyAs(TIntermNode &node);
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker     template <typename Node>
284*8975f5c5SAndroid Build Coastguard Worker     bool traverseAnyAs(TIntermNode &node, Node *&out);
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker     PreResult traversePre(TIntermNode &originalNode);
287*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseChildren(NodeType currNodeType,
288*8975f5c5SAndroid Build Coastguard Worker                                   const TIntermNode &originalNode,
289*8975f5c5SAndroid Build Coastguard Worker                                   TIntermNode &currNode,
290*8975f5c5SAndroid Build Coastguard Worker                                   VisitBits visit);
291*8975f5c5SAndroid Build Coastguard Worker     PostResult traversePost(NodeType nodeType,
292*8975f5c5SAndroid Build Coastguard Worker                             const TIntermNode &originalNode,
293*8975f5c5SAndroid Build Coastguard Worker                             TIntermNode &currNode,
294*8975f5c5SAndroid Build Coastguard Worker                             VisitBits visit);
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker     bool traverseAggregateBaseChildren(TIntermAggregateBase &node);
297*8975f5c5SAndroid Build Coastguard Worker 
298*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseUnaryChildren(TIntermUnary &node);
299*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseBinaryChildren(TIntermBinary &node);
300*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseTernaryChildren(TIntermTernary &node);
301*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseSwizzleChildren(TIntermSwizzle &node);
302*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseIfElseChildren(TIntermIfElse &node);
303*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseSwitchChildren(TIntermSwitch &node);
304*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseCaseChildren(TIntermCase &node);
305*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseLoopChildren(TIntermLoop &node);
306*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseBranchChildren(TIntermBranch &node);
307*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseDeclarationChildren(TIntermDeclaration &node);
308*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseBlockChildren(TIntermBlock &node);
309*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseAggregateChildren(TIntermAggregate &node);
310*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseFunctionDefinitionChildren(TIntermFunctionDefinition &node);
311*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *traverseGlobalQualifierDeclarationChildren(
312*8975f5c5SAndroid Build Coastguard Worker         TIntermGlobalQualifierDeclaration &node);
313*8975f5c5SAndroid Build Coastguard Worker 
314*8975f5c5SAndroid Build Coastguard Worker   protected:
315*8975f5c5SAndroid Build Coastguard Worker     TCompiler &mCompiler;
316*8975f5c5SAndroid Build Coastguard Worker     TSymbolTable &mSymbolTable;
317*8975f5c5SAndroid Build Coastguard Worker     const TFunction *mParentFunc = nullptr;
318*8975f5c5SAndroid Build Coastguard Worker     GetNodeType getNodeType;
319*8975f5c5SAndroid Build Coastguard Worker 
320*8975f5c5SAndroid Build Coastguard Worker   private:
321*8975f5c5SAndroid Build Coastguard Worker     ConsList<TIntermNode *> mNodeStack{nullptr, nullptr};
322*8975f5c5SAndroid Build Coastguard Worker     bool mPreVisit;
323*8975f5c5SAndroid Build Coastguard Worker     bool mPostVisit;
324*8975f5c5SAndroid Build Coastguard Worker };
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker }  // namespace sh
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker #endif  // COMPILER_TRANSLATOR_INTERMREBUILD_H_
329