diff --git a/Install/Windows/glslangValidator.exe b/Install/Windows/glslangValidator.exe index b31e3fce..25980178 100644 Binary files a/Install/Windows/glslangValidator.exe and b/Install/Windows/glslangValidator.exe differ diff --git a/Test/120.frag b/Test/120.frag index c00eccbc..e6ed62a6 100644 --- a/Test/120.frag +++ b/Test/120.frag @@ -114,3 +114,12 @@ void v2() { return v1(); // ERROR, no expression allowed, even though void } + +void atest() +{ + vec4 v = gl_TexCoord[1]; + v += gl_TexCoord[3]; +} + +varying vec4 gl_TexCoord[6]; // okay, assigning a size +varying vec4 gl_TexCoord[5]; // ERROR, changing size diff --git a/Test/baseResults/120.frag.out b/Test/baseResults/120.frag.out index 7d28dcd6..49efdfc2 100644 --- a/Test/baseResults/120.frag.out +++ b/Test/baseResults/120.frag.out @@ -27,7 +27,8 @@ ERROR: 0:94: 'a' : variables with qualifier 'const' must be initialized ERROR: 0:97: 'out' : overloaded functions must have the same parameter qualifiers ERROR: 0:99: 'return' : function return is not matching type: ERROR: 0:115: 'return' : void function cannot return a value -ERROR: 29 compilation errors. No code generated. +ERROR: 0:125: 'gl_TexCoord' : redeclaration of array with size +ERROR: 30 compilation errors. No code generated. ERROR: node is still EOpNull! 0:21 Function Definition: main( (void) @@ -265,6 +266,20 @@ ERROR: node is still EOpNull! 0:115 Sequence 0:115 Branch: Return with expression 0:115 Function Call: v1( (void) +0:118 Function Definition: atest( (void) +0:118 Function Parameters: +0:120 Sequence +0:120 Sequence +0:120 move second child to first child (4-component vector of float) +0:120 'v' (4-component vector of float) +0:120 direct index (smooth in 4-component vector of float) +0:120 'gl_TexCoord' (smooth in unsized array of 4-component vector of float) +0:120 1 (const int) +0:121 add second child into first child (4-component vector of float) +0:121 'v' (4-component vector of float) +0:121 direct index (smooth in 4-component vector of float) +0:121 'gl_TexCoord' (smooth in unsized array of 4-component vector of float) +0:121 3 (const int) 0:? Linker Objects 0:? 'i' (smooth in 4-component vector of float) 0:? 'o' (out 4-component vector of float) diff --git a/Test/baseResults/300.vert.out b/Test/baseResults/300.vert.out index 7f75c657..550b7483 100644 --- a/Test/baseResults/300.vert.out +++ b/Test/baseResults/300.vert.out @@ -134,7 +134,7 @@ ERROR: node is still EOpNull! 0:? 'rep2' (centroid smooth sample out highp 4-component vector of float) 0:? 'rep3' (in highp 4-component vector of float) 0:? 's' (smooth out structure) -0:? 'ubInst' (layout(shared ) uniform 1-element array of block) +0:? 'ubInst' (layout(shared ) uniform unsized array of block) 0:? 'gl_VertexID' (gl_VertexId highp int) 0:? 'gl_InstanceID' (gl_InstanceId highp int) diff --git a/Test/baseResults/array100.frag.out b/Test/baseResults/array100.frag.out index 83577c95..4dd0235f 100644 --- a/Test/baseResults/array100.frag.out +++ b/Test/baseResults/array100.frag.out @@ -5,7 +5,7 @@ ERROR: 0:9: 'arrayed type' : not supported for this version or the enabled exten ERROR: 0:11: 'arrayed constructor' : not supported for this version or the enabled extensions ERROR: 0:21: '[' : array index out of range '2' ERROR: 0:25: 'assign' : cannot convert from '4-element array of mediump float' to '5-element array of mediump float' -ERROR: 0:26: 'assign' : cannot convert from '4-element array of mediump float' to '1-element array of mediump float' +ERROR: 0:26: 'assign' : cannot convert from '4-element array of mediump float' to 'unsized array of mediump float' ERROR: 0:28: 'foo' : no matching overloaded function found ERROR: 0:31: 'arrayed constructor' : not supported for this version or the enabled extensions ERROR: 0:35: '[' : array index out of range '5' @@ -49,7 +49,7 @@ ERROR: node is still EOpNull! 0:24 Function Call: foo(f1[5]; (4-element array of mediump float) 0:24 'g5' (5-element array of mediump float) 0:25 'g5' (5-element array of mediump float) -0:26 'gu' (1-element array of mediump float) +0:26 'gu' (unsized array of mediump float) 0:28 0.000000 0:29 Function Call: bar(f1[5]; (void) 0:29 'g5' (5-element array of mediump float) @@ -64,7 +64,7 @@ ERROR: node is still EOpNull! 0:31 true case 0:32 move second child to first child (mediump float) 0:32 direct index (mediump float) -0:32 'gu' (1-element array of mediump float) +0:32 'gu' (unsized array of mediump float) 0:32 0 (const int) 0:32 2.000000 0:35 move second child to first child (mediump float) diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index e4f60555..feee5b94 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -174,12 +174,21 @@ inline TIdentifierList* NewPoolTIdentifierList() // for the vast majority of non-array types. Note that means if it // is used, it will be containing at least one size. -typedef TVector* TArraySizes; +struct TArraySizes { + TArraySizes() : maxArraySize(0) { } + int getSize() { return sizes.front(); } // TArraySizes only exists if there is at least one dimension + void setSize(int s) { sizes.push_back(s); } + bool isArrayOfArrays() { return sizes.size() > 1; } +protected: + TVector sizes; + friend class TType; + int maxArraySize; // for tracking maximum referenced index, before an explicit size is given +}; -inline TArraySizes NewPoolTArraySizes() +inline TArraySizes* NewPoolTArraySizes() { - void* memory = GetThreadPoolAllocator().allocate(sizeof(TVector)); - return new(memory) TVector; + void* memory = GetThreadPoolAllocator().allocate(sizeof(TArraySizes)); + return new(memory) TArraySizes; } // @@ -347,7 +356,7 @@ public: int vectorSize : 4; int matrixCols : 4; int matrixRows : 4; - TArraySizes arraySizes; + TArraySizes* arraySizes; const TType* userDef; TSourceLoc loc; @@ -398,16 +407,16 @@ public: typedef std::map TStructureMap; typedef std::map::const_iterator TStructureMapIterator; + // // Base class for things that have a type. // class TType { public: POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) : + explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) : basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0), - structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), - fieldName(0), typeName(0) + structure(0), structureSize(0), fieldName(0), typeName(0) { sampler.clear(); qualifier.clear(); @@ -415,8 +424,7 @@ public: } TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) : basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0), - structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), - fieldName(0), typeName(0) + structure(0), structureSize(0), fieldName(0), typeName(0) { sampler.clear(); qualifier.clear(); @@ -426,7 +434,7 @@ public: } explicit TType(const TPublicType &p) : basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes), - structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), typeName(0) + structure(0), structureSize(0), fieldName(0), typeName(0) { if (basicType == EbtSampler) sampler = p.sampler; @@ -440,7 +448,7 @@ public: } TType(TTypeList* userDef, const TString& n, TStorageQualifier blockQualifier = EvqGlobal) : basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), arraySizes(0), - structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0) + structure(userDef), fieldName(0) { sampler.clear(); qualifier.clear(); @@ -451,32 +459,37 @@ public: } typeName = NewPoolTString(n.c_str()); } - TType() {} virtual ~TType() {} - - // "dumb" copy, using built-in operator=(), not for use across pool pops. - // It will also cause multiple copies of TType to point to the same information. - // This only works if that information (like a structure's list of types) does not - // change. - explicit TType(const TType& type) { *this = type; } - - void copyType(const TType& copyOf, const TStructureMap& remapper) - { + + // Not for use across pool pops; it will cause multiple instances of TType to point to the same information. + // This only works if that information (like a structure's list of types) does not change and + // the instances are sharing the same pool. + void shallowCopy(const TType& copyOf) + { basicType = copyOf.basicType; sampler = copyOf.sampler; qualifier = copyOf.qualifier; vectorSize = copyOf.vectorSize; matrixCols = copyOf.matrixCols; matrixRows = copyOf.matrixRows; + arraySizes = copyOf.arraySizes; + structure = copyOf.structure; + structureSize = copyOf.structureSize; + fieldName = copyOf.fieldName; + typeName = copyOf.typeName; + } - if (copyOf.arraySizes) { + void deepCopy(const TType& copyOf, const TStructureMap& remapper) + { + shallowCopy(copyOf); + + if (arraySizes) { arraySizes = NewPoolTArraySizes(); *arraySizes = *copyOf.arraySizes; - } else - arraySizes = 0; + } - TStructureMapIterator iter; - if (copyOf.structure) { + if (structure) { + TStructureMapIterator iter; if ((iter = remapper.find(structure)) == remapper.end()) { // create the new structure here structure = NewPoolTTypeList(); @@ -489,20 +502,12 @@ public: } else { structure = iter->second; } - } else - structure = 0; + } - fieldName = 0; - if (copyOf.fieldName) + if (fieldName) fieldName = NewPoolTString(copyOf.fieldName->c_str()); - typeName = 0; - if (copyOf.typeName) + if (typeName) typeName = NewPoolTString(copyOf.typeName->c_str()); - - structureSize = copyOf.structureSize; - maxArraySize = copyOf.maxArraySize; - assert(copyOf.arrayInformationType == 0); - arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level } // Merge type from parent, where a parentType is at the beginning of a declaration, @@ -523,17 +528,16 @@ public: TType* clone(const TStructureMap& remapper) { TType *newType = new TType(); - newType->copyType(*this, remapper); + newType->deepCopy(*this, remapper); return newType; } virtual void dereference() { - if (arraySizes) { + if (arraySizes) arraySizes = 0; - maxArraySize = 0; - } else if (matrixCols > 0) { + else if (matrixCols > 0) { vectorSize = matrixRows; matrixCols = 0; matrixRows = 0; @@ -576,8 +580,8 @@ public: virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isArray() const { return arraySizes != 0; } - int getArraySize() const { return arraySizes->front(); } - void setArraySizes(TArraySizes s) + int getArraySize() const { return arraySizes->sizes.front(); } + void setArraySizes(TArraySizes* s) { // copy; we don't want distinct types sharing the same descriptor if (! arraySizes) @@ -585,11 +589,9 @@ public: *arraySizes = *s; } - void changeArraySize(int s) { arraySizes->front() = s; } - void setMaxArraySize (int s) { maxArraySize = s; } - int getMaxArraySize () const { return maxArraySize; } - void setArrayInformationType(TType* t) { arrayInformationType = t; } - TType* getArrayInformationType() { return arrayInformationType; } + void changeArraySize(int s) { arraySizes->sizes.front() = s; } + void setMaxArraySize (int s) { arraySizes->maxArraySize = s; } + int getMaxArraySize () const { return arraySizes->maxArraySize; } virtual bool isVector() const { return vectorSize > 1; } virtual bool isScalar() const { return vectorSize == 1; } const char* getBasicString() const @@ -660,10 +662,10 @@ public: if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal) p += snprintf(p, end - p, "%s ", getStorageQualifierString()); if (arraySizes) { - if (arraySizes->front() == 0) + if (arraySizes->sizes.front() == 0) p += snprintf(p, end - p, "unsized array of "); else - p += snprintf(p, end - p, "%d-element array of ", arraySizes->front()); + p += snprintf(p, end - p, "%d-element array of ", arraySizes->sizes.front()); } if (qualifier.precision != EpqNone) p += snprintf(p, end - p, "%s ", getPrecisionQualifierString()); @@ -706,6 +708,8 @@ public: if (isArray()) totalSize *= Max(getArraySize(), getMaxArraySize()); + // TODO: desktop arrays: it should be ill-defined to get object size if the array is not sized, so the max() above maybe should be an assert + return totalSize; } @@ -730,7 +734,7 @@ public: { return sameElementType(right) && (arraySizes == 0 && right.arraySizes == 0 || - (arraySizes && right.arraySizes && *arraySizes == *right.arraySizes)); + (arraySizes && right.arraySizes && arraySizes->sizes == right.arraySizes->sizes)); // don't check the qualifier, it's not ever what's being sought after } @@ -740,6 +744,10 @@ public: } protected: + // Require consumer to pick between deep copy and shallow copy. + TType(const TType& type); + TType& operator=(const TType& type); + void buildMangledName(TString&); int getStructSize() const; @@ -750,12 +758,10 @@ protected: TSampler sampler; TQualifier qualifier; - TArraySizes arraySizes; + TArraySizes* arraySizes; - TTypeList* structure; // 0 unless this is a struct - mutable int structureSize; // a cache, updated on first access - int maxArraySize; - TType* arrayInformationType; + TTypeList* structure; // 0 unless this is a struct + mutable int structureSize; // a cache, updated on first access TString *fieldName; // for structure field names TString *typeName; // for structure field type name }; diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index f87428a4..d735bda1 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -372,11 +372,11 @@ struct TIntermNodePair { // class TIntermTyped : public TIntermNode { public: - TIntermTyped(const TType& t) : type(t) { } + TIntermTyped(const TType& t) { type.shallowCopy(t); } virtual TIntermTyped* getAsTyped() { return this; } - virtual void setType(const TType& t) { type = t; } + virtual void setType(const TType& t) { type.shallowCopy(t); } virtual const TType& getType() const { return type; } - virtual TType* getTypePointer() { return &type; } + virtual TType& getWritableType() { return type; } virtual TBasicType getBasicType() const { return type.getBasicType(); } virtual TQualifier& getQualifier() { return type.getQualifier(); } diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 77cfcb1a..8aa4ed8e 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -71,7 +71,8 @@ bool CompareStruct(const TType& leftNodeType, TConstUnion* rightUnionArray, TCon bool CompareStructure(const TType& leftNodeType, TConstUnion* rightUnionArray, TConstUnion* leftUnionArray) { if (leftNodeType.isArray()) { - TType typeWithoutArrayness(leftNodeType); + TType typeWithoutArrayness; + typeWithoutArrayness.shallowCopy(leftNodeType); // TODO: arrays of arrays: the shallow copy won't work if arrays are shared and dereferenced typeWithoutArrayness.dereference(); int arraySize = leftNodeType.getArraySize(); @@ -137,7 +138,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod // For most cases, the return type matches the argument type, so set that // up and just code to exceptions below. - TType returnType(getType()); + TType returnType; + returnType.shallowCopy(getType()); // // A pair of nodes is to be folded together @@ -157,7 +159,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod unionArray = new TConstUnion[constantNode->getType().getObjectSize()]; for (int i = 0; i < constantNode->getType().getObjectSize(); ++i) unionArray[i] = *getUnionArrayPointer(); - returnType = node->getType(); + returnType.shallowCopy(node->getType()); objectSize = constantNode->getType().getObjectSize(); } @@ -192,7 +194,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newConstArray[column * getMatrixRows() + row].setDConst(sum); } } - returnType = TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols()); + returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols())); break; case EOpDiv: newConstArray = new TConstUnion[objectSize]; @@ -232,7 +234,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newConstArray[i].setDConst(sum); } - returnType = TType(getBasicType(), EvqConst, getMatrixRows()); + returnType.shallowCopy(TType(getBasicType(), EvqConst, getMatrixRows())); break; case EOpVectorTimesMatrix: @@ -244,7 +246,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newConstArray[i].setDConst(sum); } - returnType = TType(getBasicType(), EvqConst, node->getMatrixCols()); + returnType.shallowCopy(TType(getBasicType(), EvqConst, node->getMatrixCols())); break; case EOpMod: @@ -307,13 +309,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod assert(objectSize == 1); newConstArray = new TConstUnion[1]; newConstArray->setBConst(*unionArray < *rightUnionArray); - returnType = TType(EbtBool, EvqConst); + returnType.shallowCopy(TType(EbtBool, EvqConst)); break; case EOpGreaterThan: assert(objectSize == 1); newConstArray = new TConstUnion[1]; newConstArray->setBConst(*unionArray > *rightUnionArray); - returnType = TType(EbtBool, EvqConst); + returnType.shallowCopy(TType(EbtBool, EvqConst)); break; case EOpLessThanEqual: { @@ -322,7 +324,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod constant.setBConst(*unionArray > *rightUnionArray); newConstArray = new TConstUnion[1]; newConstArray->setBConst(!constant.getBConst()); - returnType = TType(EbtBool, EvqConst); + returnType.shallowCopy(TType(EbtBool, EvqConst)); break; } case EOpGreaterThanEqual: @@ -332,7 +334,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod constant.setBConst(*unionArray < *rightUnionArray); newConstArray = new TConstUnion[1]; newConstArray->setBConst(!constant.getBConst()); - returnType = TType(EbtBool, EvqConst); + returnType.shallowCopy(TType(EbtBool, EvqConst)); break; } @@ -351,7 +353,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newConstArray = new TConstUnion[1]; newConstArray->setBConst(! boolNodeFlag); - returnType = TType(EbtBool, EvqConst); + returnType.shallowCopy(TType(EbtBool, EvqConst)); break; case EOpNotEqual: @@ -369,7 +371,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newConstArray = new TConstUnion[1]; newConstArray->setBConst(! boolNodeFlag); - returnType = TType(EbtBool, EvqConst); + returnType.shallowCopy(TType(EbtBool, EvqConst)); break; default: @@ -607,7 +609,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) } TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType); - newNode->getTypePointer()->getQualifier().storage = EvqConst; + newNode->getWritableType().getQualifier().storage = EvqConst; newNode->setLoc(getLoc()); return newNode; @@ -775,7 +777,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) } TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType()); - newNode->getTypePointer()->getQualifier().storage = EvqConst; + newNode->getWritableType().getQualifier().storage = EvqConst; newNode->setLoc(aggrNode->getLoc()); return newNode; diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 7739d74a..0080c771 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -1654,8 +1654,8 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb if (version < FirstProfileVersion || profile == ECompatibilityProfile || (! ForwardCompatibility && profile != EEsProfile && version < 420)) { TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone; TType fragData(EbtFloat, EvqFragColor, 4); - TArraySizes arraySizes = NewPoolTArraySizes(); - arraySizes->push_back(resources.maxDrawBuffers); + TArraySizes* arraySizes = NewPoolTArraySizes(); + arraySizes->setSize(resources.maxDrawBuffers); fragData.setArraySizes(arraySizes); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); } diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 9baa2934..a4847422 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -716,8 +716,8 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T TIntermTyped *commaAggregate = growAggregate(left, right, loc); commaAggregate->getAsAggregate()->setOperator(EOpComma); commaAggregate->setType(right->getType()); - commaAggregate->getTypePointer()->getQualifier().storage = EvqTemporary; - commaAggregate->getTypePointer()->getQualifier().precision = right->getTypePointer()->getQualifier().precision; + commaAggregate->getWritableType().getQualifier().storage = EvqTemporary; + commaAggregate->getWritableType().getQualifier().precision = right->getType().getQualifier().precision; return commaAggregate; } @@ -1028,7 +1028,7 @@ bool TIntermUnary::promote() } setType(operand->getType()); - getTypePointer()->getQualifier().storage = EvqTemporary; + getWritableType().getQualifier().storage = EvqTemporary; return true; } diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index b03063e2..2ad40e7d 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -482,8 +482,7 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt if (variable->getType().getQualifier().storage == EvqConst ) { TConstUnion* constArray = variable->getConstUnionPointer(); - TType t(variable->getType()); - node = intermediate.addConstantUnion(constArray, t, loc); + node = intermediate.addConstantUnion(constArray, variable->getType(), loc); } else node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc); } @@ -527,9 +526,7 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp if (base->isArray()) { if (base->getType().getArraySize() == 0) { if (base->getType().getMaxArraySize() <= index->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) - arraySetMaxSize(base->getAsSymbolNode(), base->getTypePointer(), index->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, loc); - else - arraySetMaxSize(base->getAsSymbolNode(), base->getTypePointer(), 0, false, loc); + arraySetMaxSize(loc, base->getAsSymbolNode(), index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() + 1); } else if ( index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= base->getType().getArraySize() || index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0) error(loc, "", "[", "array index out of range '%d'", index->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); @@ -554,7 +551,8 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp unionArray->setDConst(0.0); result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc); } else { - TType newType(base->getType()); + TType newType; + newType.shallowCopy(base->getType()); if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst) newType.getQualifier().storage = EvqConst; newType.dereference(); @@ -634,7 +632,7 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped* result->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. - result->getTypePointer()->getQualifier().storage = EvqConst; + result->getWritableType().getQualifier().storage = EvqConst; } } else { TConstUnion *unionArray = new TConstUnion[1]; @@ -1213,7 +1211,7 @@ bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier // bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunction& function, TOperator op, TType& type) { - type = function.getReturnType(); + type.shallowCopy(function.getReturnType()); bool constructingMatrix = false; switch(op) { @@ -1617,33 +1615,6 @@ bool TParseContext::containsSampler(const TType& type) return false; } -bool TParseContext::insertBuiltInArrayAtGlobalLevel() -{ - TString *name = NewPoolTString("gl_TexCoord"); - TSymbol* symbol = symbolTable.find(*name); - if (! symbol) { - // assume it was not added due to version/profile - - return false; - } - const TVariable* variable = symbol->getAsVariable(); - - if (! variable) { - infoSink.info.message(EPrefixInternalError, "variable expected"); - return true; - } - - TVariable* newVariable = new TVariable(name, variable->getType()); - - if (! symbolTable.insert(*newVariable)) { - delete newVariable; - infoSink.info.message(EPrefixInternalError, "inserting new symbol"); - return true; - } - - return false; -} - // // Do size checking for an array type's size. // @@ -1688,7 +1659,7 @@ bool TParseContext::arrayQualifierError(TSourceLoc loc, const TPublicType& type) // // Require array to have size // -void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int& size) +void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size) { if (size == 0) { error(loc, "array size required", "", ""); @@ -1703,18 +1674,18 @@ void TParseContext::arrayDimError(TSourceLoc loc) profileRequires(loc, ECompatibilityProfile, 430, 0, "arrays of arrays"); } -void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes sizes1, TArraySizes sizes2) +void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySizes* sizes2) { if (sizes1 && sizes2 || - sizes1 && sizes1->size() > 1 || - sizes2 && sizes2->size() > 1) + sizes1 && sizes1->isArrayOfArrays() || + sizes2 && sizes2->isArrayOfArrays()) arrayDimError(loc); } -void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes sizes2) +void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes* sizes2) { if (type && type->isArray() && sizes2 || - sizes2 && sizes2->size() > 1) + sizes2 && sizes2->isArrayOfArrays()) arrayDimError(loc); } @@ -1733,6 +1704,8 @@ void TParseContext::arrayCheck(TSourceLoc loc, TString& identifier, const TPubli // However, reserved arrays cannot be modified in a shared symbol table, so add a new // one at a non-shared level in the table. // + // Redeclarations have to take place at the same scope; otherwise they are hiding declarations + // bool currentScope; TSymbol* symbol = symbolTable.find(identifier, 0, ¤tScope); @@ -1764,23 +1737,19 @@ void TParseContext::arrayCheck(TSourceLoc loc, TString& identifier, const TPubli return; } - TType* t = variable->getArrayInformationType(); - while (t != 0) { - if (t->getMaxArraySize() > type.arraySizes->front()) { - error(loc, "higher index value already used for the array", identifier.c_str(), ""); - return; - } - t->setArraySizes(type.arraySizes); - t = t->getArrayInformationType(); - } + // For read-only built-ins, add a new variable for holding the declared array size of an implicitly-sized shared array. + if (variable->isReadOnly()) + variable = symbolTable.copyUp(variable); + // TODO: desktop unsized arrays: include modified built-in arrays (gl_TexCoord) in the linker objects subtree + variable->getWritableType().setArraySizes(type.arraySizes); } voidErrorCheck(loc, identifier, type); } -bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc loc) +bool TParseContext::arraySetMaxSize(TSourceLoc loc, TIntermSymbol *node, int size) { TSymbol* symbol = symbolTable.find(node->getName()); if (symbol == 0) { @@ -1794,41 +1763,26 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, return true; } - // There are multiple copies of the array type tagging results of operations. - // Chain these together, so they can all reflect the final size. - type->setArrayInformationType(variable->getArrayInformationType()); - variable->updateArrayInformationType(type); + // TODO: desktop linker: make this a link-time check (note if it's here, an explicit declaration skips it) + //if (node->getName() == "gl_TexCoord") { + // TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords"); + // if (! texCoord || ! texCoord->getAsVariable()) { + // infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", loc); + // return true; + // } - // special casing to test index value of gl_TexCoord. If the accessed index is >= gl_MaxTextureCoords - // its an error - if (node->getName() == "gl_TexCoord") { - TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords"); - if (! texCoord || ! texCoord->getAsVariable()) { - infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", loc); - return true; - } + // int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst(); + // if (texCoordValue <= size) { + // error(loc, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", ""); + // return true; + // } + //} - int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst(); - if (texCoordValue <= size) { - error(loc, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", ""); - return true; - } - } + // For read-only built-ins, add a new variable for holding the maximum array size of an implicitly-sized shared array. + if (variable->isReadOnly()) + variable = symbolTable.copyUp(variable); - // We don't want to update the maxArraySize when this flag is not set, we just want to include this - // node type in the chain of node types so that it's updated when a higher maxArraySize comes in. - if (! updateFlag) - return false; - - size++; variable->getWritableType().setMaxArraySize(size); - type->setMaxArraySize(size); - TType* tt = type; - - while(tt->getArrayInformationType() != 0) { - tt = tt->getArrayInformationType(); - tt->setMaxArraySize(size); - } return false; } @@ -2104,9 +2058,10 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type if (op == EOpConstructStruct) memberTypes = type.getStruct()->begin(); - TType elementType(type); + TType elementType; + elementType.shallowCopy(type); if (type.isArray()) - elementType.dereference(); + elementType.dereference(); // TODO: arrays of arrays: shallow copy won't work if sharing same array structure and then doing a dereference bool singleArg; if (aggrNode) { @@ -2280,7 +2235,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ // // Do everything needed to add an interface block. // -void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString* instanceName, TArraySizes arraySizes) +void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes) { // First, error checks @@ -2291,7 +2246,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString* return; if (profile == EEsProfile && arraySizes) - arraySizeRequiredCheck(loc, arraySizes->front()); + arraySizeRequiredCheck(loc, arraySizes->getSize()); if (currentBlockDefaults.storage == EvqUniform) { requireProfile(loc, (EProfileMask)(~ENoProfileMask), "uniform block"); @@ -2370,8 +2325,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString* // For an identifier that is already declared, add more qualification to it. void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier) { - bool sharedLevel; - TSymbol* existing = symbolTable.find(identifier, 0, 0, &sharedLevel); + TSymbol* existing = symbolTable.find(identifier); TVariable* variable = existing ? existing->getAsVariable() : 0; if (! variable) { error(loc, "identifier not previously declared", identifier.c_str(), ""); @@ -2389,13 +2343,9 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, return; } - // - // Don't change a shared variable; rather add a new one at the current scope. - // - if (sharedLevel) { - variable = new TVariable(&variable->getName(), variable->getType()); - symbolTable.insert(*variable); - } + // For read-only built-ins, add a new variable for holding the modified qualifier. + if (variable->isReadOnly()) + variable = symbolTable.copyUp(variable); if (qualifier.invariant) variable->getWritableType().getQualifier().invariant = true; @@ -2646,8 +2596,9 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS TIntermTyped* typedNode; TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); int arraySize = node->getType().getArraySize(); - TType arrayElementType(node->getType()); - arrayElementType.dereference(); + TType arrayElementType; + arrayElementType.shallowCopy(node->getType()); + arrayElementType.dereference(); // TODO: arrays of arrays: shallow copy won't work if sharing same array structure and then doing a dereference if (index >= node->getType().getArraySize() || index < 0) { error(loc, "", "[", "array index '%d' out of range", index); diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index f077ce6e..22ded39d 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -101,12 +101,11 @@ public: bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&); void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size); bool arrayQualifierError(TSourceLoc, const TPublicType&); - void arraySizeRequiredCheck(TSourceLoc, int& size); + void arraySizeRequiredCheck(TSourceLoc, int size); void arrayDimError(TSourceLoc); - void arrayDimCheck(TSourceLoc, TArraySizes sizes1, TArraySizes sizes2); - void arrayDimCheck(TSourceLoc, const TType*, TArraySizes); + void arrayDimCheck(TSourceLoc, TArraySizes* sizes1, TArraySizes* sizes2); + void arrayDimCheck(TSourceLoc, const TType*, TArraySizes*); void arrayCheck(TSourceLoc, TString& identifier, const TPublicType&, TVariable*& variable); - bool insertBuiltInArrayAtGlobalLevel(); bool voidErrorCheck(TSourceLoc, const TString&, const TPublicType&); void boolCheck(TSourceLoc, const TIntermTyped*); void boolCheck(TSourceLoc, const TPublicType&); @@ -136,7 +135,7 @@ public: TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc); TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset); - void addBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0); + void addBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier); void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&); void updateQualifierDefaults(TQualifier); @@ -149,7 +148,7 @@ public: TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc); TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc); - bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc); + bool arraySetMaxSize(TSourceLoc, TIntermSymbol*, int); void requireProfile(TSourceLoc, EProfileMask profileMask, const char *featureDesc); void requireStage(TSourceLoc, EShLanguageMask languageMask, const char *featureDesc); diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index e6232fbe..446a0149 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -550,11 +550,12 @@ int TScanContext::tokenizeIdentifier() if (ReservedSet->find(tokenText) != ReservedSet->end()) return reservedWord(); - keyword = (*KeywordMap)[tokenText]; - if (keyword == 0) { + std::map::const_iterator it = KeywordMap->find(tokenText); + if (it == KeywordMap->end()) { // Should have an identifier of some sort return identifierOrType(); } + keyword = it->second; field = false; switch (keyword) { diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 1b1b98d2..7d7b75ed 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -449,9 +449,6 @@ bool CompileDeferred( if (! symbolTable.atGlobalLevel()) parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); - if (parseContext.insertBuiltInArrayAtGlobalLevel()) - success = false; - bool ret = parseContext.parseShaderStrings(ppContext, const_cast(shaderStrings), lengths, numStrings); if (! ret) success = false; diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index 8fd892b1..8e1c79d4 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -90,7 +90,7 @@ void TType::buildMangledName(TString& mangledName) case EbtStruct: mangledName += "struct-"; if (typeName) - mangledName += *typeName; + mangledName += *typeName; for (unsigned int i = 0; i < structure->size(); ++i) { mangledName += '-'; (*structure)[i].type->buildMangledName(mangledName); @@ -107,9 +107,9 @@ void TType::buildMangledName(TString& mangledName) } if (arraySizes) { - const int maxSize = 11; + const int maxSize = 11; char buf[maxSize]; - snprintf(buf, maxSize, "%d", arraySizes->front()); + snprintf(buf, maxSize, "%d", arraySizes->sizes.front()); mangledName += '['; mangledName += buf; mangledName += ']'; @@ -173,8 +173,8 @@ void TSymbolTable::dump(TInfoSink &infoSink) const // TFunction::~TFunction() { - for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) - delete (*i).type; + for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) + delete (*i).type; } // @@ -182,8 +182,8 @@ TFunction::~TFunction() // TSymbolTableLevel::~TSymbolTableLevel() { - for (tLevel::iterator it = level.begin(); it != level.end(); ++it) - delete (*it).second; + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) + delete (*it).second; delete [] defaultPrecision; } @@ -213,58 +213,59 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) void TSymbolTableLevel::readOnly() { for (tLevel::iterator it = level.begin(); it != level.end(); ++it) - (*it).second->readOnly(); + (*it).second->makeReadOnly(); } +// +// Copy a symbol, but the copy is writable; call readOnly() afterward if that's not desired. +// TSymbol::TSymbol(const TSymbol& copyOf) { - name = NewPoolTString(copyOf.name->c_str()); - uniqueId = copyOf.uniqueId; + name = NewPoolTString(copyOf.name->c_str()); + uniqueId = copyOf.uniqueId; + writable = true; } TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf) { - type.copyType(copyOf.type, remapper); - userType = copyOf.userType; - // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL - assert(copyOf.arrayInformationType == 0); - arrayInformationType = 0; + type.deepCopy(copyOf.type, remapper); + userType = copyOf.userType; - if (copyOf.unionArray) { - assert(!copyOf.type.getStruct()); - assert(copyOf.type.getObjectSize() == 1); - unionArray = new TConstUnion[1]; + if (copyOf.unionArray) { + assert(!copyOf.type.getStruct()); + assert(copyOf.type.getObjectSize() == 1); + unionArray = new TConstUnion[1]; unionArray[0] = copyOf.unionArray[0]; - } else - unionArray = 0; + } else + unionArray = 0; } TVariable* TVariable::clone(TStructureMap& remapper) { - TVariable *variable = new TVariable(*this, remapper); + TVariable *variable = new TVariable(*this, remapper); - return variable; + return variable; } TFunction::TFunction(const TFunction& copyOf, const TStructureMap& remapper) : TSymbol(copyOf) { - for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { - TParameter param; - parameters.push_back(param); - parameters.back().copyParam(copyOf.parameters[i], remapper); - } + for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { + TParameter param; + parameters.push_back(param); + parameters.back().copyParam(copyOf.parameters[i], remapper); + } - returnType.copyType(copyOf.returnType, remapper); - mangledName = copyOf.mangledName; - op = copyOf.op; - defined = copyOf.defined; + returnType.deepCopy(copyOf.returnType, remapper); + mangledName = copyOf.mangledName; + op = copyOf.op; + defined = copyOf.defined; } TFunction* TFunction::clone(TStructureMap& remapper) { - TFunction *function = new TFunction(*this, remapper); + TFunction *function = new TFunction(*this, remapper); - return function; + return function; } TAnonMember* TAnonMember::clone(TStructureMap& remapper) @@ -277,24 +278,24 @@ TAnonMember* TAnonMember::clone(TStructureMap& remapper) TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper) { - TSymbolTableLevel *symTableLevel = new TSymbolTableLevel(); + TSymbolTableLevel *symTableLevel = new TSymbolTableLevel(); symTableLevel->anonId = anonId; - tLevel::iterator iter; - for (iter = level.begin(); iter != level.end(); ++iter) - symTableLevel->insert(*iter->second->clone(remapper)); + tLevel::iterator iter; + for (iter = level.begin(); iter != level.end(); ++iter) + symTableLevel->insert(*iter->second->clone(remapper)); - return symTableLevel; + return symTableLevel; } void TSymbolTable::copyTable(const TSymbolTable& copyOf) { assert(adoptedLevels == copyOf.adoptedLevels); - TStructureMap remapper; - uniqueId = copyOf.uniqueId; + TStructureMap remapper; + uniqueId = copyOf.uniqueId; noBuiltInRedeclarations = copyOf.noBuiltInRedeclarations; for (unsigned int i = copyOf.adoptedLevels; i < copyOf.table.size(); ++i) - table.push_back(copyOf.table[i]->clone(remapper)); + table.push_back(copyOf.table[i]->clone(remapper)); } } // end namespace glslang diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index 2a0352c8..0b307234 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -96,7 +96,8 @@ public: int getUniqueId() const { return uniqueId; } virtual void dump(TInfoSink &infoSink) const = 0; - void readOnly() { writable = false; } + bool isReadOnly() { return ! writable; } + void makeReadOnly() { writable = false; } protected: explicit TSymbol(const TSymbol&); @@ -124,7 +125,7 @@ protected: // class TVariable : public TSymbol { public: - TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { } + TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), userType(uT), unionArray(0) { type.shallowCopy(t); } virtual TVariable* clone(TStructureMap& remapper); virtual ~TVariable() { } @@ -133,12 +134,11 @@ public: TType& getWritableType() { assert(writable); return type; } const TType& getType() const { return type; } bool isUserType() const { return userType; } - void updateArrayInformationType(TType *t) { assert(writable); arrayInformationType = t; } - TType* getArrayInformationType() { assert(writable); return arrayInformationType; } virtual void dump(TInfoSink &infoSink) const; - TConstUnion* getConstUnionPointer() { + TConstUnion* getConstUnionPointer() + { if (!unionArray) unionArray = new TConstUnion[type.getObjectSize()]; @@ -154,16 +154,15 @@ public: } protected: - explicit TVariable(TVariable&); - TVariable(const TVariable&, TStructureMap& remapper); - TVariable& operator=(TVariable&); + explicit TVariable(const TVariable&); + TVariable(const TVariable&, TStructureMap& remapper); + TVariable& operator=(const TVariable&); TType type; bool userType; // we are assuming that Pool Allocator will free the memory allocated to unionArray // when this object is destroyed TConstUnion *unionArray; - TType *arrayInformationType; // this is used for updating maxArraySize in all the references to a given symbol }; // @@ -190,15 +189,13 @@ class TFunction : public TSymbol { public: explicit TFunction(TOperator o) : TSymbol(0), - returnType(TType(EbtVoid)), op(o), defined(false) { } TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) : TSymbol(name), - returnType(retType), mangledName(*name + '('), op(tOp), - defined(false) { } + defined(false) { returnType.shallowCopy(retType); } virtual TFunction* clone(TStructureMap& remapper); virtual ~TFunction(); @@ -455,7 +452,20 @@ public: return table[currentLevel()]->insert(symbol); } - TSymbol* find(const TString& name, bool* builtIn = 0, bool *currentScope = 0, bool *sharedLevel = 0) + // + // To copy a variable from a shared level up to the current level, so it can be + // modified without impacting other users of the shared table. + // + TVariable* copyUp(TVariable* shared) + { + TVariable* variable = shared->clone(remapper); + variable->setUniqueId(shared->getUniqueId()); + table[currentLevel()]->insert(*variable); + + return variable; + } + + TSymbol* find(const TString& name, bool* builtIn = 0, bool *currentScope = 0) { int level = currentLevel(); TSymbol* symbol; @@ -467,9 +477,7 @@ public: if (builtIn) *builtIn = isBuiltInLevel(level); if (currentScope) - *currentScope = level == currentLevel(); - if (sharedLevel) - *sharedLevel = isSharedLevel(level); + *currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals return symbol; } @@ -502,6 +510,7 @@ protected: int uniqueId; // for unique identification in code generation bool noBuiltInRedeclarations; unsigned int adoptedLevels; + TStructureMap remapper; // for now, dummy for copyUp(), which is not yet used for structures }; } // end namespace glslang diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index 3de7e724..73688db1 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -90,7 +90,7 @@ using namespace glslang; glslang::TParameter param; glslang::TTypeLoc typeLine; glslang::TTypeList* typeList; - glslang::TArraySizes arraySizes; + glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; } interm; @@ -334,13 +334,15 @@ function_call_header_no_parameters function_call_header_with_parameters : function_call_header assignment_expression { - TParameter param = { 0, new TType($2->getType()) }; + TParameter param = { 0, new TType }; + param.type->shallowCopy($2->getType()); $1.function->addParameter(param); $$.function = $1.function; $$.intermNode = $2; } | function_call_header_with_parameters COMMA assignment_expression { - TParameter param = { 0, new TType($3->getType()) }; + TParameter param = { 0, new TType }; + param.type->shallowCopy($3->getType()); $1.function->addParameter(param); $$.function = $1.function; $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc); @@ -890,7 +892,7 @@ parameter_declarator if ($1.arraySizes) { parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize()); } if ($1.basicType == EbtVoid) { parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), ""); @@ -905,11 +907,11 @@ parameter_declarator if ($1.arraySizes) { parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize()); } parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes); - parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->front()); + parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->getSize()); parseContext.reservedErrorCheck($2.loc, *$2.string); $1.arraySizes = $3.arraySizes; @@ -976,7 +978,7 @@ init_declarator_list | init_declarator_list COMMA IDENTIFIER array_specifier { parseContext.nonInitConstCheck($3.loc, *$3.string, $1.type); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($4.loc, $4.arraySizes->front()); + parseContext.arraySizeRequiredCheck($4.loc, $4.arraySizes->getSize()); parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes); $$ = $1; @@ -1047,7 +1049,7 @@ single_declaration $$.intermAggregate = 0; parseContext.nonInitConstCheck($2.loc, *$2.string, $1); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->front()); + parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->getSize()); parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes); $$.type = $1; @@ -1111,7 +1113,7 @@ fully_specified_type parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize()); } parseContext.precisionQualifierCheck($$.loc, $$); @@ -1123,7 +1125,7 @@ fully_specified_type parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front()); + parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize()); } if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1)) @@ -1391,7 +1393,7 @@ array_specifier : LEFT_BRACKET RIGHT_BRACKET { $$.loc = $1.loc; $$.arraySizes = NewPoolTArraySizes(); - $$.arraySizes->push_back(0); + $$.arraySizes->setSize(0); } | LEFT_BRACKET constant_expression RIGHT_BRACKET { $$.loc = $1.loc; @@ -1399,18 +1401,18 @@ array_specifier int size; parseContext.arraySizeCheck($2->getLoc(), $2, size); - $$.arraySizes->push_back(size); + $$.arraySizes->setSize(size); } | array_specifier LEFT_BRACKET RIGHT_BRACKET { $$ = $1; - $$.arraySizes->push_back(0); + $$.arraySizes->setSize(0); } | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET { $$ = $1; int size; parseContext.arraySizeCheck($3->getLoc(), $3, size); - $$.arraySizes->push_back(size); + $$.arraySizes->setSize(size); } ; @@ -2114,7 +2116,7 @@ struct_declaration parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize()); } $$ = $2; @@ -2132,7 +2134,7 @@ struct_declaration parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front()); + parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize()); } $$ = $3; @@ -2166,7 +2168,7 @@ struct_declarator } | IDENTIFIER array_specifier { if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front()); + parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize()); parseContext.arrayDimCheck($1.loc, $2.arraySizes, 0); $$.type = new TType(EbtVoid);