Commit 0600ff1a by Jamie Madill Committed by Shannon Woods

Simplified TType class by carving out TStructure and TField.

TRAC #23369 Signed-off-by: Nicolas Capens Signed-off-by: Geoff Lang Merged-by: Jamie Madill Authored-by: alokp@chromium.org 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 95c66250
......@@ -388,19 +388,17 @@ void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltI
//
// Depth range in window coordinates
//
TTypeList *members = NewPoolTTypeList();
TType *near = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
TType *far = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
TType *diff = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
near->setFieldName("near");
far->setFieldName("far");
diff->setFieldName("diff");
members->push_back(near);
members->push_back(far);
members->push_back(diff);
TVariable *depthRangeParameters = new TVariable(NewPoolTString("gl_DepthRangeParameters"), TType(members, "gl_DepthRangeParameters"), true);
TFieldList *fields = NewPoolTFieldList();
TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"));
TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"));
TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"));
fields->push_back(near);
fields->push_back(far);
fields->push_back(diff);
TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
symbolTable.insert(*depthRangeParameters);
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(members, "gl_DepthRangeParameters"));
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
depthRange->setQualifier(EvqUniform);
symbolTable.insert(*depthRange);
......
......@@ -1019,23 +1019,22 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
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;
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++) {
if ((*fields)[j]->getBasicType() == EbtStruct) {
if (!CompareStructure(*(*fields)[j], &rightUnionArray[index], &leftUnionArray[index]))
if (fields[j]->type()->getBasicType() == EbtStruct) {
if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
return false;
} else {
if (leftUnionArray[index] != rightUnionArray[index])
return false;
index++;
}
}
}
return true;
......
......@@ -79,25 +79,9 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
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()))
if ((type.getBasicType() == EbtStruct) && !structDeclared(type.getStruct()))
{
out << "struct " << hashName(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];
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());
declareStruct(type.getStruct());
}
else
{
......@@ -138,15 +122,16 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
if (type.getBasicType() == EbtStruct)
{
out << hashName(type.getTypeName()) << "(";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
const TStructure* structure = type.getStruct();
out << hashName(structure->name()) << "(";
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);
pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
if (i != structure->size() - 1) out << ", ";
if (i != fields.size() - 1) out << ", ";
}
out << ")";
}
......@@ -260,12 +245,18 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
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 << ".";
// TODO(alokp): ASSERT
TString fieldName = node->getType().getFieldName();
const TStructure* structure = node->getLeft()->getType().getStruct();
const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion();
const TField* field = structure->fields()[index->getIConst(0)];
const TType& structType = node->getLeft()->getType();
if (!mSymbolTable.findBuiltIn(structType.getTypeName()))
TString fieldName = field->name();
if (!mSymbolTable.findBuiltIn(structure->name()))
fieldName = hashName(fieldName);
out << fieldName;
......@@ -596,7 +587,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
{
const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct);
out << hashName(type.getTypeName()) << "(";
out << hashName(type.getStruct()->name()) << "(";
}
else if (visit == InVisit)
{
......@@ -765,7 +756,7 @@ TString TOutputGLSLBase::getTypeName(const TType& type)
else
{
if (type.getBasicType() == EbtStruct)
out << hashName(type.getTypeName());
out << hashName(type.getStruct()->name());
else
out << type.getBasicString();
}
......@@ -798,3 +789,29 @@ TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
return 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:
TString hashFunctionName(const TString& mangled_name);
private:
bool structDeclared(const TStructure* structure) const;
void declareStruct(const TStructure* structure);
TInfoSinkBase& mObjSink;
bool mDeclaringVariables;
......
......@@ -1296,7 +1296,10 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
case EOpIndexDirectStruct:
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;
}
......@@ -1365,18 +1368,18 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
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);
out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()) + " == ";
out << "." + decorateField(field->name(), node->getLeft()->getType()) + " == ";
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 << " && ";
}
......@@ -1626,7 +1629,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
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
......@@ -1753,7 +1756,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (symbol->getType().getStruct())
{
addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL);
addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL);
}
out << argumentString(symbol);
......@@ -2014,8 +2017,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
outputTriplet(visit, "mat4(", ", ", ")");
break;
case EOpConstructStruct:
addConstructor(node->getType(), scopedStruct(node->getType().getTypeName()), &node->getSequence());
outputTriplet(visit, structLookup(node->getType().getTypeName()) + "_ctor(", ", ", ")");
addConstructor(node->getType(), scopedStruct(node->getType().getStruct()->name()), &node->getSequence());
outputTriplet(visit, structLookup(node->getType().getStruct()->name()) + "_ctor(", ", ", ")");
break;
case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break;
......@@ -2586,22 +2589,23 @@ TString OutputHLSL::typeString(const TType &type)
{
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
{
const TTypeList &fields = *type.getStruct();
const TFieldList &fields = type.getStruct()->fields();
TString string = "struct\n"
"{\n";
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 += "} ";
......@@ -2739,13 +2743,13 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
structure += "struct " + decorate(name) + "\n"
"{\n";
const TTypeList &fields = *type.getStruct();
const TFieldList &fields = type.getStruct()->fields();
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";
......@@ -2757,7 +2761,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
for (unsigned int i = 0; i < fields.size(); i++)
{
ctorParameters.push_back(*fields[i]);
ctorParameters.push_back(*fields[i]->type());
}
}
else if (parameters)
......@@ -2930,17 +2934,17 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
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);
if (i != structure->size() - 1)
if (i != fields.size() - 1)
{
out << ", ";
}
......@@ -3047,7 +3051,7 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type)
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);
}
......@@ -3095,7 +3099,7 @@ int OutputHLSL::uniformRegister(TIntermSymbol *uniform)
void OutputHLSL::declareUniform(const TType &type, const TString &name, int index)
{
const TTypeList *structure = type.getStruct();
TStructure *structure = type.getStruct();
if (!structure)
{
......@@ -3103,18 +3107,18 @@ void OutputHLSL::declareUniform(const TType &type, const TString &name, int inde
}
else
{
const TFieldList &fields = structure->fields();
if (type.isArray())
{
int elementIndex = index;
for (int i = 0; i < type.getArraySize(); i++)
{
for (size_t j = 0; j < structure->size(); j++)
for (size_t j = 0; j < fields.size(); j++)
{
const TType &fieldType = *(*structure)[j];
const TString &fieldName = fieldType.getFieldName();
const TString uniformName = name + "[" + str(i) + "]." + fieldName;
const TType &fieldType = *fields[j]->type();
const TString uniformName = name + "[" + str(i) + "]." + fields[j]->name();
declareUniform(fieldType, uniformName, elementIndex);
elementIndex += fieldType.totalRegisterCount();
}
......@@ -3124,12 +3128,10 @@ void OutputHLSL::declareUniform(const TType &type, const TString &name, int inde
{
int fieldIndex = index;
for (size_t i = 0; i < structure->size(); i++)
for (size_t i = 0; i < fields.size(); i++)
{
const TType &fieldType = *(*structure)[i];
const TString &fieldName = fieldType.getFieldName();
const TString uniformName = name + "." + fieldName;
const TType &fieldType = *fields[i]->type();
const TString uniformName = name + "." + fields[i]->name();
declareUniform(fieldType, uniformName, fieldIndex);
fieldIndex += fieldType.totalRegisterCount();
}
......
......@@ -535,7 +535,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n
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");
return true;
}
......@@ -658,9 +658,9 @@ bool TParseContext::containsSampler(TType& type)
return true;
if (type.getBasicType() == EbtStruct) {
TTypeList& structure = *type.getStruct();
for (unsigned int i = 0; i < structure.size(); ++i) {
if (containsSampler(*structure[i]))
const TFieldList& fields = type.getStruct()->fields();
for (unsigned int i = 0; i < fields.size(); ++i) {
if (containsSampler(*fields[i]->type()))
return true;
}
}
......@@ -1063,9 +1063,9 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
TIntermAggregate* aggrNode = node->getAsAggregate();
TTypeList::const_iterator memberTypes;
TFieldList::const_iterator memberFields;
if (op == EOpConstructStruct)
memberTypes = type->getStruct()->begin();
memberFields = type->getStruct()->fields().begin();
TType elementType = *type;
if (type->isArray())
......@@ -1087,7 +1087,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
if (type->isArray())
newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
else if (op == EOpConstructStruct)
newNode = constructStruct(node, *memberTypes, 1, node->getLine(), false);
newNode = constructStruct(node, (*memberFields)->type(), 1, node->getLine(), false);
else
newNode = constructBuiltIn(type, op, node, node->getLine(), false);
......@@ -1118,7 +1118,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
if (type->isArray())
newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
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
newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
......@@ -1370,14 +1370,14 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, co
//
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;
for (size_t index = 0; index < fields->size(); ++index) {
if ((*fields)[index]->getFieldName() == identifier) {
for (size_t index = 0; index < fields.size(); ++index) {
if (fields[index]->name() == identifier) {
break;
} else {
instanceSize += (*fields)[index]->getObjectSize();
instanceSize += fields[index]->type()->getObjectSize();
}
}
......@@ -1423,21 +1423,21 @@ const int kWebGLMaxStructNesting = 4;
} // namespace
bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TType& fieldType)
bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field)
{
if (!isWebGLBasedSpec(shaderSpec)) {
return false;
}
if (fieldType.getBasicType() != EbtStruct) {
if (field.type()->getBasicType() != EbtStruct) {
return false;
}
// We're already inside a structure definition at this point, so add
// one to the field's struct nesting.
if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) {
if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) {
std::stringstream extraInfoStream;
extraInfoStream << "Reference of struct type " << fieldType.getTypeName()
extraInfoStream << "Reference of struct type " << field.name()
<< " exceeds maximum struct nesting of " << kWebGLMaxStructNesting;
std::string extraInfo = extraInfoStream.str();
error(line, "", "", extraInfo.c_str());
......
......@@ -124,7 +124,7 @@ struct TParseContext {
bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier);
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[],
......
......@@ -20,44 +20,31 @@
#include <climits>
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),
structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0)
{
if (p.userDef) {
if (p.userDef)
structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
computeDeepestStructNesting();
}
}
//
// Recursively generate mangled names.
//
void TType::buildMangledName(TString& mangledName)
TString TType::buildMangledName() const
{
TString mangledName;
if (isMatrix())
mangledName += 'm';
else if (isVector())
mangledName += 'v';
switch (type) {
case EbtFloat: mangledName += 'f'; break;
case EbtInt: mangledName += 'i'; break;
case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break;
case EbtSamplerCube: mangledName += "sC"; break;
case EbtStruct:
mangledName += "struct-";
if (typeName)
mangledName += *typeName;
{// support MSVC++6.0
for (unsigned int i = 0; i < structure->size(); ++i) {
mangledName += '-';
(*structure)[i]->buildMangledName(mangledName);
}
}
default:
break;
case EbtFloat: mangledName += 'f'; break;
case EbtInt: mangledName += 'i'; break;
case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break;
case EbtSamplerCube: mangledName += "sC"; break;
case EbtStruct: mangledName += structure->mangledName(); break;
default: break;
}
mangledName += static_cast<char>('0' + getNominalSize());
......@@ -68,6 +55,7 @@ void TType::buildMangledName(TString& mangledName)
mangledName += buf;
mangledName += ']';
}
return mangledName;
}
size_t TType::getObjectSize() const
......@@ -75,7 +63,7 @@ size_t TType::getObjectSize() const
size_t totalSize = 0;
if (getBasicType() == EbtStruct)
totalSize = getStructSize();
totalSize = structure->objectSize();
else if (matrix)
totalSize = size * size;
else
......@@ -92,57 +80,47 @@ size_t TType::getObjectSize() const
return totalSize;
}
size_t TType::getStructSize() const
bool TStructure::containsArrays() const
{
if (!getStruct()) {
assert(false && "Not a struct");
return 0;
}
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;
}
for (size_t i = 0; i < mFields->size(); ++i) {
const TType* fieldType = (*mFields)[i]->type();
if (fieldType->isArray() || fieldType->isStructureContainingArrays())
return true;
}
return structureSize;
return false;
}
void TType::computeDeepestStructNesting()
TString TStructure::buildMangledName() const
{
if (!getStruct()) {
return;
}
int maxNesting = 0;
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
maxNesting = std::max(maxNesting, (*tl)->getDeepestStructNesting());
TString mangledName("struct-");
mangledName += *mName;
for (size_t i = 0; i < mFields->size(); ++i) {
mangledName += '-';
mangledName += (*mFields)[i]->type()->getMangledName();
}
deepestStructNesting = 1 + maxNesting;
return mangledName;
}
bool TType::isStructureContainingArrays() const
size_t TStructure::calculateObjectSize() const
{
if (!structure)
{
return false;
size_t size = 0;
for (size_t i = 0; i < mFields->size(); ++i) {
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++)
{
if ((*member)->isArray() ||
(*member)->isStructureContainingArrays())
{
return true;
}
int TStructure::calculateDeepestNesting() const
{
int maxNesting = 0;
for (size_t i = 0; i < mFields->size(); ++i) {
maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
}
return false;
return 1 + maxNesting;
}
//
......
......@@ -7,21 +7,86 @@
#ifndef _TYPES_INCLUDED
#define _TYPES_INCLUDED
#include "common/angleutils.h"
#include "compiler/BaseTypes.h"
#include "compiler/Common.h"
#include "compiler/debug.h"
class TType;
struct TPublicType;
class TType;
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; }
typedef TVector<TType*> TTypeList;
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));
return new(memory) TTypeList;
void* memory = GlobalPoolAllocator.allocate(sizeof(TFieldList));
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.
//
......@@ -31,16 +96,13 @@ public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TType() {}
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),
structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0)
{
}
explicit TType(const TPublicType &p);
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
TType(TStructure* userDef, TPrecision p = EbpUndefined) :
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
{
typeName = NewPoolTString(n.c_str());
}
TBasicType getBasicType() const { return type; }
......@@ -60,15 +122,14 @@ public:
int elementRegisterCount() const
{
TTypeList *structure = getStruct();
if (structure)
{
const TFieldList &fields = getStruct()->fields();
int registerCount = 0;
for (size_t i = 0; i < structure->size(); i++)
for (size_t i = 0; i < fields.size(); i++)
{
registerCount += (*structure)[i]->totalRegisterCount();
registerCount += fields[i]->type()->totalRegisterCount();
}
return registerCount;
......@@ -106,38 +167,15 @@ public:
bool isVector() const { return size > 1 && !matrix; }
bool isScalar() const { return size == 1 && !matrix && !structure; }
TTypeList* getStruct() const { return structure; }
void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
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());
}
TStructure* getStruct() const { return structure; }
void setStruct(TStructure* s) { structure = s; }
TString& getMangledName() {
if (!mangled) {
mangled = NewPoolTString("");
buildMangledName(*mangled);
*mangled += ';' ;
const TString& getMangledName() const {
if (mangled.empty()) {
mangled = buildMangledName();
mangled += ';';
}
return *mangled;
return mangled;
}
bool sameElementType(const TType& right) const {
......@@ -185,14 +223,16 @@ public:
// 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 { return deepestStructNesting; }
int getDeepestStructNesting() const {
return structure ? structure->deepestNesting() : 0;
}
bool isStructureContainingArrays() const;
bool isStructureContainingArrays() const {
return structure ? structure->containsArrays() : false;
}
private:
void buildMangledName(TString&);
size_t getStructSize() const;
void computeDeepestStructNesting();
TString buildMangledName() const;
TBasicType type : 6;
TPrecision precision;
......@@ -202,13 +242,9 @@ private:
unsigned int array : 1;
int arraySize;
TTypeList* structure; // 0 unless this is a struct
mutable size_t structureSize;
int deepestStructNesting;
TStructure* structure; // 0 unless this is a struct
TString *fieldName; // for structure field names
TString *mangled;
TString *typeName; // for structure field type name
mutable TString mangled;
};
//
......
......@@ -131,12 +131,13 @@ void getUserDefinedVariableInfo(const TType& type,
{
ASSERT(type.getBasicType() == EbtStruct);
const TTypeList* structure = type.getStruct();
for (size_t i = 0; i < structure->size(); ++i) {
const TType* fieldType = (*structure)[i];
getVariableInfo(*fieldType,
name + "." + fieldType->getFieldName(),
mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction),
const TFieldList& fields = type.getStruct()->fields();
for (size_t i = 0; i < fields.size(); ++i) {
const TType& fieldType = *(fields[i]->type());
const TString& fieldName = fields[i]->name();
getVariableInfo(fieldType,
name + "." + fieldName,
mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
infoList,
hashFunction);
}
......
......@@ -77,8 +77,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TQualifier qualifier;
TFunction* function;
TParameter param;
TType* field;
TTypeList* structure;
TField* field;
TFieldList* fieldList;
};
} interm;
}
......@@ -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> struct_specifier
%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_with_parameters function_call_header
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
......@@ -317,7 +317,7 @@ postfix_expression
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), @2);
} else if ($1->isArray()) {
if ($1->getType().getStruct())
$$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
$$->setType(TType($1->getType().getStruct()));
else
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
......@@ -391,44 +391,38 @@ postfix_expression
}
} else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false;
const TTypeList* fields = $1->getType().getStruct();
if (fields == 0) {
context->error(@2, "structure has no fields", "Internal Error");
context->recover();
$$ = $1;
} else {
unsigned int i;
for (i = 0; i < fields->size(); ++i) {
if ((*fields)[i]->getFieldName() == *$3.string) {
fieldFound = true;
break;
}
const TFieldList& fields = $1->getType().getStruct()->fields();
unsigned int i;
for (i = 0; i < fields.size(); ++i) {
if (fields[i]->name() == *$3.string) {
fieldFound = true;
break;
}
if (fieldFound) {
if ($1->getType().getQualifier() == EvqConst) {
$$ = context->addConstStruct(*$3.string, $1, @2);
if ($$ == 0) {
context->recover();
$$ = $1;
}
else {
$$->setType(*(*fields)[i]);
// change the qualifier of the return type, not of the structure field
// 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]);
}
if (fieldFound) {
if ($1->getType().getQualifier() == EvqConst) {
$$ = context->addConstStruct(*$3.string, $1, @2);
if ($$ == 0) {
context->recover();
$$ = $1;
}
else {
$$->setType(*fields[i]->type());
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
$$->getTypePointer()->setQualifier(EvqConst);
}
} else {
context->error(@2, " no such field in structure", $3.string->c_str());
context->recover();
$$ = $1;
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
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 {
context->error(@2, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str());
......@@ -1625,7 +1619,7 @@ struct_specifier
if (context->reservedErrorCheck(@2, *$2.string))
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);
if (! context->symbolTable.insert(*userTypeDef)) {
context->error(@2, "redefinition", $2.string->c_str(), "struct");
......@@ -1636,7 +1630,7 @@ struct_specifier
context->exitStructDeclaration();
}
| 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);
$$.userDef = structure;
context->exitStructDeclaration();
......@@ -1649,15 +1643,15 @@ struct_declaration_list
}
| struct_declaration_list struct_declaration {
$$ = $1;
for (size_t i = 0; i < $2.structure->size(); ++i) {
TType* field = (*$2.structure)[i];
for (size_t j = 0; j < $$.structure->size(); ++j) {
if ((*$$.structure)[j]->getFieldName() == field->getFieldName()) {
context->error(@2, "duplicate field name in structure:", "struct", field->getFieldName().c_str());
for (size_t i = 0; i < $2->size(); ++i) {
TField* field = (*$2)[i];
for (size_t j = 0; j < $$->size(); ++j) {
if ((*$$)[j]->name() == field->name()) {
context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str());
context->recover();
}
}
$$.structure->push_back(field);
$$->push_back(field);
}
}
;
......@@ -1666,14 +1660,14 @@ struct_declaration
: type_specifier struct_declarator_list SEMICOLON {
$$ = $2;
if (context->voidErrorCheck(@1, (*$2.structure)[0]->getFieldName(), $1)) {
if (context->voidErrorCheck(@1, (*$2)[0]->name(), $1)) {
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
//
TType* type = (*$$.structure)[i];
TType* type = (*$$)[i]->type();
type->setBasicType($1.type);
type->setNominalSize($1.size);
type->setMatrix($1.matrix);
......@@ -1686,25 +1680,22 @@ struct_declaration
}
if ($1.array)
type->setArraySize($1.arraySize);
if ($1.userDef) {
if ($1.userDef)
type->setStruct($1.userDef->getStruct());
type->setTypeName($1.userDef->getTypeName());
}
if (context->structNestingErrorCheck(@1, *type)) {
if (context->structNestingErrorCheck(@1, *(*$$)[i]))
context->recover();
}
}
}
;
struct_declarator_list
: struct_declarator {
$$.structure = NewPoolTTypeList();
$$.structure->push_back($1);
$$ = NewPoolTFieldList();
$$->push_back($1);
}
| struct_declarator_list COMMA struct_declarator {
$$.structure->push_back($3);
$$->push_back($3);
}
;
......@@ -1713,20 +1704,20 @@ struct_declarator
if (context->reservedErrorCheck(@1, *$1.string))
context->recover();
$$ = new TType(EbtVoid, EbpUndefined);
$$->setFieldName(*$1.string);
TType* type = new TType(EbtVoid, EbpUndefined);
$$ = new TField(type, $1.string);
}
| identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck(@1, *$1.string))
context->recover();
$$ = new TType(EbtVoid, EbpUndefined);
$$->setFieldName(*$1.string);
int size;
if (context->arraySizeErrorCheck(@2, $3, size))
TType* type = new TType(EbtVoid, EbpUndefined);
int size = 0;
if (context->arraySizeErrorCheck(@3, $3, size))
context->recover();
$$->setArraySize(size);
type->setArraySize(size);
$$ = new TField(type, $1.string);
}
;
......
......@@ -260,8 +260,8 @@ typedef union YYSTYPE
TQualifier qualifier;
TFunction* function;
TParameter param;
TType* field;
TTypeList* structure;
TField* field;
TFieldList* fieldList;
};
} interm;
......@@ -714,26 +714,26 @@ static const yytype_int16 yyrhs[] =
static const yytype_uint16 yyrline[] =
{
0, 179, 179, 180, 183, 226, 229, 242, 247, 252,
258, 261, 336, 339, 440, 450, 463, 471, 571, 574,
582, 585, 591, 595, 602, 608, 617, 625, 680, 690,
693, 703, 713, 734, 735, 736, 741, 742, 750, 761,
762, 770, 781, 785, 786, 796, 806, 816, 829, 830,
840, 853, 857, 861, 865, 866, 879, 880, 893, 894,
907, 908, 925, 926, 939, 940, 941, 942, 943, 947,
950, 961, 969, 996, 1001, 1015, 1052, 1055, 1062, 1070,
1091, 1112, 1122, 1150, 1155, 1165, 1170, 1180, 1183, 1186,
1189, 1195, 1202, 1205, 1227, 1245, 1269, 1292, 1296, 1314,
1322, 1354, 1374, 1395, 1404, 1427, 1430, 1436, 1444, 1452,
1460, 1470, 1477, 1480, 1483, 1489, 1492, 1507, 1511, 1515,
1519, 1523, 1528, 1533, 1538, 1543, 1548, 1553, 1558, 1563,
1568, 1573, 1578, 1583, 1587, 1591, 1599, 1607, 1611, 1624,
1624, 1638, 1638, 1647, 1650, 1666, 1702, 1706, 1712, 1719,
1734, 1738, 1742, 1743, 1749, 1750, 1751, 1752, 1753, 1757,
1758, 1758, 1758, 1768, 1769, 1773, 1773, 1774, 1774, 1779,
1782, 1792, 1795, 1801, 1802, 1806, 1814, 1818, 1828, 1833,
1850, 1850, 1855, 1855, 1862, 1862, 1870, 1873, 1879, 1882,
1888, 1892, 1899, 1906, 1913, 1920, 1931, 1940, 1944, 1951,
1954, 1960, 1960
258, 261, 336, 339, 434, 444, 457, 465, 565, 568,
576, 579, 585, 589, 596, 602, 611, 619, 674, 684,
687, 697, 707, 728, 729, 730, 735, 736, 744, 755,
756, 764, 775, 779, 780, 790, 800, 810, 823, 824,
834, 847, 851, 855, 859, 860, 873, 874, 887, 888,
901, 902, 919, 920, 933, 934, 935, 936, 937, 941,
944, 955, 963, 990, 995, 1009, 1046, 1049, 1056, 1064,
1085, 1106, 1116, 1144, 1149, 1159, 1164, 1174, 1177, 1180,
1183, 1189, 1196, 1199, 1221, 1239, 1263, 1286, 1290, 1308,
1316, 1348, 1368, 1389, 1398, 1421, 1424, 1430, 1438, 1446,
1454, 1464, 1471, 1474, 1477, 1483, 1486, 1501, 1505, 1509,
1513, 1517, 1522, 1527, 1532, 1537, 1542, 1547, 1552, 1557,
1562, 1567, 1572, 1577, 1581, 1585, 1593, 1601, 1605, 1618,
1618, 1632, 1632, 1641, 1644, 1660, 1693, 1697, 1703, 1710,
1725, 1729, 1733, 1734, 1740, 1741, 1742, 1743, 1744, 1748,
1749, 1749, 1749, 1759, 1760, 1764, 1764, 1765, 1765, 1770,
1773, 1783, 1786, 1792, 1793, 1797, 1805, 1809, 1819, 1824,
1841, 1841, 1846, 1846, 1853, 1853, 1861, 1864, 1870, 1873,
1879, 1883, 1890, 1897, 1904, 1911, 1922, 1931, 1935, 1942,
1945, 1951, 1951
};
#endif
......@@ -2404,7 +2404,7 @@ yyreduce:
(yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), (yylsp[(2) - (4)]));
} else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct())
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getTypeName()));
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct()));
else
(yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize(), (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()));
......@@ -2486,44 +2486,38 @@ yyreduce:
}
} else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType() == EbtStruct) {
bool fieldFound = false;
const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct();
if (fields == 0) {
context->error((yylsp[(2) - (3)]), "structure has no fields", "Internal Error");
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
} else {
unsigned int i;
for (i = 0; i < fields->size(); ++i) {
if ((*fields)[i]->getFieldName() == *(yyvsp[(3) - (3)].lex).string) {
fieldFound = true;
break;
}
const TFieldList& fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct()->fields();
unsigned int i;
for (i = 0; i < fields.size(); ++i) {
if (fields[i]->name() == *(yyvsp[(3) - (3)].lex).string) {
fieldFound = true;
break;
}
if (fieldFound) {
if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) {
(yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
if ((yyval.interm.intermTypedNode) == 0) {
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
else {
(yyval.interm.intermTypedNode)->setType(*(*fields)[i]);
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
(yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
}
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i], (yylsp[(3) - (3)]));
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
(yyval.interm.intermTypedNode)->setType(*(*fields)[i]);
}
if (fieldFound) {
if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) {
(yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
if ((yyval.interm.intermTypedNode) == 0) {
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
else {
(yyval.interm.intermTypedNode)->setType(*fields[i]->type());
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
(yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
}
} else {
context->error((yylsp[(2) - (3)]), " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str());
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *fields[i]->type(), (yylsp[(3) - (3)]));
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
(yyval.interm.intermTypedNode)->setType(*fields[i]->type());
}
} else {
context->error((yylsp[(2) - (3)]), " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str());
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
} else {
context->error((yylsp[(2) - (3)]), " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str());
......@@ -4080,7 +4074,7 @@ yyreduce:
if (context->reservedErrorCheck((yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string))
context->recover();
TType* structure = new TType((yyvsp[(5) - (6)].interm).structure, *(yyvsp[(2) - (6)].lex).string);
TType* structure = new TType(new TStructure((yyvsp[(2) - (6)].lex).string, (yyvsp[(5) - (6)].interm.fieldList)));
TVariable* userTypeDef = new TVariable((yyvsp[(2) - (6)].lex).string, *structure, true);
if (! context->symbolTable.insert(*userTypeDef)) {
context->error((yylsp[(2) - (6)]), "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct");
......@@ -4100,7 +4094,7 @@ yyreduce:
case 142:
{
TType* structure = new TType((yyvsp[(4) - (5)].interm).structure, TString(""));
TType* structure = new TType(new TStructure(NewPoolTString(""), (yyvsp[(4) - (5)].interm.fieldList)));
(yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yylsp[(1) - (5)]));
(yyval.interm.type).userDef = structure;
context->exitStructDeclaration();
......@@ -4110,23 +4104,23 @@ yyreduce:
case 143:
{
(yyval.interm) = (yyvsp[(1) - (1)].interm);
(yyval.interm.fieldList) = (yyvsp[(1) - (1)].interm.fieldList);
}
break;
case 144:
{
(yyval.interm) = (yyvsp[(1) - (2)].interm);
for (size_t i = 0; i < (yyvsp[(2) - (2)].interm).structure->size(); ++i) {
TType* field = (*(yyvsp[(2) - (2)].interm).structure)[i];
for (size_t j = 0; j < (yyval.interm).structure->size(); ++j) {
if ((*(yyval.interm).structure)[j]->getFieldName() == field->getFieldName()) {
context->error((yylsp[(2) - (2)]), "duplicate field name in structure:", "struct", field->getFieldName().c_str());
(yyval.interm.fieldList) = (yyvsp[(1) - (2)].interm.fieldList);
for (size_t i = 0; i < (yyvsp[(2) - (2)].interm.fieldList)->size(); ++i) {
TField* field = (*(yyvsp[(2) - (2)].interm.fieldList))[i];
for (size_t j = 0; j < (yyval.interm.fieldList)->size(); ++j) {
if ((*(yyval.interm.fieldList))[j]->name() == field->name()) {
context->error((yylsp[(2) - (2)]), "duplicate field name in structure:", "struct", field->name().c_str());
context->recover();
}
}
(yyval.interm).structure->push_back(field);
(yyval.interm.fieldList)->push_back(field);
}
}
break;
......@@ -4134,16 +4128,16 @@ yyreduce:
case 145:
{
(yyval.interm) = (yyvsp[(2) - (3)].interm);
(yyval.interm.fieldList) = (yyvsp[(2) - (3)].interm.fieldList);
if (context->voidErrorCheck((yylsp[(1) - (3)]), (*(yyvsp[(2) - (3)].interm).structure)[0]->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
if (context->voidErrorCheck((yylsp[(1) - (3)]), (*(yyvsp[(2) - (3)].interm.fieldList))[0]->name(), (yyvsp[(1) - (3)].interm.type))) {
context->recover();
}
for (unsigned int i = 0; i < (yyval.interm).structure->size(); ++i) {
for (unsigned int i = 0; i < (yyval.interm.fieldList)->size(); ++i) {
//
// Careful not to replace already known aspects of type, like array-ness
//
TType* type = (*(yyval.interm).structure)[i];
TType* type = (*(yyval.interm.fieldList))[i]->type();
type->setBasicType((yyvsp[(1) - (3)].interm.type).type);
type->setNominalSize((yyvsp[(1) - (3)].interm.type).size);
type->setMatrix((yyvsp[(1) - (3)].interm.type).matrix);
......@@ -4156,14 +4150,11 @@ yyreduce:
}
if ((yyvsp[(1) - (3)].interm.type).array)
type->setArraySize((yyvsp[(1) - (3)].interm.type).arraySize);
if ((yyvsp[(1) - (3)].interm.type).userDef) {
if ((yyvsp[(1) - (3)].interm.type).userDef)
type->setStruct((yyvsp[(1) - (3)].interm.type).userDef->getStruct());
type->setTypeName((yyvsp[(1) - (3)].interm.type).userDef->getTypeName());
}
if (context->structNestingErrorCheck((yylsp[(1) - (3)]), *type)) {
if (context->structNestingErrorCheck((yylsp[(1) - (3)]), *(*(yyval.interm.fieldList))[i]))
context->recover();
}
}
}
break;
......@@ -4171,15 +4162,15 @@ yyreduce:
case 146:
{
(yyval.interm).structure = NewPoolTTypeList();
(yyval.interm).structure->push_back((yyvsp[(1) - (1)].interm.field));
(yyval.interm.fieldList) = NewPoolTFieldList();
(yyval.interm.fieldList)->push_back((yyvsp[(1) - (1)].interm.field));
}
break;
case 147:
{
(yyval.interm).structure->push_back((yyvsp[(3) - (3)].interm.field));
(yyval.interm.fieldList)->push_back((yyvsp[(3) - (3)].interm.field));
}
break;
......@@ -4189,8 +4180,8 @@ yyreduce:
if (context->reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string))
context->recover();
(yyval.interm.field) = new TType(EbtVoid, EbpUndefined);
(yyval.interm.field)->setFieldName(*(yyvsp[(1) - (1)].lex).string);
TType* type = new TType(EbtVoid, EbpUndefined);
(yyval.interm.field) = new TField(type, (yyvsp[(1) - (1)].lex).string);
}
break;
......@@ -4200,13 +4191,13 @@ yyreduce:
if (context->reservedErrorCheck((yylsp[(1) - (4)]), *(yyvsp[(1) - (4)].lex).string))
context->recover();
(yyval.interm.field) = new TType(EbtVoid, EbpUndefined);
(yyval.interm.field)->setFieldName(*(yyvsp[(1) - (4)].lex).string);
int size;
if (context->arraySizeErrorCheck((yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
TType* type = new TType(EbtVoid, EbpUndefined);
int size = 0;
if (context->arraySizeErrorCheck((yylsp[(3) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
context->recover();
(yyval.interm.field)->setArraySize(size);
type->setArraySize(size);
(yyval.interm.field) = new TField(type, (yyvsp[(1) - (4)].lex).string);
}
break;
......
......@@ -178,8 +178,8 @@ typedef union YYSTYPE
TQualifier qualifier;
TFunction* function;
TParameter param;
TType* field;
TTypeList* structure;
TField* field;
TFieldList* fieldList;
};
} 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