Full thread safety working:

- don't use [] for map lookups, it can modify the map
 - copy up built-in symbols out of shared symbol table levels before modifying them
 - enforce shallow vs. deep TType copies
 - combine maxArraySize with the array dimensions vector, encapsulate
 - remove chaining of array types


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22953 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-09-08 21:04:46 +00:00
parent 38f3b890de
commit 5f753e0222
17 changed files with 259 additions and 267 deletions

Binary file not shown.

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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<int>* 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<int> 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<int>));
return new(memory) TVector<int>;
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<TTypeList*, TTypeList*> TStructureMap;
typedef std::map<TTypeList*, TTypeList*>::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
};

View File

@ -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(); }

View File

@ -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;

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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, &currentScope);
@ -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);

View File

@ -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);

View File

@ -550,11 +550,12 @@ int TScanContext::tokenizeIdentifier()
if (ReservedSet->find(tokenText) != ReservedSet->end())
return reservedWord();
keyword = (*KeywordMap)[tokenText];
if (keyword == 0) {
std::map<std::string, int>::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) {

View File

@ -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<char**>(shaderStrings), lengths, numStrings);
if (! ret)
success = false;

View File

@ -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

View File

@ -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

View File

@ -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);