Commit 27446bda by Olli Etuaho

Move traverse functions under TIntermTraverser

This enables implementing specialized variants of TIntermTraverser. Intermediate subclasses of TIntermTraverser are expected to maintain contextual information in their traverse* functions, which is then used by the visit* functions in the actual traversers. This approach is better than adding a flag to TIntermTraverser, since it will make the code cleaner and easier to understand. Traverse() functions in TIntermNode subclasses are still kept around to redirect calls to TIntermTraverser traversal functions. This is less hacky than choosing the function with switch/case in TIntermTraverser would be, and if new TIntermNode subclasses get added, it's not as likely that adding the traversal support would be forgotten. TEST=angle_unittests BUG=angleproject:1116 Change-Id: Ie6889be1d7e955518f13cd3390dce17871ba49b5 Reviewed-on: https://chromium-review.googlesource.com/292720Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent b4b0b482
...@@ -155,7 +155,7 @@ class TIntermLoop : public TIntermNode ...@@ -155,7 +155,7 @@ class TIntermLoop : public TIntermNode
mUnrollFlag(false) { } mUnrollFlag(false) { }
virtual TIntermLoop *getAsLoopNode() { return this; } virtual TIntermLoop *getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual bool replaceChildNode( virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement); TIntermNode *original, TIntermNode *replacement);
...@@ -188,7 +188,7 @@ class TIntermBranch : public TIntermNode ...@@ -188,7 +188,7 @@ class TIntermBranch : public TIntermNode
: mFlowOp(op), : mFlowOp(op),
mExpression(e) { } mExpression(e) { }
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual bool replaceChildNode( virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement); TIntermNode *original, TIntermNode *replacement);
...@@ -227,7 +227,7 @@ class TIntermSymbol : public TIntermTyped ...@@ -227,7 +227,7 @@ class TIntermSymbol : public TIntermTyped
bool isInternal() const { return mInternal; } bool isInternal() const { return mInternal; }
void setInternal(bool isInternal) { mInternal = isInternal; } void setInternal(bool isInternal) { mInternal = isInternal; }
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual TIntermSymbol *getAsSymbolNode() { return this; } virtual TIntermSymbol *getAsSymbolNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
...@@ -251,7 +251,7 @@ class TIntermRaw : public TIntermTyped ...@@ -251,7 +251,7 @@ class TIntermRaw : public TIntermTyped
TString getRawText() const { return mRawText; } TString getRawText() const { return mRawText; }
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual TIntermRaw *getAsRawNode() { return this; } virtual TIntermRaw *getAsRawNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
...@@ -296,7 +296,7 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -296,7 +296,7 @@ class TIntermConstantUnion : public TIntermTyped
} }
virtual TIntermConstantUnion *getAsConstantUnion() { return this; } virtual TIntermConstantUnion *getAsConstantUnion() { return this; }
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink); TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink);
...@@ -350,7 +350,7 @@ class TIntermBinary : public TIntermOperator ...@@ -350,7 +350,7 @@ class TIntermBinary : public TIntermOperator
mAddIndexClamp(false) {} mAddIndexClamp(false) {}
virtual TIntermBinary *getAsBinaryNode() { return this; } virtual TIntermBinary *getAsBinaryNode() { return this; }
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual bool replaceChildNode( virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement); TIntermNode *original, TIntermNode *replacement);
...@@ -392,7 +392,7 @@ class TIntermUnary : public TIntermOperator ...@@ -392,7 +392,7 @@ class TIntermUnary : public TIntermOperator
mOperand(NULL), mOperand(NULL),
mUseEmulatedFunction(false) {} mUseEmulatedFunction(false) {}
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual TIntermUnary *getAsUnaryNode() { return this; } virtual TIntermUnary *getAsUnaryNode() { return this; }
virtual bool replaceChildNode( virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement); TIntermNode *original, TIntermNode *replacement);
...@@ -443,7 +443,7 @@ class TIntermAggregate : public TIntermOperator ...@@ -443,7 +443,7 @@ class TIntermAggregate : public TIntermOperator
~TIntermAggregate() { } ~TIntermAggregate() { }
virtual TIntermAggregate *getAsAggregate() { return this; } virtual TIntermAggregate *getAsAggregate() { return this; }
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual bool replaceChildNode( virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement); TIntermNode *original, TIntermNode *replacement);
bool replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements); bool replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements);
...@@ -513,7 +513,7 @@ class TIntermSelection : public TIntermTyped ...@@ -513,7 +513,7 @@ class TIntermSelection : public TIntermTyped
mTrueBlock(trueB), mTrueBlock(trueB),
mFalseBlock(falseB) {} mFalseBlock(falseB) {}
virtual void traverse(TIntermTraverser *); void traverse(TIntermTraverser *it) override;
virtual bool replaceChildNode( virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement); TIntermNode *original, TIntermNode *replacement);
...@@ -551,6 +551,7 @@ class TIntermSwitch : public TIntermNode ...@@ -551,6 +551,7 @@ class TIntermSwitch : public TIntermNode
TIntermSwitch *getAsSwitchNode() override { return this; } TIntermSwitch *getAsSwitchNode() override { return this; }
TIntermTyped *getInit() { return mInit; }
TIntermAggregate *getStatementList() { return mStatementList; } TIntermAggregate *getStatementList() { return mStatementList; }
void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; } void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; }
...@@ -592,9 +593,12 @@ enum Visit ...@@ -592,9 +593,12 @@ enum Visit
}; };
// //
// For traversing the tree. User should derive from this, // For traversing the tree. User should derive from this class overriding the visit functions,
// put their traversal specific data in it, and then pass // and then pass an object of the subclass to a traverse method of a node.
// it to a Traverse method. //
// The traverse*() functions may also be overridden do other bookkeeping on the tree to provide
// contextual information to the visit functions, such as whether the node is the target of an
// assignment.
// //
// When using this, just fill in the methods for nodes you want visited. // When using this, just fill in the methods for nodes you want visited.
// Return false from a pre-visit to skip visiting that node's subtree. // Return false from a pre-visit to skip visiting that node's subtree.
...@@ -616,20 +620,48 @@ class TIntermTraverser : angle::NonCopyable ...@@ -616,20 +620,48 @@ class TIntermTraverser : angle::NonCopyable
} }
virtual ~TIntermTraverser() {} virtual ~TIntermTraverser() {}
virtual void visitSymbol(TIntermSymbol *) {} virtual void visitSymbol(TIntermSymbol *node) {}
virtual void visitRaw(TIntermRaw *) {} virtual void visitRaw(TIntermRaw *node) {}
virtual void visitConstantUnion(TIntermConstantUnion *) {} virtual void visitConstantUnion(TIntermConstantUnion *node) {}
virtual bool visitBinary(Visit, TIntermBinary *) { return true; } virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; }
virtual bool visitUnary(Visit, TIntermUnary *) { return true; } virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; }
virtual bool visitSelection(Visit, TIntermSelection *) { return true; } virtual bool visitSelection(Visit visit, TIntermSelection *node) { return true; }
virtual bool visitSwitch(Visit, TIntermSwitch *) { return true; } virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; }
virtual bool visitCase(Visit, TIntermCase *) { return true; } virtual bool visitCase(Visit visit, TIntermCase *node) { return true; }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; } virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; }
virtual bool visitLoop(Visit, TIntermLoop *) { return true; } virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; }
virtual bool visitBranch(Visit, TIntermBranch *) { return true; } virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; }
// The traverse functions contain logic for iterating over the children of the node
// and calling the visit functions in the appropriate places. They also track some
// context that may be used by the visit functions.
virtual void traverseSymbol(TIntermSymbol *node);
virtual void traverseRaw(TIntermRaw *node);
virtual void traverseConstantUnion(TIntermConstantUnion *node);
virtual void traverseBinary(TIntermBinary *node);
virtual void traverseUnary(TIntermUnary *node);
virtual void traverseSelection(TIntermSelection *node);
virtual void traverseSwitch(TIntermSwitch *node);
virtual void traverseCase(TIntermCase *node);
virtual void traverseAggregate(TIntermAggregate *node);
virtual void traverseLoop(TIntermLoop *node);
virtual void traverseBranch(TIntermBranch *node);
int getMaxDepth() const { return mMaxDepth; } int getMaxDepth() const { return mMaxDepth; }
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
static TString hash(const TString &name, ShHashFunction64 hashFunction);
// If traversers need to replace nodes, they can add the replacements in
// mReplacements/mMultiReplacements during traversal and the user of the traverser should call
// this function after traversal to perform them.
void updateTree();
// Start creating temporary symbols from the given temporary symbol index + 1.
void useTemporaryIndex(unsigned int *temporaryIndex);
protected:
void incrementDepth(TIntermNode *current) void incrementDepth(TIntermNode *current)
{ {
mDepth++; mDepth++;
...@@ -657,22 +689,10 @@ class TIntermTraverser : angle::NonCopyable ...@@ -657,22 +689,10 @@ class TIntermTraverser : angle::NonCopyable
return !mParentBlockStack.empty() && getParentNode() == mParentBlockStack.back().node; return !mParentBlockStack.empty() && getParentNode() == mParentBlockStack.back().node;
} }
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
static TString hash(const TString& name, ShHashFunction64 hashFunction);
const bool preVisit; const bool preVisit;
const bool inVisit; const bool inVisit;
const bool postVisit; const bool postVisit;
// If traversers need to replace nodes, they can add the replacements in
// mReplacements/mMultiReplacements during traversal and the user of the traverser should call
// this function after traversal to perform them.
void updateTree();
// Start creating temporary symbols from the given temporary symbol index + 1.
void useTemporaryIndex(unsigned int *temporaryIndex);
// Track whether an l-value is required in the node that is currently being traversed. // Track whether an l-value is required in the node that is currently being traversed.
// These functions are intended to be called only from traversal functions, not from subclasses // These functions are intended to be called only from traversal functions, not from subclasses
// of TIntermTraverser. // of TIntermTraverser.
...@@ -703,7 +723,6 @@ class TIntermTraverser : angle::NonCopyable ...@@ -703,7 +723,6 @@ class TIntermTraverser : angle::NonCopyable
return mOperatorRequiresLValue || mInFunctionCallOutParameter; return mOperatorRequiresLValue || mInFunctionCallOutParameter;
} }
protected:
int mDepth; int mDepth;
int mMaxDepth; int mMaxDepth;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment