#include "GLSLANG/ShaderLang.h"
#include <algorithm>
+#include <queue>
#include "compiler/translator/Common.h"
#include "compiler/translator/Types.h"
#include "compiler/translator/ConstantUnion.h"
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement) = 0;
+ // For traversing a tree in no particular order, but using
+ // heap memory.
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const = 0;
+
protected:
TSourceLoc line;
};
void setUnrollFlag(bool flag) { unrollFlag = flag; }
bool getUnrollFlag() { return unrollFlag; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
+
protected:
TLoopType type;
TIntermNode* init; // for-loop initialization
TOperator getFlowOp() { return flowOp; }
TIntermTyped* getExpression() { return expression; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
+
protected:
TOperator flowOp;
TIntermTyped* expression; // non-zero except for "return exp;" statements
virtual TIntermSymbol* getAsSymbolNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {}
+
protected:
int id;
TString symbol;
virtual TIntermRaw* getAsRawNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {}
+
protected:
TString rawText;
};
TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const {}
+
protected:
ConstantUnion *unionArrayPointer;
};
void setAddIndexClamp() { addIndexClamp = true; }
bool getAddIndexClamp() { return addIndexClamp; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
+
protected:
TIntermTyped* left;
TIntermTyped* right;
void setUseEmulatedFunction() { useEmulatedFunction = true; }
bool getUseEmulatedFunction() { return useEmulatedFunction; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
+
protected:
TIntermTyped* operand;
void setUseEmulatedFunction() { useEmulatedFunction = true; }
bool getUseEmulatedFunction() { return useEmulatedFunction; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
+
protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
TIntermNode* getFalseBlock() const { return falseBlock; }
TIntermSelection* getAsSelectionNode() { return this; }
+ virtual void enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const;
+
protected:
TIntermTyped* condition;
TIntermNode* trueBlock;
TVector<TIntermNode *> path;
};
+//
+// For traversing the tree, and computing max depth.
+// Takes a maximum depth limit to prevent stack overflow.
+//
+class TMaxDepthTraverser : public TIntermTraverser
+{
+public:
+ POOL_ALLOCATOR_NEW_DELETE();
+ TMaxDepthTraverser(int depthLimit)
+ : TIntermTraverser(true, true, false, false),
+ depthLimit(depthLimit)
+ {}
+
+ virtual bool visitBinary(Visit visit, TIntermBinary*) { return depthCheck(); }
+ virtual bool visitUnary(Visit visit, TIntermUnary*) { return depthCheck(); }
+ virtual bool visitSelection(Visit visit, TIntermSelection*) { return depthCheck(); }
+ virtual bool visitAggregate(Visit visit, TIntermAggregate*) { return depthCheck(); }
+ virtual bool visitLoop(Visit visit, TIntermLoop*) { return depthCheck(); }
+ virtual bool visitBranch(Visit visit, TIntermBranch*) { return depthCheck(); }
+
+protected:
+ int depthLimit;
+
+ bool depthCheck() const { return maxDepth < depthLimit; }
+};
+
#endif // __INTERMEDIATE_H