Commit a8b364b7 by Alexis Hetu Committed by Alexis Hétu

Adding Struct related types

Added TField, TFieldListCollection, TStructure and TInterfaceBlock for structures and uniform blocks. In the TType class, changed structure's type from TTypeList to TStructure and made related changes in other files to reflect this change. Change-Id: Ided4c535651a566952c3314c8c4f31c2d0ccdcca Reviewed-on: https://swiftshader-review.googlesource.com/3451Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 5f4ee797
...@@ -399,19 +399,17 @@ void InsertBuiltInFunctions(GLenum type, const ShBuiltInResources &resources, TS ...@@ -399,19 +399,17 @@ void InsertBuiltInFunctions(GLenum type, const ShBuiltInResources &resources, TS
// //
// Depth range in window coordinates // Depth range in window coordinates
// //
TTypeList *members = NewPoolTTypeList(); TFieldList *fields = NewPoolTFieldList();
TTypeLine near = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), 0);
TTypeLine far = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), 0);
TTypeLine diff = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), 0);
near.type->setFieldName("near"); fields->push_back(near);
far.type->setFieldName("far"); fields->push_back(far);
diff.type->setFieldName("diff"); fields->push_back(diff);
members->push_back(near); TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
members->push_back(far); TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
members->push_back(diff);
TVariable *depthRangeParameters = new TVariable(NewPoolTString("gl_DepthRangeParameters"), TType(members, "gl_DepthRangeParameters"), true);
symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters); symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters);
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(members, "gl_DepthRangeParameters")); TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
depthRange->setQualifier(EvqUniform); depthRange->setQualifier(EvqUniform);
symbolTable.insert(COMMON_BUILTINS, *depthRange); symbolTable.insert(COMMON_BUILTINS, *depthRange);
......
...@@ -993,16 +993,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -993,16 +993,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray) bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{ {
const TTypeList* fields = leftNodeType.getStruct(); const TFieldList& fields = leftNodeType.getStruct()->fields();
size_t structSize = fields->size(); size_t structSize = fields.size();
int index = 0; int index = 0;
for (size_t j = 0; j < structSize; j++) { for (size_t j = 0; j < structSize; j++) {
int size = (*fields)[j].type->getObjectSize(); int size = fields[j]->type()->getObjectSize();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if ((*fields)[j].type->getBasicType() == EbtStruct) { if (fields[j]->type()->getBasicType() == EbtStruct) {
if (!CompareStructure(*(*fields)[j].type, &rightUnionArray[index], &leftUnionArray[index])) if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
return false; return false;
} else { } else {
if (leftUnionArray[index] != rightUnionArray[index]) if (leftUnionArray[index] != rightUnionArray[index])
......
...@@ -326,20 +326,13 @@ namespace glsl ...@@ -326,20 +326,13 @@ namespace glsl
{ {
ASSERT(leftType.isStruct()); ASSERT(leftType.isStruct());
const TTypeList *structure = leftType.getStruct(); const TFieldList& fields = leftType.getStruct()->fields();
const TString &fieldName = rightType.getFieldName(); int index = right->getAsConstantUnion()->getIConst(0);
int fieldOffset = 0; int fieldOffset = 0;
for(size_t i = 0; i < structure->size(); i++) for(int i = 0; i < index; i++)
{ {
const TType &fieldType = *(*structure)[i].type; fieldOffset += fields[i]->type()->totalRegisterCount();
if(fieldType.getFieldName() == fieldName)
{
break;
}
fieldOffset += fieldType.totalRegisterCount();
} }
copy(result, left, fieldOffset); copy(result, left, fieldOffset);
...@@ -1439,12 +1432,12 @@ namespace glsl ...@@ -1439,12 +1432,12 @@ namespace glsl
if(type.isStruct()) if(type.isStruct())
{ {
TTypeList *structure = type.getStruct(); const TFieldList& fields = type.getStruct()->fields();
int elements = 0; int elements = 0;
for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++) for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
{ {
const TType &fieldType = *field->type; const TType &fieldType = *((*field)->type());
if(fieldType.totalRegisterCount() <= registers) if(fieldType.totalRegisterCount() <= registers)
{ {
...@@ -1472,7 +1465,7 @@ namespace glsl ...@@ -1472,7 +1465,7 @@ namespace glsl
{ {
if(type.isStruct()) if(type.isStruct())
{ {
return registerSize(*type.getStruct()->begin()->type, 0); return registerSize(*((*(type.getStruct()->fields().begin()))->type()), 0);
} }
return type.isMatrix() ? type.getSecondarySize() : type.getNominalSize(); return type.isMatrix() ? type.getSecondarySize() : type.getNominalSize();
...@@ -1487,12 +1480,12 @@ namespace glsl ...@@ -1487,12 +1480,12 @@ namespace glsl
if(type.isStruct()) if(type.isStruct())
{ {
TTypeList *structure = type.getStruct(); const TFieldList& fields = type.getStruct()->fields();
int elements = 0; int elements = 0;
for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++) for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
{ {
const TType &fieldType = *field->type; const TType &fieldType = *((*field)->type());
if(fieldType.totalRegisterCount() <= registers) if(fieldType.totalRegisterCount() <= registers)
{ {
...@@ -1520,7 +1513,6 @@ namespace glsl ...@@ -1520,7 +1513,6 @@ namespace glsl
{ {
TIntermTyped *arg = argument->getAsTyped(); TIntermTyped *arg = argument->getAsTyped();
const TType &type = arg->getType(); const TType &type = arg->getType();
const TTypeList *structure = type.getStruct();
index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index; index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;
int size = registerSize(type, index); int size = registerSize(type, index);
...@@ -1771,23 +1763,20 @@ namespace glsl ...@@ -1771,23 +1763,20 @@ namespace glsl
break; break;
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
{ {
const TTypeList *structure = left->getType().getStruct(); const TFieldList& fields = left->getType().getStruct()->fields();
const TString &fieldName = right->getType().getFieldName(); int index = right->getAsConstantUnion()->getIConst(0);
int fieldOffset = 0;
int offset = 0; for(int i = 0; i < index; i++)
for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)
{ {
if(field->type->getFieldName() == fieldName) fieldOffset += fields[i]->type()->totalRegisterCount();
{
dst.type = registerType(left);
dst.index += offset;
dst.mask = writeMask(right);
return 0xE4;
}
offset += field->type->totalRegisterCount();
} }
dst.type = registerType(left);
dst.index += fieldOffset;
dst.mask = writeMask(right);
return 0xE4;
} }
break; break;
case EOpVectorSwizzle: case EOpVectorSwizzle:
...@@ -2354,7 +2343,7 @@ namespace glsl ...@@ -2354,7 +2343,7 @@ namespace glsl
void OutputASM::declareUniform(const TType &type, const TString &name, int index) void OutputASM::declareUniform(const TType &type, const TString &name, int index)
{ {
const TTypeList *structure = type.getStruct(); const TStructure *structure = type.getStruct();
ActiveUniforms &activeUniforms = shaderObject->activeUniforms; ActiveUniforms &activeUniforms = shaderObject->activeUniforms;
if(!structure) if(!structure)
...@@ -2371,16 +2360,17 @@ namespace glsl ...@@ -2371,16 +2360,17 @@ namespace glsl
} }
else else
{ {
const TFieldList& fields = structure->fields();
if(type.isArray()) if(type.isArray())
{ {
int elementIndex = index; int elementIndex = index;
for(int i = 0; i < type.getArraySize(); i++) 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].type; const TType &fieldType = *(fields[j]->type());
const TString &fieldName = fieldType.getFieldName(); const TString &fieldName = fields[j]->name();
const TString uniformName = name + "[" + str(i) + "]." + fieldName; const TString uniformName = name + "[" + str(i) + "]." + fieldName;
declareUniform(fieldType, uniformName, elementIndex); declareUniform(fieldType, uniformName, elementIndex);
...@@ -2392,10 +2382,10 @@ namespace glsl ...@@ -2392,10 +2382,10 @@ namespace glsl
{ {
int fieldIndex = index; 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].type; const TType &fieldType = *(fields[i]->type());
const TString &fieldName = fieldType.getFieldName(); const TString &fieldName = fields[i]->name();
const TString uniformName = name + "." + fieldName; const TString uniformName = name + "." + fieldName;
declareUniform(fieldType, uniformName, fieldIndex); declareUniform(fieldType, uniformName, fieldIndex);
......
...@@ -522,7 +522,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction ...@@ -522,7 +522,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
return true; return true;
} }
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) { if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
return true; return true;
} }
...@@ -682,9 +682,9 @@ bool TParseContext::containsSampler(TType& type) ...@@ -682,9 +682,9 @@ bool TParseContext::containsSampler(TType& type)
return true; return true;
if (type.getBasicType() == EbtStruct) { if (type.getBasicType() == EbtStruct) {
TTypeList& structure = *type.getStruct(); const TFieldList& fields = type.getStruct()->fields();
for (unsigned int i = 0; i < structure.size(); ++i) { for(unsigned int i = 0; i < fields.size(); ++i) {
if (containsSampler(*structure[i].type)) if (containsSampler(*fields[i]->type()))
return true; return true;
} }
} }
...@@ -1232,12 +1232,12 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType* ...@@ -1232,12 +1232,12 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType*
if(op == EOpConstructStruct) if(op == EOpConstructStruct)
{ {
TTypeList &fields = *type->getStruct(); const TFieldList &fields = type->getStruct()->fields();
TIntermSequence &args = aggregateArguments->getSequence(); TIntermSequence &args = aggregateArguments->getSequence();
for(size_t i = 0; i < fields.size(); i++) for(size_t i = 0; i < fields.size(); i++)
{ {
if(args[i]->getAsTyped()->getType() != *fields[i].type) if(args[i]->getAsTyped()->getType() != *fields[i]->type())
{ {
error(line, "Structure constructor arguments do not match structure fields", "Error"); error(line, "Structure constructor arguments do not match structure fields", "Error");
recover(); recover();
...@@ -1405,17 +1405,17 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS ...@@ -1405,17 +1405,17 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
// //
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
{ {
const TTypeList* fields = node->getType().getStruct(); const TFieldList &fields = node->getType().getStruct()->fields();
TIntermTyped *typedNode; TIntermTyped *typedNode;
int instanceSize = 0; int instanceSize = 0;
unsigned int index = 0; unsigned int index = 0;
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
for ( index = 0; index < fields->size(); ++index) { for ( index = 0; index < fields.size(); ++index) {
if ((*fields)[index].type->getFieldName() == identifier) { if (fields[index]->name() == identifier) {
break; break;
} else { } else {
instanceSize += (*fields)[index].type->getObjectSize(); instanceSize += fields[index]->type()->getObjectSize();
} }
} }
......
...@@ -26,12 +26,11 @@ int TSymbolTableLevel::uniqueId = 0; ...@@ -26,12 +26,11 @@ int TSymbolTableLevel::uniqueId = 0;
TType::TType(const TPublicType &p) : TType::TType(const TPublicType &p) :
type(p.type), precision(p.precision), primarySize(p.primarySize), secondarySize(p.secondarySize), qualifier(p.qualifier), array(p.array), arraySize(p.arraySize), type(p.type), precision(p.precision), primarySize(p.primarySize), secondarySize(p.secondarySize), qualifier(p.qualifier), array(p.array), arraySize(p.arraySize),
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0) maxArraySize(0), arrayInformationType(0), structure(0), deepestStructNesting(0), mangled(0)
{ {
if (p.userDef) if (p.userDef)
{ {
structure = p.userDef->getStruct(); structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
computeDeepestStructNesting(); computeDeepestStructNesting();
} }
} }
...@@ -52,19 +51,23 @@ void TType::buildMangledName(TString& mangledName) ...@@ -52,19 +51,23 @@ void TType::buildMangledName(TString& mangledName)
case EbtUInt: mangledName += 'u'; break; case EbtUInt: mangledName += 'u'; break;
case EbtBool: mangledName += 'b'; break; case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break; case EbtSampler2D: mangledName += "s2"; break;
case EbtSamplerCube: mangledName += "sC"; break;
case EbtSamplerExternalOES: mangledName += "sE"; break;
case EbtSampler3D: mangledName += "s3"; break; case EbtSampler3D: mangledName += "s3"; break;
case EbtStruct: case EbtSamplerCube: mangledName += "sC"; break;
mangledName += "struct-"; case EbtSampler2DArray: mangledName += "s2a"; break;
if (typeName) case EbtSamplerExternalOES: mangledName += "sext"; break;
mangledName += *typeName; case EbtISampler2D: mangledName += "is2"; break;
{// support MSVC++6.0 case EbtISampler3D: mangledName += "is3"; break;
for (unsigned int i = 0; i < structure->size(); ++i) { case EbtISamplerCube: mangledName += "isC"; break;
mangledName += '-'; case EbtISampler2DArray: mangledName += "is2a"; break;
(*structure)[i].type->buildMangledName(mangledName); case EbtUSampler2D: mangledName += "us2"; break;
} case EbtUSampler3D: mangledName += "us3"; break;
} case EbtUSamplerCube: mangledName += "usC"; break;
case EbtUSampler2DArray: mangledName += "us2a"; break;
case EbtSampler2DShadow: mangledName += "s2s"; break;
case EbtSamplerCubeShadow: mangledName += "sCs"; break;
case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
case EbtStruct: mangledName += structure->mangledName(); break;
case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
default: default:
break; break;
} }
...@@ -89,46 +92,68 @@ int TType::getStructSize() const ...@@ -89,46 +92,68 @@ int TType::getStructSize() const
return 0; return 0;
} }
if (structureSize == 0) return getStruct()->objectSize();
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
structureSize += ((*tl).type)->getObjectSize();
return structureSize;
} }
void TType::computeDeepestStructNesting() void TType::computeDeepestStructNesting()
{ {
if (!structure) deepestStructNesting = structure ? structure->deepestNesting() : 0;
{ }
return;
}
int maxNesting = 0; bool TStructure::containsArrays() const
for (TTypeList::const_iterator tl = structure->begin(); tl != structure->end(); tl++) {
{ for(size_t i = 0; i < mFields->size(); ++i)
maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting()); {
} const TType *fieldType = (*mFields)[i]->type();
if(fieldType->isArray() || fieldType->isStructureContainingArrays())
return true;
}
return false;
}
deepestStructNesting = 1 + maxNesting; bool TStructure::containsSamplers() const
{
for(size_t i = 0; i < mFields->size(); ++i)
{
const TType *fieldType = (*mFields)[i]->type();
if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
return true;
}
return false;
} }
bool TType::isStructureContainingArrays() const TString TFieldListCollection::buildMangledName() const
{ {
if (!structure) TString mangledName(mangledNamePrefix());
{ mangledName += *mName;
return false; for(size_t i = 0; i < mFields->size(); ++i)
} {
mangledName += '-';
mangledName += (*mFields)[i]->type()->getMangledName();
}
return mangledName;
}
for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++) size_t TFieldListCollection::calculateObjectSize() const
{ {
if (member->type->isArray() || size_t size = 0;
member->type->isStructureContainingArrays()) for(size_t i = 0; i < mFields->size(); ++i)
{ {
return true; size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
} if(fieldSize > INT_MAX - size)
} size = INT_MAX;
else
size += fieldSize;
}
return size;
}
return false; 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 1 + maxNesting;
} }
// //
......
...@@ -75,8 +75,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). ...@@ -75,8 +75,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TQualifier qualifier; TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TTypeLine typeLine; TField* field;
TTypeList* typeList; TFieldList* fieldList;
}; };
} interm; } interm;
} }
...@@ -176,8 +176,8 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -176,8 +176,8 @@ extern void yyerror(TParseContext* context, const char* reason);
%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier %type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier
%type <interm.type> type_specifier_no_prec type_specifier_nonarray %type <interm.type> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier %type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator %type <interm.field> struct_declarator
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier %type <interm.function> function_header function_declarator function_identifier
%type <interm.function> function_header_with_parameters function_call_header %type <interm.function> function_header_with_parameters function_call_header
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
...@@ -316,7 +316,7 @@ postfix_expression ...@@ -316,7 +316,7 @@ postfix_expression
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), $2.line); $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), $2.line);
} else if ($1->isArray()) { } else if ($1->isArray()) {
if ($1->getType().getStruct()) if ($1->getType().getStruct())
$$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName())); $$->setType(TType($1->getType().getStruct()));
else else
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->getSecondarySize())); $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->getSecondarySize()));
...@@ -391,15 +391,16 @@ postfix_expression ...@@ -391,15 +391,16 @@ postfix_expression
} }
} else if ($1->getBasicType() == EbtStruct) { } else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false; bool fieldFound = false;
const TTypeList* fields = $1->getType().getStruct(); const TStructure* structure = $1->getType().getStruct();
if (fields == 0) { if (structure == 0) {
context->error($2.line, "structure has no fields", "Internal Error"); context->error($2.line, "structure has no fields", "Internal Error");
context->recover(); context->recover();
$$ = $1; $$ = $1;
} else { } else {
unsigned int i; unsigned int i;
for (i = 0; i < fields->size(); ++i) { const TFieldList& fields = structure->fields();
if ((*fields)[i].type->getFieldName() == *$3.string) { for (i = 0; i < fields.size(); ++i) {
if (fields[i]->name() == *$3.string) {
fieldFound = true; fieldFound = true;
break; break;
} }
...@@ -412,7 +413,7 @@ postfix_expression ...@@ -412,7 +413,7 @@ postfix_expression
$$ = $1; $$ = $1;
} }
else { else {
$$->setType(*(*fields)[i].type); $$->setType(*fields[i]->type());
// change the qualifier of the return type, not of the structure field // change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures. // as the structure definition is shared between various structures.
$$->getTypePointer()->setQualifier(EvqConstExpr); $$->getTypePointer()->setQualifier(EvqConstExpr);
...@@ -420,9 +421,9 @@ postfix_expression ...@@ -420,9 +421,9 @@ postfix_expression
} else { } else {
ConstantUnion *unionArray = new ConstantUnion[1]; ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i); unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line); TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(fields[i]->type()), $3.line);
$$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line); $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
$$->setType(*(*fields)[i].type); $$->setType(*fields[i]->type());
} }
} else { } else {
context->error($2.line, " no such field in structure", $3.string->c_str()); context->error($2.line, " no such field in structure", $3.string->c_str());
...@@ -2007,7 +2008,7 @@ struct_specifier ...@@ -2007,7 +2008,7 @@ struct_specifier
if (context->reservedErrorCheck($2.line, *$2.string)) if (context->reservedErrorCheck($2.line, *$2.string))
context->recover(); context->recover();
TType* structure = new TType($5, *$2.string); TType* structure = new TType(new TStructure($2.string, $5));
TVariable* userTypeDef = new TVariable($2.string, *structure, true); TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! context->symbolTable.declare(*userTypeDef)) { if (! context->symbolTable.declare(*userTypeDef)) {
context->error($2.line, "redefinition", $2.string->c_str(), "struct"); context->error($2.line, "redefinition", $2.string->c_str(), "struct");
...@@ -2018,7 +2019,8 @@ struct_specifier ...@@ -2018,7 +2019,8 @@ struct_specifier
context->exitStructDeclaration(); context->exitStructDeclaration();
} }
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { | STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4, TString("")); TString emptyName("");
TType* structure = new TType(new TStructure(&emptyName, $4));
$$.setBasic(EbtStruct, EvqTemporary, $1.line); $$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.userDef = structure; $$.userDef = structure;
context->exitStructDeclaration(); context->exitStructDeclaration();
...@@ -2032,9 +2034,10 @@ struct_declaration_list ...@@ -2032,9 +2034,10 @@ struct_declaration_list
| struct_declaration_list struct_declaration { | struct_declaration_list struct_declaration {
$$ = $1; $$ = $1;
for (unsigned int i = 0; i < $2->size(); ++i) { for (unsigned int i = 0; i < $2->size(); ++i) {
TField* field = (*$2)[i];
for (unsigned int j = 0; j < $$->size(); ++j) { for (unsigned int j = 0; j < $$->size(); ++j) {
if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) { if ((*$$)[j]->name() == field->name()) {
context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str()); context->error((*$2)[i]->line(), "duplicate field name in structure:", "struct", field->name().c_str());
context->recover(); context->recover();
} }
} }
...@@ -2047,14 +2050,14 @@ struct_declaration ...@@ -2047,14 +2050,14 @@ struct_declaration
: type_specifier struct_declarator_list SEMICOLON { : type_specifier struct_declarator_list SEMICOLON {
$$ = $2; $$ = $2;
if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) { if (context->voidErrorCheck($1.line, (*$2)[0]->name(), $1)) {
context->recover(); context->recover();
} }
for (unsigned int i = 0; i < $$->size(); ++i) { for (unsigned int i = 0; i < $$->size(); ++i) {
// //
// Careful not to replace already known aspects of type, like array-ness // Careful not to replace already known aspects of type, like array-ness
// //
TType* type = (*$$)[i].type; TType* type = (*$$)[i]->type();
type->setBasicType($1.type); type->setBasicType($1.type);
type->setNominalSize($1.primarySize); type->setNominalSize($1.primarySize);
type->setSecondarySize($1.secondarySize); type->setSecondarySize($1.secondarySize);
...@@ -2069,7 +2072,6 @@ struct_declaration ...@@ -2069,7 +2072,6 @@ struct_declaration
type->setArraySize($1.arraySize); type->setArraySize($1.arraySize);
if ($1.userDef) { if ($1.userDef) {
type->setStruct($1.userDef->getStruct()); type->setStruct($1.userDef->getStruct());
type->setTypeName($1.userDef->getTypeName());
} }
} }
} }
...@@ -2077,7 +2079,7 @@ struct_declaration ...@@ -2077,7 +2079,7 @@ struct_declaration
struct_declarator_list struct_declarator_list
: struct_declarator { : struct_declarator {
$$ = NewPoolTTypeList(); $$ = NewPoolTFieldList();
$$->push_back($1); $$->push_back($1);
} }
| struct_declarator_list COMMA struct_declarator { | struct_declarator_list COMMA struct_declarator {
...@@ -2090,22 +2092,20 @@ struct_declarator ...@@ -2090,22 +2092,20 @@ struct_declarator
if (context->reservedErrorCheck($1.line, *$1.string)) if (context->reservedErrorCheck($1.line, *$1.string))
context->recover(); context->recover();
$$.type = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
$$.line = $1.line; $$ = new TField(type, $1.string, $1.line);
$$.type->setFieldName(*$1.string);
} }
| IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck($1.line, *$1.string)) if (context->reservedErrorCheck($1.line, *$1.string))
context->recover(); context->recover();
$$.type = new TType(EbtVoid, EbpUndefined); TType* type = new TType(EbtVoid, EbpUndefined);
$$.line = $1.line;
$$.type->setFieldName(*$1.string);
int size; int size;
if (context->arraySizeErrorCheck($2.line, $3, size)) if (context->arraySizeErrorCheck($3->getLine(), $3, size))
context->recover(); context->recover();
$$.type->setArraySize(size); type->setArraySize(size);
$$ = new TField(type, $1.string, $1.line);
} }
; ;
......
...@@ -201,8 +201,8 @@ typedef union YYSTYPE ...@@ -201,8 +201,8 @@ typedef union YYSTYPE
TQualifier qualifier; TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TTypeLine typeLine; TField* field;
TTypeList* typeList; TFieldList* fieldList;
}; };
} interm; } interm;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment