Commit 194522f6 by alokp@chromium.org

Fixed all issues with variable and function argument declaration. Multiple…

Fixed all issues with variable and function argument declaration. Multiple declarations of arrays in the same line had bugs. Also sepearated out declaration of varaibles and function arguments which makes it easier to understand. Review URL: http://codereview.appspot.com/1142041 git-svn-id: https://angleproject.googlecode.com/svn/trunk@242 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent baeb8c5b
...@@ -38,13 +38,21 @@ TString getTypeName(const TType& type) ...@@ -38,13 +38,21 @@ TString getTypeName(const TType& type)
} }
return TString(out.c_str()); return TString(out.c_str());
} }
TString arrayBrackets(const TType& type)
{
ASSERT(type.isArray());
TInfoSinkBase out;
out << "[" << type.getArraySize() << "]";
return TString(out.c_str());
}
} // namespace } // namespace
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink) TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink)
: TIntermTraverser(true, true, true), : TIntermTraverser(true, true, true),
mObjSink(objSink), mObjSink(objSink),
mWriteFullSymbol(false), mScopeSequences(false),
mScopeSequences(false) mDeclaringVariables(false)
{ {
} }
...@@ -65,7 +73,70 @@ void TOutputGLSL::writeTriplet(Visit visit, const char* preStr, const char* inSt ...@@ -65,7 +73,70 @@ void TOutputGLSL::writeTriplet(Visit visit, const char* preStr, const char* inSt
} }
} }
const ConstantUnion* TOutputGLSL::writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion) void TOutputGLSL::writeVariableType(const TType& type)
{
TInfoSinkBase& out = objSink();
TQualifier qualifier = type.getQualifier();
// TODO(alokp): Validate qualifier for variable declarations.
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
out << type.getQualifierString() << " ";
// Declare the struct if we have not done so already.
if ((type.getBasicType() == EbtStruct) &&
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{
out << "struct " << type.getTypeName() << "{\n";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
{
const TType* fieldType = (*structure)[i].type;
ASSERT(fieldType != NULL);
out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
if (fieldType->isArray())
out << arrayBrackets(*fieldType);
out << ";\n";
}
out << "}";
mDeclaredStructs.insert(type.getTypeName());
}
else
{
out << getTypeName(type);
}
}
void TOutputGLSL::writeFunctionParameters(const TIntermSequence& args)
{
TInfoSinkBase& out = objSink();
for (TIntermSequence::const_iterator iter = args.begin();
iter != args.end(); ++iter)
{
const TIntermSymbol* arg = (*iter)->getAsSymbolNode();
ASSERT(arg != NULL);
const TType& type = arg->getType();
TQualifier qualifier = type.getQualifier();
// TODO(alokp): Validate qualifier for function arguments.
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
out << type.getQualifierString() << " ";
out << getTypeName(type);
const TString& name = arg->getSymbol();
if (!name.empty())
out << " " << name;
if (type.isArray())
out << arrayBrackets(type);
// Put a comma if this is not the last argument.
if (iter != --args.end())
out << ", ";
}
}
const ConstantUnion* TOutputGLSL::writeConstantUnion(const TType& type,
const ConstantUnion* pConstUnion)
{ {
TInfoSinkBase& out = objSink(); TInfoSinkBase& out = objSink();
...@@ -112,41 +183,10 @@ const ConstantUnion* TOutputGLSL::writeConstantUnion(const TType& type, const Co ...@@ -112,41 +183,10 @@ const ConstantUnion* TOutputGLSL::writeConstantUnion(const TType& type, const Co
void TOutputGLSL::visitSymbol(TIntermSymbol* node) void TOutputGLSL::visitSymbol(TIntermSymbol* node)
{ {
TInfoSinkBase& out = objSink(); TInfoSinkBase& out = objSink();
const TType& type = node->getType();
if (mWriteFullSymbol)
{
TQualifier qualifier = node->getQualifier();
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
out << node->getQualifierString() << " ";
// Declare the struct if we have not done so already.
if ((type.getBasicType() == EbtStruct) && (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{
out << "struct " << type.getTypeName() << "{\n";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
{
const TType* fieldType = (*structure)[i].type;
ASSERT(fieldType != NULL);
out << getTypeName(*fieldType) << " " << fieldType->getFieldName() << ";\n";
}
out << "} ";
mDeclaredStructs.insert(type.getTypeName());
}
else
{
out << getTypeName(type) << " ";
}
}
out << node->getSymbol(); out << node->getSymbol();
if (mWriteFullSymbol && node->getType().isArray()) if (mDeclaringVariables && node->getType().isArray())
{ out << arrayBrackets(node->getType());
out << "[" << node->getType().getArraySize() << "]";
}
} }
void TOutputGLSL::visitConstantUnion(TIntermConstantUnion* node) void TOutputGLSL::visitConstantUnion(TIntermConstantUnion* node)
...@@ -160,13 +200,15 @@ bool TOutputGLSL::visitBinary(Visit visit, TIntermBinary* node) ...@@ -160,13 +200,15 @@ bool TOutputGLSL::visitBinary(Visit visit, TIntermBinary* node)
TInfoSinkBase& out = objSink(); TInfoSinkBase& out = objSink();
switch (node->getOp()) switch (node->getOp())
{ {
case EOpAssign: writeTriplet(visit, NULL, " = ", NULL); break;
case EOpInitialize: case EOpInitialize:
if (visit == InVisit) { if (visit == InVisit)
{
out << " = "; out << " = ";
mWriteFullSymbol= false; // RHS of initialize is not being declared.
mDeclaringVariables = false;
} }
break; break;
case EOpAssign: writeTriplet(visit, NULL, " = ", NULL); break;
case EOpAddAssign: writeTriplet(visit, NULL, " += ", NULL); break; case EOpAddAssign: writeTriplet(visit, NULL, " += ", NULL); break;
case EOpSubAssign: writeTriplet(visit, NULL, " -= ", NULL); break; case EOpSubAssign: writeTriplet(visit, NULL, " -= ", NULL); break;
case EOpDivAssign: writeTriplet(visit, NULL, " /= ", NULL); break; case EOpDivAssign: writeTriplet(visit, NULL, " /= ", NULL); break;
...@@ -392,28 +434,22 @@ bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -392,28 +434,22 @@ bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node)
out << "}\n"; out << "}\n";
} }
break; break;
case EOpPrototype: case EOpPrototype: {
// Function declaration. // Function declaration.
if (visit == PreVisit) ASSERT(visit == PreVisit);
{ TString returnType = getTypeName(node->getType());
TString returnType = getTypeName(node->getType()); out << returnType << " " << node->getName();
out << returnType << " " << node->getName() << "(";
mWriteFullSymbol = true; out << "(";
} writeFunctionParameters(node->getSequence());
else if (visit == InVisit) out << ")";
{
// Called in between function arguments. visitChildren = false;
out << ", ";
}
else if (visit == PostVisit)
{
// Called after fucntion arguments.
out << ")";
mWriteFullSymbol = false;
}
break; break;
}
case EOpFunction: { case EOpFunction: {
// Function definition. // Function definition.
ASSERT(visit == PreVisit);
TString returnType = getTypeName(node->getType()); TString returnType = getTypeName(node->getType());
TString functionName = TFunction::unmangleName(node->getName()); TString functionName = TFunction::unmangleName(node->getName());
out << returnType << " " << functionName; out << returnType << " " << functionName;
...@@ -469,40 +505,36 @@ bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -469,40 +505,36 @@ bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node)
out << ")"; out << ")";
} }
break; break;
case EOpParameters: case EOpParameters: {
// Function parameters. // Function parameters.
if (visit == PreVisit) ASSERT(visit == PreVisit);
{ out << "(";
out << "("; writeFunctionParameters(node->getSequence());
mWriteFullSymbol = true; out << ")";
} visitChildren = false;
else if (visit == InVisit)
{
out << ", ";
}
else
{
out << ")";
mWriteFullSymbol = false;
}
break; break;
case EOpDeclaration: }
case EOpDeclaration: {
// Variable declaration. // Variable declaration.
if (visit == PreVisit) if (visit == PreVisit)
{ {
mWriteFullSymbol = true; const TIntermSequence& sequence = node->getSequence();
const TIntermTyped* variable = sequence.front()->getAsTyped();
writeVariableType(variable->getType());
out << " ";
mDeclaringVariables = true;
} }
else if (visit == InVisit) else if (visit == InVisit)
{ {
out << ", "; out << ", ";
mWriteFullSymbol = false; mDeclaringVariables = true;
} }
else else
{ {
mWriteFullSymbol = false; mDeclaringVariables = false;
} }
break; break;
}
case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break; case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break;
case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break; case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break;
case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break; case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break;
......
...@@ -18,6 +18,8 @@ public: ...@@ -18,6 +18,8 @@ public:
protected: protected:
TInfoSinkBase& objSink() { return mObjSink; } TInfoSinkBase& objSink() { return mObjSink; }
void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr); void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr);
void writeVariableType(const TType& type);
void writeFunctionParameters(const TIntermSequence& args);
const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion); const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
virtual void visitSymbol(TIntermSymbol* node); virtual void visitSymbol(TIntermSymbol* node);
...@@ -31,8 +33,8 @@ protected: ...@@ -31,8 +33,8 @@ protected:
private: private:
TInfoSinkBase& mObjSink; TInfoSinkBase& mObjSink;
bool mWriteFullSymbol;
bool mScopeSequences; bool mScopeSequences;
bool mDeclaringVariables;
// Structs are declared as the tree is traversed. This set contains all // Structs are declared as the tree is traversed. This set contains all
// the structs already declared. It is maintained so that a struct is // the structs already declared. It is maintained so that a struct is
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment