mirror of
https://github.com/RPCS3/glslang.git
synced 2025-02-01 16:42:14 +00:00
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:
parent
38f3b890de
commit
5f753e0222
Binary file not shown.
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user