xref: /aosp_15_r20/external/angle/src/compiler/translator/IntermRebuild.cpp (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 #include <algorithm>
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/Compiler.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/SymbolTable.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/AsNode.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/IntermRebuild.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker #define GUARD2(cond, failVal) \
15*8975f5c5SAndroid Build Coastguard Worker     do                        \
16*8975f5c5SAndroid Build Coastguard Worker     {                         \
17*8975f5c5SAndroid Build Coastguard Worker         if (!(cond))          \
18*8975f5c5SAndroid Build Coastguard Worker         {                     \
19*8975f5c5SAndroid Build Coastguard Worker             return failVal;   \
20*8975f5c5SAndroid Build Coastguard Worker         }                     \
21*8975f5c5SAndroid Build Coastguard Worker     } while (false)
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker #define GUARD(cond) GUARD2(cond, nullptr)
24*8975f5c5SAndroid Build Coastguard Worker 
25*8975f5c5SAndroid Build Coastguard Worker namespace sh
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker 
28*8975f5c5SAndroid Build Coastguard Worker template <typename T, typename U>
AllBits(T haystack,U needle)29*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE bool AllBits(T haystack, U needle)
30*8975f5c5SAndroid Build Coastguard Worker {
31*8975f5c5SAndroid Build Coastguard Worker     return (haystack & needle) == needle;
32*8975f5c5SAndroid Build Coastguard Worker }
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker template <typename T, typename U>
AnyBits(T haystack,U needle)35*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE bool AnyBits(T haystack, U needle)
36*8975f5c5SAndroid Build Coastguard Worker {
37*8975f5c5SAndroid Build Coastguard Worker     return (haystack & needle) != 0;
38*8975f5c5SAndroid Build Coastguard Worker }
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
41*8975f5c5SAndroid Build Coastguard Worker 
BaseResult(BaseResult & other)42*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::BaseResult::BaseResult(BaseResult &other)
43*8975f5c5SAndroid Build Coastguard Worker     : mAction(other.mAction),
44*8975f5c5SAndroid Build Coastguard Worker       mVisit(other.mVisit),
45*8975f5c5SAndroid Build Coastguard Worker       mSingle(other.mSingle),
46*8975f5c5SAndroid Build Coastguard Worker       mMulti(std::move(other.mMulti))
47*8975f5c5SAndroid Build Coastguard Worker {}
48*8975f5c5SAndroid Build Coastguard Worker 
BaseResult(TIntermNode & node,VisitBits visit)49*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::BaseResult::BaseResult(TIntermNode &node, VisitBits visit)
50*8975f5c5SAndroid Build Coastguard Worker     : mAction(Action::ReplaceSingle), mVisit(visit), mSingle(&node)
51*8975f5c5SAndroid Build Coastguard Worker {}
52*8975f5c5SAndroid Build Coastguard Worker 
BaseResult(TIntermNode * node,VisitBits visit)53*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::BaseResult::BaseResult(TIntermNode *node, VisitBits visit)
54*8975f5c5SAndroid Build Coastguard Worker     : mAction(node ? Action::ReplaceSingle : Action::Drop),
55*8975f5c5SAndroid Build Coastguard Worker       mVisit(node ? visit : VisitBits::Neither),
56*8975f5c5SAndroid Build Coastguard Worker       mSingle(node)
57*8975f5c5SAndroid Build Coastguard Worker {}
58*8975f5c5SAndroid Build Coastguard Worker 
BaseResult(std::nullptr_t)59*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::BaseResult::BaseResult(std::nullptr_t)
60*8975f5c5SAndroid Build Coastguard Worker     : mAction(Action::Drop), mVisit(VisitBits::Neither), mSingle(nullptr)
61*8975f5c5SAndroid Build Coastguard Worker {}
62*8975f5c5SAndroid Build Coastguard Worker 
BaseResult(Fail)63*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::BaseResult::BaseResult(Fail)
64*8975f5c5SAndroid Build Coastguard Worker     : mAction(Action::Fail), mVisit(VisitBits::Neither), mSingle(nullptr)
65*8975f5c5SAndroid Build Coastguard Worker {}
66*8975f5c5SAndroid Build Coastguard Worker 
BaseResult(std::vector<TIntermNode * > && nodes)67*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::BaseResult::BaseResult(std::vector<TIntermNode *> &&nodes)
68*8975f5c5SAndroid Build Coastguard Worker     : mAction(Action::ReplaceMulti),
69*8975f5c5SAndroid Build Coastguard Worker       mVisit(VisitBits::Neither),
70*8975f5c5SAndroid Build Coastguard Worker       mSingle(nullptr),
71*8975f5c5SAndroid Build Coastguard Worker       mMulti(std::move(nodes))
72*8975f5c5SAndroid Build Coastguard Worker {}
73*8975f5c5SAndroid Build Coastguard Worker 
moveAssignImpl(BaseResult & other)74*8975f5c5SAndroid Build Coastguard Worker void TIntermRebuild::BaseResult::moveAssignImpl(BaseResult &other)
75*8975f5c5SAndroid Build Coastguard Worker {
76*8975f5c5SAndroid Build Coastguard Worker     mAction = other.mAction;
77*8975f5c5SAndroid Build Coastguard Worker     mVisit  = other.mVisit;
78*8975f5c5SAndroid Build Coastguard Worker     mSingle = other.mSingle;
79*8975f5c5SAndroid Build Coastguard Worker     mMulti  = std::move(other.mMulti);
80*8975f5c5SAndroid Build Coastguard Worker }
81*8975f5c5SAndroid Build Coastguard Worker 
Multi(std::vector<TIntermNode * > && nodes)82*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::BaseResult TIntermRebuild::BaseResult::Multi(std::vector<TIntermNode *> &&nodes)
83*8975f5c5SAndroid Build Coastguard Worker {
84*8975f5c5SAndroid Build Coastguard Worker     auto it = std::remove(nodes.begin(), nodes.end(), nullptr);
85*8975f5c5SAndroid Build Coastguard Worker     nodes.erase(it, nodes.end());
86*8975f5c5SAndroid Build Coastguard Worker     return std::move(nodes);
87*8975f5c5SAndroid Build Coastguard Worker }
88*8975f5c5SAndroid Build Coastguard Worker 
isFail() const89*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::BaseResult::isFail() const
90*8975f5c5SAndroid Build Coastguard Worker {
91*8975f5c5SAndroid Build Coastguard Worker     return mAction == Action::Fail;
92*8975f5c5SAndroid Build Coastguard Worker }
93*8975f5c5SAndroid Build Coastguard Worker 
isDrop() const94*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::BaseResult::isDrop() const
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker     return mAction == Action::Drop;
97*8975f5c5SAndroid Build Coastguard Worker }
98*8975f5c5SAndroid Build Coastguard Worker 
single() const99*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::BaseResult::single() const
100*8975f5c5SAndroid Build Coastguard Worker {
101*8975f5c5SAndroid Build Coastguard Worker     return mSingle;
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker 
multi() const104*8975f5c5SAndroid Build Coastguard Worker const std::vector<TIntermNode *> *TIntermRebuild::BaseResult::multi() const
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker     if (mAction == Action::ReplaceMulti)
107*8975f5c5SAndroid Build Coastguard Worker     {
108*8975f5c5SAndroid Build Coastguard Worker         return &mMulti;
109*8975f5c5SAndroid Build Coastguard Worker     }
110*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
111*8975f5c5SAndroid Build Coastguard Worker }
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker using PreResult = TIntermRebuild::PreResult;
116*8975f5c5SAndroid Build Coastguard Worker 
PreResult(TIntermNode & node,VisitBits visit)117*8975f5c5SAndroid Build Coastguard Worker PreResult::PreResult(TIntermNode &node, VisitBits visit) : BaseResult(node, visit) {}
PreResult(TIntermNode * node,VisitBits visit)118*8975f5c5SAndroid Build Coastguard Worker PreResult::PreResult(TIntermNode *node, VisitBits visit) : BaseResult(node, visit) {}
PreResult(std::nullptr_t)119*8975f5c5SAndroid Build Coastguard Worker PreResult::PreResult(std::nullptr_t) : BaseResult(nullptr) {}
PreResult(Fail)120*8975f5c5SAndroid Build Coastguard Worker PreResult::PreResult(Fail) : BaseResult(Fail()) {}
121*8975f5c5SAndroid Build Coastguard Worker 
PreResult(BaseResult && other)122*8975f5c5SAndroid Build Coastguard Worker PreResult::PreResult(BaseResult &&other) : BaseResult(other) {}
PreResult(PreResult && other)123*8975f5c5SAndroid Build Coastguard Worker PreResult::PreResult(PreResult &&other) : BaseResult(other) {}
124*8975f5c5SAndroid Build Coastguard Worker 
operator =(PreResult && other)125*8975f5c5SAndroid Build Coastguard Worker void PreResult::operator=(PreResult &&other)
126*8975f5c5SAndroid Build Coastguard Worker {
127*8975f5c5SAndroid Build Coastguard Worker     moveAssignImpl(other);
128*8975f5c5SAndroid Build Coastguard Worker }
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
131*8975f5c5SAndroid Build Coastguard Worker 
132*8975f5c5SAndroid Build Coastguard Worker using PostResult = TIntermRebuild::PostResult;
133*8975f5c5SAndroid Build Coastguard Worker 
PostResult(TIntermNode & node)134*8975f5c5SAndroid Build Coastguard Worker PostResult::PostResult(TIntermNode &node) : BaseResult(node, VisitBits::Neither) {}
PostResult(TIntermNode * node)135*8975f5c5SAndroid Build Coastguard Worker PostResult::PostResult(TIntermNode *node) : BaseResult(node, VisitBits::Neither) {}
PostResult(std::nullptr_t)136*8975f5c5SAndroid Build Coastguard Worker PostResult::PostResult(std::nullptr_t) : BaseResult(nullptr) {}
PostResult(Fail)137*8975f5c5SAndroid Build Coastguard Worker PostResult::PostResult(Fail) : BaseResult(Fail()) {}
138*8975f5c5SAndroid Build Coastguard Worker 
PostResult(PostResult && other)139*8975f5c5SAndroid Build Coastguard Worker PostResult::PostResult(PostResult &&other) : BaseResult(other) {}
PostResult(BaseResult && other)140*8975f5c5SAndroid Build Coastguard Worker PostResult::PostResult(BaseResult &&other) : BaseResult(other) {}
141*8975f5c5SAndroid Build Coastguard Worker 
operator =(PostResult && other)142*8975f5c5SAndroid Build Coastguard Worker void PostResult::operator=(PostResult &&other)
143*8975f5c5SAndroid Build Coastguard Worker {
144*8975f5c5SAndroid Build Coastguard Worker     moveAssignImpl(other);
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
148*8975f5c5SAndroid Build Coastguard Worker 
TIntermRebuild(TCompiler & compiler,bool preVisit,bool postVisit)149*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::TIntermRebuild(TCompiler &compiler, bool preVisit, bool postVisit)
150*8975f5c5SAndroid Build Coastguard Worker     : mCompiler(compiler),
151*8975f5c5SAndroid Build Coastguard Worker       mSymbolTable(compiler.getSymbolTable()),
152*8975f5c5SAndroid Build Coastguard Worker       mPreVisit(preVisit),
153*8975f5c5SAndroid Build Coastguard Worker       mPostVisit(postVisit)
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker     ASSERT(preVisit || postVisit);
156*8975f5c5SAndroid Build Coastguard Worker }
157*8975f5c5SAndroid Build Coastguard Worker 
~TIntermRebuild()158*8975f5c5SAndroid Build Coastguard Worker TIntermRebuild::~TIntermRebuild()
159*8975f5c5SAndroid Build Coastguard Worker {
160*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mNodeStack.value);
161*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mNodeStack.tail);
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker 
getParentFunction() const164*8975f5c5SAndroid Build Coastguard Worker const TFunction *TIntermRebuild::getParentFunction() const
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker     return mParentFunc;
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker 
getParentNode(size_t offset) const169*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::getParentNode(size_t offset) const
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mNodeStack.tail);
172*8975f5c5SAndroid Build Coastguard Worker     auto parent = *mNodeStack.tail;
173*8975f5c5SAndroid Build Coastguard Worker     while (offset > 0)
174*8975f5c5SAndroid Build Coastguard Worker     {
175*8975f5c5SAndroid Build Coastguard Worker         --offset;
176*8975f5c5SAndroid Build Coastguard Worker         ASSERT(parent.tail);
177*8975f5c5SAndroid Build Coastguard Worker         parent = *parent.tail;
178*8975f5c5SAndroid Build Coastguard Worker     }
179*8975f5c5SAndroid Build Coastguard Worker     return parent.value;
180*8975f5c5SAndroid Build Coastguard Worker }
181*8975f5c5SAndroid Build Coastguard Worker 
rebuildRoot(TIntermBlock & root)182*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::rebuildRoot(TIntermBlock &root)
183*8975f5c5SAndroid Build Coastguard Worker {
184*8975f5c5SAndroid Build Coastguard Worker     if (!rebuildInPlace(root))
185*8975f5c5SAndroid Build Coastguard Worker     {
186*8975f5c5SAndroid Build Coastguard Worker         return false;
187*8975f5c5SAndroid Build Coastguard Worker     }
188*8975f5c5SAndroid Build Coastguard Worker     return mCompiler.validateAST(&root);
189*8975f5c5SAndroid Build Coastguard Worker }
190*8975f5c5SAndroid Build Coastguard Worker 
rebuildInPlace(TIntermAggregate & node)191*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::rebuildInPlace(TIntermAggregate &node)
192*8975f5c5SAndroid Build Coastguard Worker {
193*8975f5c5SAndroid Build Coastguard Worker     return rebuildInPlaceImpl(node);
194*8975f5c5SAndroid Build Coastguard Worker }
195*8975f5c5SAndroid Build Coastguard Worker 
rebuildInPlace(TIntermBlock & node)196*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::rebuildInPlace(TIntermBlock &node)
197*8975f5c5SAndroid Build Coastguard Worker {
198*8975f5c5SAndroid Build Coastguard Worker     return rebuildInPlaceImpl(node);
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker 
rebuildInPlace(TIntermDeclaration & node)201*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::rebuildInPlace(TIntermDeclaration &node)
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker     return rebuildInPlaceImpl(node);
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker template <typename Node>
rebuildInPlaceImpl(Node & node)207*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::rebuildInPlaceImpl(Node &node)
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker     auto *newNode = traverseAnyAs<Node>(node);
210*8975f5c5SAndroid Build Coastguard Worker     if (!newNode)
211*8975f5c5SAndroid Build Coastguard Worker     {
212*8975f5c5SAndroid Build Coastguard Worker         return false;
213*8975f5c5SAndroid Build Coastguard Worker     }
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker     if (newNode != &node)
216*8975f5c5SAndroid Build Coastguard Worker     {
217*8975f5c5SAndroid Build Coastguard Worker         *node.getSequence() = std::move(*newNode->getSequence());
218*8975f5c5SAndroid Build Coastguard Worker     }
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker     return true;
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker 
rebuild(TIntermNode & node)223*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::rebuild(TIntermNode &node)
224*8975f5c5SAndroid Build Coastguard Worker {
225*8975f5c5SAndroid Build Coastguard Worker     return traverseAny(node);
226*8975f5c5SAndroid Build Coastguard Worker }
227*8975f5c5SAndroid Build Coastguard Worker 
228*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
229*8975f5c5SAndroid Build Coastguard Worker 
230*8975f5c5SAndroid Build Coastguard Worker template <typename Node>
traverseAnyAs(TIntermNode & node)231*8975f5c5SAndroid Build Coastguard Worker Node *TIntermRebuild::traverseAnyAs(TIntermNode &node)
232*8975f5c5SAndroid Build Coastguard Worker {
233*8975f5c5SAndroid Build Coastguard Worker     PostResult result(traverseAny(node));
234*8975f5c5SAndroid Build Coastguard Worker     if (result.mAction == Action::Fail || !result.mSingle)
235*8975f5c5SAndroid Build Coastguard Worker     {
236*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
237*8975f5c5SAndroid Build Coastguard Worker     }
238*8975f5c5SAndroid Build Coastguard Worker     return asNode<Node>(result.mSingle);
239*8975f5c5SAndroid Build Coastguard Worker }
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker template <typename Node>
traverseAnyAs(TIntermNode & node,Node * & out)242*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::traverseAnyAs(TIntermNode &node, Node *&out)
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker     PostResult result(traverseAny(node));
245*8975f5c5SAndroid Build Coastguard Worker     if (result.mAction == Action::Fail || result.mAction == Action::ReplaceMulti)
246*8975f5c5SAndroid Build Coastguard Worker     {
247*8975f5c5SAndroid Build Coastguard Worker         return false;
248*8975f5c5SAndroid Build Coastguard Worker     }
249*8975f5c5SAndroid Build Coastguard Worker     if (!result.mSingle)
250*8975f5c5SAndroid Build Coastguard Worker     {
251*8975f5c5SAndroid Build Coastguard Worker         return true;
252*8975f5c5SAndroid Build Coastguard Worker     }
253*8975f5c5SAndroid Build Coastguard Worker     out = asNode<Node>(result.mSingle);
254*8975f5c5SAndroid Build Coastguard Worker     return out != nullptr;
255*8975f5c5SAndroid Build Coastguard Worker }
256*8975f5c5SAndroid Build Coastguard Worker 
traverseAggregateBaseChildren(TIntermAggregateBase & node)257*8975f5c5SAndroid Build Coastguard Worker bool TIntermRebuild::traverseAggregateBaseChildren(TIntermAggregateBase &node)
258*8975f5c5SAndroid Build Coastguard Worker {
259*8975f5c5SAndroid Build Coastguard Worker     auto *const children = node.getSequence();
260*8975f5c5SAndroid Build Coastguard Worker     ASSERT(children);
261*8975f5c5SAndroid Build Coastguard Worker     TIntermSequence newChildren;
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker     for (TIntermNode *child : *children)
264*8975f5c5SAndroid Build Coastguard Worker     {
265*8975f5c5SAndroid Build Coastguard Worker         ASSERT(child);
266*8975f5c5SAndroid Build Coastguard Worker         PostResult result(traverseAny(*child));
267*8975f5c5SAndroid Build Coastguard Worker 
268*8975f5c5SAndroid Build Coastguard Worker         switch (result.mAction)
269*8975f5c5SAndroid Build Coastguard Worker         {
270*8975f5c5SAndroid Build Coastguard Worker             case Action::ReplaceSingle:
271*8975f5c5SAndroid Build Coastguard Worker                 newChildren.push_back(result.mSingle);
272*8975f5c5SAndroid Build Coastguard Worker                 break;
273*8975f5c5SAndroid Build Coastguard Worker 
274*8975f5c5SAndroid Build Coastguard Worker             case Action::ReplaceMulti:
275*8975f5c5SAndroid Build Coastguard Worker                 for (TIntermNode *newNode : result.mMulti)
276*8975f5c5SAndroid Build Coastguard Worker                 {
277*8975f5c5SAndroid Build Coastguard Worker                     if (newNode)
278*8975f5c5SAndroid Build Coastguard Worker                     {
279*8975f5c5SAndroid Build Coastguard Worker                         newChildren.push_back(newNode);
280*8975f5c5SAndroid Build Coastguard Worker                     }
281*8975f5c5SAndroid Build Coastguard Worker                 }
282*8975f5c5SAndroid Build Coastguard Worker                 break;
283*8975f5c5SAndroid Build Coastguard Worker 
284*8975f5c5SAndroid Build Coastguard Worker             case Action::Drop:
285*8975f5c5SAndroid Build Coastguard Worker                 break;
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker             case Action::Fail:
288*8975f5c5SAndroid Build Coastguard Worker                 return false;
289*8975f5c5SAndroid Build Coastguard Worker 
290*8975f5c5SAndroid Build Coastguard Worker             default:
291*8975f5c5SAndroid Build Coastguard Worker                 ASSERT(false);
292*8975f5c5SAndroid Build Coastguard Worker                 return false;
293*8975f5c5SAndroid Build Coastguard Worker         }
294*8975f5c5SAndroid Build Coastguard Worker     }
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker     *children = std::move(newChildren);
297*8975f5c5SAndroid Build Coastguard Worker 
298*8975f5c5SAndroid Build Coastguard Worker     return true;
299*8975f5c5SAndroid Build Coastguard Worker }
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
302*8975f5c5SAndroid Build Coastguard Worker 
303*8975f5c5SAndroid Build Coastguard Worker struct TIntermRebuild::NodeStackGuard
304*8975f5c5SAndroid Build Coastguard Worker {
305*8975f5c5SAndroid Build Coastguard Worker     ConsList<TIntermNode *> oldNodeStack;
306*8975f5c5SAndroid Build Coastguard Worker     ConsList<TIntermNode *> &nodeStack;
NodeStackGuardsh::TIntermRebuild::NodeStackGuard307*8975f5c5SAndroid Build Coastguard Worker     NodeStackGuard(ConsList<TIntermNode *> &nodeStack, TIntermNode *node)
308*8975f5c5SAndroid Build Coastguard Worker         : oldNodeStack(nodeStack), nodeStack(nodeStack)
309*8975f5c5SAndroid Build Coastguard Worker     {
310*8975f5c5SAndroid Build Coastguard Worker         nodeStack = {node, &oldNodeStack};
311*8975f5c5SAndroid Build Coastguard Worker     }
~NodeStackGuardsh::TIntermRebuild::NodeStackGuard312*8975f5c5SAndroid Build Coastguard Worker     ~NodeStackGuard() { nodeStack = oldNodeStack; }
313*8975f5c5SAndroid Build Coastguard Worker };
314*8975f5c5SAndroid Build Coastguard Worker 
traverseAny(TIntermNode & originalNode)315*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::traverseAny(TIntermNode &originalNode)
316*8975f5c5SAndroid Build Coastguard Worker {
317*8975f5c5SAndroid Build Coastguard Worker     PreResult preResult = traversePre(originalNode);
318*8975f5c5SAndroid Build Coastguard Worker     if (!preResult.mSingle)
319*8975f5c5SAndroid Build Coastguard Worker     {
320*8975f5c5SAndroid Build Coastguard Worker         ASSERT(preResult.mVisit == VisitBits::Neither);
321*8975f5c5SAndroid Build Coastguard Worker         return std::move(preResult);
322*8975f5c5SAndroid Build Coastguard Worker     }
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *currNode       = preResult.mSingle;
325*8975f5c5SAndroid Build Coastguard Worker     const VisitBits visit       = preResult.mVisit;
326*8975f5c5SAndroid Build Coastguard Worker     const NodeType currNodeType = getNodeType(*currNode);
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker     currNode = traverseChildren(currNodeType, originalNode, *currNode, visit);
329*8975f5c5SAndroid Build Coastguard Worker     if (!currNode)
330*8975f5c5SAndroid Build Coastguard Worker     {
331*8975f5c5SAndroid Build Coastguard Worker         return Fail();
332*8975f5c5SAndroid Build Coastguard Worker     }
333*8975f5c5SAndroid Build Coastguard Worker 
334*8975f5c5SAndroid Build Coastguard Worker     return traversePost(currNodeType, originalNode, *currNode, visit);
335*8975f5c5SAndroid Build Coastguard Worker }
336*8975f5c5SAndroid Build Coastguard Worker 
traversePre(TIntermNode & originalNode)337*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::traversePre(TIntermNode &originalNode)
338*8975f5c5SAndroid Build Coastguard Worker {
339*8975f5c5SAndroid Build Coastguard Worker     if (!mPreVisit)
340*8975f5c5SAndroid Build Coastguard Worker     {
341*8975f5c5SAndroid Build Coastguard Worker         return {originalNode, VisitBits::Both};
342*8975f5c5SAndroid Build Coastguard Worker     }
343*8975f5c5SAndroid Build Coastguard Worker 
344*8975f5c5SAndroid Build Coastguard Worker     NodeStackGuard guard(mNodeStack, &originalNode);
345*8975f5c5SAndroid Build Coastguard Worker 
346*8975f5c5SAndroid Build Coastguard Worker     const NodeType originalNodeType = getNodeType(originalNode);
347*8975f5c5SAndroid Build Coastguard Worker 
348*8975f5c5SAndroid Build Coastguard Worker     switch (originalNodeType)
349*8975f5c5SAndroid Build Coastguard Worker     {
350*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Unknown:
351*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false);
352*8975f5c5SAndroid Build Coastguard Worker             return Fail();
353*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Symbol:
354*8975f5c5SAndroid Build Coastguard Worker             return visitSymbolPre(*originalNode.getAsSymbolNode());
355*8975f5c5SAndroid Build Coastguard Worker         case NodeType::ConstantUnion:
356*8975f5c5SAndroid Build Coastguard Worker             return visitConstantUnionPre(*originalNode.getAsConstantUnion());
357*8975f5c5SAndroid Build Coastguard Worker         case NodeType::FunctionPrototype:
358*8975f5c5SAndroid Build Coastguard Worker             return visitFunctionPrototypePre(*originalNode.getAsFunctionPrototypeNode());
359*8975f5c5SAndroid Build Coastguard Worker         case NodeType::PreprocessorDirective:
360*8975f5c5SAndroid Build Coastguard Worker             return visitPreprocessorDirectivePre(*originalNode.getAsPreprocessorDirective());
361*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Unary:
362*8975f5c5SAndroid Build Coastguard Worker             return visitUnaryPre(*originalNode.getAsUnaryNode());
363*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Binary:
364*8975f5c5SAndroid Build Coastguard Worker             return visitBinaryPre(*originalNode.getAsBinaryNode());
365*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Ternary:
366*8975f5c5SAndroid Build Coastguard Worker             return visitTernaryPre(*originalNode.getAsTernaryNode());
367*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Swizzle:
368*8975f5c5SAndroid Build Coastguard Worker             return visitSwizzlePre(*originalNode.getAsSwizzleNode());
369*8975f5c5SAndroid Build Coastguard Worker         case NodeType::IfElse:
370*8975f5c5SAndroid Build Coastguard Worker             return visitIfElsePre(*originalNode.getAsIfElseNode());
371*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Switch:
372*8975f5c5SAndroid Build Coastguard Worker             return visitSwitchPre(*originalNode.getAsSwitchNode());
373*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Case:
374*8975f5c5SAndroid Build Coastguard Worker             return visitCasePre(*originalNode.getAsCaseNode());
375*8975f5c5SAndroid Build Coastguard Worker         case NodeType::FunctionDefinition:
376*8975f5c5SAndroid Build Coastguard Worker             return visitFunctionDefinitionPre(*originalNode.getAsFunctionDefinition());
377*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Aggregate:
378*8975f5c5SAndroid Build Coastguard Worker             return visitAggregatePre(*originalNode.getAsAggregate());
379*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Block:
380*8975f5c5SAndroid Build Coastguard Worker             return visitBlockPre(*originalNode.getAsBlock());
381*8975f5c5SAndroid Build Coastguard Worker         case NodeType::GlobalQualifierDeclaration:
382*8975f5c5SAndroid Build Coastguard Worker             return visitGlobalQualifierDeclarationPre(
383*8975f5c5SAndroid Build Coastguard Worker                 *originalNode.getAsGlobalQualifierDeclarationNode());
384*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Declaration:
385*8975f5c5SAndroid Build Coastguard Worker             return visitDeclarationPre(*originalNode.getAsDeclarationNode());
386*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Loop:
387*8975f5c5SAndroid Build Coastguard Worker             return visitLoopPre(*originalNode.getAsLoopNode());
388*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Branch:
389*8975f5c5SAndroid Build Coastguard Worker             return visitBranchPre(*originalNode.getAsBranchNode());
390*8975f5c5SAndroid Build Coastguard Worker         default:
391*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false);
392*8975f5c5SAndroid Build Coastguard Worker             return Fail();
393*8975f5c5SAndroid Build Coastguard Worker     }
394*8975f5c5SAndroid Build Coastguard Worker }
395*8975f5c5SAndroid Build Coastguard Worker 
traverseChildren(NodeType currNodeType,const TIntermNode & originalNode,TIntermNode & currNode,VisitBits visit)396*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseChildren(NodeType currNodeType,
397*8975f5c5SAndroid Build Coastguard Worker                                               const TIntermNode &originalNode,
398*8975f5c5SAndroid Build Coastguard Worker                                               TIntermNode &currNode,
399*8975f5c5SAndroid Build Coastguard Worker                                               VisitBits visit)
400*8975f5c5SAndroid Build Coastguard Worker {
401*8975f5c5SAndroid Build Coastguard Worker     if (!AnyBits(visit, VisitBits::Children))
402*8975f5c5SAndroid Build Coastguard Worker     {
403*8975f5c5SAndroid Build Coastguard Worker         return &currNode;
404*8975f5c5SAndroid Build Coastguard Worker     }
405*8975f5c5SAndroid Build Coastguard Worker 
406*8975f5c5SAndroid Build Coastguard Worker     if (AnyBits(visit, VisitBits::ChildrenRequiresSame) && &originalNode != &currNode)
407*8975f5c5SAndroid Build Coastguard Worker     {
408*8975f5c5SAndroid Build Coastguard Worker         return &currNode;
409*8975f5c5SAndroid Build Coastguard Worker     }
410*8975f5c5SAndroid Build Coastguard Worker 
411*8975f5c5SAndroid Build Coastguard Worker     NodeStackGuard guard(mNodeStack, &currNode);
412*8975f5c5SAndroid Build Coastguard Worker 
413*8975f5c5SAndroid Build Coastguard Worker     switch (currNodeType)
414*8975f5c5SAndroid Build Coastguard Worker     {
415*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Unknown:
416*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false);
417*8975f5c5SAndroid Build Coastguard Worker             return nullptr;
418*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Symbol:
419*8975f5c5SAndroid Build Coastguard Worker             return &currNode;
420*8975f5c5SAndroid Build Coastguard Worker         case NodeType::ConstantUnion:
421*8975f5c5SAndroid Build Coastguard Worker             return &currNode;
422*8975f5c5SAndroid Build Coastguard Worker         case NodeType::FunctionPrototype:
423*8975f5c5SAndroid Build Coastguard Worker             return &currNode;
424*8975f5c5SAndroid Build Coastguard Worker         case NodeType::PreprocessorDirective:
425*8975f5c5SAndroid Build Coastguard Worker             return &currNode;
426*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Unary:
427*8975f5c5SAndroid Build Coastguard Worker             return traverseUnaryChildren(*currNode.getAsUnaryNode());
428*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Binary:
429*8975f5c5SAndroid Build Coastguard Worker             return traverseBinaryChildren(*currNode.getAsBinaryNode());
430*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Ternary:
431*8975f5c5SAndroid Build Coastguard Worker             return traverseTernaryChildren(*currNode.getAsTernaryNode());
432*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Swizzle:
433*8975f5c5SAndroid Build Coastguard Worker             return traverseSwizzleChildren(*currNode.getAsSwizzleNode());
434*8975f5c5SAndroid Build Coastguard Worker         case NodeType::IfElse:
435*8975f5c5SAndroid Build Coastguard Worker             return traverseIfElseChildren(*currNode.getAsIfElseNode());
436*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Switch:
437*8975f5c5SAndroid Build Coastguard Worker             return traverseSwitchChildren(*currNode.getAsSwitchNode());
438*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Case:
439*8975f5c5SAndroid Build Coastguard Worker             return traverseCaseChildren(*currNode.getAsCaseNode());
440*8975f5c5SAndroid Build Coastguard Worker         case NodeType::FunctionDefinition:
441*8975f5c5SAndroid Build Coastguard Worker             return traverseFunctionDefinitionChildren(*currNode.getAsFunctionDefinition());
442*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Aggregate:
443*8975f5c5SAndroid Build Coastguard Worker             return traverseAggregateChildren(*currNode.getAsAggregate());
444*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Block:
445*8975f5c5SAndroid Build Coastguard Worker             return traverseBlockChildren(*currNode.getAsBlock());
446*8975f5c5SAndroid Build Coastguard Worker         case NodeType::GlobalQualifierDeclaration:
447*8975f5c5SAndroid Build Coastguard Worker             return traverseGlobalQualifierDeclarationChildren(
448*8975f5c5SAndroid Build Coastguard Worker                 *currNode.getAsGlobalQualifierDeclarationNode());
449*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Declaration:
450*8975f5c5SAndroid Build Coastguard Worker             return traverseDeclarationChildren(*currNode.getAsDeclarationNode());
451*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Loop:
452*8975f5c5SAndroid Build Coastguard Worker             return traverseLoopChildren(*currNode.getAsLoopNode());
453*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Branch:
454*8975f5c5SAndroid Build Coastguard Worker             return traverseBranchChildren(*currNode.getAsBranchNode());
455*8975f5c5SAndroid Build Coastguard Worker         default:
456*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false);
457*8975f5c5SAndroid Build Coastguard Worker             return nullptr;
458*8975f5c5SAndroid Build Coastguard Worker     }
459*8975f5c5SAndroid Build Coastguard Worker }
460*8975f5c5SAndroid Build Coastguard Worker 
traversePost(NodeType currNodeType,const TIntermNode & originalNode,TIntermNode & currNode,VisitBits visit)461*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::traversePost(NodeType currNodeType,
462*8975f5c5SAndroid Build Coastguard Worker                                         const TIntermNode &originalNode,
463*8975f5c5SAndroid Build Coastguard Worker                                         TIntermNode &currNode,
464*8975f5c5SAndroid Build Coastguard Worker                                         VisitBits visit)
465*8975f5c5SAndroid Build Coastguard Worker {
466*8975f5c5SAndroid Build Coastguard Worker     if (!mPostVisit)
467*8975f5c5SAndroid Build Coastguard Worker     {
468*8975f5c5SAndroid Build Coastguard Worker         return currNode;
469*8975f5c5SAndroid Build Coastguard Worker     }
470*8975f5c5SAndroid Build Coastguard Worker 
471*8975f5c5SAndroid Build Coastguard Worker     if (!AnyBits(visit, VisitBits::Post))
472*8975f5c5SAndroid Build Coastguard Worker     {
473*8975f5c5SAndroid Build Coastguard Worker         return currNode;
474*8975f5c5SAndroid Build Coastguard Worker     }
475*8975f5c5SAndroid Build Coastguard Worker 
476*8975f5c5SAndroid Build Coastguard Worker     if (AnyBits(visit, VisitBits::PostRequiresSame) && &originalNode != &currNode)
477*8975f5c5SAndroid Build Coastguard Worker     {
478*8975f5c5SAndroid Build Coastguard Worker         return currNode;
479*8975f5c5SAndroid Build Coastguard Worker     }
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker     NodeStackGuard guard(mNodeStack, &currNode);
482*8975f5c5SAndroid Build Coastguard Worker 
483*8975f5c5SAndroid Build Coastguard Worker     switch (currNodeType)
484*8975f5c5SAndroid Build Coastguard Worker     {
485*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Unknown:
486*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false);
487*8975f5c5SAndroid Build Coastguard Worker             return Fail();
488*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Symbol:
489*8975f5c5SAndroid Build Coastguard Worker             return visitSymbolPost(*currNode.getAsSymbolNode());
490*8975f5c5SAndroid Build Coastguard Worker         case NodeType::ConstantUnion:
491*8975f5c5SAndroid Build Coastguard Worker             return visitConstantUnionPost(*currNode.getAsConstantUnion());
492*8975f5c5SAndroid Build Coastguard Worker         case NodeType::FunctionPrototype:
493*8975f5c5SAndroid Build Coastguard Worker             return visitFunctionPrototypePost(*currNode.getAsFunctionPrototypeNode());
494*8975f5c5SAndroid Build Coastguard Worker         case NodeType::PreprocessorDirective:
495*8975f5c5SAndroid Build Coastguard Worker             return visitPreprocessorDirectivePost(*currNode.getAsPreprocessorDirective());
496*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Unary:
497*8975f5c5SAndroid Build Coastguard Worker             return visitUnaryPost(*currNode.getAsUnaryNode());
498*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Binary:
499*8975f5c5SAndroid Build Coastguard Worker             return visitBinaryPost(*currNode.getAsBinaryNode());
500*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Ternary:
501*8975f5c5SAndroid Build Coastguard Worker             return visitTernaryPost(*currNode.getAsTernaryNode());
502*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Swizzle:
503*8975f5c5SAndroid Build Coastguard Worker             return visitSwizzlePost(*currNode.getAsSwizzleNode());
504*8975f5c5SAndroid Build Coastguard Worker         case NodeType::IfElse:
505*8975f5c5SAndroid Build Coastguard Worker             return visitIfElsePost(*currNode.getAsIfElseNode());
506*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Switch:
507*8975f5c5SAndroid Build Coastguard Worker             return visitSwitchPost(*currNode.getAsSwitchNode());
508*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Case:
509*8975f5c5SAndroid Build Coastguard Worker             return visitCasePost(*currNode.getAsCaseNode());
510*8975f5c5SAndroid Build Coastguard Worker         case NodeType::FunctionDefinition:
511*8975f5c5SAndroid Build Coastguard Worker             return visitFunctionDefinitionPost(*currNode.getAsFunctionDefinition());
512*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Aggregate:
513*8975f5c5SAndroid Build Coastguard Worker             return visitAggregatePost(*currNode.getAsAggregate());
514*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Block:
515*8975f5c5SAndroid Build Coastguard Worker             return visitBlockPost(*currNode.getAsBlock());
516*8975f5c5SAndroid Build Coastguard Worker         case NodeType::GlobalQualifierDeclaration:
517*8975f5c5SAndroid Build Coastguard Worker             return visitGlobalQualifierDeclarationPost(
518*8975f5c5SAndroid Build Coastguard Worker                 *currNode.getAsGlobalQualifierDeclarationNode());
519*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Declaration:
520*8975f5c5SAndroid Build Coastguard Worker             return visitDeclarationPost(*currNode.getAsDeclarationNode());
521*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Loop:
522*8975f5c5SAndroid Build Coastguard Worker             return visitLoopPost(*currNode.getAsLoopNode());
523*8975f5c5SAndroid Build Coastguard Worker         case NodeType::Branch:
524*8975f5c5SAndroid Build Coastguard Worker             return visitBranchPost(*currNode.getAsBranchNode());
525*8975f5c5SAndroid Build Coastguard Worker         default:
526*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false);
527*8975f5c5SAndroid Build Coastguard Worker             return Fail();
528*8975f5c5SAndroid Build Coastguard Worker     }
529*8975f5c5SAndroid Build Coastguard Worker }
530*8975f5c5SAndroid Build Coastguard Worker 
531*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
532*8975f5c5SAndroid Build Coastguard Worker 
traverseAggregateChildren(TIntermAggregate & node)533*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseAggregateChildren(TIntermAggregate &node)
534*8975f5c5SAndroid Build Coastguard Worker {
535*8975f5c5SAndroid Build Coastguard Worker     if (traverseAggregateBaseChildren(node))
536*8975f5c5SAndroid Build Coastguard Worker     {
537*8975f5c5SAndroid Build Coastguard Worker         return &node;
538*8975f5c5SAndroid Build Coastguard Worker     }
539*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
540*8975f5c5SAndroid Build Coastguard Worker }
541*8975f5c5SAndroid Build Coastguard Worker 
traverseBlockChildren(TIntermBlock & node)542*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseBlockChildren(TIntermBlock &node)
543*8975f5c5SAndroid Build Coastguard Worker {
544*8975f5c5SAndroid Build Coastguard Worker     if (traverseAggregateBaseChildren(node))
545*8975f5c5SAndroid Build Coastguard Worker     {
546*8975f5c5SAndroid Build Coastguard Worker         return &node;
547*8975f5c5SAndroid Build Coastguard Worker     }
548*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
549*8975f5c5SAndroid Build Coastguard Worker }
550*8975f5c5SAndroid Build Coastguard Worker 
traverseDeclarationChildren(TIntermDeclaration & node)551*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseDeclarationChildren(TIntermDeclaration &node)
552*8975f5c5SAndroid Build Coastguard Worker {
553*8975f5c5SAndroid Build Coastguard Worker     if (traverseAggregateBaseChildren(node))
554*8975f5c5SAndroid Build Coastguard Worker     {
555*8975f5c5SAndroid Build Coastguard Worker         return &node;
556*8975f5c5SAndroid Build Coastguard Worker     }
557*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
558*8975f5c5SAndroid Build Coastguard Worker }
559*8975f5c5SAndroid Build Coastguard Worker 
traverseSwizzleChildren(TIntermSwizzle & node)560*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseSwizzleChildren(TIntermSwizzle &node)
561*8975f5c5SAndroid Build Coastguard Worker {
562*8975f5c5SAndroid Build Coastguard Worker     auto *const operand = node.getOperand();
563*8975f5c5SAndroid Build Coastguard Worker     ASSERT(operand);
564*8975f5c5SAndroid Build Coastguard Worker 
565*8975f5c5SAndroid Build Coastguard Worker     auto *newOperand = traverseAnyAs<TIntermTyped>(*operand);
566*8975f5c5SAndroid Build Coastguard Worker     GUARD(newOperand);
567*8975f5c5SAndroid Build Coastguard Worker 
568*8975f5c5SAndroid Build Coastguard Worker     if (newOperand != operand)
569*8975f5c5SAndroid Build Coastguard Worker     {
570*8975f5c5SAndroid Build Coastguard Worker         return new TIntermSwizzle(newOperand, node.getSwizzleOffsets());
571*8975f5c5SAndroid Build Coastguard Worker     }
572*8975f5c5SAndroid Build Coastguard Worker 
573*8975f5c5SAndroid Build Coastguard Worker     return &node;
574*8975f5c5SAndroid Build Coastguard Worker }
575*8975f5c5SAndroid Build Coastguard Worker 
traverseBinaryChildren(TIntermBinary & node)576*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseBinaryChildren(TIntermBinary &node)
577*8975f5c5SAndroid Build Coastguard Worker {
578*8975f5c5SAndroid Build Coastguard Worker     auto *const left = node.getLeft();
579*8975f5c5SAndroid Build Coastguard Worker     ASSERT(left);
580*8975f5c5SAndroid Build Coastguard Worker     auto *const right = node.getRight();
581*8975f5c5SAndroid Build Coastguard Worker     ASSERT(right);
582*8975f5c5SAndroid Build Coastguard Worker 
583*8975f5c5SAndroid Build Coastguard Worker     auto *const newLeft = traverseAnyAs<TIntermTyped>(*left);
584*8975f5c5SAndroid Build Coastguard Worker     GUARD(newLeft);
585*8975f5c5SAndroid Build Coastguard Worker     auto *const newRight = traverseAnyAs<TIntermTyped>(*right);
586*8975f5c5SAndroid Build Coastguard Worker     GUARD(newRight);
587*8975f5c5SAndroid Build Coastguard Worker 
588*8975f5c5SAndroid Build Coastguard Worker     if (newLeft != left || newRight != right)
589*8975f5c5SAndroid Build Coastguard Worker     {
590*8975f5c5SAndroid Build Coastguard Worker         TOperator op = node.getOp();
591*8975f5c5SAndroid Build Coastguard Worker         switch (op)
592*8975f5c5SAndroid Build Coastguard Worker         {
593*8975f5c5SAndroid Build Coastguard Worker             case TOperator::EOpIndexDirectStruct:
594*8975f5c5SAndroid Build Coastguard Worker             {
595*8975f5c5SAndroid Build Coastguard Worker                 if (newLeft->getType().getInterfaceBlock())
596*8975f5c5SAndroid Build Coastguard Worker                 {
597*8975f5c5SAndroid Build Coastguard Worker                     op = TOperator::EOpIndexDirectInterfaceBlock;
598*8975f5c5SAndroid Build Coastguard Worker                 }
599*8975f5c5SAndroid Build Coastguard Worker             }
600*8975f5c5SAndroid Build Coastguard Worker             break;
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker             case TOperator::EOpIndexDirectInterfaceBlock:
603*8975f5c5SAndroid Build Coastguard Worker             {
604*8975f5c5SAndroid Build Coastguard Worker                 if (newLeft->getType().getStruct())
605*8975f5c5SAndroid Build Coastguard Worker                 {
606*8975f5c5SAndroid Build Coastguard Worker                     op = TOperator::EOpIndexDirectStruct;
607*8975f5c5SAndroid Build Coastguard Worker                 }
608*8975f5c5SAndroid Build Coastguard Worker             }
609*8975f5c5SAndroid Build Coastguard Worker             break;
610*8975f5c5SAndroid Build Coastguard Worker 
611*8975f5c5SAndroid Build Coastguard Worker             case TOperator::EOpComma:
612*8975f5c5SAndroid Build Coastguard Worker                 return TIntermBinary::CreateComma(newLeft, newRight, mCompiler.getShaderVersion());
613*8975f5c5SAndroid Build Coastguard Worker 
614*8975f5c5SAndroid Build Coastguard Worker             default:
615*8975f5c5SAndroid Build Coastguard Worker                 break;
616*8975f5c5SAndroid Build Coastguard Worker         }
617*8975f5c5SAndroid Build Coastguard Worker 
618*8975f5c5SAndroid Build Coastguard Worker         return new TIntermBinary(op, newLeft, newRight);
619*8975f5c5SAndroid Build Coastguard Worker     }
620*8975f5c5SAndroid Build Coastguard Worker 
621*8975f5c5SAndroid Build Coastguard Worker     return &node;
622*8975f5c5SAndroid Build Coastguard Worker }
623*8975f5c5SAndroid Build Coastguard Worker 
traverseUnaryChildren(TIntermUnary & node)624*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseUnaryChildren(TIntermUnary &node)
625*8975f5c5SAndroid Build Coastguard Worker {
626*8975f5c5SAndroid Build Coastguard Worker     auto *const operand = node.getOperand();
627*8975f5c5SAndroid Build Coastguard Worker     ASSERT(operand);
628*8975f5c5SAndroid Build Coastguard Worker 
629*8975f5c5SAndroid Build Coastguard Worker     auto *const newOperand = traverseAnyAs<TIntermTyped>(*operand);
630*8975f5c5SAndroid Build Coastguard Worker     GUARD(newOperand);
631*8975f5c5SAndroid Build Coastguard Worker 
632*8975f5c5SAndroid Build Coastguard Worker     if (newOperand != operand)
633*8975f5c5SAndroid Build Coastguard Worker     {
634*8975f5c5SAndroid Build Coastguard Worker         return new TIntermUnary(node.getOp(), newOperand, node.getFunction());
635*8975f5c5SAndroid Build Coastguard Worker     }
636*8975f5c5SAndroid Build Coastguard Worker 
637*8975f5c5SAndroid Build Coastguard Worker     return &node;
638*8975f5c5SAndroid Build Coastguard Worker }
639*8975f5c5SAndroid Build Coastguard Worker 
traverseTernaryChildren(TIntermTernary & node)640*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseTernaryChildren(TIntermTernary &node)
641*8975f5c5SAndroid Build Coastguard Worker {
642*8975f5c5SAndroid Build Coastguard Worker     auto *const cond = node.getCondition();
643*8975f5c5SAndroid Build Coastguard Worker     ASSERT(cond);
644*8975f5c5SAndroid Build Coastguard Worker     auto *const true_ = node.getTrueExpression();
645*8975f5c5SAndroid Build Coastguard Worker     ASSERT(true_);
646*8975f5c5SAndroid Build Coastguard Worker     auto *const false_ = node.getFalseExpression();
647*8975f5c5SAndroid Build Coastguard Worker     ASSERT(false_);
648*8975f5c5SAndroid Build Coastguard Worker 
649*8975f5c5SAndroid Build Coastguard Worker     auto *const newCond = traverseAnyAs<TIntermTyped>(*cond);
650*8975f5c5SAndroid Build Coastguard Worker     GUARD(newCond);
651*8975f5c5SAndroid Build Coastguard Worker     auto *const newTrue = traverseAnyAs<TIntermTyped>(*true_);
652*8975f5c5SAndroid Build Coastguard Worker     GUARD(newTrue);
653*8975f5c5SAndroid Build Coastguard Worker     auto *const newFalse = traverseAnyAs<TIntermTyped>(*false_);
654*8975f5c5SAndroid Build Coastguard Worker     GUARD(newFalse);
655*8975f5c5SAndroid Build Coastguard Worker 
656*8975f5c5SAndroid Build Coastguard Worker     if (newCond != cond || newTrue != true_ || newFalse != false_)
657*8975f5c5SAndroid Build Coastguard Worker     {
658*8975f5c5SAndroid Build Coastguard Worker         return new TIntermTernary(newCond, newTrue, newFalse);
659*8975f5c5SAndroid Build Coastguard Worker     }
660*8975f5c5SAndroid Build Coastguard Worker 
661*8975f5c5SAndroid Build Coastguard Worker     return &node;
662*8975f5c5SAndroid Build Coastguard Worker }
663*8975f5c5SAndroid Build Coastguard Worker 
traverseIfElseChildren(TIntermIfElse & node)664*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseIfElseChildren(TIntermIfElse &node)
665*8975f5c5SAndroid Build Coastguard Worker {
666*8975f5c5SAndroid Build Coastguard Worker     auto *const cond = node.getCondition();
667*8975f5c5SAndroid Build Coastguard Worker     ASSERT(cond);
668*8975f5c5SAndroid Build Coastguard Worker     auto *const true_  = node.getTrueBlock();
669*8975f5c5SAndroid Build Coastguard Worker     auto *const false_ = node.getFalseBlock();
670*8975f5c5SAndroid Build Coastguard Worker 
671*8975f5c5SAndroid Build Coastguard Worker     auto *const newCond = traverseAnyAs<TIntermTyped>(*cond);
672*8975f5c5SAndroid Build Coastguard Worker     GUARD(newCond);
673*8975f5c5SAndroid Build Coastguard Worker     TIntermBlock *newTrue = nullptr;
674*8975f5c5SAndroid Build Coastguard Worker     if (true_)
675*8975f5c5SAndroid Build Coastguard Worker     {
676*8975f5c5SAndroid Build Coastguard Worker         GUARD(traverseAnyAs(*true_, newTrue));
677*8975f5c5SAndroid Build Coastguard Worker     }
678*8975f5c5SAndroid Build Coastguard Worker     TIntermBlock *newFalse = nullptr;
679*8975f5c5SAndroid Build Coastguard Worker     if (false_)
680*8975f5c5SAndroid Build Coastguard Worker     {
681*8975f5c5SAndroid Build Coastguard Worker         GUARD(traverseAnyAs(*false_, newFalse));
682*8975f5c5SAndroid Build Coastguard Worker     }
683*8975f5c5SAndroid Build Coastguard Worker 
684*8975f5c5SAndroid Build Coastguard Worker     if (newCond != cond || newTrue != true_ || newFalse != false_)
685*8975f5c5SAndroid Build Coastguard Worker     {
686*8975f5c5SAndroid Build Coastguard Worker         return new TIntermIfElse(newCond, newTrue, newFalse);
687*8975f5c5SAndroid Build Coastguard Worker     }
688*8975f5c5SAndroid Build Coastguard Worker 
689*8975f5c5SAndroid Build Coastguard Worker     return &node;
690*8975f5c5SAndroid Build Coastguard Worker }
691*8975f5c5SAndroid Build Coastguard Worker 
traverseSwitchChildren(TIntermSwitch & node)692*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseSwitchChildren(TIntermSwitch &node)
693*8975f5c5SAndroid Build Coastguard Worker {
694*8975f5c5SAndroid Build Coastguard Worker     auto *const init = node.getInit();
695*8975f5c5SAndroid Build Coastguard Worker     ASSERT(init);
696*8975f5c5SAndroid Build Coastguard Worker     auto *const stmts = node.getStatementList();
697*8975f5c5SAndroid Build Coastguard Worker     ASSERT(stmts);
698*8975f5c5SAndroid Build Coastguard Worker 
699*8975f5c5SAndroid Build Coastguard Worker     auto *const newInit = traverseAnyAs<TIntermTyped>(*init);
700*8975f5c5SAndroid Build Coastguard Worker     GUARD(newInit);
701*8975f5c5SAndroid Build Coastguard Worker     auto *const newStmts = traverseAnyAs<TIntermBlock>(*stmts);
702*8975f5c5SAndroid Build Coastguard Worker     GUARD(newStmts);
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker     if (newInit != init || newStmts != stmts)
705*8975f5c5SAndroid Build Coastguard Worker     {
706*8975f5c5SAndroid Build Coastguard Worker         return new TIntermSwitch(newInit, newStmts);
707*8975f5c5SAndroid Build Coastguard Worker     }
708*8975f5c5SAndroid Build Coastguard Worker 
709*8975f5c5SAndroid Build Coastguard Worker     return &node;
710*8975f5c5SAndroid Build Coastguard Worker }
711*8975f5c5SAndroid Build Coastguard Worker 
traverseCaseChildren(TIntermCase & node)712*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseCaseChildren(TIntermCase &node)
713*8975f5c5SAndroid Build Coastguard Worker {
714*8975f5c5SAndroid Build Coastguard Worker     auto *const cond = node.getCondition();
715*8975f5c5SAndroid Build Coastguard Worker 
716*8975f5c5SAndroid Build Coastguard Worker     TIntermTyped *newCond = nullptr;
717*8975f5c5SAndroid Build Coastguard Worker     if (cond)
718*8975f5c5SAndroid Build Coastguard Worker     {
719*8975f5c5SAndroid Build Coastguard Worker         GUARD(traverseAnyAs(*cond, newCond));
720*8975f5c5SAndroid Build Coastguard Worker     }
721*8975f5c5SAndroid Build Coastguard Worker 
722*8975f5c5SAndroid Build Coastguard Worker     if (newCond != cond)
723*8975f5c5SAndroid Build Coastguard Worker     {
724*8975f5c5SAndroid Build Coastguard Worker         return new TIntermCase(newCond);
725*8975f5c5SAndroid Build Coastguard Worker     }
726*8975f5c5SAndroid Build Coastguard Worker 
727*8975f5c5SAndroid Build Coastguard Worker     return &node;
728*8975f5c5SAndroid Build Coastguard Worker }
729*8975f5c5SAndroid Build Coastguard Worker 
traverseFunctionDefinitionChildren(TIntermFunctionDefinition & node)730*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseFunctionDefinitionChildren(TIntermFunctionDefinition &node)
731*8975f5c5SAndroid Build Coastguard Worker {
732*8975f5c5SAndroid Build Coastguard Worker     GUARD(!mParentFunc);  // Function definitions cannot be nested.
733*8975f5c5SAndroid Build Coastguard Worker     mParentFunc = node.getFunction();
734*8975f5c5SAndroid Build Coastguard Worker     struct OnExit
735*8975f5c5SAndroid Build Coastguard Worker     {
736*8975f5c5SAndroid Build Coastguard Worker         const TFunction *&parentFunc;
737*8975f5c5SAndroid Build Coastguard Worker         OnExit(const TFunction *&parentFunc) : parentFunc(parentFunc) {}
738*8975f5c5SAndroid Build Coastguard Worker         ~OnExit() { parentFunc = nullptr; }
739*8975f5c5SAndroid Build Coastguard Worker     } onExit(mParentFunc);
740*8975f5c5SAndroid Build Coastguard Worker 
741*8975f5c5SAndroid Build Coastguard Worker     auto *const proto = node.getFunctionPrototype();
742*8975f5c5SAndroid Build Coastguard Worker     ASSERT(proto);
743*8975f5c5SAndroid Build Coastguard Worker     auto *const body = node.getBody();
744*8975f5c5SAndroid Build Coastguard Worker     ASSERT(body);
745*8975f5c5SAndroid Build Coastguard Worker 
746*8975f5c5SAndroid Build Coastguard Worker     auto *const newProto = traverseAnyAs<TIntermFunctionPrototype>(*proto);
747*8975f5c5SAndroid Build Coastguard Worker     GUARD(newProto);
748*8975f5c5SAndroid Build Coastguard Worker     auto *const newBody = traverseAnyAs<TIntermBlock>(*body);
749*8975f5c5SAndroid Build Coastguard Worker     GUARD(newBody);
750*8975f5c5SAndroid Build Coastguard Worker 
751*8975f5c5SAndroid Build Coastguard Worker     if (newProto != proto || newBody != body)
752*8975f5c5SAndroid Build Coastguard Worker     {
753*8975f5c5SAndroid Build Coastguard Worker         return new TIntermFunctionDefinition(newProto, newBody);
754*8975f5c5SAndroid Build Coastguard Worker     }
755*8975f5c5SAndroid Build Coastguard Worker 
756*8975f5c5SAndroid Build Coastguard Worker     return &node;
757*8975f5c5SAndroid Build Coastguard Worker }
758*8975f5c5SAndroid Build Coastguard Worker 
traverseGlobalQualifierDeclarationChildren(TIntermGlobalQualifierDeclaration & node)759*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseGlobalQualifierDeclarationChildren(
760*8975f5c5SAndroid Build Coastguard Worker     TIntermGlobalQualifierDeclaration &node)
761*8975f5c5SAndroid Build Coastguard Worker {
762*8975f5c5SAndroid Build Coastguard Worker     auto *const symbol = node.getSymbol();
763*8975f5c5SAndroid Build Coastguard Worker     ASSERT(symbol);
764*8975f5c5SAndroid Build Coastguard Worker 
765*8975f5c5SAndroid Build Coastguard Worker     auto *const newSymbol = traverseAnyAs<TIntermSymbol>(*symbol);
766*8975f5c5SAndroid Build Coastguard Worker     GUARD(newSymbol);
767*8975f5c5SAndroid Build Coastguard Worker 
768*8975f5c5SAndroid Build Coastguard Worker     if (newSymbol != symbol)
769*8975f5c5SAndroid Build Coastguard Worker     {
770*8975f5c5SAndroid Build Coastguard Worker         return new TIntermGlobalQualifierDeclaration(newSymbol, node.isPrecise(), node.getLine());
771*8975f5c5SAndroid Build Coastguard Worker     }
772*8975f5c5SAndroid Build Coastguard Worker 
773*8975f5c5SAndroid Build Coastguard Worker     return &node;
774*8975f5c5SAndroid Build Coastguard Worker }
775*8975f5c5SAndroid Build Coastguard Worker 
traverseLoopChildren(TIntermLoop & node)776*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseLoopChildren(TIntermLoop &node)
777*8975f5c5SAndroid Build Coastguard Worker {
778*8975f5c5SAndroid Build Coastguard Worker     const TLoopType loopType = node.getType();
779*8975f5c5SAndroid Build Coastguard Worker 
780*8975f5c5SAndroid Build Coastguard Worker     auto *const init = node.getInit();
781*8975f5c5SAndroid Build Coastguard Worker     auto *const cond = node.getCondition();
782*8975f5c5SAndroid Build Coastguard Worker     auto *const expr = node.getExpression();
783*8975f5c5SAndroid Build Coastguard Worker     auto *const body = node.getBody();
784*8975f5c5SAndroid Build Coastguard Worker 
785*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
786*8975f5c5SAndroid Build Coastguard Worker     switch (loopType)
787*8975f5c5SAndroid Build Coastguard Worker     {
788*8975f5c5SAndroid Build Coastguard Worker         case TLoopType::ELoopFor:
789*8975f5c5SAndroid Build Coastguard Worker             break;
790*8975f5c5SAndroid Build Coastguard Worker         case TLoopType::ELoopWhile:
791*8975f5c5SAndroid Build Coastguard Worker         case TLoopType::ELoopDoWhile:
792*8975f5c5SAndroid Build Coastguard Worker             ASSERT(cond);
793*8975f5c5SAndroid Build Coastguard Worker             ASSERT(!init && !expr);
794*8975f5c5SAndroid Build Coastguard Worker             break;
795*8975f5c5SAndroid Build Coastguard Worker         default:
796*8975f5c5SAndroid Build Coastguard Worker             ASSERT(false);
797*8975f5c5SAndroid Build Coastguard Worker             break;
798*8975f5c5SAndroid Build Coastguard Worker     }
799*8975f5c5SAndroid Build Coastguard Worker #endif
800*8975f5c5SAndroid Build Coastguard Worker 
801*8975f5c5SAndroid Build Coastguard Worker     auto *const newBody = traverseAnyAs<TIntermBlock>(*body);
802*8975f5c5SAndroid Build Coastguard Worker     GUARD(newBody);
803*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *newInit = nullptr;
804*8975f5c5SAndroid Build Coastguard Worker     if (init)
805*8975f5c5SAndroid Build Coastguard Worker     {
806*8975f5c5SAndroid Build Coastguard Worker         GUARD(traverseAnyAs(*init, newInit));
807*8975f5c5SAndroid Build Coastguard Worker     }
808*8975f5c5SAndroid Build Coastguard Worker     TIntermTyped *newCond = nullptr;
809*8975f5c5SAndroid Build Coastguard Worker     if (cond)
810*8975f5c5SAndroid Build Coastguard Worker     {
811*8975f5c5SAndroid Build Coastguard Worker         GUARD(traverseAnyAs(*cond, newCond));
812*8975f5c5SAndroid Build Coastguard Worker     }
813*8975f5c5SAndroid Build Coastguard Worker     TIntermTyped *newExpr = nullptr;
814*8975f5c5SAndroid Build Coastguard Worker     if (expr)
815*8975f5c5SAndroid Build Coastguard Worker     {
816*8975f5c5SAndroid Build Coastguard Worker         GUARD(traverseAnyAs(*expr, newExpr));
817*8975f5c5SAndroid Build Coastguard Worker     }
818*8975f5c5SAndroid Build Coastguard Worker 
819*8975f5c5SAndroid Build Coastguard Worker     if (newInit != init || newCond != cond || newExpr != expr || newBody != body)
820*8975f5c5SAndroid Build Coastguard Worker     {
821*8975f5c5SAndroid Build Coastguard Worker         switch (loopType)
822*8975f5c5SAndroid Build Coastguard Worker         {
823*8975f5c5SAndroid Build Coastguard Worker             case TLoopType::ELoopFor:
824*8975f5c5SAndroid Build Coastguard Worker                 break;
825*8975f5c5SAndroid Build Coastguard Worker             case TLoopType::ELoopWhile:
826*8975f5c5SAndroid Build Coastguard Worker             case TLoopType::ELoopDoWhile:
827*8975f5c5SAndroid Build Coastguard Worker                 GUARD(newCond);
828*8975f5c5SAndroid Build Coastguard Worker                 GUARD(!newInit && !newExpr);
829*8975f5c5SAndroid Build Coastguard Worker                 break;
830*8975f5c5SAndroid Build Coastguard Worker             default:
831*8975f5c5SAndroid Build Coastguard Worker                 ASSERT(false);
832*8975f5c5SAndroid Build Coastguard Worker                 break;
833*8975f5c5SAndroid Build Coastguard Worker         }
834*8975f5c5SAndroid Build Coastguard Worker         return new TIntermLoop(loopType, newInit, newCond, newExpr, newBody);
835*8975f5c5SAndroid Build Coastguard Worker     }
836*8975f5c5SAndroid Build Coastguard Worker 
837*8975f5c5SAndroid Build Coastguard Worker     return &node;
838*8975f5c5SAndroid Build Coastguard Worker }
839*8975f5c5SAndroid Build Coastguard Worker 
traverseBranchChildren(TIntermBranch & node)840*8975f5c5SAndroid Build Coastguard Worker TIntermNode *TIntermRebuild::traverseBranchChildren(TIntermBranch &node)
841*8975f5c5SAndroid Build Coastguard Worker {
842*8975f5c5SAndroid Build Coastguard Worker     auto *const expr = node.getExpression();
843*8975f5c5SAndroid Build Coastguard Worker 
844*8975f5c5SAndroid Build Coastguard Worker     TIntermTyped *newExpr = nullptr;
845*8975f5c5SAndroid Build Coastguard Worker     if (expr)
846*8975f5c5SAndroid Build Coastguard Worker     {
847*8975f5c5SAndroid Build Coastguard Worker         GUARD(traverseAnyAs<TIntermTyped>(*expr, newExpr));
848*8975f5c5SAndroid Build Coastguard Worker     }
849*8975f5c5SAndroid Build Coastguard Worker 
850*8975f5c5SAndroid Build Coastguard Worker     if (newExpr != expr)
851*8975f5c5SAndroid Build Coastguard Worker     {
852*8975f5c5SAndroid Build Coastguard Worker         return new TIntermBranch(node.getFlowOp(), newExpr);
853*8975f5c5SAndroid Build Coastguard Worker     }
854*8975f5c5SAndroid Build Coastguard Worker 
855*8975f5c5SAndroid Build Coastguard Worker     return &node;
856*8975f5c5SAndroid Build Coastguard Worker }
857*8975f5c5SAndroid Build Coastguard Worker 
858*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
859*8975f5c5SAndroid Build Coastguard Worker 
visitSymbolPre(TIntermSymbol & node)860*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitSymbolPre(TIntermSymbol &node)
861*8975f5c5SAndroid Build Coastguard Worker {
862*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
863*8975f5c5SAndroid Build Coastguard Worker }
864*8975f5c5SAndroid Build Coastguard Worker 
visitConstantUnionPre(TIntermConstantUnion & node)865*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitConstantUnionPre(TIntermConstantUnion &node)
866*8975f5c5SAndroid Build Coastguard Worker {
867*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
868*8975f5c5SAndroid Build Coastguard Worker }
869*8975f5c5SAndroid Build Coastguard Worker 
visitFunctionPrototypePre(TIntermFunctionPrototype & node)870*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitFunctionPrototypePre(TIntermFunctionPrototype &node)
871*8975f5c5SAndroid Build Coastguard Worker {
872*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
873*8975f5c5SAndroid Build Coastguard Worker }
874*8975f5c5SAndroid Build Coastguard Worker 
visitPreprocessorDirectivePre(TIntermPreprocessorDirective & node)875*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitPreprocessorDirectivePre(TIntermPreprocessorDirective &node)
876*8975f5c5SAndroid Build Coastguard Worker {
877*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
878*8975f5c5SAndroid Build Coastguard Worker }
879*8975f5c5SAndroid Build Coastguard Worker 
visitUnaryPre(TIntermUnary & node)880*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitUnaryPre(TIntermUnary &node)
881*8975f5c5SAndroid Build Coastguard Worker {
882*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
883*8975f5c5SAndroid Build Coastguard Worker }
884*8975f5c5SAndroid Build Coastguard Worker 
visitBinaryPre(TIntermBinary & node)885*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitBinaryPre(TIntermBinary &node)
886*8975f5c5SAndroid Build Coastguard Worker {
887*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
888*8975f5c5SAndroid Build Coastguard Worker }
889*8975f5c5SAndroid Build Coastguard Worker 
visitTernaryPre(TIntermTernary & node)890*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitTernaryPre(TIntermTernary &node)
891*8975f5c5SAndroid Build Coastguard Worker {
892*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
893*8975f5c5SAndroid Build Coastguard Worker }
894*8975f5c5SAndroid Build Coastguard Worker 
visitSwizzlePre(TIntermSwizzle & node)895*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitSwizzlePre(TIntermSwizzle &node)
896*8975f5c5SAndroid Build Coastguard Worker {
897*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
898*8975f5c5SAndroid Build Coastguard Worker }
899*8975f5c5SAndroid Build Coastguard Worker 
visitIfElsePre(TIntermIfElse & node)900*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitIfElsePre(TIntermIfElse &node)
901*8975f5c5SAndroid Build Coastguard Worker {
902*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
903*8975f5c5SAndroid Build Coastguard Worker }
904*8975f5c5SAndroid Build Coastguard Worker 
visitSwitchPre(TIntermSwitch & node)905*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitSwitchPre(TIntermSwitch &node)
906*8975f5c5SAndroid Build Coastguard Worker {
907*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
908*8975f5c5SAndroid Build Coastguard Worker }
909*8975f5c5SAndroid Build Coastguard Worker 
visitCasePre(TIntermCase & node)910*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitCasePre(TIntermCase &node)
911*8975f5c5SAndroid Build Coastguard Worker {
912*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
913*8975f5c5SAndroid Build Coastguard Worker }
914*8975f5c5SAndroid Build Coastguard Worker 
visitLoopPre(TIntermLoop & node)915*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitLoopPre(TIntermLoop &node)
916*8975f5c5SAndroid Build Coastguard Worker {
917*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
918*8975f5c5SAndroid Build Coastguard Worker }
919*8975f5c5SAndroid Build Coastguard Worker 
visitBranchPre(TIntermBranch & node)920*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitBranchPre(TIntermBranch &node)
921*8975f5c5SAndroid Build Coastguard Worker {
922*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
923*8975f5c5SAndroid Build Coastguard Worker }
924*8975f5c5SAndroid Build Coastguard Worker 
visitDeclarationPre(TIntermDeclaration & node)925*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitDeclarationPre(TIntermDeclaration &node)
926*8975f5c5SAndroid Build Coastguard Worker {
927*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
928*8975f5c5SAndroid Build Coastguard Worker }
929*8975f5c5SAndroid Build Coastguard Worker 
visitBlockPre(TIntermBlock & node)930*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitBlockPre(TIntermBlock &node)
931*8975f5c5SAndroid Build Coastguard Worker {
932*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
933*8975f5c5SAndroid Build Coastguard Worker }
934*8975f5c5SAndroid Build Coastguard Worker 
visitAggregatePre(TIntermAggregate & node)935*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitAggregatePre(TIntermAggregate &node)
936*8975f5c5SAndroid Build Coastguard Worker {
937*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
938*8975f5c5SAndroid Build Coastguard Worker }
939*8975f5c5SAndroid Build Coastguard Worker 
visitFunctionDefinitionPre(TIntermFunctionDefinition & node)940*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitFunctionDefinitionPre(TIntermFunctionDefinition &node)
941*8975f5c5SAndroid Build Coastguard Worker {
942*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
943*8975f5c5SAndroid Build Coastguard Worker }
944*8975f5c5SAndroid Build Coastguard Worker 
visitGlobalQualifierDeclarationPre(TIntermGlobalQualifierDeclaration & node)945*8975f5c5SAndroid Build Coastguard Worker PreResult TIntermRebuild::visitGlobalQualifierDeclarationPre(
946*8975f5c5SAndroid Build Coastguard Worker     TIntermGlobalQualifierDeclaration &node)
947*8975f5c5SAndroid Build Coastguard Worker {
948*8975f5c5SAndroid Build Coastguard Worker     return {node, VisitBits::Both};
949*8975f5c5SAndroid Build Coastguard Worker }
950*8975f5c5SAndroid Build Coastguard Worker 
951*8975f5c5SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
952*8975f5c5SAndroid Build Coastguard Worker 
visitSymbolPost(TIntermSymbol & node)953*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitSymbolPost(TIntermSymbol &node)
954*8975f5c5SAndroid Build Coastguard Worker {
955*8975f5c5SAndroid Build Coastguard Worker     return node;
956*8975f5c5SAndroid Build Coastguard Worker }
957*8975f5c5SAndroid Build Coastguard Worker 
visitConstantUnionPost(TIntermConstantUnion & node)958*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitConstantUnionPost(TIntermConstantUnion &node)
959*8975f5c5SAndroid Build Coastguard Worker {
960*8975f5c5SAndroid Build Coastguard Worker     return node;
961*8975f5c5SAndroid Build Coastguard Worker }
962*8975f5c5SAndroid Build Coastguard Worker 
visitFunctionPrototypePost(TIntermFunctionPrototype & node)963*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitFunctionPrototypePost(TIntermFunctionPrototype &node)
964*8975f5c5SAndroid Build Coastguard Worker {
965*8975f5c5SAndroid Build Coastguard Worker     return node;
966*8975f5c5SAndroid Build Coastguard Worker }
967*8975f5c5SAndroid Build Coastguard Worker 
visitPreprocessorDirectivePost(TIntermPreprocessorDirective & node)968*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitPreprocessorDirectivePost(TIntermPreprocessorDirective &node)
969*8975f5c5SAndroid Build Coastguard Worker {
970*8975f5c5SAndroid Build Coastguard Worker     return node;
971*8975f5c5SAndroid Build Coastguard Worker }
972*8975f5c5SAndroid Build Coastguard Worker 
visitUnaryPost(TIntermUnary & node)973*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitUnaryPost(TIntermUnary &node)
974*8975f5c5SAndroid Build Coastguard Worker {
975*8975f5c5SAndroid Build Coastguard Worker     return node;
976*8975f5c5SAndroid Build Coastguard Worker }
977*8975f5c5SAndroid Build Coastguard Worker 
visitBinaryPost(TIntermBinary & node)978*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitBinaryPost(TIntermBinary &node)
979*8975f5c5SAndroid Build Coastguard Worker {
980*8975f5c5SAndroid Build Coastguard Worker     return node;
981*8975f5c5SAndroid Build Coastguard Worker }
982*8975f5c5SAndroid Build Coastguard Worker 
visitTernaryPost(TIntermTernary & node)983*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitTernaryPost(TIntermTernary &node)
984*8975f5c5SAndroid Build Coastguard Worker {
985*8975f5c5SAndroid Build Coastguard Worker     return node;
986*8975f5c5SAndroid Build Coastguard Worker }
987*8975f5c5SAndroid Build Coastguard Worker 
visitSwizzlePost(TIntermSwizzle & node)988*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitSwizzlePost(TIntermSwizzle &node)
989*8975f5c5SAndroid Build Coastguard Worker {
990*8975f5c5SAndroid Build Coastguard Worker     return node;
991*8975f5c5SAndroid Build Coastguard Worker }
992*8975f5c5SAndroid Build Coastguard Worker 
visitIfElsePost(TIntermIfElse & node)993*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitIfElsePost(TIntermIfElse &node)
994*8975f5c5SAndroid Build Coastguard Worker {
995*8975f5c5SAndroid Build Coastguard Worker     return node;
996*8975f5c5SAndroid Build Coastguard Worker }
997*8975f5c5SAndroid Build Coastguard Worker 
visitSwitchPost(TIntermSwitch & node)998*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitSwitchPost(TIntermSwitch &node)
999*8975f5c5SAndroid Build Coastguard Worker {
1000*8975f5c5SAndroid Build Coastguard Worker     return node;
1001*8975f5c5SAndroid Build Coastguard Worker }
1002*8975f5c5SAndroid Build Coastguard Worker 
visitCasePost(TIntermCase & node)1003*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitCasePost(TIntermCase &node)
1004*8975f5c5SAndroid Build Coastguard Worker {
1005*8975f5c5SAndroid Build Coastguard Worker     return node;
1006*8975f5c5SAndroid Build Coastguard Worker }
1007*8975f5c5SAndroid Build Coastguard Worker 
visitLoopPost(TIntermLoop & node)1008*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitLoopPost(TIntermLoop &node)
1009*8975f5c5SAndroid Build Coastguard Worker {
1010*8975f5c5SAndroid Build Coastguard Worker     return node;
1011*8975f5c5SAndroid Build Coastguard Worker }
1012*8975f5c5SAndroid Build Coastguard Worker 
visitBranchPost(TIntermBranch & node)1013*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitBranchPost(TIntermBranch &node)
1014*8975f5c5SAndroid Build Coastguard Worker {
1015*8975f5c5SAndroid Build Coastguard Worker     return node;
1016*8975f5c5SAndroid Build Coastguard Worker }
1017*8975f5c5SAndroid Build Coastguard Worker 
visitDeclarationPost(TIntermDeclaration & node)1018*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitDeclarationPost(TIntermDeclaration &node)
1019*8975f5c5SAndroid Build Coastguard Worker {
1020*8975f5c5SAndroid Build Coastguard Worker     return node;
1021*8975f5c5SAndroid Build Coastguard Worker }
1022*8975f5c5SAndroid Build Coastguard Worker 
visitBlockPost(TIntermBlock & node)1023*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitBlockPost(TIntermBlock &node)
1024*8975f5c5SAndroid Build Coastguard Worker {
1025*8975f5c5SAndroid Build Coastguard Worker     return node;
1026*8975f5c5SAndroid Build Coastguard Worker }
1027*8975f5c5SAndroid Build Coastguard Worker 
visitAggregatePost(TIntermAggregate & node)1028*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitAggregatePost(TIntermAggregate &node)
1029*8975f5c5SAndroid Build Coastguard Worker {
1030*8975f5c5SAndroid Build Coastguard Worker     return node;
1031*8975f5c5SAndroid Build Coastguard Worker }
1032*8975f5c5SAndroid Build Coastguard Worker 
visitFunctionDefinitionPost(TIntermFunctionDefinition & node)1033*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitFunctionDefinitionPost(TIntermFunctionDefinition &node)
1034*8975f5c5SAndroid Build Coastguard Worker {
1035*8975f5c5SAndroid Build Coastguard Worker     return node;
1036*8975f5c5SAndroid Build Coastguard Worker }
1037*8975f5c5SAndroid Build Coastguard Worker 
visitGlobalQualifierDeclarationPost(TIntermGlobalQualifierDeclaration & node)1038*8975f5c5SAndroid Build Coastguard Worker PostResult TIntermRebuild::visitGlobalQualifierDeclarationPost(
1039*8975f5c5SAndroid Build Coastguard Worker     TIntermGlobalQualifierDeclaration &node)
1040*8975f5c5SAndroid Build Coastguard Worker {
1041*8975f5c5SAndroid Build Coastguard Worker     return node;
1042*8975f5c5SAndroid Build Coastguard Worker }
1043*8975f5c5SAndroid Build Coastguard Worker 
1044*8975f5c5SAndroid Build Coastguard Worker }  // namespace sh
1045