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