OSDN Git Service

Adding Struct related types
authorAlexis Hetu <sugoi@google.com>
Wed, 10 Jun 2015 15:48:40 +0000 (11:48 -0400)
committerAlexis Hétu <sugoi@google.com>
Wed, 10 Jun 2015 16:44:35 +0000 (16:44 +0000)
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/3451
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/compiler/Initialize.cpp
src/OpenGL/compiler/Intermediate.cpp
src/OpenGL/compiler/OutputASM.cpp
src/OpenGL/compiler/ParseHelper.cpp
src/OpenGL/compiler/SymbolTable.cpp
src/OpenGL/compiler/Types.h
src/OpenGL/compiler/glslang.y
src/OpenGL/compiler/glslang_tab.cpp
src/OpenGL/compiler/glslang_tab.h

index 8bb7c82..7bad154 100644 (file)
@@ -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);
 
index 779565b..8307b15 100644 (file)
@@ -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])
index 55c512e..562a577 100644 (file)
@@ -326,20 +326,13 @@ namespace glsl
                        {\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
@@ -1439,12 +1432,12 @@ namespace glsl
 \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
@@ -1472,7 +1465,7 @@ namespace glsl
                {\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
@@ -1487,12 +1480,12 @@ namespace glsl
 \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
@@ -1520,7 +1513,6 @@ namespace glsl
                {\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
@@ -1771,23 +1763,20 @@ namespace glsl
                                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
@@ -2354,7 +2343,7 @@ namespace glsl
 \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
@@ -2371,16 +2360,17 @@ namespace glsl
                }\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
@@ -2392,10 +2382,10 @@ namespace glsl
                        {\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
index b403feb..22e38a7 100644 (file)
@@ -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();
         }
     }
 
index 1935478..2881977 100644 (file)
@@ -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;
 }
 
 //
index b89c860..9887bf2 100644 (file)
 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_
index b7d7a06..a145694 100644 (file)
@@ -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);
     }
     ;
 
index e3777f0..e2b3472 100644 (file)
@@ -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;
 
index 6ec3a32..e1ada23 100644 (file)
@@ -201,8 +201,8 @@ typedef union YYSTYPE
             TQualifier qualifier;
             TFunction* function;
             TParameter param;
-            TTypeLine typeLine;
-            TTypeList* typeList;
+            TField* field;
+            TFieldList* fieldList;
         };
     } interm;