Commit 71550929 by alokp@chromium.org

Simplified TType class by carving out TStructure and TField.

R=kbr@chromium.org Review URL: https://codereview.appspot.com/9866043 git-svn-id: https://angleproject.googlecode.com/svn/trunk@2423 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 41fc482d
...@@ -1019,23 +1019,22 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -1019,23 +1019,22 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray) bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{ {
const TTypeList* fields = leftNodeType.getStruct(); const TFieldList& fields = leftNodeType.getStruct()->fields();
size_t structSize = fields->size(); size_t structSize = fields.size();
size_t index = 0; size_t index = 0;
for (size_t j = 0; j < structSize; j++) { for (size_t j = 0; j < structSize; j++) {
size_t size = (*fields)[j]->getObjectSize(); size_t size = fields[j]->type()->getObjectSize();
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
if ((*fields)[j]->getBasicType() == EbtStruct) { if (fields[j]->type()->getBasicType() == EbtStruct) {
if (!CompareStructure(*(*fields)[j], &rightUnionArray[index], &leftUnionArray[index])) if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
return false; return false;
} else { } else {
if (leftUnionArray[index] != rightUnionArray[index]) if (leftUnionArray[index] != rightUnionArray[index])
return false; return false;
index++; index++;
} }
} }
} }
return true; return true;
......
...@@ -79,25 +79,9 @@ void TOutputGLSLBase::writeVariableType(const TType& type) ...@@ -79,25 +79,9 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal))
out << type.getQualifierString() << " "; out << type.getQualifierString() << " ";
// Declare the struct if we have not done so already. // Declare the struct if we have not done so already.
if ((type.getBasicType() == EbtStruct) && if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct()))
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{ {
out << "struct " << hashName(type.getTypeName()) << "{\n"; declareStruct(type.getStruct());
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
{
const TType* fieldType = (*structure)[i];
ASSERT(fieldType != NULL);
if (writeVariablePrecision(fieldType->getPrecision()))
out << " ";
out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
if (fieldType->isArray())
out << arrayBrackets(*fieldType);
out << ";\n";
}
out << "}";
mDeclaredStructs.insert(type.getTypeName());
} }
else else
{ {
...@@ -138,15 +122,16 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type, ...@@ -138,15 +122,16 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
{ {
out << hashName(type.getTypeName()) << "("; const TStructure* structure = type.getStruct();
const TTypeList* structure = type.getStruct(); out << hashName(structure->name()) << "(";
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i) const TFieldList& fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{ {
const TType* fieldType = (*structure)[i]; const TType* fieldType = fields[i]->type();
ASSERT(fieldType != NULL); ASSERT(fieldType != NULL);
pConstUnion = writeConstantUnion(*fieldType, pConstUnion); pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
if (i != structure->size() - 1) out << ", "; if (i != fields.size() - 1) out << ", ";
} }
out << ")"; out << ")";
} }
...@@ -260,12 +245,18 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node) ...@@ -260,12 +245,18 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
if (visit == InVisit) 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 << "."; out << ".";
// TODO(alokp): ASSERT const TStructure* structure = node->getLeft()->getType().getStruct();
TString fieldName = node->getType().getFieldName(); const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
const TField* field = structure->fields()[index->getIConst(0)];
const TType& structType = node->getLeft()->getType(); TString fieldName = field->name();
if (!mSymbolTable.findBuiltIn(structType.getTypeName())) if (!mSymbolTable.findBuiltIn(structure->name()))
fieldName = hashName(fieldName); fieldName = hashName(fieldName);
out << fieldName; out << fieldName;
...@@ -596,7 +587,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -596,7 +587,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
{ {
const TType& type = node->getType(); const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct); ASSERT(type.getBasicType() == EbtStruct);
out << hashName(type.getTypeName()) << "("; out << hashName(type.getStruct()->name()) << "(";
} }
else if (visit == InVisit) else if (visit == InVisit)
{ {
...@@ -765,7 +756,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type) ...@@ -765,7 +756,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type)
else else
{ {
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
out << hashName(type.getTypeName()); out << hashName(type.getStruct()->name());
else else
out << type.getBasicString(); out << type.getBasicString();
} }
...@@ -798,3 +789,29 @@ TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name) ...@@ -798,3 +789,29 @@ TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
return name; return name;
return hashName(name); return hashName(name);
} }
bool TOutputGLSLBase::structDeclared(const TStructure* structure) const
{
return mDeclaredStructs.find(structure->name()) != mDeclaredStructs.end();
}
void TOutputGLSLBase::declareStruct(const TStructure* structure)
{
TInfoSinkBase& out = objSink();
out << "struct " << hashName(structure->name()) << "{\n";
const TFieldList& fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i)
{
const TField* field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(field->name());
if (field->type()->isArray())
out << arrayBrackets(*field->type());
out << ";\n";
}
out << "}";
mDeclaredStructs.insert(structure->name());
}
...@@ -52,6 +52,9 @@ protected: ...@@ -52,6 +52,9 @@ protected:
TString hashFunctionName(const TString& mangled_name); TString hashFunctionName(const TString& mangled_name);
private: private:
bool structDeclared(const TStructure* structure) const;
void declareStruct(const TStructure* structure);
TInfoSinkBase& mObjSink; TInfoSinkBase& mObjSink;
bool mDeclaringVariables; bool mDeclaringVariables;
......
...@@ -968,7 +968,10 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -968,7 +968,10 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
if (visit == InVisit) if (visit == InVisit)
{ {
out << "." + decorateField(node->getType().getFieldName(), node->getLeft()->getType()); const TStructure* structure = node->getLeft()->getType().getStruct();
const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
const TField* field = structure->fields()[index->getIConst(0)];
out << "." + decorateField(field->name(), node->getLeft()->getType());
return false; return false;
} }
...@@ -1037,18 +1040,18 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1037,18 +1040,18 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
out << "!("; out << "!(";
} }
const TTypeList *fields = node->getLeft()->getType().getStruct(); const TFieldList &fields = node->getLeft()->getType().getStruct()->fields();
for (size_t i = 0; i < fields->size(); i++) for (size_t i = 0; i < fields.size(); i++)
{ {
const TType *fieldType = (*fields)[i]; const TField *field = fields[i];
node->getLeft()->traverse(this); node->getLeft()->traverse(this);
out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()) + " == "; out << "." + decorateField(field->name(), node->getLeft()->getType()) + " == ";
node->getRight()->traverse(this); node->getRight()->traverse(this);
out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()); out << "." + decorateField(field->name(), node->getLeft()->getType());
if (i < fields->size() - 1) if (i < fields.size() - 1)
{ {
out << " && "; out << " && ";
} }
...@@ -1299,7 +1302,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1299,7 +1302,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (variable->getType().getStruct()) if (variable->getType().getStruct())
{ {
addConstructor(variable->getType(), scopedStruct(variable->getType().getTypeName()), NULL); addConstructor(variable->getType(), scopedStruct(variable->getType().getStruct()->name()), NULL);
} }
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
...@@ -1417,7 +1420,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1417,7 +1420,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (symbol->getType().getStruct()) if (symbol->getType().getStruct())
{ {
addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL); addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL);
} }
out << argumentString(symbol); out << argumentString(symbol);
...@@ -1666,8 +1669,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1666,8 +1669,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
outputTriplet(visit, "mat4(", ", ", ")"); outputTriplet(visit, "mat4(", ", ", ")");
break; break;
case EOpConstructStruct: case EOpConstructStruct:
addConstructor(node->getType(), scopedStruct(node->getType().getTypeName()), &node->getSequence()); addConstructor(node->getType(), scopedStruct(node->getType().getStruct()->name()), &node->getSequence());
outputTriplet(visit, structLookup(node->getType().getTypeName()) + "_ctor(", ", ", ")"); outputTriplet(visit, structLookup(node->getType().getStruct()->name()) + "_ctor(", ", ", ")");
break; break;
case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break;
...@@ -2229,22 +2232,23 @@ TString OutputHLSL::typeString(const TType &type) ...@@ -2229,22 +2232,23 @@ TString OutputHLSL::typeString(const TType &type)
{ {
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
{ {
if (type.getTypeName() != "") const TString& typeName = type.getStruct()->name();
if (typeName != "")
{ {
return structLookup(type.getTypeName()); return structLookup(typeName);
} }
else // Nameless structure, define in place else // Nameless structure, define in place
{ {
const TTypeList &fields = *type.getStruct(); const TFieldList &fields = type.getStruct()->fields();
TString string = "struct\n" TString string = "struct\n"
"{\n"; "{\n";
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
const TType &field = *fields[i]; const TField *field = fields[i];
string += " " + typeString(field) + " " + decorate(field.getFieldName()) + arrayString(field) + ";\n"; string += " " + typeString(*field->type()) + " " + decorate(field->name()) + arrayString(*field->type()) + ";\n";
} }
string += "} "; string += "} ";
...@@ -2364,13 +2368,13 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ...@@ -2364,13 +2368,13 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
structure += "struct " + decorate(name) + "\n" structure += "struct " + decorate(name) + "\n"
"{\n"; "{\n";
const TTypeList &fields = *type.getStruct(); const TFieldList &fields = type.getStruct()->fields();
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
const TType &field = *fields[i]; const TField *field = fields[i];
structure += " " + typeString(field) + " " + decorateField(field.getFieldName(), type) + arrayString(field) + ";\n"; structure += " " + typeString(*field->type()) + " " + decorateField(field->name(), type) + arrayString(*field->type()) + ";\n";
} }
structure += "};\n"; structure += "};\n";
...@@ -2382,7 +2386,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ...@@ -2382,7 +2386,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
for (unsigned int i = 0; i < fields.size(); i++) for (unsigned int i = 0; i < fields.size(); i++)
{ {
ctorParameters.push_back(*fields[i]); ctorParameters.push_back(*fields[i]->type());
} }
} }
else if (parameters) else if (parameters)
...@@ -2555,17 +2559,17 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con ...@@ -2555,17 +2559,17 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
{ {
out << structLookup(type.getTypeName()) + "_ctor("; out << structLookup(type.getStruct()->name()) + "_ctor(";
const TTypeList *structure = type.getStruct(); const TFieldList &fields = type.getStruct()->fields();
for (size_t i = 0; i < structure->size(); i++) for (size_t i = 0; i < fields.size(); i++)
{ {
const TType *fieldType = (*structure)[i]; const TType *fieldType = fields[i]->type();
constUnion = writeConstantUnion(*fieldType, constUnion); constUnion = writeConstantUnion(*fieldType, constUnion);
if (i != structure->size() - 1) if (i != fields.size() - 1)
{ {
out << ", "; out << ", ";
} }
...@@ -2676,7 +2680,7 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type) ...@@ -2676,7 +2680,7 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type)
TString OutputHLSL::decorateField(const TString &string, const TType &structure) TString OutputHLSL::decorateField(const TString &string, const TType &structure)
{ {
if (structure.getTypeName().compare(0, 3, "gl_") != 0) if (structure.getStruct()->name().compare(0, 3, "gl_") != 0)
{ {
return decorate(string); return decorate(string);
} }
......
...@@ -535,7 +535,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n ...@@ -535,7 +535,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n
return true; return true;
} }
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) { if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
return true; return true;
} }
...@@ -658,9 +658,9 @@ bool TParseContext::containsSampler(TType& type) ...@@ -658,9 +658,9 @@ bool TParseContext::containsSampler(TType& type)
return true; return true;
if (type.getBasicType() == EbtStruct) { if (type.getBasicType() == EbtStruct) {
TTypeList& structure = *type.getStruct(); const TFieldList& fields = type.getStruct()->fields();
for (unsigned int i = 0; i < structure.size(); ++i) { for (unsigned int i = 0; i < fields.size(); ++i) {
if (containsSampler(*structure[i])) if (containsSampler(*fields[i]->type()))
return true; return true;
} }
} }
...@@ -1063,9 +1063,9 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type ...@@ -1063,9 +1063,9 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
TIntermAggregate* aggrNode = node->getAsAggregate(); TIntermAggregate* aggrNode = node->getAsAggregate();
TTypeList::const_iterator memberTypes; TFieldList::const_iterator memberFields;
if (op == EOpConstructStruct) if (op == EOpConstructStruct)
memberTypes = type->getStruct()->begin(); memberFields = type->getStruct()->fields().begin();
TType elementType = *type; TType elementType = *type;
if (type->isArray()) if (type->isArray())
...@@ -1087,7 +1087,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type ...@@ -1087,7 +1087,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
if (type->isArray()) if (type->isArray())
newNode = constructStruct(node, &elementType, 1, node->getLine(), false); newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
else if (op == EOpConstructStruct) else if (op == EOpConstructStruct)
newNode = constructStruct(node, *memberTypes, 1, node->getLine(), false); newNode = constructStruct(node, (*memberFields)->type(), 1, node->getLine(), false);
else else
newNode = constructBuiltIn(type, op, node, node->getLine(), false); newNode = constructBuiltIn(type, op, node, node->getLine(), false);
...@@ -1118,7 +1118,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type ...@@ -1118,7 +1118,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
if (type->isArray()) if (type->isArray())
newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true); newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
else if (op == EOpConstructStruct) else if (op == EOpConstructStruct)
newNode = constructStruct(*p, memberTypes[paramCount], paramCount+1, node->getLine(), true); newNode = constructStruct(*p, memberFields[paramCount]->type(), paramCount+1, node->getLine(), true);
else else
newNode = constructBuiltIn(type, op, *p, node->getLine(), true); newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
...@@ -1370,14 +1370,14 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, co ...@@ -1370,14 +1370,14 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, co
// //
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, const TSourceLoc& line) TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, const TSourceLoc& line)
{ {
const TTypeList* fields = node->getType().getStruct(); const TFieldList& fields = node->getType().getStruct()->fields();
size_t instanceSize = 0; size_t instanceSize = 0;
for (size_t index = 0; index < fields->size(); ++index) { for (size_t index = 0; index < fields.size(); ++index) {
if ((*fields)[index]->getFieldName() == identifier) { if (fields[index]->name() == identifier) {
break; break;
} else { } else {
instanceSize += (*fields)[index]->getObjectSize(); instanceSize += fields[index]->type()->getObjectSize();
} }
} }
...@@ -1423,21 +1423,21 @@ const int kWebGLMaxStructNesting = 4; ...@@ -1423,21 +1423,21 @@ const int kWebGLMaxStructNesting = 4;
} // namespace } // namespace
bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType) bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field)
{ {
if (!isWebGLBasedSpec(shaderSpec)) { if (!isWebGLBasedSpec(shaderSpec)) {
return false; return false;
} }
if (fieldType.getBasicType() != EbtStruct) { if (field.type()->getBasicType() != EbtStruct) {
return false; return false;
} }
// We're already inside a structure definition at this point, so add // We're already inside a structure definition at this point, so add
// one to the field's struct nesting. // one to the field's struct nesting.
if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) { if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "Reference of struct type " << fieldType.getTypeName() extraInfoStream << "Reference of struct type " << field.name()
<< " exceeds maximum struct nesting of " << kWebGLMaxStructNesting; << " exceeds maximum struct nesting of " << kWebGLMaxStructNesting;
std::string extraInfo = extraInfoStream.str(); std::string extraInfo = extraInfoStream.str();
error(line, "", "", extraInfo.c_str()); error(line, "", "", extraInfo.c_str());
......
...@@ -124,7 +124,7 @@ struct TParseContext { ...@@ -124,7 +124,7 @@ struct TParseContext {
bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier); bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier);
void exitStructDeclaration(); void exitStructDeclaration();
bool structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType); bool structNestingErrorCheck(const TSourceLoc& line, const TField& field);
}; };
int PaParseStrings(size_t count, const char* const string[], const int length[], int PaParseStrings(size_t count, const char* const string[], const int length[],
......
...@@ -20,44 +20,31 @@ ...@@ -20,44 +20,31 @@
#include <climits> #include <climits>
TType::TType(const TPublicType &p) : TType::TType(const TPublicType &p) :
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0)
structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
{ {
if (p.userDef) { if (p.userDef)
structure = p.userDef->getStruct(); structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
computeDeepestStructNesting();
}
} }
// //
// Recursively generate mangled names. // Recursively generate mangled names.
// //
void TType::buildMangledName(TString& mangledName) TString TType::buildMangledName() const
{ {
TString mangledName;
if (isMatrix()) if (isMatrix())
mangledName += 'm'; mangledName += 'm';
else if (isVector()) else if (isVector())
mangledName += 'v'; mangledName += 'v';
switch (type) { switch (type) {
case EbtFloat: mangledName += 'f'; break; case EbtFloat: mangledName += 'f'; break;
case EbtInt: mangledName += 'i'; break; case EbtInt: mangledName += 'i'; break;
case EbtBool: mangledName += 'b'; break; case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break; case EbtSampler2D: mangledName += "s2"; break;
case EbtSamplerCube: mangledName += "sC"; break; case EbtSamplerCube: mangledName += "sC"; break;
case EbtStruct: case EbtStruct: mangledName += structure->mangledName(); break;
mangledName += "struct-"; default: break;
if (typeName)
mangledName += *typeName;
{// support MSVC++6.0
for (unsigned int i = 0; i < structure->size(); ++i) {
mangledName += '-';
(*structure)[i]->buildMangledName(mangledName);
}
}
default:
break;
} }
mangledName += static_cast<char>('0' + getNominalSize()); mangledName += static_cast<char>('0' + getNominalSize());
...@@ -68,6 +55,7 @@ void TType::buildMangledName(TString& mangledName) ...@@ -68,6 +55,7 @@ void TType::buildMangledName(TString& mangledName)
mangledName += buf; mangledName += buf;
mangledName += ']'; mangledName += ']';
} }
return mangledName;
} }
size_t TType::getObjectSize() const size_t TType::getObjectSize() const
...@@ -75,7 +63,7 @@ size_t TType::getObjectSize() const ...@@ -75,7 +63,7 @@ size_t TType::getObjectSize() const
size_t totalSize = 0; size_t totalSize = 0;
if (getBasicType() == EbtStruct) if (getBasicType() == EbtStruct)
totalSize = getStructSize(); totalSize = structure->objectSize();
else if (matrix) else if (matrix)
totalSize = size * size; totalSize = size * size;
else else
...@@ -92,57 +80,47 @@ size_t TType::getObjectSize() const ...@@ -92,57 +80,47 @@ size_t TType::getObjectSize() const
return totalSize; return totalSize;
} }
size_t TType::getStructSize() const bool TStructure::containsArrays() const
{ {
if (!getStruct()) { for (size_t i = 0; i < mFields->size(); ++i) {
assert(false && "Not a struct"); const TType* fieldType = (*mFields)[i]->type();
return 0; if (fieldType->isArray() || fieldType->isStructureContainingArrays())
} return true;
if (structureSize == 0) {
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++) {
size_t fieldSize = (*tl)->getObjectSize();
if (fieldSize > INT_MAX - structureSize)
structureSize = INT_MAX;
else
structureSize += fieldSize;
}
} }
return false;
return structureSize;
} }
void TType::computeDeepestStructNesting() TString TStructure::buildMangledName() const
{ {
if (!getStruct()) { TString mangledName("struct-");
return; mangledName += *mName;
} for (size_t i = 0; i < mFields->size(); ++i) {
mangledName += '-';
int maxNesting = 0; mangledName += (*mFields)[i]->type()->getMangledName();
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
maxNesting = std::max(maxNesting, (*tl)->getDeepestStructNesting());
} }
return mangledName;
deepestStructNesting = 1 + maxNesting;
} }
bool TType::isStructureContainingArrays() const size_t TStructure::calculateObjectSize() const
{ {
if (!structure) size_t size = 0;
{ for (size_t i = 0; i < mFields->size(); ++i) {
return false; size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
if (fieldSize > INT_MAX - size)
size = INT_MAX;
else
size += fieldSize;
} }
return size;
}
for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++) int TStructure::calculateDeepestNesting() const
{ {
if ((*member)->isArray() || int maxNesting = 0;
(*member)->isStructureContainingArrays()) for (size_t i = 0; i < mFields->size(); ++i) {
{ maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
return true;
}
} }
return 1 + maxNesting;
return false;
} }
// //
......
...@@ -7,21 +7,86 @@ ...@@ -7,21 +7,86 @@
#ifndef _TYPES_INCLUDED #ifndef _TYPES_INCLUDED
#define _TYPES_INCLUDED #define _TYPES_INCLUDED
#include "common/angleutils.h"
#include "compiler/BaseTypes.h" #include "compiler/BaseTypes.h"
#include "compiler/Common.h" #include "compiler/Common.h"
#include "compiler/debug.h" #include "compiler/debug.h"
class TType;
struct TPublicType; struct TPublicType;
class TType;
typedef TVector<TType*> TTypeList; class TField
{
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator);
TField(TType* type, TString* name) : mType(type), mName(name) {}
// TODO(alokp): We should only return const type.
// Fix it by tweaking grammar.
TType* type() { return mType; }
const TType* type() const { return mType; }
const TString& name() const { return *mName; }
private:
DISALLOW_COPY_AND_ASSIGN(TField);
TType* mType;
TString* mName;
};
inline TTypeList* NewPoolTTypeList() typedef TVector<TField*> TFieldList;
inline TFieldList* NewPoolTFieldList()
{ {
void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList)); void* memory = GlobalPoolAllocator.allocate(sizeof(TFieldList));
return new(memory) TTypeList; return new(memory) TFieldList;
} }
class TStructure
{
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator);
TStructure(TString* name, TFieldList* fields)
: mName(name),
mFields(fields),
mObjectSize(0),
mDeepestNesting(0) {
}
const TString& name() const { return *mName; }
const TFieldList& fields() const { return *mFields; }
const TString& mangledName() const {
if (mMangledName.empty())
mMangledName = buildMangledName();
return mMangledName;
}
size_t objectSize() const {
if (mObjectSize == 0)
mObjectSize = calculateObjectSize();
return mObjectSize;
};
int deepestNesting() const {
if (mDeepestNesting == 0)
mDeepestNesting = calculateDeepestNesting();
return mDeepestNesting;
}
bool containsArrays() const;
private:
DISALLOW_COPY_AND_ASSIGN(TStructure);
TString buildMangledName() const;
size_t calculateObjectSize() const;
int calculateDeepestNesting() const;
TString* mName;
TFieldList* mFields;
mutable TString mMangledName;
mutable size_t mObjectSize;
mutable int mDeepestNesting;
};
// //
// Base class for things that have a type. // Base class for things that have a type.
// //
...@@ -31,16 +96,13 @@ public: ...@@ -31,16 +96,13 @@ public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TType() {} TType() {}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) : TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0)
structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
{ {
} }
explicit TType(const TPublicType &p); explicit TType(const TPublicType &p);
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) : TType(TStructure* userDef, TPrecision p = EbpUndefined) :
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
{ {
typeName = NewPoolTString(n.c_str());
} }
TBasicType getBasicType() const { return type; } TBasicType getBasicType() const { return type; }
...@@ -69,38 +131,15 @@ public: ...@@ -69,38 +131,15 @@ public:
bool isVector() const { return size > 1 && !matrix; } bool isVector() const { return size > 1 && !matrix; }
bool isScalar() const { return size == 1 && !matrix && !structure; } bool isScalar() const { return size == 1 && !matrix && !structure; }
TTypeList* getStruct() const { return structure; } TStructure* getStruct() const { return structure; }
void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); } void setStruct(TStructure* s) { structure = s; }
const TString& getTypeName() const
{
assert(typeName);
return *typeName;
}
void setTypeName(const TString& n)
{
typeName = NewPoolTString(n.c_str());
}
bool isField() const { return fieldName != 0; }
const TString& getFieldName() const
{
assert(fieldName);
return *fieldName;
}
void setFieldName(const TString& n)
{
fieldName = NewPoolTString(n.c_str());
}
TString& getMangledName() { const TString& getMangledName() const {
if (!mangled) { if (mangled.empty()) {
mangled = NewPoolTString(""); mangled = buildMangledName();
buildMangledName(*mangled); mangled += ';';
*mangled += ';' ;
} }
return mangled;
return *mangled;
} }
bool sameElementType(const TType& right) const { bool sameElementType(const TType& right) const {
...@@ -148,14 +187,16 @@ public: ...@@ -148,14 +187,16 @@ public:
// For type "nesting2", this method would return 2 -- the number // For type "nesting2", this method would return 2 -- the number
// of structures through which indirection must occur to reach the // of structures through which indirection must occur to reach the
// deepest field (nesting2.field1.position). // deepest field (nesting2.field1.position).
int getDeepestStructNesting() const { return deepestStructNesting; } int getDeepestStructNesting() const {
return structure ? structure->deepestNesting() : 0;
}
bool isStructureContainingArrays() const; bool isStructureContainingArrays() const {
return structure ? structure->containsArrays() : false;
}
private: private:
void buildMangledName(TString&); TString buildMangledName() const;
size_t getStructSize() const;
void computeDeepestStructNesting();
TBasicType type : 6; TBasicType type : 6;
TPrecision precision; TPrecision precision;
...@@ -165,13 +206,9 @@ private: ...@@ -165,13 +206,9 @@ private:
unsigned int array : 1; unsigned int array : 1;
int arraySize; int arraySize;
TTypeList* structure; // 0 unless this is a struct TStructure* structure; // 0 unless this is a struct
mutable size_t structureSize;
int deepestStructNesting;
TString *fieldName; // for structure field names mutable TString mangled;
TString *mangled;
TString *typeName; // for structure field type name
}; };
// //
......
...@@ -131,12 +131,13 @@ void getUserDefinedVariableInfo(const TType& type, ...@@ -131,12 +131,13 @@ void getUserDefinedVariableInfo(const TType& type,
{ {
ASSERT(type.getBasicType() == EbtStruct); ASSERT(type.getBasicType() == EbtStruct);
const TTypeList* structure = type.getStruct(); const TFieldList& fields = type.getStruct()->fields();
for (size_t i = 0; i < structure->size(); ++i) { for (size_t i = 0; i < fields.size(); ++i) {
const TType* fieldType = (*structure)[i]; const TType& fieldType = *(fields[i]->type());
getVariableInfo(*fieldType, const TString& fieldName = fields[i]->name();
name + "." + fieldType->getFieldName(), getVariableInfo(fieldType,
mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction), name + "." + fieldName,
mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
infoList, infoList,
hashFunction); hashFunction);
} }
......
...@@ -77,8 +77,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -77,8 +77,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TQualifier qualifier; TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TType* field; TField* field;
TTypeList* structure; TFieldList* fieldList;
}; };
} interm; } interm;
} }
...@@ -166,7 +166,7 @@ static void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) ...@@ -166,7 +166,7 @@ static void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason)
%type <interm.type> type_specifier_no_prec type_specifier_nonarray %type <interm.type> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier %type <interm.type> struct_specifier
%type <interm.field> struct_declarator %type <interm.field> struct_declarator
%type <interm> struct_declarator_list struct_declaration struct_declaration_list %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier %type <interm.function> function_header function_declarator function_identifier
%type <interm.function> function_header_with_parameters function_call_header %type <interm.function> function_header_with_parameters function_call_header
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
...@@ -317,7 +317,7 @@ postfix_expression ...@@ -317,7 +317,7 @@ postfix_expression
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), @2); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), @2);
} else if ($1->isArray()) { } else if ($1->isArray()) {
if ($1->getType().getStruct()) if ($1->getType().getStruct())
$$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName())); $$->setType(TType($1->getType().getStruct()));
else else
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix())); $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
...@@ -391,44 +391,38 @@ postfix_expression ...@@ -391,44 +391,38 @@ postfix_expression
} }
} else if ($1->getBasicType() == EbtStruct) { } else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false; bool fieldFound = false;
const TTypeList* fields = $1->getType().getStruct(); const TFieldList& fields = $1->getType().getStruct()->fields();
if (fields == 0) { unsigned int i;
context->error(@2, "structure has no fields", "Internal Error"); for (i = 0; i < fields.size(); ++i) {
context->recover(); if (fields[i]->name() == *$3.string) {
$$ = $1; fieldFound = true;
} else { break;
unsigned int i;
for (i = 0; i < fields->size(); ++i) {
if ((*fields)[i]->getFieldName() == *$3.string) {
fieldFound = true;
break;
}
} }
if (fieldFound) { }
if ($1->getType().getQualifier() == EvqConst) { if (fieldFound) {
$$ = context->addConstStruct(*$3.string, $1, @2); if ($1->getType().getQualifier() == EvqConst) {
if ($$ == 0) { $$ = context->addConstStruct(*$3.string, $1, @2);
context->recover(); if ($$ == 0) {
$$ = $1; context->recover();
} $$ = $1;
else { }
$$->setType(*(*fields)[i]); else {
// change the qualifier of the return type, not of the structure field $$->setType(*fields[i]->type());
// as the structure definition is shared between various structures. // change the qualifier of the return type, not of the structure field
$$->getTypePointer()->setQualifier(EvqConst); // as the structure definition is shared between various structures.
} $$->getTypePointer()->setQualifier(EvqConst);
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], @3);
$$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2);
$$->setType(*(*fields)[i]);
} }
} else { } else {
context->error(@2, " no such field in structure", $3.string->c_str()); ConstantUnion *unionArray = new ConstantUnion[1];
context->recover(); unionArray->setIConst(i);
$$ = $1; TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *fields[i]->type(), @3);
$$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2);
$$->setType(*fields[i]->type());
} }
} else {
context->error(@2, " no such field in structure", $3.string->c_str());
context->recover();
$$ = $1;
} }
} else { } else {
context->error(@2, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str()); context->error(@2, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
...@@ -1625,7 +1619,7 @@ struct_specifier ...@@ -1625,7 +1619,7 @@ struct_specifier
if (context->reservedErrorCheck(@2, *$2.string)) if (context->reservedErrorCheck(@2, *$2.string))
context->recover(); context->recover();
TType* structure = new TType($5.structure, *$2.string); TType* structure = new TType(new TStructure($2.string, $5));
TVariable* userTypeDef = new TVariable($2.string, *structure, true); TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! context->symbolTable.insert(*userTypeDef)) { if (! context->symbolTable.insert(*userTypeDef)) {
context->error(@2, "redefinition", $2.string->c_str(), "struct"); context->error(@2, "redefinition", $2.string->c_str(), "struct");
...@@ -1636,7 +1630,7 @@ struct_specifier ...@@ -1636,7 +1630,7 @@ struct_specifier
context->exitStructDeclaration(); context->exitStructDeclaration();
} }
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4.structure, TString("")); TType* structure = new TType(new TStructure(NewPoolTString(""), $4));
$$.setBasic(EbtStruct, EvqTemporary, @1); $$.setBasic(EbtStruct, EvqTemporary, @1);
$$.userDef = structure; $$.userDef = structure;
context->exitStructDeclaration(); context->exitStructDeclaration();
...@@ -1649,15 +1643,15 @@ struct_declaration_list ...@@ -1649,15 +1643,15 @@ struct_declaration_list
} }
| struct_declaration_list struct_declaration { | struct_declaration_list struct_declaration {
$$ = $1; $$ = $1;
for (size_t i = 0; i < $2.structure->size(); ++i) { for (size_t i = 0; i < $2->size(); ++i) {
TType* field = (*$2.structure)[i]; TField* field = (*$2)[i];
for (size_t j = 0; j < $$.structure->size(); ++j) { for (size_t j = 0; j < $$->size(); ++j) {
if ((*$$.structure)[j]->getFieldName() == field->getFieldName()) { if ((*$$)[j]->name() == field->name()) {
context->error(@2, "duplicate field name in structure:", "struct", field->getFieldName().c_str()); context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
context->recover(); context->recover();
} }
} }
$$.structure->push_back(field); $$->push_back(field);
} }
} }
; ;
...@@ -1666,14 +1660,14 @@ struct_declaration ...@@ -1666,14 +1660,14 @@ struct_declaration
: type_specifier struct_declarator_list SEMICOLON { : type_specifier struct_declarator_list SEMICOLON {
$$ = $2; $$ = $2;
if (context->voidErrorCheck(@1, (*$2.structure)[0]->getFieldName(), $1)) { if (context->voidErrorCheck(@1, (*$2)[0]->name(), $1)) {
context->recover(); context->recover();
} }
for (unsigned int i = 0; i < $$.structure->size(); ++i) { for (unsigned int i = 0; i < $$->size(); ++i) {
// //
// Careful not to replace already known aspects of type, like array-ness // Careful not to replace already known aspects of type, like array-ness
// //
TType* type = (*$$.structure)[i]; TType* type = (*$$)[i]->type();
type->setBasicType($1.type); type->setBasicType($1.type);
type->setNominalSize($1.size); type->setNominalSize($1.size);
type->setMatrix($1.matrix); type->setMatrix($1.matrix);
...@@ -1686,25 +1680,22 @@ struct_declaration ...@@ -1686,25 +1680,22 @@ struct_declaration
} }
if ($1.array) if ($1.array)
type->setArraySize($1.arraySize); type->setArraySize($1.arraySize);
if ($1.userDef) { if ($1.userDef)
type->setStruct($1.userDef->getStruct()); type->setStruct($1.userDef->getStruct());
type->setTypeName($1.userDef->getTypeName());
}
if (context->structNestingErrorCheck(@1, *type)) { if (context->structNestingErrorCheck(@1, *(*$$)[i]))
context->recover(); context->recover();
}
} }
} }
; ;
struct_declarator_list struct_declarator_list
: struct_declarator { : struct_declarator {
$$.structure = NewPoolTTypeList(); $$ = NewPoolTFieldList();
$$.structure->push_back($1); $$->push_back($1);
} }
| struct_declarator_list COMMA struct_declarator { | struct_declarator_list COMMA struct_declarator {
$$.structure->push_back($3); $$->push_back($3);
} }
; ;
...@@ -1713,20 +1704,20 @@ struct_declarator ...@@ -1713,20 +1704,20 @@ struct_declarator
if (context->reservedErrorCheck(@1, *$1.string)) if (context->reservedErrorCheck(@1, *$1.string))
context->recover(); context->recover();
$$ = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
$$->setFieldName(*$1.string); $$ = new TField(type, $1.string);
} }
| identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck(@1, *$1.string)) if (context->reservedErrorCheck(@1, *$1.string))
context->recover(); context->recover();
$$ = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
$$->setFieldName(*$1.string); int size = 0;
if (context->arraySizeErrorCheck(@3, $3, size))
int size;
if (context->arraySizeErrorCheck(@2, $3, size))
context->recover(); context->recover();
$$->setArraySize(size); type->setArraySize(size);
$$ = new TField(type, $1.string);
} }
; ;
......
...@@ -178,8 +178,8 @@ typedef union YYSTYPE ...@@ -178,8 +178,8 @@ typedef union YYSTYPE
TQualifier qualifier; TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TType* field; TField* field;
TTypeList* structure; TFieldList* fieldList;
}; };
} interm; } interm;
......
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