Fix code styles in OutputGLSLBase, SymbolTable, and Types.
I came across these three classes in the last CL, so do some
cleanup as I touched these classes.
BUG=
TEST=webgl conformance, no regressions
Change-Id: I2819bab5965fcb4917f85c2eded571a7f95ab9a2
Reviewed-on: https://chromium-review.googlesource.com/199423
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Tested-by: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 1830b17..6995594 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -11,7 +11,7 @@
namespace
{
-TString arrayBrackets(const TType& type)
+TString arrayBrackets(const TType &type)
{
ASSERT(type.isArray());
TInfoSinkBase out;
@@ -19,13 +19,14 @@
return TString(out.c_str());
}
-bool isSingleStatement(TIntermNode* node) {
- if (const TIntermAggregate* aggregate = node->getAsAggregate())
+bool isSingleStatement(TIntermNode *node)
+{
+ if (const TIntermAggregate *aggregate = node->getAsAggregate())
{
return (aggregate->getOp() != EOpFunction) &&
(aggregate->getOp() != EOpSequence);
}
- else if (const TIntermSelection* selection = node->getAsSelectionNode())
+ else if (const TIntermSelection *selection = node->getAsSelectionNode())
{
// Ternary operators are usually part of an assignment operator.
// This handles those rare cases in which they are all by themselves.
@@ -39,11 +40,11 @@
}
} // namespace
-TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink,
+TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
- NameMap& nameMap,
- TSymbolTable& symbolTable,
+ NameMap &nameMap,
+ TSymbolTable &symbolTable,
int shaderVersion)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
@@ -58,32 +59,35 @@
mDeclaredStructs.push_back(ScopedDeclaredStructs());
}
-void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr)
+void TOutputGLSLBase::writeTriplet(
+ Visit visit, const char *preStr, const char *inStr, const char *postStr)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
if (visit == PreVisit && preStr)
- {
out << preStr;
- }
else if (visit == InVisit && inStr)
- {
out << inStr;
- }
else if (visit == PostVisit && postStr)
- {
out << postStr;
- }
}
-void TOutputGLSLBase::writeVariableType(const TType& type)
+void TOutputGLSLBase::writeBuiltInFunctionTriplet(
+ Visit visit, const char *preStr, bool useEmulatedFunction)
{
- TInfoSinkBase& out = objSink();
+ TString preString = useEmulatedFunction ?
+ BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr) : preStr;
+ writeTriplet(visit, preString.c_str(), ", ", ")");
+}
+
+void TOutputGLSLBase::writeVariableType(const TType &type)
+{
+ TInfoSinkBase &out = objSink();
TQualifier qualifier = type.getQualifier();
// TODO(alokp): Validate qualifier for variable declarations.
- if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
+ if (qualifier != EvqTemporary && qualifier != EvqGlobal)
out << type.getQualifierString() << " ";
// Declare the struct if we have not done so already.
- if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct()))
+ if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
{
declareStruct(type.getStruct());
mDeclaredStructs[mDeclaredStructs.size() - 1].push_back(type.getStruct());
@@ -96,19 +100,19 @@
}
}
-void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args)
+void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
for (TIntermSequence::const_iterator iter = args.begin();
iter != args.end(); ++iter)
{
- const TIntermSymbol* arg = (*iter)->getAsSymbolNode();
+ const TIntermSymbol *arg = (*iter)->getAsSymbolNode();
ASSERT(arg != NULL);
- const TType& type = arg->getType();
+ const TType &type = arg->getType();
writeVariableType(type);
- const TString& name = arg->getSymbol();
+ const TString &name = arg->getSymbol();
if (!name.empty())
out << " " << hashName(name);
if (type.isArray())
@@ -120,23 +124,24 @@
}
}
-const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
- const ConstantUnion* pConstUnion)
+const ConstantUnion *TOutputGLSLBase::writeConstantUnion(
+ const TType &type, const ConstantUnion *pConstUnion)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
if (type.getBasicType() == EbtStruct)
{
- const TStructure* structure = type.getStruct();
+ const TStructure *structure = type.getStruct();
out << hashName(structure->name()) << "(";
- const TFieldList& fields = structure->fields();
+ const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
- const TType* fieldType = fields[i]->type();
+ const TType *fieldType = fields[i]->type();
ASSERT(fieldType != NULL);
pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
- if (i != fields.size() - 1) out << ", ";
+ if (i != fields.size() - 1)
+ out << ", ";
}
out << ")";
}
@@ -144,26 +149,35 @@
{
size_t size = type.getObjectSize();
bool writeType = size > 1;
- if (writeType) out << getTypeName(type) << "(";
+ if (writeType)
+ out << getTypeName(type) << "(";
for (size_t i = 0; i < size; ++i, ++pConstUnion)
{
switch (pConstUnion->getType())
{
- case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst())); break;
- case EbtInt: out << pConstUnion->getIConst(); break;
- case EbtBool: out << pConstUnion->getBConst(); break;
- default: UNREACHABLE();
+ case EbtFloat:
+ out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst()));
+ break;
+ case EbtInt:
+ out << pConstUnion->getIConst();
+ break;
+ case EbtBool:
+ out << pConstUnion->getBConst();
+ break;
+ default: UNREACHABLE();
}
- if (i != size - 1) out << ", ";
+ if (i != size - 1)
+ out << ", ";
}
- if (writeType) out << ")";
+ if (writeType)
+ out << ")";
}
return pConstUnion;
}
-void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
+void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node))
out << mLoopUnrollStack.getLoopIndexValue(node);
else
@@ -173,240 +187,364 @@
out << arrayBrackets(node->getType());
}
-void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node)
+void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node)
{
writeConstantUnion(node->getType(), node->getUnionArrayPointer());
}
-bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
+bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
{
bool visitChildren = true;
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
switch (node->getOp())
{
- case EOpInitialize:
+ case EOpInitialize:
+ if (visit == InVisit)
+ {
+ out << " = ";
+ // RHS of initialize is not being declared.
+ mDeclaringVariables = false;
+ }
+ break;
+ case EOpAssign:
+ writeTriplet(visit, "(", " = ", ")");
+ break;
+ case EOpAddAssign:
+ writeTriplet(visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ writeTriplet(visit, "(", " -= ", ")");
+ break;
+ case EOpDivAssign:
+ writeTriplet(visit, "(", " /= ", ")");
+ break;
+ // Notice the fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ writeTriplet(visit, "(", " *= ", ")");
+ break;
+
+ case EOpIndexDirect:
+ writeTriplet(visit, NULL, "[", "]");
+ break;
+ case EOpIndexIndirect:
+ if (node->getAddIndexClamp())
+ {
if (visit == InVisit)
{
- out << " = ";
- // RHS of initialize is not being declared.
- mDeclaringVariables = false;
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ out << "[int(clamp(float(";
+ else
+ out << "[webgl_int_clamp(";
}
- break;
- case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break;
- case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break;
- case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break;
- case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break;
- // Notice the fall-through.
- case EOpMulAssign:
- case EOpVectorTimesMatrixAssign:
- case EOpVectorTimesScalarAssign:
- case EOpMatrixTimesScalarAssign:
- case EOpMatrixTimesMatrixAssign:
- writeTriplet(visit, "(", " *= ", ")");
- break;
+ else if (visit == PostVisit)
+ {
+ int maxSize;
+ TIntermTyped *left = node->getLeft();
+ TType leftType = left->getType();
- case EOpIndexDirect:
+ if (left->isArray())
+ {
+ // The shader will fail validation if the array length is not > 0.
+ maxSize = leftType.getArraySize() - 1;
+ }
+ else
+ {
+ maxSize = leftType.getNominalSize() - 1;
+ }
+
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ out << "), 0.0, float(" << maxSize << ")))]";
+ else
+ out << ", 0, " << maxSize << ")]";
+ }
+ }
+ else
+ {
writeTriplet(visit, NULL, "[", "]");
- break;
- case EOpIndexIndirect:
- if (node->getAddIndexClamp())
+ }
+ break;
+ case EOpIndexDirectStruct:
+ if (visit == InVisit)
+ {
+ // Here we are writing out "foo.bar", where "foo" is struct
+ // and "bar" is field. In AST, it is represented as a binary
+ // node, where left child represents "foo" and right child "bar".
+ // The node itself represents ".". The struct field "bar" is
+ // actually stored as an index into TStructure::fields.
+ out << ".";
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+
+ TString fieldName = field->name();
+ if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion))
+ fieldName = hashName(fieldName);
+
+ out << fieldName;
+ visitChildren = false;
+ }
+ break;
+ case EOpVectorSwizzle:
+ if (visit == InVisit)
+ {
+ out << ".";
+ TIntermAggregate *rightChild = node->getRight()->getAsAggregate();
+ TIntermSequence &sequence = rightChild->getSequence();
+ for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
{
- if (visit == InVisit)
+ TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
+ ASSERT(element->getBasicType() == EbtInt);
+ ASSERT(element->getNominalSize() == 1);
+ const ConstantUnion& data = element->getUnionArrayPointer()[0];
+ ASSERT(data.getType() == EbtInt);
+ switch (data.getIConst())
{
- if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
- out << "[int(clamp(float(";
- } else {
- out << "[webgl_int_clamp(";
- }
- }
- else if (visit == PostVisit)
- {
- int maxSize;
- TIntermTyped *left = node->getLeft();
- TType leftType = left->getType();
-
- if (left->isArray())
- {
- // The shader will fail validation if the array length is not > 0.
- maxSize = leftType.getArraySize() - 1;
- }
- else
- {
- maxSize = leftType.getNominalSize() - 1;
- }
-
- if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
- out << "), 0.0, float(" << maxSize << ")))]";
- } else {
- out << ", 0, " << maxSize << ")]";
- }
+ case 0:
+ out << "x";
+ break;
+ case 1:
+ out << "y";
+ break;
+ case 2:
+ out << "z";
+ break;
+ case 3:
+ out << "w";
+ break;
+ default:
+ UNREACHABLE();
}
}
- else
- {
- writeTriplet(visit, NULL, "[", "]");
- }
- break;
- case EOpIndexDirectStruct:
- if (visit == InVisit)
- {
- // Here we are writing out "foo.bar", where "foo" is struct
- // and "bar" is field. In AST, it is represented as a binary
- // node, where left child represents "foo" and right child "bar".
- // The node itself represents ".". The struct field "bar" is
- // actually stored as an index into TStructure::fields.
- out << ".";
- const TStructure* structure = node->getLeft()->getType().getStruct();
- const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
- const TField* field = structure->fields()[index->getIConst(0)];
+ visitChildren = false;
+ }
+ break;
- TString fieldName = field->name();
- if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion))
- fieldName = hashName(fieldName);
+ case EOpAdd:
+ writeTriplet(visit, "(", " + ", ")");
+ break;
+ case EOpSub:
+ writeTriplet(visit, "(", " - ", ")");
+ break;
+ case EOpMul:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+ case EOpDiv:
+ writeTriplet(visit, "(", " / ", ")");
+ break;
+ case EOpMod:
+ UNIMPLEMENTED();
+ break;
+ case EOpEqual:
+ writeTriplet(visit, "(", " == ", ")");
+ break;
+ case EOpNotEqual:
+ writeTriplet(visit, "(", " != ", ")");
+ break;
+ case EOpLessThan:
+ writeTriplet(visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThan:
+ writeTriplet(visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqual:
+ writeTriplet(visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqual:
+ writeTriplet(visit, "(", " >= ", ")");
+ break;
- out << fieldName;
- visitChildren = false;
- }
- break;
- case EOpVectorSwizzle:
- if (visit == InVisit)
- {
- out << ".";
- TIntermAggregate* rightChild = node->getRight()->getAsAggregate();
- TIntermSequence& sequence = rightChild->getSequence();
- for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
- {
- TIntermConstantUnion* element = (*sit)->getAsConstantUnion();
- ASSERT(element->getBasicType() == EbtInt);
- ASSERT(element->getNominalSize() == 1);
- const ConstantUnion& data = element->getUnionArrayPointer()[0];
- ASSERT(data.getType() == EbtInt);
- switch (data.getIConst())
- {
- case 0: out << "x"; break;
- case 1: out << "y"; break;
- case 2: out << "z"; break;
- case 3: out << "w"; break;
- default: UNREACHABLE(); break;
- }
- }
- visitChildren = false;
- }
- break;
+ // Notice the fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
- case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break;
- case EOpSub: writeTriplet(visit, "(", " - ", ")"); break;
- case EOpMul: writeTriplet(visit, "(", " * ", ")"); break;
- case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break;
- case EOpMod: UNIMPLEMENTED(); break;
- case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break;
- case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break;
- case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break;
- case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break;
- case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break;
- case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break;
-
- // Notice the fall-through.
- case EOpVectorTimesScalar:
- case EOpVectorTimesMatrix:
- case EOpMatrixTimesVector:
- case EOpMatrixTimesScalar:
- case EOpMatrixTimesMatrix:
- writeTriplet(visit, "(", " * ", ")");
- break;
-
- case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break;
- case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break;
- case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break;
- default: UNREACHABLE(); break;
+ case EOpLogicalOr:
+ writeTriplet(visit, "(", " || ", ")");
+ break;
+ case EOpLogicalXor:
+ writeTriplet(visit, "(", " ^^ ", ")");
+ break;
+ case EOpLogicalAnd:
+ writeTriplet(visit, "(", " && ", ")");
+ break;
+ default:
+ UNREACHABLE();
}
return visitChildren;
}
-bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node)
+bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
{
TString preString;
TString postString = ")";
switch (node->getOp())
{
- case EOpNegative: preString = "(-"; break;
- case EOpVectorLogicalNot: preString = "not("; break;
- case EOpLogicalNot: preString = "(!"; break;
+ case EOpNegative: preString = "(-"; break;
+ case EOpVectorLogicalNot: preString = "not("; break;
+ case EOpLogicalNot: preString = "(!"; break;
- case EOpPostIncrement: preString = "("; postString = "++)"; break;
- case EOpPostDecrement: preString = "("; postString = "--)"; break;
- case EOpPreIncrement: preString = "(++"; break;
- case EOpPreDecrement: preString = "(--"; break;
+ case EOpPostIncrement: preString = "("; postString = "++)"; break;
+ case EOpPostDecrement: preString = "("; postString = "--)"; break;
+ case EOpPreIncrement: preString = "(++"; break;
+ case EOpPreDecrement: preString = "(--"; break;
- case EOpConvIntToBool:
- case EOpConvFloatToBool:
- switch (node->getOperand()->getType().getNominalSize())
- {
- case 1: preString = "bool("; break;
- case 2: preString = "bvec2("; break;
- case 3: preString = "bvec3("; break;
- case 4: preString = "bvec4("; break;
- default: UNREACHABLE();
- }
+ case EOpConvIntToBool:
+ case EOpConvFloatToBool:
+ switch (node->getOperand()->getType().getNominalSize())
+ {
+ case 1:
+ preString = "bool(";
break;
- case EOpConvBoolToFloat:
- case EOpConvIntToFloat:
- switch (node->getOperand()->getType().getNominalSize())
- {
- case 1: preString = "float("; break;
- case 2: preString = "vec2("; break;
- case 3: preString = "vec3("; break;
- case 4: preString = "vec4("; break;
- default: UNREACHABLE();
- }
+ case 2:
+ preString = "bvec2(";
break;
- case EOpConvFloatToInt:
- case EOpConvBoolToInt:
- switch (node->getOperand()->getType().getNominalSize())
- {
- case 1: preString = "int("; break;
- case 2: preString = "ivec2("; break;
- case 3: preString = "ivec3("; break;
- case 4: preString = "ivec4("; break;
- default: UNREACHABLE();
- }
+ case 3:
+ preString = "bvec3(";
break;
+ case 4:
+ preString = "bvec4(";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case EOpConvBoolToFloat:
+ case EOpConvIntToFloat:
+ switch (node->getOperand()->getType().getNominalSize())
+ {
+ case 1:
+ preString = "float(";
+ break;
+ case 2:
+ preString = "vec2(";
+ break;
+ case 3:
+ preString = "vec3(";
+ break;
+ case 4:
+ preString = "vec4(";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case EOpConvFloatToInt:
+ case EOpConvBoolToInt:
+ switch (node->getOperand()->getType().getNominalSize())
+ {
+ case 1:
+ preString = "int(";
+ break;
+ case 2:
+ preString = "ivec2(";
+ break;
+ case 3:
+ preString = "ivec3(";
+ break;
+ case 4:
+ preString = "ivec4(";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
- case EOpRadians: preString = "radians("; break;
- case EOpDegrees: preString = "degrees("; break;
- case EOpSin: preString = "sin("; break;
- case EOpCos: preString = "cos("; break;
- case EOpTan: preString = "tan("; break;
- case EOpAsin: preString = "asin("; break;
- case EOpAcos: preString = "acos("; break;
- case EOpAtan: preString = "atan("; break;
+ case EOpRadians:
+ preString = "radians(";
+ break;
+ case EOpDegrees:
+ preString = "degrees(";
+ break;
+ case EOpSin:
+ preString = "sin(";
+ break;
+ case EOpCos:
+ preString = "cos(";
+ break;
+ case EOpTan:
+ preString = "tan(";
+ break;
+ case EOpAsin:
+ preString = "asin(";
+ break;
+ case EOpAcos:
+ preString = "acos(";
+ break;
+ case EOpAtan:
+ preString = "atan(";
+ break;
- case EOpExp: preString = "exp("; break;
- case EOpLog: preString = "log("; break;
- case EOpExp2: preString = "exp2("; break;
- case EOpLog2: preString = "log2("; break;
- case EOpSqrt: preString = "sqrt("; break;
- case EOpInverseSqrt: preString = "inversesqrt("; break;
+ case EOpExp:
+ preString = "exp(";
+ break;
+ case EOpLog:
+ preString = "log(";
+ break;
+ case EOpExp2:
+ preString = "exp2(";
+ break;
+ case EOpLog2:
+ preString = "log2(";
+ break;
+ case EOpSqrt:
+ preString = "sqrt(";
+ break;
+ case EOpInverseSqrt:
+ preString = "inversesqrt(";
+ break;
- case EOpAbs: preString = "abs("; break;
- case EOpSign: preString = "sign("; break;
- case EOpFloor: preString = "floor("; break;
- case EOpCeil: preString = "ceil("; break;
- case EOpFract: preString = "fract("; break;
+ case EOpAbs:
+ preString = "abs(";
+ break;
+ case EOpSign:
+ preString = "sign(";
+ break;
+ case EOpFloor:
+ preString = "floor(";
+ break;
+ case EOpCeil:
+ preString = "ceil(";
+ break;
+ case EOpFract:
+ preString = "fract(";
+ break;
- case EOpLength: preString = "length("; break;
- case EOpNormalize: preString = "normalize("; break;
+ case EOpLength:
+ preString = "length(";
+ break;
+ case EOpNormalize:
+ preString = "normalize(";
+ break;
- case EOpDFdx: preString = "dFdx("; break;
- case EOpDFdy: preString = "dFdy("; break;
- case EOpFwidth: preString = "fwidth("; break;
+ case EOpDFdx:
+ preString = "dFdx(";
+ break;
+ case EOpDFdy:
+ preString = "dFdy(";
+ break;
+ case EOpFwidth:
+ preString = "fwidth(";
+ break;
- case EOpAny: preString = "any("; break;
- case EOpAll: preString = "all("; break;
+ case EOpAny:
+ preString = "any(";
+ break;
+ case EOpAll:
+ preString = "all(";
+ break;
- default: UNREACHABLE(); break;
+ default:
+ UNREACHABLE();
}
if (visit == PreVisit && node->getUseEmulatedFunction())
@@ -416,9 +554,9 @@
return true;
}
-bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node)
+bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
if (node->usesTernaryOperator())
{
@@ -453,203 +591,264 @@
return false;
}
-bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
+bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = true;
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
TString preString;
- bool delayedWrite = false;
+ bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction());
switch (node->getOp())
{
- case EOpSequence: {
- // Scope the sequences except when at the global scope.
- if (depth > 0)
- {
- out << "{\n";
- pushDeclaredStructsScope();
- }
-
- incrementDepth(node);
- const TIntermSequence& sequence = node->getSequence();
- for (TIntermSequence::const_iterator iter = sequence.begin();
- iter != sequence.end(); ++iter)
- {
- TIntermNode* node = *iter;
- ASSERT(node != NULL);
- node->traverse(this);
-
- if (isSingleStatement(node))
- out << ";\n";
- }
- decrementDepth();
-
- // Scope the sequences except when at the global scope.
- if (depth > 0)
- {
- popDeclaredStructsScope();
- out << "}\n";
- }
- visitChildren = false;
- break;
+ case EOpSequence:
+ // Scope the sequences except when at the global scope.
+ if (depth > 0)
+ {
+ out << "{\n";
+ pushDeclaredStructsScope();
}
- case EOpPrototype: {
- // Function declaration.
- ASSERT(visit == PreVisit);
- writeVariableType(node->getType());
- out << " " << hashName(node->getName());
- out << "(";
- writeFunctionParameters(node->getSequence());
+ incrementDepth(node);
+ for (TIntermSequence::const_iterator iter = node->getSequence().begin();
+ iter != node->getSequence().end(); ++iter)
+ {
+ TIntermNode *node = *iter;
+ ASSERT(node != NULL);
+ node->traverse(this);
+
+ if (isSingleStatement(node))
+ out << ";\n";
+ }
+ decrementDepth();
+
+ // Scope the sequences except when at the global scope.
+ if (depth > 0)
+ {
+ popDeclaredStructsScope();
+ out << "}\n";
+ }
+ visitChildren = false;
+ break;
+ case EOpPrototype:
+ // Function declaration.
+ ASSERT(visit == PreVisit);
+ writeVariableType(node->getType());
+ out << " " << hashName(node->getName());
+
+ out << "(";
+ writeFunctionParameters(node->getSequence());
+ out << ")";
+
+ visitChildren = false;
+ break;
+ case EOpFunction: {
+ // Function definition.
+ ASSERT(visit == PreVisit);
+ writeVariableType(node->getType());
+ out << " " << hashFunctionName(node->getName());
+
+ incrementDepth(node);
+ // Function definition node contains one or two children nodes
+ // representing function parameters and function body. The latter
+ // is not present in case of empty function bodies.
+ const TIntermSequence &sequence = node->getSequence();
+ ASSERT((sequence.size() == 1) || (sequence.size() == 2));
+ TIntermSequence::const_iterator seqIter = sequence.begin();
+
+ // Traverse function parameters.
+ TIntermAggregate *params = (*seqIter)->getAsAggregate();
+ ASSERT(params != NULL);
+ ASSERT(params->getOp() == EOpParameters);
+ params->traverse(this);
+
+ // Traverse function body.
+ TIntermAggregate *body = ++seqIter != sequence.end() ?
+ (*seqIter)->getAsAggregate() : NULL;
+ visitCodeBlock(body);
+ decrementDepth();
+
+ // Fully processed; no need to visit children.
+ visitChildren = false;
+ break;
+ }
+ case EOpFunctionCall:
+ // Function call.
+ if (visit == PreVisit)
+ out << hashFunctionName(node->getName()) << "(";
+ else if (visit == InVisit)
+ out << ", ";
+ else
out << ")";
-
- visitChildren = false;
- break;
+ break;
+ case EOpParameters:
+ // Function parameters.
+ ASSERT(visit == PreVisit);
+ out << "(";
+ writeFunctionParameters(node->getSequence());
+ out << ")";
+ visitChildren = false;
+ break;
+ case EOpDeclaration:
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = node->getSequence();
+ const TIntermTyped *variable = sequence.front()->getAsTyped();
+ writeVariableType(variable->getType());
+ out << " ";
+ mDeclaringVariables = true;
}
- case EOpFunction: {
- // Function definition.
- ASSERT(visit == PreVisit);
- writeVariableType(node->getType());
- out << " " << hashFunctionName(node->getName());
-
- incrementDepth(node);
- // Function definition node contains one or two children nodes
- // representing function parameters and function body. The latter
- // is not present in case of empty function bodies.
- const TIntermSequence& sequence = node->getSequence();
- ASSERT((sequence.size() == 1) || (sequence.size() == 2));
- TIntermSequence::const_iterator seqIter = sequence.begin();
-
- // Traverse function parameters.
- TIntermAggregate* params = (*seqIter)->getAsAggregate();
- ASSERT(params != NULL);
- ASSERT(params->getOp() == EOpParameters);
- params->traverse(this);
-
- // Traverse function body.
- TIntermAggregate* body = ++seqIter != sequence.end() ?
- (*seqIter)->getAsAggregate() : NULL;
- visitCodeBlock(body);
- decrementDepth();
-
- // Fully processed; no need to visit children.
- visitChildren = false;
- break;
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ mDeclaringVariables = true;
}
- case EOpFunctionCall:
- // Function call.
- if (visit == PreVisit)
- {
- out << hashFunctionName(node->getName()) << "(";
- }
- else if (visit == InVisit)
- {
- out << ", ";
- }
- else
- {
- out << ")";
- }
- break;
- case EOpParameters: {
- // Function parameters.
- ASSERT(visit == PreVisit);
- out << "(";
- writeFunctionParameters(node->getSequence());
+ else
+ {
+ mDeclaringVariables = false;
+ }
+ break;
+ case EOpConstructFloat:
+ writeTriplet(visit, "float(", NULL, ")");
+ break;
+ case EOpConstructVec2:
+ writeBuiltInFunctionTriplet(visit, "vec2(", false);
+ break;
+ case EOpConstructVec3:
+ writeBuiltInFunctionTriplet(visit, "vec3(", false);
+ break;
+ case EOpConstructVec4:
+ writeBuiltInFunctionTriplet(visit, "vec4(", false);
+ break;
+ case EOpConstructBool:
+ writeTriplet(visit, "bool(", NULL, ")");
+ break;
+ case EOpConstructBVec2:
+ writeBuiltInFunctionTriplet(visit, "bvec2(", false);
+ break;
+ case EOpConstructBVec3:
+ writeBuiltInFunctionTriplet(visit, "bvec3(", false);
+ break;
+ case EOpConstructBVec4:
+ writeBuiltInFunctionTriplet(visit, "bvec4(", false);
+ break;
+ case EOpConstructInt:
+ writeTriplet(visit, "int(", NULL, ")");
+ break;
+ case EOpConstructIVec2:
+ writeBuiltInFunctionTriplet(visit, "ivec2(", false);
+ break;
+ case EOpConstructIVec3:
+ writeBuiltInFunctionTriplet(visit, "ivec3(", false);
+ break;
+ case EOpConstructIVec4:
+ writeBuiltInFunctionTriplet(visit, "ivec4(", false);
+ break;
+ case EOpConstructMat2:
+ writeBuiltInFunctionTriplet(visit, "mat2(", false);
+ break;
+ case EOpConstructMat3:
+ writeBuiltInFunctionTriplet(visit, "mat3(", false);
+ break;
+ case EOpConstructMat4:
+ writeBuiltInFunctionTriplet(visit, "mat4(", false);
+ break;
+ case EOpConstructStruct:
+ if (visit == PreVisit)
+ {
+ const TType &type = node->getType();
+ ASSERT(type.getBasicType() == EbtStruct);
+ out << hashName(type.getStruct()->name()) << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ }
+ else
+ {
out << ")";
- visitChildren = false;
- break;
}
- case EOpDeclaration: {
- // Variable declaration.
- if (visit == PreVisit)
- {
- const TIntermSequence& sequence = node->getSequence();
- const TIntermTyped* variable = sequence.front()->getAsTyped();
- writeVariableType(variable->getType());
- out << " ";
- mDeclaringVariables = true;
- }
- else if (visit == InVisit)
- {
- out << ", ";
- mDeclaringVariables = true;
- }
- else
- {
- mDeclaringVariables = false;
- }
- break;
- }
- case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break;
- case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break;
- case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break;
- case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break;
- case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break;
- case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break;
- case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break;
- case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break;
- case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break;
- case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break;
- case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break;
- case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break;
- case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break;
- case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break;
- case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break;
- case EOpConstructStruct:
- if (visit == PreVisit)
- {
- const TType& type = node->getType();
- ASSERT(type.getBasicType() == EbtStruct);
- out << hashName(type.getStruct()->name()) << "(";
- }
- else if (visit == InVisit)
- {
- out << ", ";
- }
- else
- {
- out << ")";
- }
- break;
+ break;
- case EOpLessThan: preString = "lessThan("; delayedWrite = true; break;
- case EOpGreaterThan: preString = "greaterThan("; delayedWrite = true; break;
- case EOpLessThanEqual: preString = "lessThanEqual("; delayedWrite = true; break;
- case EOpGreaterThanEqual: preString = "greaterThanEqual("; delayedWrite = true; break;
- case EOpVectorEqual: preString = "equal("; delayedWrite = true; break;
- case EOpVectorNotEqual: preString = "notEqual("; delayedWrite = true; break;
- case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break;
+ case EOpLessThan:
+ writeBuiltInFunctionTriplet(visit, "lessThan(", useEmulatedFunction);
+ break;
+ case EOpGreaterThan:
+ writeBuiltInFunctionTriplet(visit, "greaterThan(", useEmulatedFunction);
+ break;
+ case EOpLessThanEqual:
+ writeBuiltInFunctionTriplet(visit, "lessThanEqual(", useEmulatedFunction);
+ break;
+ case EOpGreaterThanEqual:
+ writeBuiltInFunctionTriplet(visit, "greaterThanEqual(", useEmulatedFunction);
+ break;
+ case EOpVectorEqual:
+ writeBuiltInFunctionTriplet(visit, "equal(", useEmulatedFunction);
+ break;
+ case EOpVectorNotEqual:
+ writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
+ break;
+ case EOpComma:
+ writeTriplet(visit, NULL, ", ", NULL);
+ break;
- case EOpMod: preString = "mod("; delayedWrite = true; break;
- case EOpPow: preString = "pow("; delayedWrite = true; break;
- case EOpAtan: preString = "atan("; delayedWrite = true; break;
- case EOpMin: preString = "min("; delayedWrite = true; break;
- case EOpMax: preString = "max("; delayedWrite = true; break;
- case EOpClamp: preString = "clamp("; delayedWrite = true; break;
- case EOpMix: preString = "mix("; delayedWrite = true; break;
- case EOpStep: preString = "step("; delayedWrite = true; break;
- case EOpSmoothStep: preString = "smoothstep("; delayedWrite = true; break;
+ case EOpMod:
+ writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction);
+ break;
+ case EOpPow:
+ writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction);
+ break;
+ case EOpAtan:
+ writeBuiltInFunctionTriplet(visit, "atan(", useEmulatedFunction);
+ break;
+ case EOpMin:
+ writeBuiltInFunctionTriplet(visit, "min(", useEmulatedFunction);
+ break;
+ case EOpMax:
+ writeBuiltInFunctionTriplet(visit, "max(", useEmulatedFunction);
+ break;
+ case EOpClamp:
+ writeBuiltInFunctionTriplet(visit, "clamp(", useEmulatedFunction);
+ break;
+ case EOpMix:
+ writeBuiltInFunctionTriplet(visit, "mix(", useEmulatedFunction);
+ break;
+ case EOpStep:
+ writeBuiltInFunctionTriplet(visit, "step(", useEmulatedFunction);
+ break;
+ case EOpSmoothStep:
+ writeBuiltInFunctionTriplet(visit, "smoothstep(", useEmulatedFunction);
+ break;
+ case EOpDistance:
+ writeBuiltInFunctionTriplet(visit, "distance(", useEmulatedFunction);
+ break;
+ case EOpDot:
+ writeBuiltInFunctionTriplet(visit, "dot(", useEmulatedFunction);
+ break;
+ case EOpCross:
+ writeBuiltInFunctionTriplet(visit, "cross(", useEmulatedFunction);
+ break;
+ case EOpFaceForward:
+ writeBuiltInFunctionTriplet(visit, "faceforward(", useEmulatedFunction);
+ break;
+ case EOpReflect:
+ writeBuiltInFunctionTriplet(visit, "reflect(", useEmulatedFunction);
+ break;
+ case EOpRefract:
+ writeBuiltInFunctionTriplet(visit, "refract(", useEmulatedFunction);
+ break;
+ case EOpMul:
+ writeBuiltInFunctionTriplet(visit, "matrixCompMult(", useEmulatedFunction);
+ break;
- case EOpDistance: preString = "distance("; delayedWrite = true; break;
- case EOpDot: preString = "dot("; delayedWrite = true; break;
- case EOpCross: preString = "cross("; delayedWrite = true; break;
- case EOpFaceForward: preString = "faceforward("; delayedWrite = true; break;
- case EOpReflect: preString = "reflect("; delayedWrite = true; break;
- case EOpRefract: preString = "refract("; delayedWrite = true; break;
- case EOpMul: preString = "matrixCompMult("; delayedWrite = true; break;
-
- default: UNREACHABLE(); break;
+ default:
+ UNREACHABLE();
}
- if (delayedWrite && visit == PreVisit && node->getUseEmulatedFunction())
- preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
- if (delayedWrite)
- writeTriplet(visit, preString.c_str(), ", ", ")");
return visitChildren;
}
-bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
+bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
incrementDepth(node);
// Loop header.
@@ -730,21 +929,31 @@
return false;
}
-bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch* node)
+bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch *node)
{
switch (node->getFlowOp())
{
- case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
- case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break;
- case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break;
- case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break;
- default: UNREACHABLE(); break;
+ case EOpKill:
+ writeTriplet(visit, "discard", NULL, NULL);
+ break;
+ case EOpBreak:
+ writeTriplet(visit, "break", NULL, NULL);
+ break;
+ case EOpContinue:
+ writeTriplet(visit, "continue", NULL, NULL);
+ break;
+ case EOpReturn:
+ writeTriplet(visit, "return ", NULL, NULL);
+ break;
+ default:
+ UNREACHABLE();
}
return true;
}
-void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
+void TOutputGLSLBase::visitCodeBlock(TIntermNode *node)
+{
TInfoSinkBase &out = objSink();
if (node != NULL)
{
@@ -760,7 +969,7 @@
}
}
-TString TOutputGLSLBase::getTypeName(const TType& type)
+TString TOutputGLSLBase::getTypeName(const TType &type)
{
TInfoSinkBase out;
if (type.isMatrix())
@@ -772,10 +981,17 @@
{
switch (type.getBasicType())
{
- case EbtFloat: out << "vec"; break;
- case EbtInt: out << "ivec"; break;
- case EbtBool: out << "bvec"; break;
- default: UNREACHABLE(); break;
+ case EbtFloat:
+ out << "vec";
+ break;
+ case EbtInt:
+ out << "ivec";
+ break;
+ case EbtBool:
+ out << "bvec";
+ break;
+ default:
+ UNREACHABLE();
}
out << type.getNominalSize();
}
@@ -789,7 +1005,7 @@
return TString(out.c_str());
}
-TString TOutputGLSLBase::hashName(const TString& name)
+TString TOutputGLSLBase::hashName(const TString &name)
{
if (mHashFunction == NULL || name.empty())
return name;
@@ -801,30 +1017,28 @@
return hashedName;
}
-TString TOutputGLSLBase::hashVariableName(const TString& name)
+TString TOutputGLSLBase::hashVariableName(const TString &name)
{
if (mSymbolTable.findBuiltIn(name, mShaderVersion) != NULL)
return name;
return hashName(name);
}
-TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
+TString TOutputGLSLBase::hashFunctionName(const TString &mangled_name)
{
TString name = TFunction::unmangleName(mangled_name);
if (mSymbolTable.findBuiltIn(mangled_name, mShaderVersion) != NULL || name == "main")
- {
return translateTextureFunction(name);
- }
return hashName(name);
}
-bool TOutputGLSLBase::structDeclared(const TStructure* structure) const
+bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
{
ASSERT(structure);
ASSERT(mDeclaredStructs.size() > 0);
for (size_t ii = mDeclaredStructs.size(); ii > 0; --ii)
{
- const ScopedDeclaredStructs& scope = mDeclaredStructs[ii - 1];
+ const ScopedDeclaredStructs &scope = mDeclaredStructs[ii - 1];
for (size_t jj = 0; jj < scope.size(); ++jj)
{
if (scope[jj]->equals(*structure))
@@ -834,15 +1048,15 @@
return false;
}
-void TOutputGLSLBase::declareStruct(const TStructure* structure)
+void TOutputGLSLBase::declareStruct(const TStructure *structure)
{
- TInfoSinkBase& out = objSink();
+ TInfoSinkBase &out = objSink();
out << "struct " << hashName(structure->name()) << "{\n";
- const TFieldList& fields = structure->fields();
+ const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
- const TField* field = fields[i];
+ const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(field->name());
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index 1f751e2..ae40f85 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -15,52 +15,53 @@
class TOutputGLSLBase : public TIntermTraverser
{
-public:
- TOutputGLSLBase(TInfoSinkBase& objSink,
+ public:
+ TOutputGLSLBase(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
- NameMap& nameMap,
+ NameMap &nameMap,
TSymbolTable& symbolTable,
int shaderVersion);
-protected:
- TInfoSinkBase& objSink() { return mObjSink; }
- void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr);
- void writeVariableType(const TType& type);
+ protected:
+ TInfoSinkBase &objSink() { return mObjSink; }
+ void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
+ void writeVariableType(const TType &type);
virtual bool writeVariablePrecision(TPrecision precision) = 0;
- void writeFunctionParameters(const TIntermSequence& args);
- const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
- TString getTypeName(const TType& type);
+ void writeFunctionParameters(const TIntermSequence &args);
+ const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *pConstUnion);
+ TString getTypeName(const TType &type);
- virtual void visitSymbol(TIntermSymbol* node);
- virtual void visitConstantUnion(TIntermConstantUnion* node);
- virtual bool visitBinary(Visit visit, TIntermBinary* node);
- virtual bool visitUnary(Visit visit, TIntermUnary* node);
- virtual bool visitSelection(Visit visit, TIntermSelection* node);
- virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
- virtual bool visitLoop(Visit visit, TIntermLoop* node);
- virtual bool visitBranch(Visit visit, TIntermBranch* node);
+ virtual void visitSymbol(TIntermSymbol *node);
+ virtual void visitConstantUnion(TIntermConstantUnion *node);
+ virtual bool visitBinary(Visit visit, TIntermBinary *node);
+ virtual bool visitUnary(Visit visit, TIntermUnary *node);
+ virtual bool visitSelection(Visit visit, TIntermSelection *node);
+ virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
+ virtual bool visitLoop(Visit visit, TIntermLoop *node);
+ virtual bool visitBranch(Visit visit, TIntermBranch *node);
- void visitCodeBlock(TIntermNode* node);
-
+ void visitCodeBlock(TIntermNode *node);
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
- TString hashName(const TString& name);
+ TString hashName(const TString &name);
// Same as hashName(), but without hashing built-in variables.
- TString hashVariableName(const TString& name);
+ TString hashVariableName(const TString &name);
// Same as hashName(), but without hashing built-in functions.
- TString hashFunctionName(const TString& mangled_name);
+ TString hashFunctionName(const TString &mangled_name);
// Used to translate function names for differences between ESSL and GLSL
- virtual TString translateTextureFunction(TString& name) { return name; }
+ virtual TString translateTextureFunction(TString &name) { return name; }
-private:
- bool structDeclared(const TStructure* structure) const;
- void declareStruct(const TStructure* structure);
+ private:
+ bool structDeclared(const TStructure *structure) const;
+ void declareStruct(const TStructure *structure);
void pushDeclaredStructsScope();
void popDeclaredStructsScope();
- TInfoSinkBase& mObjSink;
+ void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction);
+
+ TInfoSinkBase &mObjSink;
bool mDeclaringVariables;
// Structs are declared as the tree is traversed. This list contains all
@@ -80,9 +81,9 @@
// name hashing.
ShHashFunction64 mHashFunction;
- NameMap& mNameMap;
+ NameMap &mNameMap;
- TSymbolTable& mSymbolTable;
+ TSymbolTable &mSymbolTable;
const int mShaderVersion;
};
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 2b8e1ff..5eb0434 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -44,12 +44,13 @@
// performance operation, and only intended for symbol tables that
// live across a large number of compiles.
//
-void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
+void TSymbolTableLevel::relateToOperator(const char *name, TOperator op)
{
- tLevel::iterator it;
- for (it = level.begin(); it != level.end(); ++it) {
- if ((*it).second->isFunction()) {
- TFunction* function = static_cast<TFunction*>((*it).second);
+ for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
+ {
+ if ((*it).second->isFunction())
+ {
+ TFunction *function = static_cast<TFunction*>((*it).second);
if (function->getName() == name)
function->relateToOperator(op);
}
@@ -62,17 +63,17 @@
// performance operation, and only intended for symbol tables that
// live across a large number of compiles.
//
-void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
+void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext)
{
- for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
- TSymbol* symbol = it->second;
- if (symbol->getName() == name) {
+ for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
+ {
+ TSymbol *symbol = it->second;
+ if (symbol->getName() == name)
symbol->relateToExtension(ext);
- }
}
}
-TSymbol::TSymbol(const TSymbol& copyOf)
+TSymbol::TSymbol(const TSymbol ©Of)
{
name = NewPoolTString(copyOf.name->c_str());
uniqueId = copyOf.uniqueId;
@@ -85,8 +86,10 @@
do
{
- if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
- if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
+ if (level == ESSL3_BUILTINS && shaderVersion != 300)
+ level--;
+ if (level == ESSL1_BUILTINS && shaderVersion != 100)
+ level--;
symbol = table[level]->find(name);
}
@@ -104,8 +107,10 @@
{
for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
{
- if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
- if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
+ if (level == ESSL3_BUILTINS && shaderVersion != 300)
+ level--;
+ if (level == ESSL1_BUILTINS && shaderVersion != 100)
+ level--;
TSymbol *symbol = table[level]->find(name);
@@ -121,3 +126,92 @@
while (table.size() > 0)
pop();
}
+
+void TSymbolTable::insertBuiltIn(
+ ESymbolLevel level, TType *rvalue, const char *name,
+ TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
+{
+ if (ptype1->getBasicType() == EbtGSampler2D)
+ {
+ bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
+ new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
+ new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
+ new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
+ return;
+ }
+ if (ptype1->getBasicType() == EbtGSampler3D)
+ {
+ bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
+ new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
+ new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
+ new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
+ return;
+ }
+ if (ptype1->getBasicType() == EbtGSamplerCube)
+ {
+ bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
+ new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
+ new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
+ new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
+ return;
+ }
+ if (ptype1->getBasicType() == EbtGSampler2DArray)
+ {
+ bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
+ new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
+ new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
+ new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
+ return;
+ }
+
+ TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
+
+ TType *types[] = {ptype1, ptype2, ptype3, ptype4, ptype5};
+ for (size_t ii = 0; ii < sizeof(types) / sizeof(types[0]); ++ii)
+ {
+ if (types[ii])
+ {
+ TParameter param = {NULL, types[ii]};
+ function->addParameter(param);
+ }
+ }
+
+ insert(level, *function);
+}
+
+TPrecision TSymbolTable::getDefaultPrecision(TBasicType type)
+{
+ if (!SupportsPrecision(type))
+ return EbpUndefined;
+
+ // unsigned integers use the same precision as signed
+ TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
+
+ int level = static_cast<int>(precisionStack.size()) - 1;
+ assert(level >= 0); // Just to be safe. Should not happen.
+ // If we dont find anything we return this. Should we error check this?
+ TPrecision prec = EbpUndefined;
+ while (level >= 0)
+ {
+ PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
+ if (it != precisionStack[level]->end())
+ {
+ prec = (*it).second;
+ break;
+ }
+ level--;
+ }
+ return prec;
+}
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 04147d2..2119d8b 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -36,33 +36,62 @@
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/intermediate.h"
-//
-// Symbol base class. (Can build functions or variables out of these...)
-//
-class TSymbol {
-public:
+// Symbol base class. (Can build functions or variables out of these...)
+class TSymbol
+{
+ public:
POOL_ALLOCATOR_NEW_DELETE();
- TSymbol(const TString* n) : uniqueId(0), name(n) { }
- virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
+ TSymbol(const TString *n)
+ : uniqueId(0),
+ name(n)
+ {
+ }
+ virtual ~TSymbol()
+ {
+ // don't delete name, it's from the pool
+ }
- const TString& getName() const { return *name; }
- virtual const TString& getMangledName() const { return getName(); }
- virtual bool isFunction() const { return false; }
- virtual bool isVariable() const { return false; }
- void setUniqueId(int id) { uniqueId = id; }
- int getUniqueId() const { return uniqueId; }
- void relateToExtension(const TString& ext) { extension = ext; }
- const TString& getExtension() const { return extension; }
+ const TString &getName() const
+ {
+ return *name;
+ }
+ virtual const TString &getMangledName() const
+ {
+ return getName();
+ }
+ virtual bool isFunction() const
+ {
+ return false;
+ }
+ virtual bool isVariable() const
+ {
+ return false;
+ }
+ void setUniqueId(int id)
+ {
+ uniqueId = id;
+ }
+ int getUniqueId() const
+ {
+ return uniqueId;
+ }
+ void relateToExtension(const TString &ext)
+ {
+ extension = ext;
+ }
+ const TString &getExtension() const
+ {
+ return extension;
+ }
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(TSymbol);
- int uniqueId; // For real comparing during code generation
+ int uniqueId; // For real comparing during code generation
const TString *name;
TString extension;
};
-//
// Variable class, meaning a symbol that's not a function.
//
// There could be a separate class heirarchy for Constant variables;
@@ -71,18 +100,41 @@
// seem worth having separate classes, and "getConst" can't simply return
// different values for different types polymorphically, so this is
// just simple and pragmatic.
-//
-class TVariable : public TSymbol {
-public:
- TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0) { }
- virtual ~TVariable() { }
- virtual bool isVariable() const { return true; }
- TType& getType() { return type; }
- const TType& getType() const { return type; }
- bool isUserType() const { return userType; }
- void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
+class TVariable : public TSymbol
+{
+ public:
+ TVariable(const TString *name, const TType &t, bool uT = false)
+ : TSymbol(name),
+ type(t),
+ userType(uT),
+ unionArray(0)
+ {
+ }
+ virtual ~TVariable()
+ {
+ }
+ virtual bool isVariable() const
+ {
+ return true;
+ }
+ TType &getType()
+ {
+ return type;
+ }
+ const TType &getType() const
+ {
+ return type;
+ }
+ bool isUserType() const
+ {
+ return userType;
+ }
+ void setQualifier(TQualifier qualifier)
+ {
+ type.setQualifier(qualifier);
+ }
- ConstantUnion* getConstPointer()
+ ConstantUnion *getConstPointer()
{
if (!unionArray)
unionArray = new ConstantUnion[type.getObjectSize()];
@@ -90,9 +142,12 @@
return unionArray;
}
- ConstantUnion* getConstPointer() const { return unionArray; }
+ ConstantUnion *getConstPointer() const
+ {
+ return unionArray;
+ }
- void shareConstPointer( ConstantUnion *constArray)
+ void shareConstPointer(ConstantUnion *constArray)
{
if (unionArray == constArray)
return;
@@ -101,69 +156,101 @@
unionArray = constArray;
}
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(TVariable);
TType type;
bool userType;
- // we are assuming that Pool Allocator will free the memory allocated to unionArray
- // when this object is destroyed
+ // we are assuming that Pool Allocator will free the memory
+ // allocated to unionArray when this object is destroyed.
ConstantUnion *unionArray;
};
-//
// The function sub-class of symbols and the parser will need to
// share this definition of a function parameter.
-//
-struct TParameter {
+struct TParameter
+{
TString *name;
TType *type;
};
-//
// The function sub-class of a symbol.
-//
-class TFunction : public TSymbol {
-public:
- TFunction(TOperator o) :
- TSymbol(0),
- returnType(TType(EbtVoid, EbpUndefined)),
- op(o),
- defined(false) { }
- TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) :
- TSymbol(name),
- returnType(retType),
- mangledName(TFunction::mangleName(*name)),
- op(tOp),
- defined(false) { }
+class TFunction : public TSymbol
+{
+ public:
+ TFunction(TOperator o)
+ : TSymbol(0),
+ returnType(TType(EbtVoid, EbpUndefined)),
+ op(o),
+ defined(false)
+ {
+ }
+ TFunction(const TString *name, TType &retType, TOperator tOp = EOpNull)
+ : TSymbol(name),
+ returnType(retType),
+ mangledName(TFunction::mangleName(*name)),
+ op(tOp),
+ defined(false)
+ {
+ }
virtual ~TFunction();
- virtual bool isFunction() const { return true; }
+ virtual bool isFunction() const
+ {
+ return true;
+ }
- static TString mangleName(const TString& name) { return name + '('; }
- static TString unmangleName(const TString& mangledName)
+ static TString mangleName(const TString &name)
+ {
+ return name + '(';
+ }
+ static TString unmangleName(const TString &mangledName)
{
return TString(mangledName.c_str(), mangledName.find_first_of('('));
}
- void addParameter(TParameter& p)
+ void addParameter(TParameter &p)
{
parameters.push_back(p);
mangledName = mangledName + p.type->getMangledName();
}
- const TString& getMangledName() const { return mangledName; }
- const TType& getReturnType() const { return returnType; }
+ const TString &getMangledName() const
+ {
+ return mangledName;
+ }
+ const TType &getReturnType() const
+ {
+ return returnType;
+ }
- void relateToOperator(TOperator o) { op = o; }
- TOperator getBuiltInOp() const { return op; }
+ void relateToOperator(TOperator o)
+ {
+ op = o;
+ }
+ TOperator getBuiltInOp() const
+ {
+ return op;
+ }
- void setDefined() { defined = true; }
- bool isDefined() { return defined; }
+ void setDefined()
+ {
+ defined = true;
+ }
+ bool isDefined()
+ {
+ return defined;
+ }
- size_t getParamCount() const { return parameters.size(); }
- const TParameter& getParam(size_t i) const { return parameters[i]; }
+ size_t getParamCount() const
+ {
+ return parameters.size();
+ }
+ const TParameter &getParam(size_t i) const
+ {
+ return parameters[i];
+ }
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(TFunction);
typedef TVector<TParameter> TParamList;
@@ -174,36 +261,38 @@
bool defined;
};
-//
// Interface block name sub-symbol
-//
class TInterfaceBlockName : public TSymbol
{
-public:
+ public:
TInterfaceBlockName(const TString *name)
: TSymbol(name)
- {}
+ {
+ }
- virtual ~TInterfaceBlockName() {}
+ virtual ~TInterfaceBlockName()
+ {
+ }
};
-class TSymbolTableLevel {
-public:
- typedef TMap<TString, TSymbol*> tLevel;
+class TSymbolTableLevel
+{
+ public:
+ typedef TMap<TString, TSymbol *> tLevel;
typedef tLevel::const_iterator const_iterator;
typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult;
- TSymbolTableLevel() { }
+ TSymbolTableLevel()
+ {
+ }
~TSymbolTableLevel();
bool insert(const TString &name, TSymbol &symbol)
{
symbol.setUniqueId(++uniqueId);
- //
// returning true means symbol was added to the table
- //
tInsertResult result = level.insert(tLevelPair(name, &symbol));
return result.second;
@@ -214,7 +303,7 @@
return insert(symbol.getMangledName(), symbol);
}
- TSymbol* find(const TString& name) const
+ TSymbol *find(const TString &name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
@@ -223,12 +312,12 @@
return (*it).second;
}
- void relateToOperator(const char* name, TOperator op);
- void relateToExtension(const char* name, const TString& ext);
+ void relateToOperator(const char *name, TOperator op);
+ void relateToExtension(const char *name, const TString &ext);
-protected:
+ protected:
tLevel level;
- static int uniqueId; // for unique identification in code generation
+ static int uniqueId; // for unique identification in code generation
};
enum ESymbolLevel
@@ -240,27 +329,33 @@
GLOBAL_LEVEL = 3
};
-class TSymbolTable {
-public:
+class TSymbolTable
+{
+ public:
TSymbolTable()
{
- //
// The symbol table cannot be used until push() is called, but
// the lack of an initial call to push() can be used to detect
// that the symbol table has not been preloaded with built-ins.
- //
}
~TSymbolTable();
- //
// When the symbol table is initialized with the built-ins, there should
// 'push' calls, so that built-ins are at level 0 and the shader
// globals are at level 1.
- //
- bool isEmpty() { return table.empty(); }
- bool atBuiltInLevel() { return currentLevel() <= LAST_BUILTIN_LEVEL; }
- bool atGlobalLevel() { return currentLevel() <= GLOBAL_LEVEL; }
+ bool isEmpty()
+ {
+ return table.empty();
+ }
+ bool atBuiltInLevel()
+ {
+ return currentLevel() <= LAST_BUILTIN_LEVEL;
+ }
+ bool atGlobalLevel()
+ {
+ return currentLevel() <= GLOBAL_LEVEL;
+ }
void push()
{
table.push_back(new TSymbolTableLevel);
@@ -288,134 +383,61 @@
bool insertConstInt(ESymbolLevel level, const char *name, int value)
{
- TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
+ TVariable *constant = new TVariable(
+ NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
constant->getConstPointer()->setIConst(value);
return insert(level, *constant);
}
- void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
- {
- if (ptype1->getBasicType() == EbtGSampler2D)
- {
- bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
- return;
- }
- else if (ptype1->getBasicType() == EbtGSampler3D)
- {
- bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
- return;
- }
- else if (ptype1->getBasicType() == EbtGSamplerCube)
- {
- bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
- return;
- }
- else if (ptype1->getBasicType() == EbtGSampler2DArray)
- {
- bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
- return;
- }
+ void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name,
+ TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0,
+ TType *ptype4 = 0, TType *ptype5 = 0);
- TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
-
- TParameter param1 = {NULL, ptype1};
- function->addParameter(param1);
-
- if (ptype2)
- {
- TParameter param2 = {NULL, ptype2};
- function->addParameter(param2);
- }
-
- if (ptype3)
- {
- TParameter param3 = {NULL, ptype3};
- function->addParameter(param3);
- }
-
- if (ptype4)
- {
- TParameter param4 = {NULL, ptype4};
- function->addParameter(param4);
- }
-
- if (ptype5)
- {
- TParameter param5 = {NULL, ptype5};
- function->addParameter(param5);
- }
-
- insert(level, *function);
- }
-
- TSymbol *find(const TString &name, int shaderVersion, bool *builtIn = NULL, bool *sameScope = NULL);
+ TSymbol *find(const TString &name, int shaderVersion,
+ bool *builtIn = NULL, bool *sameScope = NULL);
TSymbol *findBuiltIn(const TString &name, int shaderVersion);
- TSymbolTableLevel *getOuterLevel() {
+ TSymbolTableLevel *getOuterLevel()
+ {
assert(currentLevel() >= 1);
return table[currentLevel() - 1];
}
- void relateToOperator(ESymbolLevel level, const char* name, TOperator op) {
+ void relateToOperator(ESymbolLevel level, const char *name, TOperator op)
+ {
table[level]->relateToOperator(name, op);
}
- void relateToExtension(ESymbolLevel level, const char* name, const TString& ext) {
+ void relateToExtension(ESymbolLevel level, const char *name, const TString &ext)
+ {
table[level]->relateToExtension(name, ext);
}
void dump(TInfoSink &infoSink) const;
- bool setDefaultPrecision(const TPublicType& type, TPrecision prec) {
+ bool setDefaultPrecision(const TPublicType &type, TPrecision prec)
+ {
if (!SupportsPrecision(type.type))
return false;
if (type.isAggregate())
return false; // Not allowed to set for aggregate types
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
- (*precisionStack[indexOfLastElement])[type.type] = prec; // Uses map operator [], overwrites the current value
+ // Uses map operator [], overwrites the current value
+ (*precisionStack[indexOfLastElement])[type.type] = prec;
return true;
}
- // Searches down the precisionStack for a precision qualifier for the specified TBasicType
- TPrecision getDefaultPrecision( TBasicType type){
+ // Searches down the precisionStack for a precision qualifier
+ // for the specified TBasicType
+ TPrecision getDefaultPrecision(TBasicType type);
- if (!SupportsPrecision(type))
- return EbpUndefined;
-
- // unsigned integers use the same precision as signed
- TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
-
- int level = static_cast<int>(precisionStack.size()) - 1;
- assert(level >= 0); // Just to be safe. Should not happen.
- PrecisionStackLevel::iterator it;
- TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
- while (level >= 0) {
- it = precisionStack[level]->find(baseType);
- if (it != precisionStack[level]->end()) {
- prec = (*it).second;
- break;
- }
- level--;
- }
- return prec;
+ private:
+ ESymbolLevel currentLevel() const
+ {
+ return static_cast<ESymbolLevel>(table.size() - 1);
}
-private:
- ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
-
- std::vector<TSymbolTableLevel*> table;
+ std::vector<TSymbolTableLevel *> table;
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
- std::vector< PrecisionStackLevel*> precisionStack;
+ std::vector< PrecisionStackLevel *> precisionStack;
};
#endif // _SYMBOL_TABLE_INCLUDED_
diff --git a/src/compiler/translator/Types.cpp b/src/compiler/translator/Types.cpp
index 56130d9..6229f52 100644
--- a/src/compiler/translator/Types.cpp
+++ b/src/compiler/translator/Types.cpp
@@ -19,9 +19,7 @@
interfaceBlock(0), structure(0)
{
if (p.userDef)
- {
structure = p.userDef->getStruct();
- }
}
bool TType::equals(const TType &other) const
@@ -34,13 +32,9 @@
return false;
}
if (interfaceBlock && !interfaceBlock->equals(*(other.interfaceBlock)))
- {
return false;
- }
if (structure && !structure->equals(*(other.structure)))
- {
return false;
- }
return true;
}
@@ -89,30 +83,77 @@
switch (type)
{
- case EbtFloat: mangledName += 'f'; break;
- case EbtInt: mangledName += 'i'; break;
- case EbtUInt: mangledName += 'u'; break;
- case EbtBool: mangledName += 'b'; break;
- case EbtSampler2D: mangledName += "s2"; break;
- case EbtSampler3D: mangledName += "s3"; break;
- case EbtSamplerCube: mangledName += "sC"; break;
- case EbtSampler2DArray: mangledName += "s2a"; break;
- case EbtSamplerExternalOES: mangledName += "sext"; break;
- case EbtSampler2DRect: mangledName += "s2r"; break;
- case EbtISampler2D: mangledName += "is2"; break;
- case EbtISampler3D: mangledName += "is3"; break;
- case EbtISamplerCube: mangledName += "isC"; break;
- case EbtISampler2DArray: mangledName += "is2a"; break;
- case EbtUSampler2D: mangledName += "us2"; break;
- case EbtUSampler3D: mangledName += "us3"; break;
- case EbtUSamplerCube: mangledName += "usC"; break;
- case EbtUSampler2DArray: mangledName += "us2a"; break;
- case EbtSampler2DShadow: mangledName += "s2s"; break;
- case EbtSamplerCubeShadow: mangledName += "sCs"; break;
- case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
- case EbtStruct: mangledName += structure->mangledName(); break;
- case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
- default: UNREACHABLE();
+ case EbtFloat:
+ mangledName += 'f';
+ break;
+ case EbtInt:
+ mangledName += 'i';
+ break;
+ case EbtUInt:
+ mangledName += 'u';
+ break;
+ case EbtBool:
+ mangledName += 'b';
+ break;
+ case EbtSampler2D:
+ mangledName += "s2";
+ break;
+ case EbtSampler3D:
+ mangledName += "s3";
+ break;
+ case EbtSamplerCube:
+ mangledName += "sC";
+ break;
+ case EbtSampler2DArray:
+ mangledName += "s2a";
+ break;
+ case EbtSamplerExternalOES:
+ mangledName += "sext";
+ break;
+ case EbtSampler2DRect:
+ mangledName += "s2r";
+ break;
+ case EbtISampler2D:
+ mangledName += "is2";
+ break;
+ case EbtISampler3D:
+ mangledName += "is3";
+ break;
+ case EbtISamplerCube:
+ mangledName += "isC";
+ break;
+ case EbtISampler2DArray:
+ mangledName += "is2a";
+ break;
+ case EbtUSampler2D:
+ mangledName += "us2";
+ break;
+ case EbtUSampler3D:
+ mangledName += "us3";
+ break;
+ case EbtUSamplerCube:
+ mangledName += "usC";
+ break;
+ case EbtUSampler2DArray:
+ mangledName += "us2a";
+ break;
+ case EbtSampler2DShadow:
+ mangledName += "s2s";
+ break;
+ case EbtSamplerCubeShadow:
+ mangledName += "sCs";
+ break;
+ case EbtSampler2DArrayShadow:
+ mangledName += "s2as";
+ break;
+ case EbtStruct:
+ mangledName += structure->mangledName();
+ break;
+ case EbtInterfaceBlock:
+ mangledName += interfaceBlock->mangledName();
+ break;
+ default:
+ UNREACHABLE();
}
if (isMatrix())
@@ -160,8 +201,9 @@
bool TStructure::containsArrays() const
{
- for (size_t i = 0; i < mFields->size(); ++i) {
- const TType* fieldType = (*mFields)[i]->type();
+ for (size_t i = 0; i < mFields->size(); ++i)
+ {
+ const TType *fieldType = (*mFields)[i]->type();
if (fieldType->isArray() || fieldType->isStructureContainingArrays())
return true;
}
@@ -183,7 +225,8 @@
size_t TFieldListCollection::calculateObjectSize() const
{
size_t size = 0;
- for (size_t i = 0; i < mFields->size(); ++i) {
+ for (size_t i = 0; i < mFields->size(); ++i)
+ {
size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
if (fieldSize > INT_MAX - size)
size = INT_MAX;
@@ -196,8 +239,7 @@
int TStructure::calculateDeepestNesting() const
{
int maxNesting = 0;
- for (size_t i = 0; i < mFields->size(); ++i) {
+ for (size_t i = 0; i < mFields->size(); ++i)
maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
- }
return 1 + maxNesting;
}
diff --git a/src/compiler/translator/Types.h b/src/compiler/translator/Types.h
index f82c63d..df70098 100644
--- a/src/compiler/translator/Types.h
+++ b/src/compiler/translator/Types.h
@@ -18,46 +18,71 @@
class TField
{
-public:
+ public:
POOL_ALLOCATOR_NEW_DELETE();
- TField(TType* type, TString* name, const TSourceLoc& line) : mType(type), mName(name), mLine(line) {}
+ TField(TType *type, TString *name, const TSourceLoc &line)
+ : mType(type),
+ mName(name),
+ mLine(line)
+ {
+ }
// TODO(alokp): We should only return const type.
// Fix it by tweaking grammar.
- TType* type() { return mType; }
- const TType* type() const { return mType; }
+ TType *type()
+ {
+ return mType;
+ }
+ const TType *type() const
+ {
+ return mType;
+ }
- const TString& name() const { return *mName; }
- const TSourceLoc& line() const { return mLine; }
+ const TString &name() const
+ {
+ return *mName;
+ }
+ const TSourceLoc &line() const
+ {
+ return mLine;
+ }
bool equals(const TField &other) const;
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(TField);
- TType* mType;
- TString* mName;
+ TType *mType;
+ TString *mName;
TSourceLoc mLine;
};
-typedef TVector<TField*> TFieldList;
-inline TFieldList* NewPoolTFieldList()
+typedef TVector<TField *> TFieldList;
+inline TFieldList *NewPoolTFieldList()
{
- void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
+ void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
return new(memory) TFieldList;
}
class TFieldListCollection
{
-public:
- const TString& name() const { return *mName; }
- const TFieldList& fields() const { return *mFields; }
+ public:
+ const TString &name() const
+ {
+ return *mName;
+ }
+ const TFieldList &fields() const
+ {
+ return *mFields;
+ }
- const TString& mangledName() const {
+ const TString &mangledName() const
+ {
if (mMangledName.empty())
mMangledName = buildMangledName();
return mMangledName;
}
- size_t objectSize() const {
+ size_t objectSize() const
+ {
if (mObjectSize == 0)
mObjectSize = calculateObjectSize();
return mObjectSize;
@@ -65,18 +90,19 @@
virtual bool equals(const TFieldListCollection &other) const;
-protected:
- TFieldListCollection(const TString* name, TFieldList* fields)
+ protected:
+ TFieldListCollection(const TString *name, TFieldList *fields)
: mName(name),
mFields(fields),
- mObjectSize(0) {
+ mObjectSize(0)
+ {
}
TString buildMangledName() const;
size_t calculateObjectSize() const;
virtual TString mangledNamePrefix() const = 0;
- const TString* mName;
- TFieldList* mFields;
+ const TString *mName;
+ TFieldList *mFields;
mutable TString mMangledName;
mutable size_t mObjectSize;
@@ -85,23 +111,28 @@
// May also represent interface blocks
class TStructure : public TFieldListCollection
{
-public:
+ public:
POOL_ALLOCATOR_NEW_DELETE();
- TStructure(const TString* name, TFieldList* fields)
+ TStructure(const TString *name, TFieldList *fields)
: TFieldListCollection(name, fields),
- mDeepestNesting(0) {
+ mDeepestNesting(0)
+ {
}
- int deepestNesting() const {
+ int deepestNesting() const
+ {
if (mDeepestNesting == 0)
mDeepestNesting = calculateDeepestNesting();
return mDeepestNesting;
}
bool containsArrays() const;
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(TStructure);
- virtual TString mangledNamePrefix() const { return "struct-"; }
+ virtual TString mangledNamePrefix() const
+ {
+ return "struct-";
+ }
int calculateDeepestNesting() const;
mutable int mDeepestNesting;
@@ -109,30 +140,53 @@
class TInterfaceBlock : public TFieldListCollection
{
-public:
+ public:
POOL_ALLOCATOR_NEW_DELETE();
- TInterfaceBlock(const TString* name, TFieldList* fields, const TString* instanceName, int arraySize, const TLayoutQualifier& layoutQualifier)
+ TInterfaceBlock(const TString *name, TFieldList *fields, const TString *instanceName,
+ int arraySize, const TLayoutQualifier &layoutQualifier)
: TFieldListCollection(name, fields),
mInstanceName(instanceName),
mArraySize(arraySize),
mBlockStorage(layoutQualifier.blockStorage),
- mMatrixPacking(layoutQualifier.matrixPacking) {
+ mMatrixPacking(layoutQualifier.matrixPacking)
+ {
}
- const TString& instanceName() const { return *mInstanceName; }
- bool hasInstanceName() const { return mInstanceName != NULL; }
- bool isArray() const { return mArraySize > 0; }
- int arraySize() const { return mArraySize; }
- TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
- TLayoutMatrixPacking matrixPacking() const { return mMatrixPacking; }
+ const TString &instanceName() const
+ {
+ return *mInstanceName;
+ }
+ bool hasInstanceName() const
+ {
+ return mInstanceName != NULL;
+ }
+ bool isArray() const
+ {
+ return mArraySize > 0;
+ }
+ int arraySize() const
+ {
+ return mArraySize;
+ }
+ TLayoutBlockStorage blockStorage() const
+ {
+ return mBlockStorage;
+ }
+ TLayoutMatrixPacking matrixPacking() const
+ {
+ return mMatrixPacking;
+ }
virtual bool equals(const TInterfaceBlock &other) const;
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(TInterfaceBlock);
- virtual TString mangledNamePrefix() const { return "iblock-"; }
+ virtual TString mangledNamePrefix() const
+ {
+ return "iblock-";
+ }
- const TString* mInstanceName; // for interface block instance names
+ const TString *mInstanceName; // for interface block instance names
int mArraySize; // 0 if not an array
TLayoutBlockStorage mBlockStorage;
TLayoutMatrixPacking mMatrixPacking;
@@ -143,72 +197,171 @@
//
class TType
{
-public:
+ public:
POOL_ALLOCATOR_NEW_DELETE();
- TType() {}
- TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1) :
- type(t), precision(EbpUndefined), qualifier(EvqGlobal), layoutQualifier(TLayoutQualifier::create()), primarySize(ps), secondarySize(ss), array(false), arraySize(0),
- interfaceBlock(0), structure(0)
+ TType()
{
}
- TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, unsigned char ps = 1, unsigned char ss = 1, bool a = false) :
- type(t), precision(p), qualifier(q), layoutQualifier(TLayoutQualifier::create()), primarySize(ps), secondarySize(ss), array(a), arraySize(0),
- interfaceBlock(0), structure(0)
+ TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
+ : type(t), precision(EbpUndefined), qualifier(EvqGlobal),
+ layoutQualifier(TLayoutQualifier::create()),
+ primarySize(ps), secondarySize(ss), array(false), arraySize(0),
+ interfaceBlock(0), structure(0)
+ {
+ }
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary,
+ unsigned char ps = 1, unsigned char ss = 1, bool a = false)
+ : type(t), precision(p), qualifier(q),
+ layoutQualifier(TLayoutQualifier::create()),
+ primarySize(ps), secondarySize(ss), array(a), arraySize(0),
+ interfaceBlock(0), structure(0)
{
}
explicit TType(const TPublicType &p);
- TType(TStructure* userDef, TPrecision p = EbpUndefined) :
- type(EbtStruct), precision(p), qualifier(EvqTemporary), layoutQualifier(TLayoutQualifier::create()), primarySize(1), secondarySize(1), array(false), arraySize(0),
- interfaceBlock(0), structure(userDef)
+ TType(TStructure *userDef, TPrecision p = EbpUndefined)
+ : type(EbtStruct), precision(p), qualifier(EvqTemporary),
+ layoutQualifier(TLayoutQualifier::create()),
+ primarySize(1), secondarySize(1), array(false), arraySize(0),
+ interfaceBlock(0), structure(userDef)
{
}
- TType(TInterfaceBlock* interfaceBlockIn, TQualifier qualifierIn, TLayoutQualifier layoutQualifierIn, int arraySizeIn) :
- type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn), layoutQualifier(layoutQualifierIn), primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn),
- interfaceBlock(interfaceBlockIn), structure(0)
+ TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn, int arraySizeIn)
+ : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
+ layoutQualifier(layoutQualifierIn),
+ primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn),
+ interfaceBlock(interfaceBlockIn), structure(0)
{
}
- TBasicType getBasicType() const { return type; }
- void setBasicType(TBasicType t) { type = t; }
+ TBasicType getBasicType() const
+ {
+ return type;
+ }
+ void setBasicType(TBasicType t)
+ {
+ type = t;
+ }
- TPrecision getPrecision() const { return precision; }
- void setPrecision(TPrecision p) { precision = p; }
+ TPrecision getPrecision() const
+ {
+ return precision;
+ }
+ void setPrecision(TPrecision p)
+ {
+ precision = p;
+ }
- TQualifier getQualifier() const { return qualifier; }
- void setQualifier(TQualifier q) { qualifier = q; }
+ TQualifier getQualifier() const
+ {
+ return qualifier;
+ }
+ void setQualifier(TQualifier q)
+ {
+ qualifier = q;
+ }
- TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
- void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
+ TLayoutQualifier getLayoutQualifier() const
+ {
+ return layoutQualifier;
+ }
+ void setLayoutQualifier(TLayoutQualifier lq)
+ {
+ layoutQualifier = lq;
+ }
- int getNominalSize() const { return primarySize; }
- int getSecondarySize() const { return secondarySize; }
- int getCols() const { ASSERT(isMatrix()); return primarySize; }
- int getRows() const { ASSERT(isMatrix()); return secondarySize; }
- void setPrimarySize(unsigned char ps) { primarySize = ps; }
- void setSecondarySize(unsigned char ss) { secondarySize = ss; }
+ int getNominalSize() const
+ {
+ return primarySize;
+ }
+ int getSecondarySize() const
+ {
+ return secondarySize;
+ }
+ int getCols() const
+ {
+ ASSERT(isMatrix());
+ return primarySize;
+ }
+ int getRows() const
+ {
+ ASSERT(isMatrix());
+ return secondarySize;
+ }
+ void setPrimarySize(unsigned char ps)
+ {
+ primarySize = ps;
+ }
+ void setSecondarySize(unsigned char ss)
+ {
+ secondarySize = ss;
+ }
// Full size of single instance of type
size_t getObjectSize() const;
- bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
- bool isArray() const { return array ? true : false; }
- int getArraySize() const { return arraySize; }
- void setArraySize(int s) { array = true; arraySize = s; }
- void clearArrayness() { array = false; arraySize = 0; }
+ bool isMatrix() const
+ {
+ return primarySize > 1 && secondarySize > 1;
+ }
+ bool isArray() const
+ {
+ return array ? true : false;
+ }
+ int getArraySize() const
+ {
+ return arraySize;
+ }
+ void setArraySize(int s)
+ {
+ array = true;
+ arraySize = s;
+ }
+ void clearArrayness()
+ {
+ array = false;
+ arraySize = 0;
+ }
- TInterfaceBlock* getInterfaceBlock() const { return interfaceBlock; }
- void setInterfaceBlock(TInterfaceBlock* interfaceBlockIn) { interfaceBlock = interfaceBlockIn; }
- bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
+ TInterfaceBlock *getInterfaceBlock() const
+ {
+ return interfaceBlock;
+ }
+ void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
+ {
+ interfaceBlock = interfaceBlockIn;
+ }
+ bool isInterfaceBlock() const
+ {
+ return type == EbtInterfaceBlock;
+ }
- bool isVector() const { return primarySize > 1 && secondarySize == 1; }
- bool isScalar() const { return primarySize == 1 && secondarySize == 1 && !structure; }
- bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
+ bool isVector() const
+ {
+ return primarySize > 1 && secondarySize == 1;
+ }
+ bool isScalar() const
+ {
+ return primarySize == 1 && secondarySize == 1 && !structure;
+ }
+ bool isScalarInt() const
+ {
+ return isScalar() && (type == EbtInt || type == EbtUInt);
+ }
- TStructure* getStruct() const { return structure; }
- void setStruct(TStructure* s) { structure = s; }
+ TStructure *getStruct() const
+ {
+ return structure;
+ }
+ void setStruct(TStructure *s)
+ {
+ structure = s;
+ }
- const TString& getMangledName() {
- if (mangled.empty()) {
+ const TString &getMangledName()
+ {
+ if (mangled.empty())
+ {
mangled = buildMangledName();
mangled += ';';
}
@@ -220,37 +373,56 @@
// precision here.
bool equals(const TType &other) const;
- bool sameElementType(const TType& right) const {
- return type == right.type &&
- primarySize == right.primarySize &&
- secondarySize == right.secondarySize &&
- structure == right.structure;
+ bool sameElementType(const TType &right) const
+ {
+ return type == right.type &&
+ primarySize == right.primarySize &&
+ secondarySize == right.secondarySize &&
+ structure == right.structure;
}
- bool operator==(const TType& right) const {
- return type == right.type &&
- primarySize == right.primarySize &&
- secondarySize == right.secondarySize &&
- array == right.array && (!array || arraySize == right.arraySize) &&
- structure == right.structure;
+ bool operator==(const TType &right) const
+ {
+ return type == right.type &&
+ primarySize == right.primarySize &&
+ secondarySize == right.secondarySize &&
+ array == right.array && (!array || arraySize == right.arraySize) &&
+ structure == right.structure;
// don't check the qualifier, it's not ever what's being sought after
}
- bool operator!=(const TType& right) const {
+ bool operator!=(const TType &right) const
+ {
return !operator==(right);
}
- bool operator<(const TType& right) const {
- if (type != right.type) return type < right.type;
- if (primarySize != right.primarySize) return primarySize < right.primarySize;
- if (secondarySize != right.secondarySize) return secondarySize < right.secondarySize;
- if (array != right.array) return array < right.array;
- if (arraySize != right.arraySize) return arraySize < right.arraySize;
- if (structure != right.structure) return structure < right.structure;
+ bool operator<(const TType &right) const
+ {
+ if (type != right.type)
+ return type < right.type;
+ if (primarySize != right.primarySize)
+ return primarySize < right.primarySize;
+ if (secondarySize != right.secondarySize)
+ return secondarySize < right.secondarySize;
+ if (array != right.array)
+ return array < right.array;
+ if (arraySize != right.arraySize)
+ return arraySize < right.arraySize;
+ if (structure != right.structure)
+ return structure < right.structure;
return false;
}
- const char* getBasicString() const { return ::getBasicString(type); }
- const char* getPrecisionString() const { return ::getPrecisionString(precision); }
- const char* getQualifierString() const { return ::getQualifierString(qualifier); }
+ const char *getBasicString() const
+ {
+ return ::getBasicString(type);
+ }
+ const char *getPrecisionString() const
+ {
+ return ::getPrecisionString(precision);
+ }
+ const char *getQualifierString() const
+ {
+ return ::getQualifierString(qualifier);
+ }
TString getCompleteString() const;
// If this type is a struct, returns the deepest struct nesting of
@@ -265,15 +437,17 @@
// For type "nesting2", this method would return 2 -- the number
// of structures through which indirection must occur to reach the
// deepest field (nesting2.field1.position).
- int getDeepestStructNesting() const {
+ int getDeepestStructNesting() const
+ {
return structure ? structure->deepestNesting() : 0;
}
- bool isStructureContainingArrays() const {
+ bool isStructureContainingArrays() const
+ {
return structure ? structure->containsArrays() : false;
}
-protected:
+ protected:
TString buildMangledName() const;
size_t getStructSize() const;
void computeDeepestStructNesting();
@@ -288,10 +462,10 @@
int arraySize;
// 0 unless this is an interface block, or interface block member variable
- TInterfaceBlock* interfaceBlock;
+ TInterfaceBlock *interfaceBlock;
// 0 unless this is a struct
- TStructure* structure;
+ TStructure *structure;
mutable TString mangled;
};
@@ -315,10 +489,10 @@
unsigned char secondarySize; // rows of matrix
bool array;
int arraySize;
- TType* userDef;
+ TType *userDef;
TSourceLoc line;
- void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln)
+ void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln)
{
type = bt;
layoutQualifier = TLayoutQualifier::create();