Add ES 300 matrix operations: outerProduct, determinant, inverse, and transpose, and missing ES 300 limit gl_MaxFragmentInputVectors.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20643 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
bd0747d6f0
commit
1f2a36bd6b
@ -105,6 +105,7 @@ void GenerateResources(TBuiltInResource& resources)
|
|||||||
resources.maxVaryingVectors = 8;
|
resources.maxVaryingVectors = 8;
|
||||||
resources.maxFragmentUniformVectors = 16;
|
resources.maxFragmentUniformVectors = 16;
|
||||||
resources.maxVertexOutputVectors = 16;
|
resources.maxVertexOutputVectors = 16;
|
||||||
|
resources.maxFragmentInputVectors = 15;
|
||||||
resources.minProgramTexelOffset = -8;
|
resources.minProgramTexelOffset = -8;
|
||||||
resources.maxProgramTexelOffset = 7;
|
resources.maxProgramTexelOffset = 7;
|
||||||
}
|
}
|
||||||
|
31
Test/300.vert
Normal file
31
Test/300.vert
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
uniform mat4x3 m43;
|
||||||
|
uniform mat3x3 m33;
|
||||||
|
uniform mat4x4 m44;
|
||||||
|
|
||||||
|
in vec3 v3;
|
||||||
|
in vec2 v2;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int id = gl_VertexID + gl_InstanceID;
|
||||||
|
|
||||||
|
int c0 = gl_MaxVertexAttribs;
|
||||||
|
int c1 = gl_MaxVertexUniformVectors;
|
||||||
|
int c2 = gl_MaxVertexOutputVectors;
|
||||||
|
int c3 = gl_MaxFragmentInputVectors;
|
||||||
|
int c4 = gl_MaxVertexTextureImageUnits;
|
||||||
|
int c5 = gl_MaxCombinedTextureImageUnits;
|
||||||
|
int c6 = gl_MaxTextureImageUnits;
|
||||||
|
int c7 = gl_MaxFragmentUniformVectors;
|
||||||
|
int c8 = gl_MaxDrawBuffers;
|
||||||
|
int c9 = gl_MinProgramTexelOffset;
|
||||||
|
int c10 = gl_MaxProgramTexelOffset;
|
||||||
|
|
||||||
|
mat3x4 tm = transpose(m43);
|
||||||
|
highp float dm = determinant(m44);
|
||||||
|
mat3x3 im = inverse(m33);
|
||||||
|
|
||||||
|
mat3x2 op = outerProduct(v2, v3);
|
||||||
|
}
|
@ -20,3 +20,4 @@ pointCoord.frag
|
|||||||
array.frag
|
array.frag
|
||||||
array100.frag
|
array100.frag
|
||||||
comment.frag
|
comment.frag
|
||||||
|
300.vert
|
||||||
|
@ -54,6 +54,7 @@ struct TBuiltInResource {
|
|||||||
int maxVaryingVectors;
|
int maxVaryingVectors;
|
||||||
int maxFragmentUniformVectors;
|
int maxFragmentUniformVectors;
|
||||||
int maxVertexOutputVectors;
|
int maxVertexOutputVectors;
|
||||||
|
int maxFragmentInputVectors;
|
||||||
int minProgramTexelOffset;
|
int minProgramTexelOffset;
|
||||||
int maxProgramTexelOffset;
|
int maxProgramTexelOffset;
|
||||||
};
|
};
|
||||||
|
@ -169,6 +169,10 @@ enum TOperator {
|
|||||||
EOpFwidth, // Fragment only
|
EOpFwidth, // Fragment only
|
||||||
|
|
||||||
EOpMatrixTimesMatrix,
|
EOpMatrixTimesMatrix,
|
||||||
|
EOpOuterProduct,
|
||||||
|
EOpDeterminant,
|
||||||
|
EOpMatrixInverse,
|
||||||
|
EOpTranspose,
|
||||||
|
|
||||||
EOpAny,
|
EOpAny,
|
||||||
EOpAll,
|
EOpAll,
|
||||||
|
@ -283,6 +283,38 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||||||
s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
|
s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
|
||||||
s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
|
s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
|
||||||
|
|
||||||
|
if (version >= 120) {
|
||||||
|
s.append(TString("mat2 outerProduct(vec2 c, vec2 r);"));
|
||||||
|
s.append(TString("mat3 outerProduct(vec3 c, vec3 r);"));
|
||||||
|
s.append(TString("mat4 outerProduct(vec4 c, vec4 r);"));
|
||||||
|
s.append(TString("mat2x3 outerProduct(vec3 c, vec2 r);"));
|
||||||
|
s.append(TString("mat3x2 outerProduct(vec2 c, vec3 r);"));
|
||||||
|
s.append(TString("mat2x4 outerProduct(vec4 c, vec2 r);"));
|
||||||
|
s.append(TString("mat4x2 outerProduct(vec2 c, vec4 r);"));
|
||||||
|
s.append(TString("mat3x4 outerProduct(vec4 c, vec3 r);"));
|
||||||
|
s.append(TString("mat4x3 outerProduct(vec3 c, vec4 r);"));
|
||||||
|
|
||||||
|
s.append(TString("mat2 transpose(mat2 m);"));
|
||||||
|
s.append(TString("mat3 transpose(mat3 m);"));
|
||||||
|
s.append(TString("mat4 transpose(mat4 m);"));
|
||||||
|
s.append(TString("mat2x3 transpose(mat3x2 m);"));
|
||||||
|
s.append(TString("mat3x2 transpose(mat2x3 m);"));
|
||||||
|
s.append(TString("mat2x4 transpose(mat4x2 m);"));
|
||||||
|
s.append(TString("mat4x2 transpose(mat2x4 m);"));
|
||||||
|
s.append(TString("mat3x4 transpose(mat4x3 m);"));
|
||||||
|
s.append(TString("mat4x3 transpose(mat3x4 m);"));
|
||||||
|
|
||||||
|
if (version >= 150) {
|
||||||
|
s.append(TString("float determinant(mat2 m);"));
|
||||||
|
s.append(TString("float determinant(mat3 m);"));
|
||||||
|
s.append(TString("float determinant(mat4 m);"));
|
||||||
|
|
||||||
|
s.append(TString("mat2 inverse(mat2 m);"));
|
||||||
|
s.append(TString("mat3 inverse(mat3 m);"));
|
||||||
|
s.append(TString("mat4 inverse(mat4 m);"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Vector relational functions.
|
// Vector relational functions.
|
||||||
//
|
//
|
||||||
@ -795,6 +827,9 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
|||||||
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexOutputVectors = %d;", resources.maxVertexOutputVectors);
|
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexOutputVectors = %d;", resources.maxVertexOutputVectors);
|
||||||
s.append(TString(builtInConstant));
|
s.append(TString(builtInConstant));
|
||||||
|
|
||||||
|
snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentInputVectors = %d;", resources.maxFragmentInputVectors);
|
||||||
|
s.append(TString(builtInConstant));
|
||||||
|
|
||||||
snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset);
|
snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset);
|
||||||
s.append(TString(builtInConstant));
|
s.append(TString(builtInConstant));
|
||||||
|
|
||||||
@ -964,6 +999,15 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
|
|||||||
symbolTable.relateToOperator("not", EOpVectorLogicalNot);
|
symbolTable.relateToOperator("not", EOpVectorLogicalNot);
|
||||||
|
|
||||||
symbolTable.relateToOperator("matrixCompMult", EOpMul);
|
symbolTable.relateToOperator("matrixCompMult", EOpMul);
|
||||||
|
if (version >= 120) {
|
||||||
|
symbolTable.relateToOperator("outerProduct", EOpOuterProduct);
|
||||||
|
symbolTable.relateToOperator("transpose", EOpTranspose);
|
||||||
|
if (version >= 150) {
|
||||||
|
symbolTable.relateToOperator("determinant", EOpDeterminant);
|
||||||
|
symbolTable.relateToOperator("inverse", EOpMatrixInverse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
symbolTable.relateToOperator("mod", EOpMod);
|
symbolTable.relateToOperator("mod", EOpMod);
|
||||||
|
|
||||||
symbolTable.relateToOperator("equal", EOpVectorEqual);
|
symbolTable.relateToOperator("equal", EOpVectorEqual);
|
||||||
|
@ -1202,6 +1202,18 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
}
|
}
|
||||||
returnType = TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols());
|
returnType = TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols());
|
||||||
break;
|
break;
|
||||||
|
case EOpOuterProduct:
|
||||||
|
// TODO: functionality >= 120
|
||||||
|
break;
|
||||||
|
case EOpDeterminant:
|
||||||
|
// TODO: functionality >= 150
|
||||||
|
break;
|
||||||
|
case EOpMatrixInverse:
|
||||||
|
// TODO: functionality >= 150
|
||||||
|
break;
|
||||||
|
case EOpTranspose:
|
||||||
|
// TODO: functionality >= 120
|
||||||
|
break;
|
||||||
case EOpDiv:
|
case EOpDiv:
|
||||||
tempConstArray = new constUnion[objectSize];
|
tempConstArray = new constUnion[objectSize];
|
||||||
for (int i = 0; i < objectSize; i++) {
|
for (int i = 0; i < objectSize; i++) {
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use this class to carry along data from node to node in
|
// Use this class to carry along data from node to node in
|
||||||
// the traversal
|
// the traversal
|
||||||
//
|
//
|
||||||
class TOutputTraverser : public TIntermTraverser {
|
class TOutputTraverser : public TIntermTraverser {
|
||||||
@ -80,7 +80,7 @@ TString TType::getCompleteString() const
|
|||||||
snprintf(p, end - p, "%s", getBasicString());
|
snprintf(p, end - p, "%s", getBasicString());
|
||||||
|
|
||||||
return TString(buf);
|
return TString(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helper functions for printing, not part of traversing.
|
// Helper functions for printing, not part of traversing.
|
||||||
@ -91,7 +91,7 @@ void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
infoSink.debug << FormatSourceLoc(node->getLine());
|
infoSink.debug << FormatSourceLoc(node->getLine());
|
||||||
|
|
||||||
for (i = 0; i < depth; ++i)
|
for (i = 0; i < depth; ++i)
|
||||||
infoSink.debug << " ";
|
infoSink.debug << " ";
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it
|
|||||||
case EOpVectorTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
|
case EOpVectorTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
|
||||||
case EOpVectorTimesScalarAssign: out.debug << "vector scale second child into first child"; break;
|
case EOpVectorTimesScalarAssign: out.debug << "vector scale second child into first child"; break;
|
||||||
case EOpMatrixTimesScalarAssign: out.debug << "matrix scale second child into first child"; break;
|
case EOpMatrixTimesScalarAssign: out.debug << "matrix scale second child into first child"; break;
|
||||||
case EOpMatrixTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
|
case EOpMatrixTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
|
||||||
case EOpDivAssign: out.debug << "divide second child into first child"; break;
|
case EOpDivAssign: out.debug << "divide second child into first child"; break;
|
||||||
case EOpModAssign: out.debug << "mod second child into first child"; break;
|
case EOpModAssign: out.debug << "mod second child into first child"; break;
|
||||||
case EOpAndAssign: out.debug << "and second child into first child"; break;
|
case EOpAndAssign: out.debug << "and second child into first child"; break;
|
||||||
@ -192,7 +192,7 @@ bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
|
|||||||
|
|
||||||
OutputTreeText(out, node, oit->depth);
|
OutputTreeText(out, node, oit->depth);
|
||||||
|
|
||||||
switch (node->getOp()) {
|
switch (node->getOp()) {
|
||||||
case EOpNegative: out.debug << "Negate value"; break;
|
case EOpNegative: out.debug << "Negate value"; break;
|
||||||
case EOpVectorLogicalNot:
|
case EOpVectorLogicalNot:
|
||||||
case EOpLogicalNot: out.debug << "Negate conditional"; break;
|
case EOpLogicalNot: out.debug << "Negate conditional"; break;
|
||||||
@ -234,10 +234,13 @@ bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
|
|||||||
|
|
||||||
case EOpLength: out.debug << "length"; break;
|
case EOpLength: out.debug << "length"; break;
|
||||||
case EOpNormalize: out.debug << "normalize"; break;
|
case EOpNormalize: out.debug << "normalize"; break;
|
||||||
case EOpDPdx: out.debug << "dPdx"; break;
|
case EOpDPdx: out.debug << "dPdx"; break;
|
||||||
case EOpDPdy: out.debug << "dPdy"; break;
|
case EOpDPdy: out.debug << "dPdy"; break;
|
||||||
case EOpFwidth: out.debug << "fwidth"; break;
|
case EOpFwidth: out.debug << "fwidth"; break;
|
||||||
|
case EOpDeterminant: out.debug << "determinant"; break;
|
||||||
|
case EOpMatrixInverse: out.debug << "inverse"; break;
|
||||||
|
case EOpTranspose: out.debug << "transpose"; break;
|
||||||
|
|
||||||
case EOpAny: out.debug << "any"; break;
|
case EOpAny: out.debug << "any"; break;
|
||||||
case EOpAll: out.debug << "all"; break;
|
case EOpAll: out.debug << "all"; break;
|
||||||
|
|
||||||
@ -269,7 +272,7 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
|
|||||||
case EOpFunction: out.debug << "Function Definition: " << node->getName(); break;
|
case EOpFunction: out.debug << "Function Definition: " << node->getName(); break;
|
||||||
case EOpFunctionCall: out.debug << "Function Call: " << node->getName(); break;
|
case EOpFunctionCall: out.debug << "Function Call: " << node->getName(); break;
|
||||||
case EOpParameters: out.debug << "Function Parameters: "; break;
|
case EOpParameters: out.debug << "Function Parameters: "; break;
|
||||||
|
|
||||||
case EOpConstructFloat: out.debug << "Construct float"; break;
|
case EOpConstructFloat: out.debug << "Construct float"; break;
|
||||||
case EOpConstructVec2: out.debug << "Construct vec2"; break;
|
case EOpConstructVec2: out.debug << "Construct vec2"; break;
|
||||||
case EOpConstructVec3: out.debug << "Construct vec3"; break;
|
case EOpConstructVec3: out.debug << "Construct vec3"; break;
|
||||||
@ -301,7 +304,7 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
|
|||||||
case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
|
case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
|
||||||
case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break;
|
case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break;
|
||||||
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
||||||
|
|
||||||
case EOpLessThan: out.debug << "Compare Less Than"; break;
|
case EOpLessThan: out.debug << "Compare Less Than"; break;
|
||||||
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
||||||
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
|
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
|
||||||
@ -328,13 +331,14 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
|
|||||||
case EOpReflect: out.debug << "reflect"; break;
|
case EOpReflect: out.debug << "reflect"; break;
|
||||||
case EOpRefract: out.debug << "refract"; break;
|
case EOpRefract: out.debug << "refract"; break;
|
||||||
case EOpMul: out.debug << "component-wise multiply"; break;
|
case EOpMul: out.debug << "component-wise multiply"; break;
|
||||||
|
case EOpOuterProduct: out.debug << "outer product"; break;
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
|
if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
|
||||||
out.debug << " (" << node->getCompleteString() << ")";
|
out.debug << " (" << node->getCompleteString() << ")";
|
||||||
|
|
||||||
out.debug << "\n";
|
out.debug << "\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -349,9 +353,9 @@ bool OutputSelection(bool /* preVisit */, TIntermSelection* node, TIntermTravers
|
|||||||
|
|
||||||
out.debug << "Test condition and select";
|
out.debug << "Test condition and select";
|
||||||
out.debug << " (" << node->getCompleteString() << ")\n";
|
out.debug << " (" << node->getCompleteString() << ")\n";
|
||||||
|
|
||||||
++oit->depth;
|
++oit->depth;
|
||||||
|
|
||||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||||
out.debug << "Condition\n";
|
out.debug << "Condition\n";
|
||||||
node->getCondition()->traverse(it);
|
node->getCondition()->traverse(it);
|
||||||
@ -362,13 +366,13 @@ bool OutputSelection(bool /* preVisit */, TIntermSelection* node, TIntermTravers
|
|||||||
node->getTrueBlock()->traverse(it);
|
node->getTrueBlock()->traverse(it);
|
||||||
} else
|
} else
|
||||||
out.debug << "true case is null\n";
|
out.debug << "true case is null\n";
|
||||||
|
|
||||||
if (node->getFalseBlock()) {
|
if (node->getFalseBlock()) {
|
||||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||||
out.debug << "false case\n";
|
out.debug << "false case\n";
|
||||||
node->getFalseBlock()->traverse(it);
|
node->getFalseBlock()->traverse(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
--oit->depth;
|
--oit->depth;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -378,7 +382,7 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
|
|||||||
{
|
{
|
||||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||||
TInfoSink& out = oit->infoSink;
|
TInfoSink& out = oit->infoSink;
|
||||||
|
|
||||||
int size = node->getType().getObjectSize();
|
int size = node->getType().getObjectSize();
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
@ -400,7 +404,7 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
|
|||||||
char buf[maxSize];
|
char buf[maxSize];
|
||||||
snprintf(buf, maxSize, "%f (%s)", node->getUnionArrayPointer()[i].getFConst(), "const float");
|
snprintf(buf, maxSize, "%f (%s)", node->getUnionArrayPointer()[i].getFConst(), "const float");
|
||||||
|
|
||||||
out.debug << buf << "\n";
|
out.debug << buf << "\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
@ -409,7 +413,7 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
|
|||||||
char buf[maxSize];
|
char buf[maxSize];
|
||||||
snprintf(buf, maxSize, "%f (%s)", node->getUnionArrayPointer()[i].getDConst(), "const double");
|
snprintf(buf, maxSize, "%f (%s)", node->getUnionArrayPointer()[i].getDConst(), "const double");
|
||||||
|
|
||||||
out.debug << buf << "\n";
|
out.debug << buf << "\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
@ -421,7 +425,7 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
|
|||||||
out.debug << buf << "\n";
|
out.debug << buf << "\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
|
out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -434,21 +438,21 @@ bool OutputLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
|
|||||||
TInfoSink& out = oit->infoSink;
|
TInfoSink& out = oit->infoSink;
|
||||||
|
|
||||||
OutputTreeText(out, node, oit->depth);
|
OutputTreeText(out, node, oit->depth);
|
||||||
|
|
||||||
out.debug << "Loop with condition ";
|
out.debug << "Loop with condition ";
|
||||||
if (! node->testFirst())
|
if (! node->testFirst())
|
||||||
out.debug << "not ";
|
out.debug << "not ";
|
||||||
out.debug << "tested first\n";
|
out.debug << "tested first\n";
|
||||||
|
|
||||||
++oit->depth;
|
++oit->depth;
|
||||||
|
|
||||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||||
if (node->getTest()) {
|
if (node->getTest()) {
|
||||||
out.debug << "Loop Condition\n";
|
out.debug << "Loop Condition\n";
|
||||||
node->getTest()->traverse(it);
|
node->getTest()->traverse(it);
|
||||||
} else
|
} else
|
||||||
out.debug << "No loop condition\n";
|
out.debug << "No loop condition\n";
|
||||||
|
|
||||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||||
if (node->getBody()) {
|
if (node->getBody()) {
|
||||||
out.debug << "Loop Body\n";
|
out.debug << "Loop Body\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user