summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Madill <alokp@chromium.org>2013-06-06 16:24:46 +0000
committerShannon Woods <shannonwoods@chromium.org>2013-06-26 19:07:53 -0400
commit0600ff1a7cf112aba06f71120b5bef88bf906351 (patch)
tree29abd3991550bfee5c3b83476f104e83035b7ad3
parent95c66250adc68506d5863705ec5794c3a6917dfc (diff)
downloadangle_dx11-0600ff1a7cf112aba06f71120b5bef88bf906351.tar.gz
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
-rw-r--r--src/compiler/Initialize.cpp22
-rw-r--r--src/compiler/Intermediate.cpp11
-rw-r--r--src/compiler/OutputGLSLBase.cpp77
-rw-r--r--src/compiler/OutputGLSLBase.h3
-rw-r--r--src/compiler/OutputHLSL.cpp76
-rw-r--r--src/compiler/ParseHelper.cpp32
-rw-r--r--src/compiler/ParseHelper.h2
-rw-r--r--src/compiler/SymbolTable.cpp106
-rw-r--r--src/compiler/Types.h148
-rw-r--r--src/compiler/VariableInfo.cpp13
-rw-r--r--src/compiler/glslang.y121
-rw-r--r--src/compiler/glslang_tab.cpp165
-rw-r--r--src/compiler/glslang_tab.h4
13 files changed, 398 insertions, 382 deletions
diff --git a/src/compiler/Initialize.cpp b/src/compiler/Initialize.cpp
index 9b070cad..0ed3b8df 100644
--- a/src/compiler/Initialize.cpp
+++ b/src/compiler/Initialize.cpp
@@ -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);
diff --git a/src/compiler/Intermediate.cpp b/src/compiler/Intermediate.cpp
index a2b3ddec..3b662218 100644
--- a/src/compiler/Intermediate.cpp
+++ b/src/compiler/Intermediate.cpp
@@ -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;
diff --git a/src/compiler/OutputGLSLBase.cpp b/src/compiler/OutputGLSLBase.cpp
index 35901cf6..d677c756 100644
--- a/src/compiler/OutputGLSLBase.cpp
+++ b/src/compiler/OutputGLSLBase.cpp
@@ -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());
+}
diff --git a/src/compiler/OutputGLSLBase.h b/src/compiler/OutputGLSLBase.h
index c9f72d56..df4ad68c 100644
--- a/src/compiler/OutputGLSLBase.h
+++ b/src/compiler/OutputGLSLBase.h
@@ -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;
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index c6c6e33a..e0afe546 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -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();
}
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index 76855f1b..fd2e9539 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -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());
diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h
index 289ec2f2..b2025b84 100644
--- a/src/compiler/ParseHelper.h
+++ b/src/compiler/ParseHelper.h
@@ -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[],
diff --git a/src/compiler/SymbolTable.cpp b/src/compiler/SymbolTable.cpp
index f6b6ab6f..51180aff 100644
--- a/src/compiler/SymbolTable.cpp
+++ b/src/compiler/SymbolTable.cpp
@@ -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;
}
//
diff --git a/src/compiler/Types.h b/src/compiler/Types.h
index 472f1a74..5946af04 100644
--- a/src/compiler/Types.h
+++ b/src/compiler/Types.h
@@ -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;
};
//
diff --git a/src/compiler/VariableInfo.cpp b/src/compiler/VariableInfo.cpp
index 5a1402e0..84db807a 100644
--- a/src/compiler/VariableInfo.cpp
+++ b/src/compiler/VariableInfo.cpp
@@ -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);
}
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index bcb9aec5..2c25d5b1 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -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);
}
;
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index 71ccf949..21117ee7 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -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;
diff --git a/src/compiler/glslang_tab.h b/src/compiler/glslang_tab.h
index 4789f5c2..2f0f1106 100644
--- a/src/compiler/glslang_tab.h
+++ b/src/compiler/glslang_tab.h
@@ -178,8 +178,8 @@ typedef union YYSTYPE
TQualifier qualifier;
TFunction* function;
TParameter param;
- TType* field;
- TTypeList* structure;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;