//
// Depth range in window coordinates
//
- TTypeList *members = NewPoolTTypeList();
- TTypeLine near = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0};
- TTypeLine far = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0};
- TTypeLine diff = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0};
- near.type->setFieldName("near");
- far.type->setFieldName("far");
- diff.type->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"), 0);
+ TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), 0);
+ TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), 0);
+ 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(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);
symbolTable.insert(COMMON_BUILTINS, *depthRange);
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;
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++) {
- if ((*fields)[j].type->getBasicType() == EbtStruct) {
- if (!CompareStructure(*(*fields)[j].type, &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])
{\r
ASSERT(leftType.isStruct());\r
\r
- const TTypeList *structure = leftType.getStruct();\r
- const TString &fieldName = rightType.getFieldName();\r
+ const TFieldList& fields = leftType.getStruct()->fields();\r
+ int index = right->getAsConstantUnion()->getIConst(0);\r
int fieldOffset = 0;\r
\r
- for(size_t i = 0; i < structure->size(); i++)\r
+ for(int i = 0; i < index; i++)\r
{\r
- const TType &fieldType = *(*structure)[i].type;\r
-\r
- if(fieldType.getFieldName() == fieldName)\r
- {\r
- break;\r
- }\r
-\r
- fieldOffset += fieldType.totalRegisterCount();\r
+ fieldOffset += fields[i]->type()->totalRegisterCount();\r
}\r
\r
copy(result, left, fieldOffset);\r
\r
if(type.isStruct())\r
{\r
- TTypeList *structure = type.getStruct();\r
+ const TFieldList& fields = type.getStruct()->fields();\r
int elements = 0;\r
\r
- for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)\r
+ for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)\r
{\r
- const TType &fieldType = *field->type;\r
+ const TType &fieldType = *((*field)->type());\r
\r
if(fieldType.totalRegisterCount() <= registers)\r
{\r
{\r
if(type.isStruct())\r
{\r
- return registerSize(*type.getStruct()->begin()->type, 0);\r
+ return registerSize(*((*(type.getStruct()->fields().begin()))->type()), 0);\r
}\r
\r
return type.isMatrix() ? type.getSecondarySize() : type.getNominalSize();\r
\r
if(type.isStruct())\r
{\r
- TTypeList *structure = type.getStruct();\r
+ const TFieldList& fields = type.getStruct()->fields();\r
int elements = 0;\r
\r
- for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)\r
+ for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)\r
{\r
- const TType &fieldType = *field->type;\r
+ const TType &fieldType = *((*field)->type());\r
\r
if(fieldType.totalRegisterCount() <= registers)\r
{\r
{\r
TIntermTyped *arg = argument->getAsTyped();\r
const TType &type = arg->getType();\r
- const TTypeList *structure = type.getStruct();\r
index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;\r
\r
int size = registerSize(type, index);\r
break;\r
case EOpIndexDirectStruct:\r
{\r
- const TTypeList *structure = left->getType().getStruct();\r
- const TString &fieldName = right->getType().getFieldName();\r
+ const TFieldList& fields = left->getType().getStruct()->fields();\r
+ int index = right->getAsConstantUnion()->getIConst(0);\r
+ int fieldOffset = 0;\r
\r
- int offset = 0;\r
- for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)\r
+ for(int i = 0; i < index; i++)\r
{\r
- if(field->type->getFieldName() == fieldName)\r
- {\r
- dst.type = registerType(left);\r
- dst.index += offset;\r
- dst.mask = writeMask(right);\r
- \r
- return 0xE4;\r
- }\r
-\r
- offset += field->type->totalRegisterCount();\r
+ fieldOffset += fields[i]->type()->totalRegisterCount();\r
}\r
+\r
+ dst.type = registerType(left);\r
+ dst.index += fieldOffset;\r
+ dst.mask = writeMask(right);\r
+\r
+ return 0xE4;\r
}\r
break;\r
case EOpVectorSwizzle:\r
\r
void OutputASM::declareUniform(const TType &type, const TString &name, int index)\r
{\r
- const TTypeList *structure = type.getStruct();\r
+ const TStructure *structure = type.getStruct();\r
ActiveUniforms &activeUniforms = shaderObject->activeUniforms;\r
\r
if(!structure)\r
}\r
else\r
{\r
+ const TFieldList& fields = structure->fields();\r
if(type.isArray())\r
{\r
int elementIndex = index;\r
\r
for(int i = 0; i < type.getArraySize(); i++)\r
{\r
- for(size_t j = 0; j < structure->size(); j++)\r
+ for(size_t j = 0; j < fields.size(); j++)\r
{\r
- const TType &fieldType = *(*structure)[j].type;\r
- const TString &fieldName = fieldType.getFieldName();\r
+ const TType &fieldType = *(fields[j]->type());\r
+ const TString &fieldName = fields[j]->name();\r
\r
const TString uniformName = name + "[" + str(i) + "]." + fieldName;\r
declareUniform(fieldType, uniformName, elementIndex);\r
{\r
int fieldIndex = index;\r
\r
- for(size_t i = 0; i < structure->size(); i++)\r
+ for(size_t i = 0; i < fields.size(); i++)\r
{\r
- const TType &fieldType = *(*structure)[i].type;\r
- const TString &fieldName = fieldType.getFieldName();\r
+ const TType &fieldType = *(fields[i]->type());\r
+ const TString &fieldName = fields[i]->name();\r
\r
const TString uniformName = name + "." + fieldName;\r
declareUniform(fieldType, uniformName, fieldIndex);\r
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;
}
return true;
if (type.getBasicType() == EbtStruct) {
- TTypeList& structure = *type.getStruct();
- for (unsigned int i = 0; i < structure.size(); ++i) {
- if (containsSampler(*structure[i].type))
+ const TFieldList& fields = type.getStruct()->fields();
+ for(unsigned int i = 0; i < fields.size(); ++i) {
+ if (containsSampler(*fields[i]->type()))
return true;
}
}
if(op == EOpConstructStruct)
{
- TTypeList &fields = *type->getStruct();
+ const TFieldList &fields = type->getStruct()->fields();
TIntermSequence &args = aggregateArguments->getSequence();
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");
recover();
//
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
{
- const TTypeList* fields = node->getType().getStruct();
+ const TFieldList &fields = node->getType().getStruct()->fields();
TIntermTyped *typedNode;
int instanceSize = 0;
unsigned int index = 0;
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
- for ( index = 0; index < fields->size(); ++index) {
- if ((*fields)[index].type->getFieldName() == identifier) {
+ for ( index = 0; index < fields.size(); ++index) {
+ if (fields[index]->name() == identifier) {
break;
} else {
- instanceSize += (*fields)[index].type->getObjectSize();
+ instanceSize += fields[index]->type()->getObjectSize();
}
}
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),
- 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)
{
structure = p.userDef->getStruct();
- typeName = NewPoolTString(p.userDef->getTypeName().c_str());
computeDeepestStructNesting();
}
}
case EbtUInt: mangledName += 'u'; break;
case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break;
- case EbtSamplerCube: mangledName += "sC"; break;
- case EbtSamplerExternalOES: mangledName += "sE"; break;
case EbtSampler3D: mangledName += "s3"; 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].type->buildMangledName(mangledName);
- }
- }
+ case EbtSamplerCube: mangledName += "sC"; break;
+ case EbtSampler2DArray: mangledName += "s2a"; break;
+ case EbtSamplerExternalOES: mangledName += "sext"; break;
+ case EbtISampler2D: mangledName += "is2"; break;
+ case EbtISampler3D: mangledName += "is3"; break;
+ case EbtISamplerCube: mangledName += "isC"; break;
+ case EbtISampler2DArray: mangledName += "is2a"; break;
+ 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:
break;
}
return 0;
}
- if (structureSize == 0)
- for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
- structureSize += ((*tl).type)->getObjectSize();
-
- return structureSize;
+ return getStruct()->objectSize();
}
void TType::computeDeepestStructNesting()
{
- if (!structure)
- {
- return;
- }
+ deepestStructNesting = structure ? structure->deepestNesting() : 0;
+}
- int maxNesting = 0;
- for (TTypeList::const_iterator tl = structure->begin(); tl != structure->end(); tl++)
- {
- maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
- }
+bool TStructure::containsArrays() const
+{
+ for(size_t i = 0; i < mFields->size(); ++i)
+ {
+ 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)
- {
- return false;
- }
+ TString mangledName(mangledNamePrefix());
+ mangledName += *mName;
+ 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++)
- {
- if (member->type->isArray() ||
- member->type->isStructureContainingArrays())
- {
- return true;
- }
- }
+size_t TFieldListCollection::calculateObjectSize() const
+{
+ 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;
+}
- 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;
}
//
class TType;
struct TPublicType;
-//
-// Need to have association of line numbers to types in a list for building structs.
-//
-struct TTypeLine {
- TType* type;
- int line;
+class TField
+{
+public:
+ POOL_ALLOCATOR_NEW_DELETE();
+ TField(TType *type, TString *name, const TSourceLoc &line)
+ : mType(type),
+ mName(name),
+ mLine(line)
+ {
+ }
+
+ // 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;
+ }
+ const TSourceLoc &line() const
+ {
+ return mLine;
+ }
+
+private:
+ TType *mType;
+ TString *mName;
+ TSourceLoc mLine;
};
-typedef TVector<TTypeLine> TTypeList;
-inline TTypeList* NewPoolTTypeList()
+typedef TVector<TField *> TFieldList;
+inline TFieldList *NewPoolTFieldList()
{
- void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TTypeList));
- return new(memory) TTypeList;
+ void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
+ return new(memory)TFieldList;
}
+class TFieldListCollection
+{
+public:
+ 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;
+ };
+
+protected:
+ TFieldListCollection(const TString *name, TFieldList *fields)
+ : mName(name),
+ mFields(fields),
+ mObjectSize(0)
+ {
+ }
+ TString buildMangledName() const;
+ size_t calculateObjectSize() const;
+ virtual TString mangledNamePrefix() const = 0;
+
+ const TString *mName;
+ TFieldList *mFields;
+
+ mutable TString mMangledName;
+ mutable size_t mObjectSize;
+};
+
+// May also represent interface blocks
+class TStructure : public TFieldListCollection
+{
+public:
+ POOL_ALLOCATOR_NEW_DELETE();
+ TStructure(const TString *name, TFieldList *fields)
+ : TFieldListCollection(name, fields),
+ mDeepestNesting(0),
+ mUniqueId(0),
+ mAtGlobalScope(false)
+ {
+ }
+
+ int deepestNesting() const
+ {
+ if(mDeepestNesting == 0)
+ mDeepestNesting = calculateDeepestNesting();
+ return mDeepestNesting;
+ }
+ bool containsArrays() const;
+ bool containsSamplers() const;
+
+ bool equals(const TStructure &other) const;
+
+ void setUniqueId(int uniqueId)
+ {
+ mUniqueId = uniqueId;
+ }
+
+ int uniqueId() const
+ {
+ ASSERT(mUniqueId != 0);
+ return mUniqueId;
+ }
+
+ void setAtGlobalScope(bool atGlobalScope)
+ {
+ mAtGlobalScope = atGlobalScope;
+ }
+
+ bool atGlobalScope() const
+ {
+ return mAtGlobalScope;
+ }
+
+private:
+ // TODO(zmo): Find a way to get rid of the const_cast in function
+ // setName(). At the moment keep this function private so only
+ // friend class RegenerateStructNames may call it.
+ friend class RegenerateStructNames;
+ void setName(const TString &name)
+ {
+ TString *mutableName = const_cast<TString *>(mName);
+ *mutableName = name;
+ }
+
+ virtual TString mangledNamePrefix() const
+ {
+ return "struct-";
+ }
+ int calculateDeepestNesting() const;
+
+ mutable int mDeepestNesting;
+ int mUniqueId;
+ bool mAtGlobalScope;
+};
+
+class TInterfaceBlock : public TFieldListCollection
+{
+public:
+ POOL_ALLOCATOR_NEW_DELETE();
+ TInterfaceBlock(const TString *name, TFieldList *fields, const TString *instanceName,
+ int arraySize, const TLayoutQualifier &layoutQualifier)
+ : TFieldListCollection(name, fields),
+ mInstanceName(instanceName),
+ mArraySize(arraySize),
+ mBlockStorage(layoutQualifier.blockStorage),
+ mMatrixPacking(layoutQualifier.matrixPacking)
+ {
+ }
+
+ const TString &instanceName() const
+ {
+ return *mInstanceName;
+ }
+ bool hasInstanceName() const
+ {
+ return mInstanceName != NULL;
+ }
+ bool isArray() const
+ {
+ return mArraySize > 0;
+ }
+ int arraySize() const
+ {
+ return mArraySize;
+ }
+ TLayoutBlockStorage blockStorage() const
+ {
+ return mBlockStorage;
+ }
+ TLayoutMatrixPacking matrixPacking() const
+ {
+ return mMatrixPacking;
+ }
+
+private:
+ virtual TString mangledNamePrefix() const
+ {
+ return "iblock-";
+ }
+
+ const TString *mInstanceName; // for interface block instance names
+ int mArraySize; // 0 if not an array
+ TLayoutBlockStorage mBlockStorage;
+ TLayoutMatrixPacking mMatrixPacking;
+};
+
//
// Base class for things that have a type.
//
POOL_ALLOCATOR_NEW_DELETE();
TType() {}
TType(TBasicType t, int s0 = 1, int s1 = 1) :
- type(t), precision(EbpUndefined), qualifier(EvqGlobal), primarySize(s0), secondarySize(s1), array(false), arraySize(0),
- maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
+ type(t), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), layoutQualifier(TLayoutQualifier::create()),
+ primarySize(s0), secondarySize(s1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
+ structure(0), deepestStructNesting(0), mangled(0)
{
}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s0 = 1, int s1 = 1, bool a = false) :
- type(t), precision(p), qualifier(q), primarySize(s0), secondarySize(s1), array(a), arraySize(0),
- maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
+ type(t), precision(p), qualifier(q), invariant(false), layoutQualifier(TLayoutQualifier::create()),
+ primarySize(s0), secondarySize(s1), array(a), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
+ structure(0), deepestStructNesting(0), mangled(0)
{
}
explicit TType(const TPublicType &p);
- TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
- type(EbtStruct), precision(p), qualifier(EvqTemporary), primarySize(1), secondarySize(1), array(false), arraySize(0),
- maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0)
+ TType(TStructure* userDef, TPrecision p = EbpUndefined) :
+ type(EbtStruct), precision(p), qualifier(EvqTemporary), invariant(false), layoutQualifier(TLayoutQualifier::create()),
+ primarySize(1), secondarySize(1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
+ structure(userDef), deepestStructNesting(0), mangled(0)
{
- typeName = NewPoolTString(n.c_str());
}
+ TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn, int arraySizeIn)
+ : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
+ invariant(false), layoutQualifier(layoutQualifierIn),
+ primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn), maxArraySize(0), arrayInformationType(0),
+ interfaceBlock(interfaceBlockIn), structure(0), deepestStructNesting(0), mangled(0)
+ {
+ }
+
TBasicType getBasicType() const { return type; }
void setBasicType(TBasicType t) { type = t; }
TQualifier getQualifier() const { return qualifier; }
void setQualifier(TQualifier q) { qualifier = q; }
+ bool isInvariant() const { return invariant; }
+
+ TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
+ void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
+
// One-dimensional size of single instance type
int getNominalSize() const { return primarySize; }
void setNominalSize(int s) { primarySize = s; }
int elementRegisterCount() const
{
- TTypeList *structure = getStruct();
-
if(structure)
{
int registerCount = 0;
- for(size_t i = 0; i < structure->size(); i++)
+ const TFieldList& fields = getStruct()->fields();
+ for(size_t i = 0; i < fields.size(); i++)
{
- registerCount += (*structure)[i].type->totalRegisterCount();
+ registerCount += fields[i]->type()->totalRegisterCount();
}
return registerCount;
void setArrayInformationType(TType* t) { arrayInformationType = t; }
TType* getArrayInformationType() const { return arrayInformationType; }
+ TInterfaceBlock *getInterfaceBlock() const { return interfaceBlock; }
+ void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) { interfaceBlock = interfaceBlockIn; }
+ bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
+
bool isVector() const { return primarySize > 1 && !isMatrix(); }
bool isScalar() const { return primarySize == 1 && !isMatrix() && !structure; }
bool isRegister() const { return !isMatrix() && !structure && !array; } // Fits in a 4-element register
bool isStruct() const { return structure != 0; }
bool isScalarInt() const { return isScalar() && IsInteger(type); }
- 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; computeDeepestStructNesting(); }
TString& getMangledName() {
if (!mangled) {
// 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;
+ }
+
+ bool isStructureContainingSamplers() const
+ {
+ return structure ? structure->containsSamplers() : false;
+ }
protected:
void buildMangledName(TString&);
TBasicType type;
TPrecision precision;
TQualifier qualifier;
+ bool invariant;
+ TLayoutQualifier layoutQualifier;
unsigned char primarySize; // size of vector or matrix, not size of array
unsigned char secondarySize; // secondarySize: 1 for vectors, >1 for matrices
bool array;
int maxArraySize;
TType *arrayInformationType;
- TTypeList *structure; // 0 unless this is a struct
- mutable int structureSize;
+ // 0 unless this is an interface block, or interface block member variable
+ TInterfaceBlock *interfaceBlock;
+
+ TStructure *structure; // 0 unless this is a struct
int deepestStructNesting;
- TString *fieldName; // for structure field names
TString *mangled;
- TString *typeName; // for structure field type name
};
//
secondarySize = s1;
}
+ bool isUnsizedArray() const
+ {
+ return array && arraySize == 0;
+ }
+
void setArray(bool a, int s = 0)
{
array = a;
return userDef->isStructureContainingArrays();
}
+
+ bool isMatrix() const
+ {
+ return primarySize > 1 && secondarySize > 1;
+ }
+
+ bool isVector() const
+ {
+ return primarySize > 1 && secondarySize == 1;
+ }
+
+ int getCols() const
+ {
+ ASSERT(isMatrix());
+ return primarySize;
+ }
+
+ int getRows() const
+ {
+ ASSERT(isMatrix());
+ return secondarySize;
+ }
+
+ int getNominalSize() const
+ {
+ return primarySize;
+ }
+
+ bool isAggregate() const
+ {
+ return array || isMatrix() || isVector();
+ }
};
#endif // _TYPES_INCLUDED_
TQualifier qualifier;
TFunction* function;
TParameter param;
- TTypeLine typeLine;
- TTypeList* typeList;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;
}
%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> struct_specifier
-%type <interm.typeLine> struct_declarator
-%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
+%type <interm.field> struct_declarator
+%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
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), $2.line);
} 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->getSecondarySize()));
}
} else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false;
- const TTypeList* fields = $1->getType().getStruct();
- if (fields == 0) {
+ const TStructure* structure = $1->getType().getStruct();
+ if (structure == 0) {
context->error($2.line, "structure has no fields", "Internal Error");
context->recover();
$$ = $1;
} else {
unsigned int i;
- for (i = 0; i < fields->size(); ++i) {
- if ((*fields)[i].type->getFieldName() == *$3.string) {
+ const TFieldList& fields = structure->fields();
+ for (i = 0; i < fields.size(); ++i) {
+ if (fields[i]->name() == *$3.string) {
fieldFound = true;
break;
}
$$ = $1;
}
else {
- $$->setType(*(*fields)[i].type);
+ $$->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(EvqConstExpr);
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
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);
- $$->setType(*(*fields)[i].type);
+ $$->setType(*fields[i]->type());
}
} else {
context->error($2.line, " no such field in structure", $3.string->c_str());
if (context->reservedErrorCheck($2.line, *$2.string))
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);
if (! context->symbolTable.declare(*userTypeDef)) {
context->error($2.line, "redefinition", $2.string->c_str(), "struct");
context->exitStructDeclaration();
}
| 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);
$$.userDef = structure;
context->exitStructDeclaration();
| struct_declaration_list struct_declaration {
$$ = $1;
for (unsigned int i = 0; i < $2->size(); ++i) {
+ TField* field = (*$2)[i];
for (unsigned int j = 0; j < $$->size(); ++j) {
- if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
- context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
+ if ((*$$)[j]->name() == field->name()) {
+ context->error((*$2)[i]->line(), "duplicate field name in structure:", "struct", field->name().c_str());
context->recover();
}
}
: type_specifier struct_declarator_list SEMICOLON {
$$ = $2;
- if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
+ if (context->voidErrorCheck($1.line, (*$2)[0]->name(), $1)) {
context->recover();
}
for (unsigned int i = 0; i < $$->size(); ++i) {
//
// 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->setNominalSize($1.primarySize);
type->setSecondarySize($1.secondarySize);
type->setArraySize($1.arraySize);
if ($1.userDef) {
type->setStruct($1.userDef->getStruct());
- type->setTypeName($1.userDef->getTypeName());
}
}
}
struct_declarator_list
: struct_declarator {
- $$ = NewPoolTTypeList();
+ $$ = NewPoolTFieldList();
$$->push_back($1);
}
| struct_declarator_list COMMA struct_declarator {
if (context->reservedErrorCheck($1.line, *$1.string))
context->recover();
- $$.type = new TType(EbtVoid, EbpUndefined);
- $$.line = $1.line;
- $$.type->setFieldName(*$1.string);
+ TType* type = new TType(EbtVoid, EbpUndefined);
+ $$ = new TField(type, $1.string, $1.line);
}
| IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck($1.line, *$1.string))
context->recover();
- $$.type = new TType(EbtVoid, EbpUndefined);
- $$.line = $1.line;
- $$.type->setFieldName(*$1.string);
-
+ TType* type = new TType(EbtVoid, EbpUndefined);
int size;
- if (context->arraySizeErrorCheck($2.line, $3, size))
+ if (context->arraySizeErrorCheck($3->getLine(), $3, size))
context->recover();
- $$.type->setArraySize(size);
+ type->setArraySize(size);
+
+ $$ = new TField(type, $1.string, $1.line);
}
;
TQualifier qualifier;
TFunction* function;
TParameter param;
- TTypeLine typeLine;
- TTypeList* typeList;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;
static const yytype_uint16 yyrline[] =
{
0, 190, 190, 225, 228, 233, 238, 243, 248, 254,
- 257, 336, 339, 440, 450, 463, 471, 571, 574, 582,
- 586, 593, 597, 604, 610, 619, 627, 704, 711, 721,
- 724, 734, 744, 766, 767, 768, 769, 777, 778, 787,
- 796, 809, 810, 818, 829, 830, 839, 851, 852, 862,
- 872, 882, 895, 896, 906, 919, 920, 934, 935, 949,
- 950, 964, 965, 978, 979, 992, 993, 1006, 1007, 1024,
- 1025, 1038, 1039, 1040, 1041, 1043, 1044, 1045, 1047, 1049,
- 1051, 1053, 1058, 1061, 1072, 1080, 1107, 1112, 1122, 1160,
- 1163, 1170, 1178, 1199, 1220, 1231, 1260, 1265, 1275, 1280,
- 1290, 1293, 1296, 1299, 1305, 1312, 1315, 1337, 1355, 1379,
- 1402, 1406, 1424, 1432, 1464, 1484, 1572, 1582, 1588, 1591,
- 1597, 1603, 1610, 1619, 1628, 1631, 1634, 1641, 1645, 1652,
- 1656, 1661, 1666, 1676, 1686, 1695, 1705, 1712, 1715, 1718,
- 1724, 1731, 1734, 1740, 1743, 1746, 1752, 1755, 1770, 1774,
- 1778, 1782, 1786, 1790, 1795, 1800, 1805, 1810, 1815, 1820,
- 1825, 1830, 1835, 1840, 1845, 1850, 1856, 1862, 1868, 1874,
- 1880, 1886, 1892, 1898, 1904, 1909, 1914, 1923, 1928, 1933,
- 1938, 1943, 1948, 1953, 1958, 1963, 1968, 1973, 1978, 1983,
- 1988, 1993, 2006, 2006, 2020, 2020, 2029, 2032, 2047, 2079,
- 2083, 2089, 2097, 2113, 2117, 2121, 2122, 2128, 2129, 2130,
+ 257, 336, 339, 441, 451, 464, 472, 572, 575, 583,
+ 587, 594, 598, 605, 611, 620, 628, 705, 712, 722,
+ 725, 735, 745, 767, 768, 769, 770, 778, 779, 788,
+ 797, 810, 811, 819, 830, 831, 840, 852, 853, 863,
+ 873, 883, 896, 897, 907, 920, 921, 935, 936, 950,
+ 951, 965, 966, 979, 980, 993, 994, 1007, 1008, 1025,
+ 1026, 1039, 1040, 1041, 1042, 1044, 1045, 1046, 1048, 1050,
+ 1052, 1054, 1059, 1062, 1073, 1081, 1108, 1113, 1123, 1161,
+ 1164, 1171, 1179, 1200, 1221, 1232, 1261, 1266, 1276, 1281,
+ 1291, 1294, 1297, 1300, 1306, 1313, 1316, 1338, 1356, 1380,
+ 1403, 1407, 1425, 1433, 1465, 1485, 1573, 1583, 1589, 1592,
+ 1598, 1604, 1611, 1620, 1629, 1632, 1635, 1642, 1646, 1653,
+ 1657, 1662, 1667, 1677, 1687, 1696, 1706, 1713, 1716, 1719,
+ 1725, 1732, 1735, 1741, 1744, 1747, 1753, 1756, 1771, 1775,
+ 1779, 1783, 1787, 1791, 1796, 1801, 1806, 1811, 1816, 1821,
+ 1826, 1831, 1836, 1841, 1846, 1851, 1857, 1863, 1869, 1875,
+ 1881, 1887, 1893, 1899, 1905, 1910, 1915, 1924, 1929, 1934,
+ 1939, 1944, 1949, 1954, 1959, 1964, 1969, 1974, 1979, 1984,
+ 1989, 1994, 2007, 2007, 2021, 2021, 2031, 2034, 2050, 2081,
+ 2085, 2091, 2098, 2113, 2117, 2121, 2122, 2128, 2129, 2130,
2131, 2132, 2136, 2137, 2137, 2137, 2147, 2148, 2152, 2152,
2153, 2153, 2158, 2161, 2171, 2174, 2180, 2181, 2185, 2193,
2197, 2207, 2212, 2229, 2229, 2234, 2234, 2241, 2241, 2249,
(yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), (yyvsp[(2) - (4)].lex).line);
} 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)->getSecondarySize()));
}
} 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) {
+ const TStructure* structure = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct();
+ if (structure == 0) {
context->error((yyvsp[(2) - (3)].lex).line, "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].type->getFieldName() == *(yyvsp[(3) - (3)].lex).string) {
+ const TFieldList& fields = structure->fields();
+ for (i = 0; i < fields.size(); ++i) {
+ if (fields[i]->name() == *(yyvsp[(3) - (3)].lex).string) {
fieldFound = true;
break;
}
(yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
}
else {
- (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
+ (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(EvqConstExpr);
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
- TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, (yyvsp[(3) - (3)].lex).line);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(fields[i]->type()), (yyvsp[(3) - (3)].lex).line);
(yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
- (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
+ (yyval.interm.intermTypedNode)->setType(*fields[i]->type());
}
} else {
context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str());
if (context->reservedErrorCheck((yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].lex).string))
context->recover();
- TType* structure = new TType((yyvsp[(5) - (6)].interm.typeList), *(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.declare(*userTypeDef)) {
context->error((yyvsp[(2) - (6)].lex).line, "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct");
case 195:
{
- TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), TString(""));
+ TString emptyName("");
+ TType* structure = new TType(new TStructure(&emptyName, (yyvsp[(4) - (5)].interm.fieldList)));
(yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
(yyval.interm.type).userDef = structure;
context->exitStructDeclaration();
case 196:
{
- (yyval.interm.typeList) = (yyvsp[(1) - (1)].interm.typeList);
+ (yyval.interm.fieldList) = (yyvsp[(1) - (1)].interm.fieldList);
}
break;
case 197:
{
- (yyval.interm.typeList) = (yyvsp[(1) - (2)].interm.typeList);
- for (unsigned int i = 0; i < (yyvsp[(2) - (2)].interm.typeList)->size(); ++i) {
- for (unsigned int j = 0; j < (yyval.interm.typeList)->size(); ++j) {
- if ((*(yyval.interm.typeList))[j].type->getFieldName() == (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName()) {
- context->error((*(yyvsp[(2) - (2)].interm.typeList))[i].line, "duplicate field name in structure:", "struct", (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName().c_str());
+ (yyval.interm.fieldList) = (yyvsp[(1) - (2)].interm.fieldList);
+ for (unsigned int i = 0; i < (yyvsp[(2) - (2)].interm.fieldList)->size(); ++i) {
+ TField* field = (*(yyvsp[(2) - (2)].interm.fieldList))[i];
+ for (unsigned int j = 0; j < (yyval.interm.fieldList)->size(); ++j) {
+ if ((*(yyval.interm.fieldList))[j]->name() == field->name()) {
+ context->error((*(yyvsp[(2) - (2)].interm.fieldList))[i]->line(), "duplicate field name in structure:", "struct", field->name().c_str());
context->recover();
}
}
- (yyval.interm.typeList)->push_back((*(yyvsp[(2) - (2)].interm.typeList))[i]);
+ (yyval.interm.fieldList)->push_back((*(yyvsp[(2) - (2)].interm.fieldList))[i]);
}
}
break;
case 198:
{
- (yyval.interm.typeList) = (yyvsp[(2) - (3)].interm.typeList);
+ (yyval.interm.fieldList) = (yyvsp[(2) - (3)].interm.fieldList);
- if (context->voidErrorCheck((yyvsp[(1) - (3)].interm.type).line, (*(yyvsp[(2) - (3)].interm.typeList))[0].type->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
+ if (context->voidErrorCheck((yyvsp[(1) - (3)].interm.type).line, (*(yyvsp[(2) - (3)].interm.fieldList))[0]->name(), (yyvsp[(1) - (3)].interm.type))) {
context->recover();
}
- for (unsigned int i = 0; i < (yyval.interm.typeList)->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.typeList))[i].type;
+ TType* type = (*(yyval.interm.fieldList))[i]->type();
type->setBasicType((yyvsp[(1) - (3)].interm.type).type);
type->setNominalSize((yyvsp[(1) - (3)].interm.type).primarySize);
type->setSecondarySize((yyvsp[(1) - (3)].interm.type).secondarySize);
type->setArraySize((yyvsp[(1) - (3)].interm.type).arraySize);
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());
}
}
}
case 199:
{
- (yyval.interm.typeList) = NewPoolTTypeList();
- (yyval.interm.typeList)->push_back((yyvsp[(1) - (1)].interm.typeLine));
+ (yyval.interm.fieldList) = NewPoolTFieldList();
+ (yyval.interm.fieldList)->push_back((yyvsp[(1) - (1)].interm.field));
}
break;
case 200:
{
- (yyval.interm.typeList)->push_back((yyvsp[(3) - (3)].interm.typeLine));
+ (yyval.interm.fieldList)->push_back((yyvsp[(3) - (3)].interm.field));
}
break;
if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
context->recover();
- (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
- (yyval.interm.typeLine).line = (yyvsp[(1) - (1)].lex).line;
- (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (1)].lex).string);
+ TType* type = new TType(EbtVoid, EbpUndefined);
+ (yyval.interm.field) = new TField(type, (yyvsp[(1) - (1)].lex).string, (yyvsp[(1) - (1)].lex).line);
}
break;
if (context->reservedErrorCheck((yyvsp[(1) - (4)].lex).line, *(yyvsp[(1) - (4)].lex).string))
context->recover();
- (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
- (yyval.interm.typeLine).line = (yyvsp[(1) - (4)].lex).line;
- (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (4)].lex).string);
-
+ TType* type = new TType(EbtVoid, EbpUndefined);
int size;
- if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+ if (context->arraySizeErrorCheck((yyvsp[(3) - (4)].interm.intermTypedNode)->getLine(), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
context->recover();
- (yyval.interm.typeLine).type->setArraySize(size);
+ type->setArraySize(size);
+
+ (yyval.interm.field) = new TField(type, (yyvsp[(1) - (4)].lex).string, (yyvsp[(1) - (4)].lex).line);
}
break;
TQualifier qualifier;
TFunction* function;
TParameter param;
- TTypeLine typeLine;
- TTypeList* typeList;
+ TField* field;
+ TFieldList* fieldList;
};
} interm;