Commit 807b8e3b by John Kessenich

Remove TIntermediate's dependency on infoSink, simplify folding of constant…

Remove TIntermediate's dependency on infoSink, simplify folding of constant aggregates, and infoSink use in constant folding. Added a few deep aggregate constant folding testing cases. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22912 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent fca75340
...@@ -5,7 +5,9 @@ ERROR: 0:18: '' : constant expression required ...@@ -5,7 +5,9 @@ ERROR: 0:18: '' : constant expression required
ERROR: 0:18: '' : array size must be a constant integer expression ERROR: 0:18: '' : array size must be a constant integer expression
ERROR: 0:19: '' : constant expression required ERROR: 0:19: '' : constant expression required
ERROR: 0:19: '' : array size must be a constant integer expression ERROR: 0:19: '' : array size must be a constant integer expression
ERROR: 7 compilation errors. No code generated. ERROR: 0:27: '=' : assigning non-constant to 'const structure'
ERROR: 0:33: '=' : assigning non-constant to 'const structure'
ERROR: 9 compilation errors. No code generated.
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:10 Function Definition: main( (void) 0:10 Function Definition: main( (void)
......
...@@ -129,6 +129,14 @@ ...@@ -129,6 +129,14 @@
0:69 0.028000 0:69 0.028000
0:69 0.500000 0:69 0.500000
0:69 1.000000 0:69 1.000000
0:78 Function Definition: foo( (void)
0:78 Function Parameters:
0:? Sequence
0:81 move second child to first child (float)
0:81 direct index (float)
0:81 'a' (3-element array of float)
0:81 0 (const int)
0:81 7.000000
0:? Linker Objects 0:? Linker Objects
0:? 'inv' (smooth in 4-component vector of float) 0:? 'inv' (smooth in 4-component vector of float)
0:? 'FragColor' (out 4-component vector of float) 0:? 'FragColor' (out 4-component vector of float)
......
...@@ -20,3 +20,14 @@ void main() ...@@ -20,3 +20,14 @@ void main()
vec4 g[int(sin(0.3)) + 1]; // okay vec4 g[int(sin(0.3)) + 1]; // okay
} }
const struct S {
vec3 v3;
ivec2 iv2;
} s = S(vec3(3.0), ivec2(3, constInt + uniformInt)); // ERROR, non-const y componenent
const struct S2 {
vec3 v3;
ivec2 iv2;
mat2x4 m;
} s2 = S2(vec3(3.0), ivec2(3, constInt), mat2x4(1.0, 2.0, 3.0, inVar.x, 5.0, 6.0, 7.0, 8.0)); // ERROR, non-constant matrix
...@@ -68,3 +68,15 @@ void main() ...@@ -68,3 +68,15 @@ void main()
out2 = step(0.5, vec2(0.2, 0.6)); // 0.0, 1.0 out2 = step(0.5, vec2(0.2, 0.6)); // 0.0, 1.0
out11 = smoothstep(50.0, 60.0, vec4(40.0, 51.0, 55.0, 70.0)); // 0.0, 0.028, 0.5, 1.0 out11 = smoothstep(50.0, 60.0, vec4(40.0, 51.0, 55.0, 70.0)); // 0.0, 0.028, 0.5, 1.0
} }
const struct S {
vec3 v3;
ivec2 iv2;
mat2x4 m;
} s = S(vec3(3.0), ivec2(3, a + b), mat2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0));
void foo()
{
float a[s.iv2.y]; // 3 element array
a[0] = s.m[1].z; // 7.0
}
...@@ -357,8 +357,6 @@ protected: ...@@ -357,8 +357,6 @@ protected:
glslang::TSourceLoc loc; glslang::TSourceLoc loc;
}; };
class TInfoSink;
namespace glslang { namespace glslang {
// //
...@@ -479,8 +477,8 @@ public: ...@@ -479,8 +477,8 @@ public:
void setUnionArrayPointer(TConstUnion *c) { unionArrayPointer = c; } void setUnionArrayPointer(TConstUnion *c) { unionArrayPointer = c; }
virtual TIntermConstantUnion* getAsConstantUnion() { return this; } virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
virtual void traverse(TIntermTraverser* ); virtual void traverse(TIntermTraverser* );
virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&); virtual TIntermTyped* fold(TOperator, TIntermTyped*);
virtual TIntermTyped* fold(TOperator, const TType&, TInfoSink&); virtual TIntermTyped* fold(TOperator, const TType&);
protected: protected:
TConstUnion *unionArrayPointer; TConstUnion *unionArrayPointer;
}; };
...@@ -493,7 +491,7 @@ public: ...@@ -493,7 +491,7 @@ public:
TOperator getOp() { return op; } TOperator getOp() { return op; }
bool modifiesState() const; bool modifiesState() const;
bool isConstructor() const; bool isConstructor() const;
virtual bool promote(TInfoSink&) { return true; } virtual bool promote() { return true; }
protected: protected:
TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat)), op(o) {} TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat)), op(o) {}
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {} TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
...@@ -512,7 +510,7 @@ public: ...@@ -512,7 +510,7 @@ public:
virtual TIntermTyped* getLeft() const { return left; } virtual TIntermTyped* getLeft() const { return left; }
virtual TIntermTyped* getRight() const { return right; } virtual TIntermTyped* getRight() const { return right; }
virtual TIntermBinary* getAsBinaryNode() { return this; } virtual TIntermBinary* getAsBinaryNode() { return this; }
virtual bool promote(TInfoSink&); virtual bool promote();
virtual void updatePrecision(); virtual void updatePrecision();
protected: protected:
TIntermTyped* left; TIntermTyped* left;
...@@ -530,7 +528,7 @@ public: ...@@ -530,7 +528,7 @@ public:
virtual void setOperand(TIntermTyped* o) { operand = o; } virtual void setOperand(TIntermTyped* o) { operand = o; }
virtual TIntermTyped* getOperand() { return operand; } virtual TIntermTyped* getOperand() { return operand; }
virtual TIntermUnary* getAsUnaryNode() { return this; } virtual TIntermUnary* getAsUnaryNode() { return this; }
virtual bool promote(TInfoSink&); virtual bool promote();
virtual void updatePrecision(); virtual void updatePrecision();
protected: protected:
TIntermTyped* operand; TIntermTyped* operand;
......
...@@ -129,7 +129,7 @@ namespace glslang { ...@@ -129,7 +129,7 @@ namespace glslang {
// //
// Do folding between a pair of nodes // Do folding between a pair of nodes
// //
TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink) TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode)
{ {
TConstUnion *unionArray = getUnionArrayPointer(); TConstUnion *unionArray = getUnionArrayPointer();
int objectSize = getType().getObjectSize(); int objectSize = getType().getObjectSize();
...@@ -217,7 +217,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -217,7 +217,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst()); newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLoc());
return 0; return 0;
} }
} }
...@@ -374,8 +373,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -374,8 +373,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Invalid binary operator for constant folding", getLoc());
return 0; return 0;
} }
...@@ -388,7 +385,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod ...@@ -388,7 +385,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
// //
// Do single unary node folding // Do single unary node folding
// //
TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, TInfoSink& infoSink) TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
{ {
TConstUnion *unionArray = getUnionArrayPointer(); TConstUnion *unionArray = getUnionArrayPointer();
int objectSize = getType().getObjectSize(); int objectSize = getType().getObjectSize();
...@@ -444,7 +441,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, ...@@ -444,7 +441,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break; case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
default: default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc());
return 0; return 0;
} }
break; break;
...@@ -453,7 +449,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, ...@@ -453,7 +449,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
switch (getType().getBasicType()) { switch (getType().getBasicType()) {
case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break; case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
default: default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc());
return 0; return 0;
} }
break; break;
...@@ -607,7 +602,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, ...@@ -607,7 +602,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
case EOpAll: case EOpAll:
default: default:
infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLoc());
return 0; return 0;
} }
} }
...@@ -755,7 +749,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) ...@@ -755,7 +749,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
break; break;
} }
default: default:
infoSink.info.message(EPrefixInternalError, "componentwise constant folding operation not implemented", aggrNode->getLoc());
return aggrNode; return aggrNode;
} }
} }
...@@ -774,7 +767,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) ...@@ -774,7 +767,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpReflect: case EOpReflect:
case EOpRefract: case EOpRefract:
case EOpOuterProduct: case EOpOuterProduct:
infoSink.info.message(EPrefixInternalError, "constant folding operation not implemented", aggrNode->getLoc());
return aggrNode; return aggrNode;
default: default:
...@@ -809,15 +801,15 @@ bool TIntermediate::areAllChildConst(TIntermAggregate* aggrNode) ...@@ -809,15 +801,15 @@ bool TIntermediate::areAllChildConst(TIntermAggregate* aggrNode)
TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode) TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
{ {
bool returnVal = false; bool error = false;
TConstUnion* unionArray = new TConstUnion[aggrNode->getType().getObjectSize()]; TConstUnion* unionArray = new TConstUnion[aggrNode->getType().getObjectSize()];
if (aggrNode->getSequence().size() == 1) if (aggrNode->getSequence().size() == 1)
returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true); error = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
else else
returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType()); error = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
if (returnVal) if (error)
return aggrNode; return aggrNode;
return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc()); return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc());
......
...@@ -100,7 +100,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -100,7 +100,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
node->setLeft(left); node->setLeft(left);
node->setRight(right); node->setRight(right);
if (! node->promote(infoSink)) if (! node->promote())
return 0; return 0;
node->updatePrecision(); node->updatePrecision();
...@@ -112,11 +112,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -112,11 +112,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
if (leftTempConstant && rightTempConstant) { if (leftTempConstant && rightTempConstant) {
TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink); TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant);
if (folded) if (folded)
return folded; return folded;
else
infoSink.info.message(EPrefixInternalError, "Constant folding failed", loc);
} }
return node; return node;
...@@ -148,7 +146,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm ...@@ -148,7 +146,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
node->setLeft(left); node->setLeft(left);
node->setRight(child); node->setRight(child);
if (! node->promote(infoSink)) if (! node->promote())
return 0; return 0;
node->updatePrecision(); node->updatePrecision();
...@@ -189,10 +187,8 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, ...@@ -189,10 +187,8 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
if (child->getType().getBasicType() == EbtBlock) if (child->getType().getBasicType() == EbtBlock)
return 0; return 0;
if (child == 0) { if (child == 0)
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", loc);
return 0; return 0;
}
switch (op) { switch (op) {
case EOpLogicalNot: case EOpLogicalNot:
...@@ -255,13 +251,13 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, ...@@ -255,13 +251,13 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
node->setLoc(loc); node->setLoc(loc);
node->setOperand(child); node->setOperand(child);
if (! node->promote(infoSink)) if (! node->promote())
return 0; return 0;
node->updatePrecision(); node->updatePrecision();
if (child->getAsConstantUnion()) if (child->getAsConstantUnion())
return child->getAsConstantUnion()->fold(op, node->getType(), infoSink); return child->getAsConstantUnion()->fold(op, node->getType());
return node; return node;
} }
...@@ -275,14 +271,11 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TSourceLoc loc, TOperator op ...@@ -275,14 +271,11 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TSourceLoc loc, TOperator op
// including constness (which would differ from the prototype). // including constness (which would differ from the prototype).
// //
TIntermTyped* child = childNode->getAsTyped(); TIntermTyped* child = childNode->getAsTyped();
if (child == 0) { if (child == 0)
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", child->getLoc());
return 0; return 0;
}
if (child->getAsConstantUnion()) { if (child->getAsConstantUnion()) {
TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType, infoSink); TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType);
if (folded) if (folded)
return folded; return folded;
} }
...@@ -514,7 +507,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -514,7 +507,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
//case EbtBool: newOp = EOpConvBoolToDouble; break; //case EbtBool: newOp = EOpConvBoolToDouble; break;
//case EbtFloat: newOp = EOpConvFloatToDouble; break; //case EbtFloat: newOp = EOpConvFloatToDouble; break;
//default: //default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0; return 0;
//} //}
break; break;
...@@ -525,7 +517,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -525,7 +517,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtBool: newOp = EOpConvBoolToFloat; break; case EbtBool: newOp = EOpConvBoolToFloat; break;
case EbtDouble: newOp = EOpConvDoubleToFloat; break; case EbtDouble: newOp = EOpConvDoubleToFloat; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0; return 0;
} }
break; break;
...@@ -536,7 +527,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -536,7 +527,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtFloat: newOp = EOpConvFloatToBool; break; case EbtFloat: newOp = EOpConvFloatToBool; break;
case EbtDouble: newOp = EOpConvDoubleToBool; break; case EbtDouble: newOp = EOpConvDoubleToBool; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0; return 0;
} }
break; break;
...@@ -547,7 +537,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -547,7 +537,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtFloat: newOp = EOpConvFloatToInt; break; case EbtFloat: newOp = EOpConvFloatToInt; break;
case EbtDouble: newOp = EOpConvDoubleToInt; break; case EbtDouble: newOp = EOpConvDoubleToInt; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0; return 0;
} }
break; break;
...@@ -558,12 +547,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -558,12 +547,10 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EbtFloat: newOp = EOpConvFloatToUint; break; case EbtFloat: newOp = EOpConvFloatToUint; break;
case EbtDouble: newOp = EOpConvDoubleToUint; break; case EbtDouble: newOp = EOpConvDoubleToUint; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc());
return 0; return 0;
} }
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLoc());
return 0; return 0;
} }
...@@ -982,7 +969,7 @@ bool TIntermOperator::isConstructor() const ...@@ -982,7 +969,7 @@ bool TIntermOperator::isConstructor() const
// //
// Returns false in nothing makes sense. // Returns false in nothing makes sense.
// //
bool TIntermUnary::promote(TInfoSink&) bool TIntermUnary::promote()
{ {
switch (op) { switch (op) {
case EOpLogicalNot: case EOpLogicalNot:
...@@ -1034,7 +1021,7 @@ void TIntermUnary::updatePrecision() ...@@ -1034,7 +1021,7 @@ void TIntermUnary::updatePrecision()
// //
// Returns false if operator can't work on operands. // Returns false if operator can't work on operands.
// //
bool TIntermBinary::promote(TInfoSink& infoSink) bool TIntermBinary::promote()
{ {
// Arrays and structures have to be exact matches. // Arrays and structures have to be exact matches.
if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct) if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct)
...@@ -1235,7 +1222,6 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -1235,7 +1222,6 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
setType(TType(basicType, EvqTemporary, right->getVectorSize())); setType(TType(basicType, EvqTemporary, right->getVectorSize()));
} }
} else { } else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc());
return false; return false;
} }
break; break;
...@@ -1267,7 +1253,6 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -1267,7 +1253,6 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
op = EOpVectorTimesScalarAssign; op = EOpVectorTimesScalarAssign;
} }
} else { } else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc());
return false; return false;
} }
break; break;
...@@ -1397,9 +1382,6 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) ...@@ -1397,9 +1382,6 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
{ {
if (node->getType().isArray())
infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLoc());
TConstUnion *rightUnionArray = node->getUnionArrayPointer(); TConstUnion *rightUnionArray = node->getUnionArrayPointer();
int size = node->getType().getObjectSize(); int size = node->getType().getObjectSize();
...@@ -1424,9 +1406,8 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1424,9 +1406,8 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtDouble: case EbtDouble:
leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst())); leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst()));
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return node;
return 0;
} }
break; break;
case EbtDouble: case EbtDouble:
...@@ -1445,8 +1426,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1445,8 +1426,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i] = rightUnionArray[i]; leftUnionArray[i] = rightUnionArray[i];
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return node;
return 0;
} }
break; break;
case EbtInt: case EbtInt:
...@@ -1465,8 +1445,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1465,8 +1445,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst())); leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return node;
return 0;
} }
break; break;
case EbtUint: case EbtUint:
...@@ -1485,8 +1464,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1485,8 +1464,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst())); leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return node;
return 0;
} }
break; break;
case EbtBool: case EbtBool:
...@@ -1505,13 +1483,11 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1505,13 +1483,11 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0);
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return node;
return 0;
} }
break; break;
default: default:
infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLoc()); return node;
return 0;
} }
} }
......
...@@ -103,7 +103,7 @@ TPoolAllocator* PerProcessGPA = 0; ...@@ -103,7 +103,7 @@ TPoolAllocator* PerProcessGPA = 0;
bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink, bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink,
TSymbolTable& symbolTable) TSymbolTable& symbolTable)
{ {
TIntermediate intermediate(infoSink, version, profile); TIntermediate intermediate(version, profile);
TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink); TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink);
TPpContext ppContext(parseContext); TPpContext ppContext(parseContext);
...@@ -458,7 +458,7 @@ int ShCompile( ...@@ -458,7 +458,7 @@ int ShCompile(
} }
bool goodProfile = DeduceProfile(compiler->infoSink, version, profile); bool goodProfile = DeduceProfile(compiler->infoSink, version, profile);
TIntermediate intermediate(compiler->infoSink, version, profile); TIntermediate intermediate(version, profile);
SetupBuiltinSymbolTable(version, profile); SetupBuiltinSymbolTable(version, profile);
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)] TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
...@@ -525,7 +525,7 @@ int ShCompile( ...@@ -525,7 +525,7 @@ int ShCompile(
if (success) { if (success) {
if (messages & EShMsgAST) if (messages & EShMsgAST)
intermediate.outputTree(parseContext.treeRoot); intermediate.outputTree(parseContext.treeRoot, parseContext.infoSink);
// //
// Call the machine dependent compiler // Call the machine dependent compiler
...@@ -539,7 +539,7 @@ int ShCompile( ...@@ -539,7 +539,7 @@ int ShCompile(
parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n";
success = false; success = false;
if (messages & EShMsgAST) if (messages & EShMsgAST)
intermediate.outputTree(parseContext.treeRoot); intermediate.outputTree(parseContext.treeRoot, parseContext.infoSink);
} }
intermediate.remove(parseContext.treeRoot); intermediate.remove(parseContext.treeRoot);
......
...@@ -567,7 +567,7 @@ bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it ...@@ -567,7 +567,7 @@ bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it
// Individual functions can be initialized to 0 to skip processing of that // Individual functions can be initialized to 0 to skip processing of that
// type of node. It's children will still be processed. // type of node. It's children will still be processed.
// //
void TIntermediate::outputTree(TIntermNode* root) void TIntermediate::outputTree(TIntermNode* root, TInfoSink& infoSink)
{ {
if (root == 0) if (root == 0)
return; return;
......
...@@ -54,7 +54,7 @@ class TIntermediate { ...@@ -54,7 +54,7 @@ class TIntermediate {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TIntermediate(TInfoSink& i, int v, EProfile p) : infoSink(i), version(v), profile(p) { } TIntermediate(int v, EProfile p) : version(v), profile(p) { }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc); TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
...@@ -87,10 +87,9 @@ public: ...@@ -87,10 +87,9 @@ public:
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable&);
void remove(TIntermNode*); void remove(TIntermNode*);
void outputTree(TIntermNode*); void outputTree(TIntermNode*, TInfoSink&);
protected: protected:
TInfoSink& infoSink;
EProfile profile; EProfile profile;
int version; int version;
......
...@@ -32,18 +32,19 @@ ...@@ -32,18 +32,19 @@
//POSSIBILITY OF SUCH DAMAGE. //POSSIBILITY OF SUCH DAMAGE.
// //
//
// Travarse a tree of constants to create a single folded constant.
// It should only be used when the whole tree is known to be constant.
//
#include "ParseHelper.h" #include "ParseHelper.h"
namespace glslang { namespace glslang {
//
// Use this class to carry along data from node to node in
// the traversal
//
class TConstTraverser : public TIntermTraverser { class TConstTraverser : public TIntermTraverser {
public: public:
TConstTraverser(TConstUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, const TType& t) : unionArray(cUnion), type(t), TConstTraverser(TConstUnion* cUnion, bool singleConstParam, TOperator constructType, const TType& t) : unionArray(cUnion), type(t),
constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), error(false), isMatrix(false), constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false),
matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull;} matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull;}
int index ; int index ;
TConstUnion *unionArray; TConstUnion *unionArray;
...@@ -51,7 +52,6 @@ public: ...@@ -51,7 +52,6 @@ public:
const TType& type; const TType& type;
TOperator constructorType; TOperator constructorType;
bool singleConstantParam; bool singleConstantParam;
TInfoSink& infoSink;
bool error; bool error;
int size; // size of the constructor ( 4 for vec4) int size; // size of the constructor ( 4 for vec4)
bool isMatrix; bool isMatrix;
...@@ -59,66 +59,11 @@ public: ...@@ -59,66 +59,11 @@ public:
int matrixRows; int matrixRows;
}; };
//
// The rest of the file are the traversal functions. The last one
// is the one that starts the traversal.
//
// Return true from interior nodes to have the external traversal
// continue on to children. If you process children yourself,
// return false.
//
void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLoc());
return;
}
bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
TStorageQualifier qualifier = node->getType().getQualifier().storage;
if (qualifier != EvqConst) {
const int maxSize = GlslangMaxTypeLength + 50;
char buf[maxSize];
snprintf(buf, maxSize, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
oit->error = true;
return false;
}
oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLoc());
return false;
}
bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
const int maxSize = GlslangMaxTypeLength + 50;
char buf[maxSize];
snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
oit->error = true;
return false;
}
bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it) bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
{ {
TConstTraverser* oit = static_cast<TConstTraverser*>(it); TConstTraverser* oit = static_cast<TConstTraverser*>(it);
if (!node->isConstructor() && node->getOp() != EOpComma) { if (! node->isConstructor() && node->getOp() != EOpComma) {
const int maxSize = GlslangMaxTypeLength + 50;
char buf[maxSize];
snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLoc());
oit->error = true; oit->error = true;
return false; return false;
...@@ -164,14 +109,6 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse ...@@ -164,14 +109,6 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
return false; return false;
} }
bool ParseSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLoc());
oit->error = true;
return false;
}
void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
{ {
TConstTraverser* oit = static_cast<TConstTraverser*>(it); TConstTraverser* oit = static_cast<TConstTraverser*>(it);
...@@ -201,7 +138,7 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) ...@@ -201,7 +138,7 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
isMatrix = oit->isMatrix; isMatrix = oit->isMatrix;
totalSize = oit->index + size; totalSize = oit->index + size;
TConstUnion *rightUnionArray = node->getUnionArrayPointer(); TConstUnion *rightUnionArray = node->getUnionArrayPointer();
if (!isMatrix) { if (! isMatrix) {
int count = 0; int count = 0;
for (int i = oit->index; i < totalSize; i++) { for (int i = oit->index; i < totalSize; i++) {
if (i >= instanceSize) if (i >= instanceSize)
...@@ -234,44 +171,15 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) ...@@ -234,44 +171,15 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
} }
} }
bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLoc());
oit->error = true;
return false;
}
bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLoc());
oit->error = true;
return false;
}
//
// This function is the one to call externally to start the traversal.
// Individual functions can be initialized to 0 to skip processing of that
// type of node. It's children will still be processed.
//
bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, TConstUnion* unionArray, TOperator constructorType, const TType& t, bool singleConstantParam) bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, TConstUnion* unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
{ {
if (root == 0) if (root == 0)
return false; return false;
TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, t); TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
it.visitAggregate = ParseAggregate; it.visitAggregate = ParseAggregate;
it.visitBinary = ParseBinary;
it.visitConstantUnion = ParseConstantUnion; it.visitConstantUnion = ParseConstantUnion;
it.visitSelection = ParseSelection;
it.visitSymbol = ParseSymbol;
it.visitUnary = ParseUnary;
it.visitLoop = ParseLoop;
it.visitBranch = ParseBranch;
root->traverse(&it); root->traverse(&it);
if (it.error) if (it.error)
......
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