diff options
author | Jamie Madill <alokp@chromium.org> | 2013-06-06 16:24:46 +0000 |
---|---|---|
committer | Shannon Woods <shannonwoods@chromium.org> | 2013-06-26 19:07:53 -0400 |
commit | 0600ff1a7cf112aba06f71120b5bef88bf906351 (patch) | |
tree | 29abd3991550bfee5c3b83476f104e83035b7ad3 | |
parent | 95c66250adc68506d5863705ec5794c3a6917dfc (diff) | |
download | angle_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.cpp | 22 | ||||
-rw-r--r-- | src/compiler/Intermediate.cpp | 11 | ||||
-rw-r--r-- | src/compiler/OutputGLSLBase.cpp | 77 | ||||
-rw-r--r-- | src/compiler/OutputGLSLBase.h | 3 | ||||
-rw-r--r-- | src/compiler/OutputHLSL.cpp | 76 | ||||
-rw-r--r-- | src/compiler/ParseHelper.cpp | 32 | ||||
-rw-r--r-- | src/compiler/ParseHelper.h | 2 | ||||
-rw-r--r-- | src/compiler/SymbolTable.cpp | 106 | ||||
-rw-r--r-- | src/compiler/Types.h | 148 | ||||
-rw-r--r-- | src/compiler/VariableInfo.cpp | 13 | ||||
-rw-r--r-- | src/compiler/glslang.y | 121 | ||||
-rw-r--r-- | src/compiler/glslang_tab.cpp | 165 | ||||
-rw-r--r-- | src/compiler/glslang_tab.h | 4 |
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; |