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
This commit is contained in:
John Kessenich 2013-09-03 22:14:59 +00:00
parent fca7534044
commit 807b8e3b82
11 changed files with 79 additions and 173 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -357,8 +357,6 @@ protected:
glslang::TSourceLoc loc; glslang::TSourceLoc loc;
}; };
class TInfoSink;
namespace glslang { namespace glslang {
// //
@ -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:
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:
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:
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;

View File

@ -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
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
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
// //
// 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,
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,
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,
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)
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)
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)
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());

View File

@ -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
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
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,
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,
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
// 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
//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
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
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
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
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
// //
// 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()
// //
// 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)
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)
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)
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
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
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
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
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
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;
} }
} }

View File

@ -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(
} }
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(
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(
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);

View File

@ -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;

View File

@ -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:
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;

View File

@ -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:
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:
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
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)
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)
} }
} }
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)