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
//
// 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);
......
......@@ -993,16 +993,16 @@ 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();
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])
......
......@@ -326,20 +326,13 @@ namespace glsl
{
ASSERT(leftType.isStruct());
const TTypeList *structure = leftType.getStruct();
const TString &fieldName = rightType.getFieldName();
const TFieldList& fields = leftType.getStruct()->fields();
int index = right->getAsConstantUnion()->getIConst(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;
if(fieldType.getFieldName() == fieldName)
{
break;
}
fieldOffset += fieldType.totalRegisterCount();
fieldOffset += fields[i]->type()->totalRegisterCount();
}
copy(result, left, fieldOffset);
......@@ -1439,12 +1432,12 @@ namespace glsl
if(type.isStruct())
{
TTypeList *structure = type.getStruct();
const TFieldList& fields = type.getStruct()->fields();
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)
{
......@@ -1472,7 +1465,7 @@ namespace glsl
{
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();
......@@ -1487,12 +1480,12 @@ namespace glsl
if(type.isStruct())
{
TTypeList *structure = type.getStruct();
const TFieldList& fields = type.getStruct()->fields();
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)
{
......@@ -1520,7 +1513,6 @@ namespace glsl
{
TIntermTyped *arg = argument->getAsTyped();
const TType &type = arg->getType();
const TTypeList *structure = type.getStruct();
index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;
int size = registerSize(type, index);
......@@ -1771,23 +1763,20 @@ namespace glsl
break;
case EOpIndexDirectStruct:
{
const TTypeList *structure = left->getType().getStruct();
const TString &fieldName = right->getType().getFieldName();
const TFieldList& fields = left->getType().getStruct()->fields();
int index = right->getAsConstantUnion()->getIConst(0);
int fieldOffset = 0;
int offset = 0;
for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)
for(int i = 0; i < index; i++)
{
if(field->type->getFieldName() == fieldName)
{
dst.type = registerType(left);
dst.index += offset;
dst.mask = writeMask(right);
return 0xE4;
}
offset += field->type->totalRegisterCount();
fieldOffset += fields[i]->type()->totalRegisterCount();
}
dst.type = registerType(left);
dst.index += fieldOffset;
dst.mask = writeMask(right);
return 0xE4;
}
break;
case EOpVectorSwizzle:
......@@ -2354,7 +2343,7 @@ namespace glsl
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;
if(!structure)
......@@ -2371,16 +2360,17 @@ namespace glsl
}
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].type;
const TString &fieldName = fieldType.getFieldName();
const TType &fieldType = *(fields[j]->type());
const TString &fieldName = fields[j]->name();
const TString uniformName = name + "[" + str(i) + "]." + fieldName;
declareUniform(fieldType, uniformName, elementIndex);
......@@ -2392,10 +2382,10 @@ namespace glsl
{
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 TString &fieldName = fieldType.getFieldName();
const TType &fieldType = *(fields[i]->type());
const TString &fieldName = fields[i]->name();
const TString uniformName = name + "." + fieldName;
declareUniform(fieldType, uniformName, fieldIndex);
......
......@@ -522,7 +522,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
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;
}
......@@ -682,9 +682,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].type))
const TFieldList& fields = type.getStruct()->fields();
for(unsigned int i = 0; i < fields.size(); ++i) {
if (containsSampler(*fields[i]->type()))
return true;
}
}
......@@ -1232,12 +1232,12 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType*
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();
......@@ -1405,17 +1405,17 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
//
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();
}
}
......
......@@ -26,12 +26,11 @@ int TSymbolTableLevel::uniqueId = 0;
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();
}
}
......@@ -52,19 +51,23 @@ void TType::buildMangledName(TString& mangledName)
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;
}
......@@ -89,46 +92,68 @@ int TType::getStructSize() const
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;
}
//
......
......@@ -16,21 +16,211 @@
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.
//
......@@ -40,23 +230,34 @@ public:
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; }
......@@ -66,6 +267,11 @@ public:
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; }
......@@ -100,15 +306,14 @@ public:
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;
......@@ -148,35 +353,18 @@ public:
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) {
......@@ -233,9 +421,20 @@ 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;
}
bool isStructureContainingSamplers() const
{
return structure ? structure->containsSamplers() : false;
}
protected:
void buildMangledName(TString&);
......@@ -245,6 +444,8 @@ protected:
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;
......@@ -252,13 +453,13 @@ protected:
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
};
//
......@@ -311,6 +512,11 @@ struct TPublicType
secondarySize = s1;
}
bool isUnsizedArray() const
{
return array && arraySize == 0;
}
void setArray(bool a, int s = 0)
{
array = a;
......@@ -332,6 +538,38 @@ struct TPublicType
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_
......@@ -75,8 +75,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TQualifier qualifier;
TFunction* function;
TParameter param;
TTypeLine typeLine;
TTypeList* typeList;
TField* field;
TFieldList* fieldList;
};
} interm;
}
......@@ -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_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
......@@ -316,7 +316,7 @@ postfix_expression
$$ = 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()));
......@@ -391,15 +391,16 @@ postfix_expression
}
} 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;
}
......@@ -412,7 +413,7 @@ postfix_expression
$$ = $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);
......@@ -420,9 +421,9 @@ postfix_expression
} 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());
......@@ -2007,7 +2008,7 @@ struct_specifier
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");
......@@ -2018,7 +2019,8 @@ struct_specifier
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();
......@@ -2032,9 +2034,10 @@ struct_declaration_list
| 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();
}
}
......@@ -2047,14 +2050,14 @@ struct_declaration
: 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);
......@@ -2069,7 +2072,6 @@ struct_declaration
type->setArraySize($1.arraySize);
if ($1.userDef) {
type->setStruct($1.userDef->getStruct());
type->setTypeName($1.userDef->getTypeName());
}
}
}
......@@ -2077,7 +2079,7 @@ struct_declaration
struct_declarator_list
: struct_declarator {
$$ = NewPoolTTypeList();
$$ = NewPoolTFieldList();
$$->push_back($1);
}
| struct_declarator_list COMMA struct_declarator {
......@@ -2090,22 +2092,20 @@ 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);
}
;
......
......@@ -285,8 +285,8 @@ typedef union YYSTYPE
TQualifier qualifier;
TFunction* function;
TParameter param;
TTypeLine typeLine;
TTypeList* typeList;
TField* field;
TFieldList* fieldList;
};
} interm;
......@@ -731,26 +731,26 @@ static const yytype_int16 yyrhs[] =
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,
......@@ -2458,7 +2458,7 @@ yyreduce:
(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()));
......@@ -2541,15 +2541,16 @@ 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) {
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;
}
......@@ -2562,7 +2563,7 @@ yyreduce:
(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);
......@@ -2570,9 +2571,9 @@ yyreduce:
} 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());
......@@ -4647,7 +4648,7 @@ yyreduce:
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");
......@@ -4667,7 +4668,8 @@ yyreduce:
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();
......@@ -4677,22 +4679,23 @@ yyreduce:
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;
......@@ -4700,16 +4703,16 @@ yyreduce:
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);
......@@ -4724,7 +4727,6 @@ yyreduce:
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());
}
}
}
......@@ -4733,15 +4735,15 @@ yyreduce:
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;
......@@ -4751,9 +4753,8 @@ yyreduce:
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;
......@@ -4763,14 +4764,13 @@ yyreduce:
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;
......
......@@ -201,8 +201,8 @@ typedef union YYSTYPE
TQualifier qualifier;
TFunction* function;
TParameter param;
TTypeLine typeLine;
TTypeList* typeList;
TField* field;
TFieldList* fieldList;
};
} interm;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment