summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/intermediate.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/intermediate.h')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/intermediate.h626
1 files changed, 381 insertions, 245 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/intermediate.h b/src/3rdparty/angle/src/compiler/translator/intermediate.h
index 8f9fe23d3b..892f2849e0 100644
--- a/src/3rdparty/angle/src/compiler/translator/intermediate.h
+++ b/src/3rdparty/angle/src/compiler/translator/intermediate.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -8,17 +8,19 @@
// Definition of the in-memory high-level intermediate representation
// of shaders. This is a tree that parser creates.
//
-// Nodes in the tree are defined as a hierarchy of classes derived from
+// Nodes in the tree are defined as a hierarchy of classes derived from
// TIntermNode. Each is a node in a tree. There is no preset branching factor;
// each node can have it's own type of list of children.
//
-#ifndef __INTERMEDIATE_H
-#define __INTERMEDIATE_H
+#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
+#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
#include "GLSLANG/ShaderLang.h"
#include <algorithm>
+#include <queue>
+
#include "compiler/translator/Common.h"
#include "compiler/translator/Types.h"
#include "compiler/translator/ConstantUnion.h"
@@ -26,10 +28,11 @@
//
// Operators used by the high-level (parse tree) representation.
//
-enum TOperator {
+enum TOperator
+{
EOpNull, // if in a node, should only mean a node is still being built
EOpSequence, // denotes a list of statements, or parameters, etc.
- EOpFunctionCall,
+ EOpFunctionCall,
EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function
@@ -49,13 +52,6 @@ enum TOperator {
EOpPreIncrement,
EOpPreDecrement,
- EOpConvIntToBool,
- EOpConvFloatToBool,
- EOpConvBoolToFloat,
- EOpConvIntToFloat,
- EOpConvFloatToInt,
- EOpConvBoolToInt,
-
//
// binary operations
//
@@ -86,6 +82,7 @@ enum TOperator {
EOpIndexDirect,
EOpIndexIndirect,
EOpIndexDirectStruct,
+ EOpIndexDirectInterfaceBlock,
EOpVectorSwizzle,
@@ -155,6 +152,7 @@ enum TOperator {
//
EOpConstructInt,
+ EOpConstructUInt,
EOpConstructBool,
EOpConstructFloat,
EOpConstructVec2,
@@ -166,6 +164,9 @@ enum TOperator {
EOpConstructIVec2,
EOpConstructIVec3,
EOpConstructIVec4,
+ EOpConstructUVec2,
+ EOpConstructUVec3,
+ EOpConstructUVec4,
EOpConstructMat2,
EOpConstructMat3,
EOpConstructMat4,
@@ -187,8 +188,6 @@ enum TOperator {
EOpDivAssign
};
-extern const char* getOperatorString(TOperator op);
-
class TIntermTraverser;
class TIntermAggregate;
class TIntermBinary;
@@ -199,347 +198,454 @@ class TIntermTyped;
class TIntermSymbol;
class TIntermLoop;
class TInfoSink;
+class TIntermRaw;
//
// Base class for the tree nodes
//
-class TIntermNode {
-public:
+class TIntermNode
+{
+ public:
POOL_ALLOCATOR_NEW_DELETE();
- TIntermNode() {
+ TIntermNode()
+ {
// TODO: Move this to TSourceLoc constructor
// after getting rid of TPublicType.
- line.first_file = line.last_file = 0;
- line.first_line = line.last_line = 0;
+ mLine.first_file = mLine.last_file = 0;
+ mLine.first_line = mLine.last_line = 0;
}
virtual ~TIntermNode() { }
- const TSourceLoc& getLine() const { return line; }
- void setLine(const TSourceLoc& l) { line = l; }
+ const TSourceLoc &getLine() const { return mLine; }
+ void setLine(const TSourceLoc &l) { mLine = l; }
- virtual void traverse(TIntermTraverser*) = 0;
- virtual TIntermTyped* getAsTyped() { return 0; }
- virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
- virtual TIntermAggregate* getAsAggregate() { return 0; }
- virtual TIntermBinary* getAsBinaryNode() { return 0; }
- virtual TIntermUnary* getAsUnaryNode() { return 0; }
- virtual TIntermSelection* getAsSelectionNode() { return 0; }
- virtual TIntermSymbol* getAsSymbolNode() { return 0; }
- virtual TIntermLoop* getAsLoopNode() { return 0; }
+ virtual void traverse(TIntermTraverser *) = 0;
+ virtual TIntermTyped *getAsTyped() { return 0; }
+ virtual TIntermConstantUnion *getAsConstantUnion() { return 0; }
+ virtual TIntermAggregate *getAsAggregate() { return 0; }
+ virtual TIntermBinary *getAsBinaryNode() { return 0; }
+ virtual TIntermUnary *getAsUnaryNode() { return 0; }
+ virtual TIntermSelection *getAsSelectionNode() { return 0; }
+ virtual TIntermSymbol *getAsSymbolNode() { return 0; }
+ virtual TIntermLoop *getAsLoopNode() { return 0; }
+ virtual TIntermRaw *getAsRawNode() { return 0; }
// Replace a child node. Return true if |original| is a child
// node and it is replaced; otherwise, return false.
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement) = 0;
-protected:
- TSourceLoc line;
+ // For traversing a tree in no particular order, but using
+ // heap memory.
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const = 0;
+
+ protected:
+ TSourceLoc mLine;
};
//
// This is just to help yacc.
//
-struct TIntermNodePair {
- TIntermNode* node1;
- TIntermNode* node2;
+struct TIntermNodePair
+{
+ TIntermNode *node1;
+ TIntermNode *node2;
};
//
// Intermediate class for nodes that have a type.
//
-class TIntermTyped : public TIntermNode {
-public:
- TIntermTyped(const TType& t) : type(t) { }
- virtual TIntermTyped* getAsTyped() { return this; }
+class TIntermTyped : public TIntermNode
+{
+ public:
+ TIntermTyped(const TType &t) : mType(t) { }
+ virtual TIntermTyped *getAsTyped() { return this; }
virtual bool hasSideEffects() const = 0;
- void setType(const TType& t) { type = t; }
- const TType& getType() const { return type; }
- TType* getTypePointer() { return &type; }
-
- TBasicType getBasicType() const { return type.getBasicType(); }
- TQualifier getQualifier() const { return type.getQualifier(); }
- TPrecision getPrecision() const { return type.getPrecision(); }
- int getNominalSize() const { return type.getNominalSize(); }
-
- bool isMatrix() const { return type.isMatrix(); }
- bool isArray() const { return type.isArray(); }
- bool isVector() const { return type.isVector(); }
- bool isScalar() const { return type.isScalar(); }
- const char* getBasicString() const { return type.getBasicString(); }
- const char* getQualifierString() const { return type.getQualifierString(); }
- TString getCompleteString() const { return type.getCompleteString(); }
-
- int totalRegisterCount() const { return type.totalRegisterCount(); }
- int elementRegisterCount() const { return type.elementRegisterCount(); }
- int getArraySize() const { return type.getArraySize(); }
-
-protected:
- TType type;
+ void setType(const TType &t) { mType = t; }
+ const TType &getType() const { return mType; }
+ TType *getTypePointer() { return &mType; }
+
+ TBasicType getBasicType() const { return mType.getBasicType(); }
+ TQualifier getQualifier() const { return mType.getQualifier(); }
+ TPrecision getPrecision() const { return mType.getPrecision(); }
+ int getCols() const { return mType.getCols(); }
+ int getRows() const { return mType.getRows(); }
+ int getNominalSize() const { return mType.getNominalSize(); }
+ int getSecondarySize() const { return mType.getSecondarySize(); }
+
+ bool isInterfaceBlock() const { return mType.isInterfaceBlock(); }
+ bool isMatrix() const { return mType.isMatrix(); }
+ bool isArray() const { return mType.isArray(); }
+ bool isVector() const { return mType.isVector(); }
+ bool isScalar() const { return mType.isScalar(); }
+ bool isScalarInt() const { return mType.isScalarInt(); }
+ const char *getBasicString() const { return mType.getBasicString(); }
+ const char *getQualifierString() const { return mType.getQualifierString(); }
+ TString getCompleteString() const { return mType.getCompleteString(); }
+
+ int getArraySize() const { return mType.getArraySize(); }
+
+ protected:
+ TType mType;
};
//
// Handle for, do-while, and while loops.
//
-enum TLoopType {
+enum TLoopType
+{
ELoopFor,
ELoopWhile,
ELoopDoWhile
};
-class TIntermLoop : public TIntermNode {
-public:
- TIntermLoop(TLoopType aType,
- TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
- TIntermNode* aBody) :
- type(aType),
- init(aInit),
- cond(aCond),
- expr(aExpr),
- body(aBody),
- unrollFlag(false) { }
-
- virtual TIntermLoop* getAsLoopNode() { return this; }
- virtual void traverse(TIntermTraverser*);
+class TIntermLoop : public TIntermNode
+{
+ public:
+ TIntermLoop(TLoopType type,
+ TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
+ TIntermNode *body)
+ : mType(type),
+ mInit(init),
+ mCond(cond),
+ mExpr(expr),
+ mBody(body),
+ mUnrollFlag(false) { }
+
+ virtual TIntermLoop *getAsLoopNode() { return this; }
+ virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
- TLoopType getType() const { return type; }
- TIntermNode* getInit() { return init; }
- TIntermTyped* getCondition() { return cond; }
- TIntermTyped* getExpression() { return expr; }
- TIntermNode* getBody() { return body; }
+ TLoopType getType() const { return mType; }
+ TIntermNode *getInit() { return mInit; }
+ TIntermTyped *getCondition() { return mCond; }
+ TIntermTyped *getExpression() { return mExpr; }
+ TIntermNode *getBody() { return mBody; }
- void setUnrollFlag(bool flag) { unrollFlag = flag; }
- bool getUnrollFlag() { return unrollFlag; }
+ void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
+ bool getUnrollFlag() const { return mUnrollFlag; }
-protected:
- TLoopType type;
- TIntermNode* init; // for-loop initialization
- TIntermTyped* cond; // loop exit condition
- TIntermTyped* expr; // for-loop expression
- TIntermNode* body; // loop body
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
- bool unrollFlag; // Whether the loop should be unrolled or not.
+ protected:
+ TLoopType mType;
+ TIntermNode *mInit; // for-loop initialization
+ TIntermTyped *mCond; // loop exit condition
+ TIntermTyped *mExpr; // for-loop expression
+ TIntermNode *mBody; // loop body
+
+ bool mUnrollFlag; // Whether the loop should be unrolled or not.
};
//
// Handle break, continue, return, and kill.
//
-class TIntermBranch : public TIntermNode {
-public:
- TIntermBranch(TOperator op, TIntermTyped* e) :
- flowOp(op),
- expression(e) { }
+class TIntermBranch : public TIntermNode
+{
+ public:
+ TIntermBranch(TOperator op, TIntermTyped *e)
+ : mFlowOp(op),
+ mExpression(e) { }
- virtual void traverse(TIntermTraverser*);
+ virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
- TOperator getFlowOp() { return flowOp; }
- TIntermTyped* getExpression() { return expression; }
+ TOperator getFlowOp() { return mFlowOp; }
+ TIntermTyped* getExpression() { return mExpression; }
+
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
- TOperator flowOp;
- TIntermTyped* expression; // non-zero except for "return exp;" statements
+ TOperator mFlowOp;
+ TIntermTyped *mExpression; // non-zero except for "return exp;" statements
};
//
// Nodes that correspond to symbols or constants in the source code.
//
-class TIntermSymbol : public TIntermTyped {
-public:
- // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
- // per process globalpoolallocator, then it causes increased memory usage per compile
- // it is essential to use "symbol = sym" to assign to symbol
- TIntermSymbol(int i, const TString& sym, const TType& t) :
- TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
+class TIntermSymbol : public TIntermTyped
+{
+ public:
+ // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym.
+ // If sym comes from per process globalpoolallocator, then it causes increased memory usage
+ // per compile it is essential to use "symbol = sym" to assign to symbol
+ TIntermSymbol(int id, const TString &symbol, const TType &type)
+ : TIntermTyped(type),
+ mId(id)
+ {
+ mSymbol = symbol;
+ }
virtual bool hasSideEffects() const { return false; }
- int getId() const { return id; }
- const TString& getSymbol() const { return symbol; }
+ int getId() const { return mId; }
+ const TString &getSymbol() const { return mSymbol; }
+
+ void setId(int newId) { mId = newId; }
+
+ virtual void traverse(TIntermTraverser *);
+ virtual TIntermSymbol *getAsSymbolNode() { return this; }
+ virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
- void setId(int newId) { id = newId; }
- void setSymbol(const TString& sym) { symbol = sym; }
+ protected:
+ int mId;
+ TString mSymbol;
+};
- const TString& getOriginalSymbol() const { return originalSymbol; }
+// A Raw node stores raw code, that the translator will insert verbatim
+// into the output stream. Useful for transformation operations that make
+// complex code that might not fit naturally into the GLSL model.
+class TIntermRaw : public TIntermTyped
+{
+ public:
+ TIntermRaw(const TType &type, const TString &rawText)
+ : TIntermTyped(type),
+ mRawText(rawText) { }
+
+ virtual bool hasSideEffects() const { return false; }
- virtual void traverse(TIntermTraverser*);
- virtual TIntermSymbol* getAsSymbolNode() { return this; }
+ TString getRawText() const { return mRawText; }
+
+ virtual void traverse(TIntermTraverser *);
+
+ virtual TIntermRaw *getAsRawNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
-protected:
- int id;
- TString symbol;
- TString originalSymbol;
+ protected:
+ TString mRawText;
};
-class TIntermConstantUnion : public TIntermTyped {
-public:
- TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
+class TIntermConstantUnion : public TIntermTyped
+{
+ public:
+ TIntermConstantUnion(ConstantUnion *unionPointer, const TType &type)
+ : TIntermTyped(type),
+ mUnionArrayPointer(unionPointer) { }
virtual bool hasSideEffects() const { return false; }
- ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
-
- int getIConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
- float getFConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
- bool getBConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
+ ConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; }
- virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
- virtual void traverse(TIntermTraverser*);
+ int getIConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getIConst() : 0;
+ }
+ unsigned int getUConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getUConst() : 0;
+ }
+ float getFConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getFConst() : 0.0f;
+ }
+ bool getBConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
+ }
+
+ virtual TIntermConstantUnion *getAsConstantUnion() { return this; }
+ virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
- TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+ TIntermTyped *fold(TOperator, TIntermTyped *, TInfoSink &);
-protected:
- ConstantUnion *unionArrayPointer;
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
+
+ protected:
+ ConstantUnion *mUnionArrayPointer;
};
//
// Intermediate class for node types that hold operators.
//
-class TIntermOperator : public TIntermTyped {
-public:
- TOperator getOp() const { return op; }
- void setOp(TOperator o) { op = o; }
+class TIntermOperator : public TIntermTyped
+{
+ public:
+ TOperator getOp() const { return mOp; }
+ void setOp(TOperator op) { mOp = op; }
bool isAssignment() const;
bool isConstructor() const;
virtual bool hasSideEffects() const { return isAssignment(); }
-protected:
- TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
- TIntermOperator(TOperator o, const TType& t) : TIntermTyped(t), op(o) {}
- TOperator op;
+ protected:
+ TIntermOperator(TOperator op)
+ : TIntermTyped(TType(EbtFloat, EbpUndefined)),
+ mOp(op) {}
+ TIntermOperator(TOperator op, const TType &type)
+ : TIntermTyped(type),
+ mOp(op) {}
+
+ TOperator mOp;
};
//
// Nodes for all the basic binary math operators.
//
-class TIntermBinary : public TIntermOperator {
-public:
- TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
+class TIntermBinary : public TIntermOperator
+{
+ public:
+ TIntermBinary(TOperator op)
+ : TIntermOperator(op),
+ mAddIndexClamp(false) {}
- virtual TIntermBinary* getAsBinaryNode() { return this; }
- virtual void traverse(TIntermTraverser*);
+ virtual TIntermBinary *getAsBinaryNode() { return this; }
+ virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
- virtual bool hasSideEffects() const { return (isAssignment() || left->hasSideEffects() || right->hasSideEffects()); }
+ virtual bool hasSideEffects() const
+ {
+ return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
+ }
- void setLeft(TIntermTyped* n) { left = n; }
- void setRight(TIntermTyped* n) { right = n; }
- TIntermTyped* getLeft() const { return left; }
- TIntermTyped* getRight() const { return right; }
- bool promote(TInfoSink&);
+ void setLeft(TIntermTyped *node) { mLeft = node; }
+ void setRight(TIntermTyped *node) { mRight = node; }
+ TIntermTyped *getLeft() const { return mLeft; }
+ TIntermTyped *getRight() const { return mRight; }
+ bool promote(TInfoSink &);
- void setAddIndexClamp() { addIndexClamp = true; }
- bool getAddIndexClamp() { return addIndexClamp; }
+ void setAddIndexClamp() { mAddIndexClamp = true; }
+ bool getAddIndexClamp() { return mAddIndexClamp; }
-protected:
- TIntermTyped* left;
- TIntermTyped* right;
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+ protected:
+ TIntermTyped* mLeft;
+ TIntermTyped* mRight;
// If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
- bool addIndexClamp;
+ bool mAddIndexClamp;
};
//
// Nodes for unary math operators.
//
-class TIntermUnary : public TIntermOperator {
-public:
- TIntermUnary(TOperator o, const TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
- TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
-
- virtual void traverse(TIntermTraverser*);
- virtual TIntermUnary* getAsUnaryNode() { return this; }
+class TIntermUnary : public TIntermOperator
+{
+ public:
+ TIntermUnary(TOperator op, const TType &type)
+ : TIntermOperator(op, type),
+ mOperand(NULL),
+ mUseEmulatedFunction(false) {}
+ TIntermUnary(TOperator op)
+ : TIntermOperator(op),
+ mOperand(NULL),
+ mUseEmulatedFunction(false) {}
+
+ virtual void traverse(TIntermTraverser *);
+ virtual TIntermUnary *getAsUnaryNode() { return this; }
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
- virtual bool hasSideEffects() const { return (isAssignment() || operand->hasSideEffects()); }
+ virtual bool hasSideEffects() const
+ {
+ return isAssignment() || mOperand->hasSideEffects();
+ }
- void setOperand(TIntermTyped* o) { operand = o; }
- TIntermTyped* getOperand() { return operand; }
- bool promote(TInfoSink&);
+ void setOperand(TIntermTyped *operand) { mOperand = operand; }
+ TIntermTyped *getOperand() { return mOperand; }
+ bool promote(TInfoSink &);
- void setUseEmulatedFunction() { useEmulatedFunction = true; }
- bool getUseEmulatedFunction() { return useEmulatedFunction; }
+ void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+ bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
-protected:
- TIntermTyped* operand;
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+
+ protected:
+ TIntermTyped *mOperand;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
- bool useEmulatedFunction;
+ bool mUseEmulatedFunction;
};
-typedef TVector<TIntermNode*> TIntermSequence;
+typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList;
//
// Nodes that operate on an arbitrary sized set of children.
//
-class TIntermAggregate : public TIntermOperator {
-public:
- TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), useEmulatedFunction(false) { }
- TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
+class TIntermAggregate : public TIntermOperator
+{
+ public:
+ TIntermAggregate()
+ : TIntermOperator(EOpNull),
+ mUserDefined(false),
+ mUseEmulatedFunction(false) { }
+ TIntermAggregate(TOperator op)
+ : TIntermOperator(op),
+ mUseEmulatedFunction(false) { }
~TIntermAggregate() { }
- virtual TIntermAggregate* getAsAggregate() { return this; }
- virtual void traverse(TIntermTraverser*);
+ virtual TIntermAggregate *getAsAggregate() { return this; }
+ virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
// Conservatively assume function calls and other aggregate operators have side-effects
virtual bool hasSideEffects() const { return true; }
- TIntermSequence& getSequence() { return sequence; }
+ TIntermSequence *getSequence() { return &mSequence; }
- void setName(const TString& n) { name = n; }
- const TString& getName() const { return name; }
+ void setName(const TString &name) { mName = name; }
+ const TString &getName() const { return mName; }
- void setUserDefined() { userDefined = true; }
- bool isUserDefined() const { return userDefined; }
+ void setUserDefined() { mUserDefined = true; }
+ bool isUserDefined() const { return mUserDefined; }
- void setOptimize(bool o) { optimize = o; }
- bool getOptimize() { return optimize; }
- void setDebug(bool d) { debug = d; }
- bool getDebug() { return debug; }
+ void setOptimize(bool optimize) { mOptimize = optimize; }
+ bool getOptimize() const { return mOptimize; }
+ void setDebug(bool debug) { mDebug = debug; }
+ bool getDebug() const { return mDebug; }
- void setUseEmulatedFunction() { useEmulatedFunction = true; }
- bool getUseEmulatedFunction() { return useEmulatedFunction; }
+ void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+ bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
-protected:
- TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
- TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
- TIntermSequence sequence;
- TString name;
- bool userDefined; // used for user defined function names
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
- bool optimize;
- bool debug;
+ protected:
+ TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
+ TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
+ TIntermSequence mSequence;
+ TString mName;
+ bool mUserDefined; // used for user defined function names
+
+ bool mOptimize;
+ bool mDebug;
// If set to true, replace the built-in function call with an emulated one
// to work around driver bugs.
- bool useEmulatedFunction;
+ bool mUseEmulatedFunction;
};
//
// For if tests. Simplified since there is no switch statement.
//
-class TIntermSelection : public TIntermTyped {
-public:
- TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
- TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
- TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
- TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
-
- virtual void traverse(TIntermTraverser*);
+class TIntermSelection : public TIntermTyped
+{
+ public:
+ TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB)
+ : TIntermTyped(TType(EbtVoid, EbpUndefined)),
+ mCondition(cond),
+ mTrueBlock(trueB),
+ mFalseBlock(falseB) {}
+ TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB,
+ const TType &type)
+ : TIntermTyped(type),
+ mCondition(cond),
+ mTrueBlock(trueB),
+ mFalseBlock(falseB) {}
+
+ virtual void traverse(TIntermTraverser *);
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement);
@@ -547,15 +653,17 @@ public:
virtual bool hasSideEffects() const { return true; }
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
- TIntermNode* getCondition() const { return condition; }
- TIntermNode* getTrueBlock() const { return trueBlock; }
- TIntermNode* getFalseBlock() const { return falseBlock; }
- TIntermSelection* getAsSelectionNode() { return this; }
+ TIntermNode *getCondition() const { return mCondition; }
+ TIntermNode *getTrueBlock() const { return mTrueBlock; }
+ TIntermNode *getFalseBlock() const { return mFalseBlock; }
+ TIntermSelection *getAsSelectionNode() { return this; }
+
+ virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
protected:
- TIntermTyped* condition;
- TIntermNode* trueBlock;
- TIntermNode* falseBlock;
+ TIntermTyped *mCondition;
+ TIntermNode *mTrueBlock;
+ TIntermNode *mFalseBlock;
};
enum Visit
@@ -566,7 +674,7 @@ enum Visit
};
//
-// For traversing the tree. User should derive from this,
+// For traversing the tree. User should derive from this,
// put their traversal specific data in it, and then pass
// it to a Traverse method.
//
@@ -575,44 +683,47 @@ enum Visit
//
class TIntermTraverser
{
-public:
+ public:
POOL_ALLOCATOR_NEW_DELETE();
- TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
- preVisit(preVisit),
- inVisit(inVisit),
- postVisit(postVisit),
- rightToLeft(rightToLeft),
- depth(0),
- maxDepth(0) {}
+ // TODO(zmo): remove default values.
+ TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false,
+ bool rightToLeft = false)
+ : preVisit(preVisit),
+ inVisit(inVisit),
+ postVisit(postVisit),
+ rightToLeft(rightToLeft),
+ mDepth(0),
+ mMaxDepth(0) {}
virtual ~TIntermTraverser() {}
- virtual void visitSymbol(TIntermSymbol*) {}
- virtual void visitConstantUnion(TIntermConstantUnion*) {}
- virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
- virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
- virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
- virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
- virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
- virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
+ virtual void visitSymbol(TIntermSymbol *) {}
+ virtual void visitRaw(TIntermRaw *) {}
+ virtual void visitConstantUnion(TIntermConstantUnion *) {}
+ virtual bool visitBinary(Visit, TIntermBinary *) { return true; }
+ virtual bool visitUnary(Visit, TIntermUnary *) { return true; }
+ virtual bool visitSelection(Visit, TIntermSelection *) { return true; }
+ virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; }
+ virtual bool visitLoop(Visit, TIntermLoop *) { return true; }
+ virtual bool visitBranch(Visit, TIntermBranch *) { return true; }
- int getMaxDepth() const {return maxDepth;}
+ int getMaxDepth() const { return mMaxDepth; }
void incrementDepth(TIntermNode *current)
{
- depth++;
- maxDepth = std::max(maxDepth, depth);
- path.push_back(current);
+ mDepth++;
+ mMaxDepth = std::max(mMaxDepth, mDepth);
+ mPath.push_back(current);
}
void decrementDepth()
{
- depth--;
- path.pop_back();
+ mDepth--;
+ mPath.pop_back();
}
TIntermNode *getParentNode()
{
- return path.size() == 0 ? NULL : path.back();
+ return mPath.size() == 0 ? NULL : mPath.back();
}
// Return the original name if hash function pointer is NULL;
@@ -624,12 +735,37 @@ public:
const bool postVisit;
const bool rightToLeft;
-protected:
- int depth;
- int maxDepth;
+ protected:
+ int mDepth;
+ int mMaxDepth;
// All the nodes from root to the current node's parent during traversing.
- TVector<TIntermNode *> path;
+ TVector<TIntermNode *> mPath;
+};
+
+//
+// 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),
+ mDepthLimit(depthLimit) { }
+
+ virtual bool visitBinary(Visit, TIntermBinary *) { return depthCheck(); }
+ virtual bool visitUnary(Visit, TIntermUnary *) { return depthCheck(); }
+ virtual bool visitSelection(Visit, TIntermSelection *) { return depthCheck(); }
+ virtual bool visitAggregate(Visit, TIntermAggregate *) { return depthCheck(); }
+ virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); }
+ virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); }
+
+protected:
+ bool depthCheck() const { return mMaxDepth < mDepthLimit; }
+
+ int mDepthLimit;
};
-#endif // __INTERMEDIATE_H
+#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_