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
|
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:97: 'out' : overloaded functions must have the same parameter qualifiers
|
||||||
ERROR: 0:99: 'return' : function return is not matching type:
|
ERROR: 0:99: 'return' : function return is not matching type:
|
||||||
ERROR: 0:115: 'return' : void function cannot return a value
|
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!
|
ERROR: node is still EOpNull!
|
||||||
0:21 Function Definition: main( (void)
|
0:21 Function Definition: main( (void)
|
||||||
@ -265,6 +266,20 @@ ERROR: node is still EOpNull!
|
|||||||
0:115 Sequence
|
0:115 Sequence
|
||||||
0:115 Branch: Return with expression
|
0:115 Branch: Return with expression
|
||||||
0:115 Function Call: v1( (void)
|
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:? Linker Objects
|
||||||
0:? 'i' (smooth in 4-component vector of float)
|
0:? 'i' (smooth in 4-component vector of float)
|
||||||
0:? 'o' (out 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:? 'rep2' (centroid smooth sample out highp 4-component vector of float)
|
||||||
0:? 'rep3' (in highp 4-component vector of float)
|
0:? 'rep3' (in highp 4-component vector of float)
|
||||||
0:? 's' (smooth out structure)
|
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_VertexID' (gl_VertexId highp int)
|
||||||
0:? 'gl_InstanceID' (gl_InstanceId 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:11: 'arrayed constructor' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:21: '[' : array index out of range '2'
|
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: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:28: 'foo' : no matching overloaded function found
|
||||||
ERROR: 0:31: 'arrayed constructor' : not supported for this version or the enabled extensions
|
ERROR: 0:31: 'arrayed constructor' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:35: '[' : array index out of range '5'
|
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 Function Call: foo(f1[5]; (4-element array of mediump float)
|
||||||
0:24 'g5' (5-element array of mediump float)
|
0:24 'g5' (5-element array of mediump float)
|
||||||
0:25 '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:28 0.000000
|
||||||
0:29 Function Call: bar(f1[5]; (void)
|
0:29 Function Call: bar(f1[5]; (void)
|
||||||
0:29 'g5' (5-element array of mediump float)
|
0:29 'g5' (5-element array of mediump float)
|
||||||
@ -64,7 +64,7 @@ ERROR: node is still EOpNull!
|
|||||||
0:31 true case
|
0:31 true case
|
||||||
0:32 move second child to first child (mediump float)
|
0:32 move second child to first child (mediump float)
|
||||||
0:32 direct index (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 0 (const int)
|
||||||
0:32 2.000000
|
0:32 2.000000
|
||||||
0:35 move second child to first child (mediump float)
|
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
|
// for the vast majority of non-array types. Note that means if it
|
||||||
// is used, it will be containing at least one size.
|
// 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>));
|
void* memory = GetThreadPoolAllocator().allocate(sizeof(TArraySizes));
|
||||||
return new(memory) TVector<int>;
|
return new(memory) TArraySizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -347,7 +356,7 @@ public:
|
|||||||
int vectorSize : 4;
|
int vectorSize : 4;
|
||||||
int matrixCols : 4;
|
int matrixCols : 4;
|
||||||
int matrixRows : 4;
|
int matrixRows : 4;
|
||||||
TArraySizes arraySizes;
|
TArraySizes* arraySizes;
|
||||||
const TType* userDef;
|
const TType* userDef;
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
|
|
||||||
@ -398,16 +407,16 @@ public:
|
|||||||
|
|
||||||
typedef std::map<TTypeList*, TTypeList*> TStructureMap;
|
typedef std::map<TTypeList*, TTypeList*> TStructureMap;
|
||||||
typedef std::map<TTypeList*, TTypeList*>::const_iterator TStructureMapIterator;
|
typedef std::map<TTypeList*, TTypeList*>::const_iterator TStructureMapIterator;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Base class for things that have a type.
|
// Base class for things that have a type.
|
||||||
//
|
//
|
||||||
class TType {
|
class TType {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
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),
|
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
|
structure(0), structureSize(0), fieldName(0), typeName(0)
|
||||||
fieldName(0), typeName(0)
|
|
||||||
{
|
{
|
||||||
sampler.clear();
|
sampler.clear();
|
||||||
qualifier.clear();
|
qualifier.clear();
|
||||||
@ -415,8 +424,7 @@ public:
|
|||||||
}
|
}
|
||||||
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
|
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),
|
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
|
structure(0), structureSize(0), fieldName(0), typeName(0)
|
||||||
fieldName(0), typeName(0)
|
|
||||||
{
|
{
|
||||||
sampler.clear();
|
sampler.clear();
|
||||||
qualifier.clear();
|
qualifier.clear();
|
||||||
@ -426,7 +434,7 @@ public:
|
|||||||
}
|
}
|
||||||
explicit TType(const TPublicType &p) :
|
explicit TType(const TPublicType &p) :
|
||||||
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
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)
|
if (basicType == EbtSampler)
|
||||||
sampler = p.sampler;
|
sampler = p.sampler;
|
||||||
@ -440,7 +448,7 @@ public:
|
|||||||
}
|
}
|
||||||
TType(TTypeList* userDef, const TString& n, TStorageQualifier blockQualifier = EvqGlobal) :
|
TType(TTypeList* userDef, const TString& n, TStorageQualifier blockQualifier = EvqGlobal) :
|
||||||
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), arraySizes(0),
|
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), arraySizes(0),
|
||||||
structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0)
|
structure(userDef), fieldName(0)
|
||||||
{
|
{
|
||||||
sampler.clear();
|
sampler.clear();
|
||||||
qualifier.clear();
|
qualifier.clear();
|
||||||
@ -451,32 +459,37 @@ public:
|
|||||||
}
|
}
|
||||||
typeName = NewPoolTString(n.c_str());
|
typeName = NewPoolTString(n.c_str());
|
||||||
}
|
}
|
||||||
TType() {}
|
|
||||||
virtual ~TType() {}
|
virtual ~TType() {}
|
||||||
|
|
||||||
// "dumb" copy, using built-in operator=(), not for use across pool pops.
|
// Not for use across pool pops; it will cause multiple instances of TType to point to the same information.
|
||||||
// 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 and
|
||||||
// This only works if that information (like a structure's list of types) does not
|
// the instances are sharing the same pool.
|
||||||
// change.
|
void shallowCopy(const TType& copyOf)
|
||||||
explicit TType(const TType& type) { *this = type; }
|
{
|
||||||
|
|
||||||
void copyType(const TType& copyOf, const TStructureMap& remapper)
|
|
||||||
{
|
|
||||||
basicType = copyOf.basicType;
|
basicType = copyOf.basicType;
|
||||||
sampler = copyOf.sampler;
|
sampler = copyOf.sampler;
|
||||||
qualifier = copyOf.qualifier;
|
qualifier = copyOf.qualifier;
|
||||||
vectorSize = copyOf.vectorSize;
|
vectorSize = copyOf.vectorSize;
|
||||||
matrixCols = copyOf.matrixCols;
|
matrixCols = copyOf.matrixCols;
|
||||||
matrixRows = copyOf.matrixRows;
|
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 = NewPoolTArraySizes();
|
||||||
*arraySizes = *copyOf.arraySizes;
|
*arraySizes = *copyOf.arraySizes;
|
||||||
} else
|
}
|
||||||
arraySizes = 0;
|
|
||||||
|
|
||||||
TStructureMapIterator iter;
|
if (structure) {
|
||||||
if (copyOf.structure) {
|
TStructureMapIterator iter;
|
||||||
if ((iter = remapper.find(structure)) == remapper.end()) {
|
if ((iter = remapper.find(structure)) == remapper.end()) {
|
||||||
// create the new structure here
|
// create the new structure here
|
||||||
structure = NewPoolTTypeList();
|
structure = NewPoolTTypeList();
|
||||||
@ -489,20 +502,12 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
structure = iter->second;
|
structure = iter->second;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
structure = 0;
|
|
||||||
|
|
||||||
fieldName = 0;
|
if (fieldName)
|
||||||
if (copyOf.fieldName)
|
|
||||||
fieldName = NewPoolTString(copyOf.fieldName->c_str());
|
fieldName = NewPoolTString(copyOf.fieldName->c_str());
|
||||||
typeName = 0;
|
if (typeName)
|
||||||
if (copyOf.typeName)
|
|
||||||
typeName = NewPoolTString(copyOf.typeName->c_str());
|
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,
|
// 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* clone(const TStructureMap& remapper)
|
||||||
{
|
{
|
||||||
TType *newType = new TType();
|
TType *newType = new TType();
|
||||||
newType->copyType(*this, remapper);
|
newType->deepCopy(*this, remapper);
|
||||||
|
|
||||||
return newType;
|
return newType;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void dereference()
|
virtual void dereference()
|
||||||
{
|
{
|
||||||
if (arraySizes) {
|
if (arraySizes)
|
||||||
arraySizes = 0;
|
arraySizes = 0;
|
||||||
maxArraySize = 0;
|
else if (matrixCols > 0) {
|
||||||
} else if (matrixCols > 0) {
|
|
||||||
vectorSize = matrixRows;
|
vectorSize = matrixRows;
|
||||||
matrixCols = 0;
|
matrixCols = 0;
|
||||||
matrixRows = 0;
|
matrixRows = 0;
|
||||||
@ -576,8 +580,8 @@ public:
|
|||||||
|
|
||||||
virtual bool isMatrix() const { return matrixCols ? true : false; }
|
virtual bool isMatrix() const { return matrixCols ? true : false; }
|
||||||
virtual bool isArray() const { return arraySizes != 0; }
|
virtual bool isArray() const { return arraySizes != 0; }
|
||||||
int getArraySize() const { return arraySizes->front(); }
|
int getArraySize() const { return arraySizes->sizes.front(); }
|
||||||
void setArraySizes(TArraySizes s)
|
void setArraySizes(TArraySizes* s)
|
||||||
{
|
{
|
||||||
// copy; we don't want distinct types sharing the same descriptor
|
// copy; we don't want distinct types sharing the same descriptor
|
||||||
if (! arraySizes)
|
if (! arraySizes)
|
||||||
@ -585,11 +589,9 @@ public:
|
|||||||
*arraySizes = *s;
|
*arraySizes = *s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeArraySize(int s) { arraySizes->front() = s; }
|
void changeArraySize(int s) { arraySizes->sizes.front() = s; }
|
||||||
void setMaxArraySize (int s) { maxArraySize = s; }
|
void setMaxArraySize (int s) { arraySizes->maxArraySize = s; }
|
||||||
int getMaxArraySize () const { return maxArraySize; }
|
int getMaxArraySize () const { return arraySizes->maxArraySize; }
|
||||||
void setArrayInformationType(TType* t) { arrayInformationType = t; }
|
|
||||||
TType* getArrayInformationType() { return arrayInformationType; }
|
|
||||||
virtual bool isVector() const { return vectorSize > 1; }
|
virtual bool isVector() const { return vectorSize > 1; }
|
||||||
virtual bool isScalar() const { return vectorSize == 1; }
|
virtual bool isScalar() const { return vectorSize == 1; }
|
||||||
const char* getBasicString() const
|
const char* getBasicString() const
|
||||||
@ -660,10 +662,10 @@ public:
|
|||||||
if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
|
if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
|
||||||
p += snprintf(p, end - p, "%s ", getStorageQualifierString());
|
p += snprintf(p, end - p, "%s ", getStorageQualifierString());
|
||||||
if (arraySizes) {
|
if (arraySizes) {
|
||||||
if (arraySizes->front() == 0)
|
if (arraySizes->sizes.front() == 0)
|
||||||
p += snprintf(p, end - p, "unsized array of ");
|
p += snprintf(p, end - p, "unsized array of ");
|
||||||
else
|
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)
|
if (qualifier.precision != EpqNone)
|
||||||
p += snprintf(p, end - p, "%s ", getPrecisionQualifierString());
|
p += snprintf(p, end - p, "%s ", getPrecisionQualifierString());
|
||||||
@ -706,6 +708,8 @@ public:
|
|||||||
if (isArray())
|
if (isArray())
|
||||||
totalSize *= Max(getArraySize(), getMaxArraySize());
|
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;
|
return totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,7 +734,7 @@ public:
|
|||||||
{
|
{
|
||||||
return sameElementType(right) &&
|
return sameElementType(right) &&
|
||||||
(arraySizes == 0 && right.arraySizes == 0 ||
|
(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
|
// don't check the qualifier, it's not ever what's being sought after
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,6 +744,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Require consumer to pick between deep copy and shallow copy.
|
||||||
|
TType(const TType& type);
|
||||||
|
TType& operator=(const TType& type);
|
||||||
|
|
||||||
void buildMangledName(TString&);
|
void buildMangledName(TString&);
|
||||||
int getStructSize() const;
|
int getStructSize() const;
|
||||||
|
|
||||||
@ -750,12 +758,10 @@ protected:
|
|||||||
TSampler sampler;
|
TSampler sampler;
|
||||||
TQualifier qualifier;
|
TQualifier qualifier;
|
||||||
|
|
||||||
TArraySizes arraySizes;
|
TArraySizes* arraySizes;
|
||||||
|
|
||||||
TTypeList* structure; // 0 unless this is a struct
|
TTypeList* structure; // 0 unless this is a struct
|
||||||
mutable int structureSize; // a cache, updated on first access
|
mutable int structureSize; // a cache, updated on first access
|
||||||
int maxArraySize;
|
|
||||||
TType* arrayInformationType;
|
|
||||||
TString *fieldName; // for structure field names
|
TString *fieldName; // for structure field names
|
||||||
TString *typeName; // for structure field type name
|
TString *typeName; // for structure field type name
|
||||||
};
|
};
|
||||||
|
|||||||
@ -372,11 +372,11 @@ struct TIntermNodePair {
|
|||||||
//
|
//
|
||||||
class TIntermTyped : public TIntermNode {
|
class TIntermTyped : public TIntermNode {
|
||||||
public:
|
public:
|
||||||
TIntermTyped(const TType& t) : type(t) { }
|
TIntermTyped(const TType& t) { type.shallowCopy(t); }
|
||||||
virtual TIntermTyped* getAsTyped() { return this; }
|
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 const TType& getType() const { return type; }
|
||||||
virtual TType* getTypePointer() { return &type; }
|
virtual TType& getWritableType() { return type; }
|
||||||
|
|
||||||
virtual TBasicType getBasicType() const { return type.getBasicType(); }
|
virtual TBasicType getBasicType() const { return type.getBasicType(); }
|
||||||
virtual TQualifier& getQualifier() { return type.getQualifier(); }
|
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)
|
bool CompareStructure(const TType& leftNodeType, TConstUnion* rightUnionArray, TConstUnion* leftUnionArray)
|
||||||
{
|
{
|
||||||
if (leftNodeType.isArray()) {
|
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();
|
typeWithoutArrayness.dereference();
|
||||||
|
|
||||||
int arraySize = leftNodeType.getArraySize();
|
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
|
// For most cases, the return type matches the argument type, so set that
|
||||||
// up and just code to exceptions below.
|
// up and just code to exceptions below.
|
||||||
TType returnType(getType());
|
TType returnType;
|
||||||
|
returnType.shallowCopy(getType());
|
||||||
|
|
||||||
//
|
//
|
||||||
// A pair of nodes is to be folded together
|
// 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()];
|
unionArray = new TConstUnion[constantNode->getType().getObjectSize()];
|
||||||
for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
|
for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
|
||||||
unionArray[i] = *getUnionArrayPointer();
|
unionArray[i] = *getUnionArrayPointer();
|
||||||
returnType = node->getType();
|
returnType.shallowCopy(node->getType());
|
||||||
objectSize = constantNode->getType().getObjectSize();
|
objectSize = constantNode->getType().getObjectSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +194,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
newConstArray[column * getMatrixRows() + row].setDConst(sum);
|
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;
|
break;
|
||||||
case EOpDiv:
|
case EOpDiv:
|
||||||
newConstArray = new TConstUnion[objectSize];
|
newConstArray = new TConstUnion[objectSize];
|
||||||
@ -232,7 +234,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
newConstArray[i].setDConst(sum);
|
newConstArray[i].setDConst(sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
returnType = TType(getBasicType(), EvqConst, getMatrixRows());
|
returnType.shallowCopy(TType(getBasicType(), EvqConst, getMatrixRows()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpVectorTimesMatrix:
|
case EOpVectorTimesMatrix:
|
||||||
@ -244,7 +246,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
newConstArray[i].setDConst(sum);
|
newConstArray[i].setDConst(sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
returnType = TType(getBasicType(), EvqConst, node->getMatrixCols());
|
returnType.shallowCopy(TType(getBasicType(), EvqConst, node->getMatrixCols()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpMod:
|
case EOpMod:
|
||||||
@ -307,13 +309,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
assert(objectSize == 1);
|
assert(objectSize == 1);
|
||||||
newConstArray = new TConstUnion[1];
|
newConstArray = new TConstUnion[1];
|
||||||
newConstArray->setBConst(*unionArray < *rightUnionArray);
|
newConstArray->setBConst(*unionArray < *rightUnionArray);
|
||||||
returnType = TType(EbtBool, EvqConst);
|
returnType.shallowCopy(TType(EbtBool, EvqConst));
|
||||||
break;
|
break;
|
||||||
case EOpGreaterThan:
|
case EOpGreaterThan:
|
||||||
assert(objectSize == 1);
|
assert(objectSize == 1);
|
||||||
newConstArray = new TConstUnion[1];
|
newConstArray = new TConstUnion[1];
|
||||||
newConstArray->setBConst(*unionArray > *rightUnionArray);
|
newConstArray->setBConst(*unionArray > *rightUnionArray);
|
||||||
returnType = TType(EbtBool, EvqConst);
|
returnType.shallowCopy(TType(EbtBool, EvqConst));
|
||||||
break;
|
break;
|
||||||
case EOpLessThanEqual:
|
case EOpLessThanEqual:
|
||||||
{
|
{
|
||||||
@ -322,7 +324,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
constant.setBConst(*unionArray > *rightUnionArray);
|
constant.setBConst(*unionArray > *rightUnionArray);
|
||||||
newConstArray = new TConstUnion[1];
|
newConstArray = new TConstUnion[1];
|
||||||
newConstArray->setBConst(!constant.getBConst());
|
newConstArray->setBConst(!constant.getBConst());
|
||||||
returnType = TType(EbtBool, EvqConst);
|
returnType.shallowCopy(TType(EbtBool, EvqConst));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EOpGreaterThanEqual:
|
case EOpGreaterThanEqual:
|
||||||
@ -332,7 +334,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
constant.setBConst(*unionArray < *rightUnionArray);
|
constant.setBConst(*unionArray < *rightUnionArray);
|
||||||
newConstArray = new TConstUnion[1];
|
newConstArray = new TConstUnion[1];
|
||||||
newConstArray->setBConst(!constant.getBConst());
|
newConstArray->setBConst(!constant.getBConst());
|
||||||
returnType = TType(EbtBool, EvqConst);
|
returnType.shallowCopy(TType(EbtBool, EvqConst));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,7 +353,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
|
|
||||||
newConstArray = new TConstUnion[1];
|
newConstArray = new TConstUnion[1];
|
||||||
newConstArray->setBConst(! boolNodeFlag);
|
newConstArray->setBConst(! boolNodeFlag);
|
||||||
returnType = TType(EbtBool, EvqConst);
|
returnType.shallowCopy(TType(EbtBool, EvqConst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpNotEqual:
|
case EOpNotEqual:
|
||||||
@ -369,7 +371,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
|||||||
|
|
||||||
newConstArray = new TConstUnion[1];
|
newConstArray = new TConstUnion[1];
|
||||||
newConstArray->setBConst(! boolNodeFlag);
|
newConstArray->setBConst(! boolNodeFlag);
|
||||||
returnType = TType(EbtBool, EvqConst);
|
returnType.shallowCopy(TType(EbtBool, EvqConst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -607,7 +609,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
|
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
|
||||||
newNode->getTypePointer()->getQualifier().storage = EvqConst;
|
newNode->getWritableType().getQualifier().storage = EvqConst;
|
||||||
newNode->setLoc(getLoc());
|
newNode->setLoc(getLoc());
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
@ -775,7 +777,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType());
|
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType());
|
||||||
newNode->getTypePointer()->getQualifier().storage = EvqConst;
|
newNode->getWritableType().getQualifier().storage = EvqConst;
|
||||||
newNode->setLoc(aggrNode->getLoc());
|
newNode->setLoc(aggrNode->getLoc());
|
||||||
|
|
||||||
return newNode;
|
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)) {
|
if (version < FirstProfileVersion || profile == ECompatibilityProfile || (! ForwardCompatibility && profile != EEsProfile && version < 420)) {
|
||||||
TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone;
|
TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone;
|
||||||
TType fragData(EbtFloat, EvqFragColor, 4);
|
TType fragData(EbtFloat, EvqFragColor, 4);
|
||||||
TArraySizes arraySizes = NewPoolTArraySizes();
|
TArraySizes* arraySizes = NewPoolTArraySizes();
|
||||||
arraySizes->push_back(resources.maxDrawBuffers);
|
arraySizes->setSize(resources.maxDrawBuffers);
|
||||||
fragData.setArraySizes(arraySizes);
|
fragData.setArraySizes(arraySizes);
|
||||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
|
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);
|
TIntermTyped *commaAggregate = growAggregate(left, right, loc);
|
||||||
commaAggregate->getAsAggregate()->setOperator(EOpComma);
|
commaAggregate->getAsAggregate()->setOperator(EOpComma);
|
||||||
commaAggregate->setType(right->getType());
|
commaAggregate->setType(right->getType());
|
||||||
commaAggregate->getTypePointer()->getQualifier().storage = EvqTemporary;
|
commaAggregate->getWritableType().getQualifier().storage = EvqTemporary;
|
||||||
commaAggregate->getTypePointer()->getQualifier().precision = right->getTypePointer()->getQualifier().precision;
|
commaAggregate->getWritableType().getQualifier().precision = right->getType().getQualifier().precision;
|
||||||
|
|
||||||
return commaAggregate;
|
return commaAggregate;
|
||||||
}
|
}
|
||||||
@ -1028,7 +1028,7 @@ bool TIntermUnary::promote()
|
|||||||
}
|
}
|
||||||
|
|
||||||
setType(operand->getType());
|
setType(operand->getType());
|
||||||
getTypePointer()->getQualifier().storage = EvqTemporary;
|
getWritableType().getQualifier().storage = EvqTemporary;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -482,8 +482,7 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
|
|||||||
|
|
||||||
if (variable->getType().getQualifier().storage == EvqConst ) {
|
if (variable->getType().getQualifier().storage == EvqConst ) {
|
||||||
TConstUnion* constArray = variable->getConstUnionPointer();
|
TConstUnion* constArray = variable->getConstUnionPointer();
|
||||||
TType t(variable->getType());
|
node = intermediate.addConstantUnion(constArray, variable->getType(), loc);
|
||||||
node = intermediate.addConstantUnion(constArray, t, loc);
|
|
||||||
} else
|
} else
|
||||||
node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
|
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->isArray()) {
|
||||||
if (base->getType().getArraySize() == 0) {
|
if (base->getType().getArraySize() == 0) {
|
||||||
if (base->getType().getMaxArraySize() <= index->getAsConstantUnion()->getUnionArrayPointer()->getIConst())
|
if (base->getType().getMaxArraySize() <= index->getAsConstantUnion()->getUnionArrayPointer()->getIConst())
|
||||||
arraySetMaxSize(base->getAsSymbolNode(), base->getTypePointer(), index->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, loc);
|
arraySetMaxSize(loc, base->getAsSymbolNode(), index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() + 1);
|
||||||
else
|
|
||||||
arraySetMaxSize(base->getAsSymbolNode(), base->getTypePointer(), 0, false, loc);
|
|
||||||
} else if ( index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= base->getType().getArraySize() ||
|
} else if ( index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= base->getType().getArraySize() ||
|
||||||
index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0)
|
index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0)
|
||||||
error(loc, "", "[", "array index out of range '%d'", index->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
|
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);
|
unionArray->setDConst(0.0);
|
||||||
result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc);
|
result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc);
|
||||||
} else {
|
} else {
|
||||||
TType newType(base->getType());
|
TType newType;
|
||||||
|
newType.shallowCopy(base->getType());
|
||||||
if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst)
|
if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst)
|
||||||
newType.getQualifier().storage = EvqConst;
|
newType.getQualifier().storage = EvqConst;
|
||||||
newType.dereference();
|
newType.dereference();
|
||||||
@ -634,7 +632,7 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped*
|
|||||||
result->setType(*(*fields)[i].type);
|
result->setType(*(*fields)[i].type);
|
||||||
// change the qualifier of the return type, not of the structure field
|
// change the qualifier of the return type, not of the structure field
|
||||||
// as the structure definition is shared between various structures.
|
// as the structure definition is shared between various structures.
|
||||||
result->getTypePointer()->getQualifier().storage = EvqConst;
|
result->getWritableType().getQualifier().storage = EvqConst;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TConstUnion *unionArray = new TConstUnion[1];
|
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)
|
bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
|
||||||
{
|
{
|
||||||
type = function.getReturnType();
|
type.shallowCopy(function.getReturnType());
|
||||||
|
|
||||||
bool constructingMatrix = false;
|
bool constructingMatrix = false;
|
||||||
switch(op) {
|
switch(op) {
|
||||||
@ -1617,33 +1615,6 @@ bool TParseContext::containsSampler(const TType& type)
|
|||||||
return false;
|
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.
|
// 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
|
// Require array to have size
|
||||||
//
|
//
|
||||||
void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int& size)
|
void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size)
|
||||||
{
|
{
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
error(loc, "array size required", "", "");
|
error(loc, "array size required", "", "");
|
||||||
@ -1703,18 +1674,18 @@ void TParseContext::arrayDimError(TSourceLoc loc)
|
|||||||
profileRequires(loc, ECompatibilityProfile, 430, 0, "arrays of arrays");
|
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 ||
|
if (sizes1 && sizes2 ||
|
||||||
sizes1 && sizes1->size() > 1 ||
|
sizes1 && sizes1->isArrayOfArrays() ||
|
||||||
sizes2 && sizes2->size() > 1)
|
sizes2 && sizes2->isArrayOfArrays())
|
||||||
arrayDimError(loc);
|
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 ||
|
if (type && type->isArray() && sizes2 ||
|
||||||
sizes2 && sizes2->size() > 1)
|
sizes2 && sizes2->isArrayOfArrays())
|
||||||
arrayDimError(loc);
|
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
|
// However, reserved arrays cannot be modified in a shared symbol table, so add a new
|
||||||
// one at a non-shared level in the table.
|
// 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;
|
bool currentScope;
|
||||||
TSymbol* symbol = symbolTable.find(identifier, 0, ¤tScope);
|
TSymbol* symbol = symbolTable.find(identifier, 0, ¤tScope);
|
||||||
@ -1764,23 +1737,19 @@ void TParseContext::arrayCheck(TSourceLoc loc, TString& identifier, const TPubli
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TType* t = variable->getArrayInformationType();
|
// For read-only built-ins, add a new variable for holding the declared array size of an implicitly-sized shared array.
|
||||||
while (t != 0) {
|
if (variable->isReadOnly())
|
||||||
if (t->getMaxArraySize() > type.arraySizes->front()) {
|
variable = symbolTable.copyUp(variable);
|
||||||
error(loc, "higher index value already used for the array", identifier.c_str(), "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
t->setArraySizes(type.arraySizes);
|
|
||||||
t = t->getArrayInformationType();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO: desktop unsized arrays: include modified built-in arrays (gl_TexCoord) in the linker objects subtree
|
||||||
|
|
||||||
variable->getWritableType().setArraySizes(type.arraySizes);
|
variable->getWritableType().setArraySizes(type.arraySizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
voidErrorCheck(loc, identifier, type);
|
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());
|
TSymbol* symbol = symbolTable.find(node->getName());
|
||||||
if (symbol == 0) {
|
if (symbol == 0) {
|
||||||
@ -1794,41 +1763,26 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are multiple copies of the array type tagging results of operations.
|
// TODO: desktop linker: make this a link-time check (note if it's here, an explicit declaration skips it)
|
||||||
// Chain these together, so they can all reflect the final size.
|
//if (node->getName() == "gl_TexCoord") {
|
||||||
type->setArrayInformationType(variable->getArrayInformationType());
|
// TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords");
|
||||||
variable->updateArrayInformationType(type);
|
// 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
|
// int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst();
|
||||||
// its an error
|
// if (texCoordValue <= size) {
|
||||||
if (node->getName() == "gl_TexCoord") {
|
// error(loc, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", "");
|
||||||
TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords");
|
// return true;
|
||||||
if (! texCoord || ! texCoord->getAsVariable()) {
|
// }
|
||||||
infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", loc);
|
//}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst();
|
// For read-only built-ins, add a new variable for holding the maximum array size of an implicitly-sized shared array.
|
||||||
if (texCoordValue <= size) {
|
if (variable->isReadOnly())
|
||||||
error(loc, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", "");
|
variable = symbolTable.copyUp(variable);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
variable->getWritableType().setMaxArraySize(size);
|
||||||
type->setMaxArraySize(size);
|
|
||||||
TType* tt = type;
|
|
||||||
|
|
||||||
while(tt->getArrayInformationType() != 0) {
|
|
||||||
tt = tt->getArrayInformationType();
|
|
||||||
tt->setMaxArraySize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2104,9 +2058,10 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type
|
|||||||
if (op == EOpConstructStruct)
|
if (op == EOpConstructStruct)
|
||||||
memberTypes = type.getStruct()->begin();
|
memberTypes = type.getStruct()->begin();
|
||||||
|
|
||||||
TType elementType(type);
|
TType elementType;
|
||||||
|
elementType.shallowCopy(type);
|
||||||
if (type.isArray())
|
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;
|
bool singleArg;
|
||||||
if (aggrNode) {
|
if (aggrNode) {
|
||||||
@ -2280,7 +2235,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
|
|||||||
//
|
//
|
||||||
// Do everything needed to add an interface block.
|
// 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
|
// First, error checks
|
||||||
|
|
||||||
@ -2291,7 +2246,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (profile == EEsProfile && arraySizes)
|
if (profile == EEsProfile && arraySizes)
|
||||||
arraySizeRequiredCheck(loc, arraySizes->front());
|
arraySizeRequiredCheck(loc, arraySizes->getSize());
|
||||||
|
|
||||||
if (currentBlockDefaults.storage == EvqUniform) {
|
if (currentBlockDefaults.storage == EvqUniform) {
|
||||||
requireProfile(loc, (EProfileMask)(~ENoProfileMask), "uniform block");
|
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.
|
// For an identifier that is already declared, add more qualification to it.
|
||||||
void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier)
|
void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier)
|
||||||
{
|
{
|
||||||
bool sharedLevel;
|
TSymbol* existing = symbolTable.find(identifier);
|
||||||
TSymbol* existing = symbolTable.find(identifier, 0, 0, &sharedLevel);
|
|
||||||
TVariable* variable = existing ? existing->getAsVariable() : 0;
|
TVariable* variable = existing ? existing->getAsVariable() : 0;
|
||||||
if (! variable) {
|
if (! variable) {
|
||||||
error(loc, "identifier not previously declared", identifier.c_str(), "");
|
error(loc, "identifier not previously declared", identifier.c_str(), "");
|
||||||
@ -2389,13 +2343,9 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// For read-only built-ins, add a new variable for holding the modified qualifier.
|
||||||
// Don't change a shared variable; rather add a new one at the current scope.
|
if (variable->isReadOnly())
|
||||||
//
|
variable = symbolTable.copyUp(variable);
|
||||||
if (sharedLevel) {
|
|
||||||
variable = new TVariable(&variable->getName(), variable->getType());
|
|
||||||
symbolTable.insert(*variable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qualifier.invariant)
|
if (qualifier.invariant)
|
||||||
variable->getWritableType().getQualifier().invariant = true;
|
variable->getWritableType().getQualifier().invariant = true;
|
||||||
@ -2646,8 +2596,9 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
|
|||||||
TIntermTyped* typedNode;
|
TIntermTyped* typedNode;
|
||||||
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
|
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
|
||||||
int arraySize = node->getType().getArraySize();
|
int arraySize = node->getType().getArraySize();
|
||||||
TType arrayElementType(node->getType());
|
TType arrayElementType;
|
||||||
arrayElementType.dereference();
|
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) {
|
if (index >= node->getType().getArraySize() || index < 0) {
|
||||||
error(loc, "", "[", "array index '%d' out of range", index);
|
error(loc, "", "[", "array index '%d' out of range", index);
|
||||||
|
|||||||
@ -101,12 +101,11 @@ public:
|
|||||||
bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&);
|
bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&);
|
||||||
void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
|
void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
|
||||||
bool arrayQualifierError(TSourceLoc, const TPublicType&);
|
bool arrayQualifierError(TSourceLoc, const TPublicType&);
|
||||||
void arraySizeRequiredCheck(TSourceLoc, int& size);
|
void arraySizeRequiredCheck(TSourceLoc, int size);
|
||||||
void arrayDimError(TSourceLoc);
|
void arrayDimError(TSourceLoc);
|
||||||
void arrayDimCheck(TSourceLoc, TArraySizes sizes1, TArraySizes sizes2);
|
void arrayDimCheck(TSourceLoc, TArraySizes* sizes1, TArraySizes* sizes2);
|
||||||
void arrayDimCheck(TSourceLoc, const TType*, TArraySizes);
|
void arrayDimCheck(TSourceLoc, const TType*, TArraySizes*);
|
||||||
void arrayCheck(TSourceLoc, TString& identifier, const TPublicType&, TVariable*& variable);
|
void arrayCheck(TSourceLoc, TString& identifier, const TPublicType&, TVariable*& variable);
|
||||||
bool insertBuiltInArrayAtGlobalLevel();
|
|
||||||
bool voidErrorCheck(TSourceLoc, const TString&, const TPublicType&);
|
bool voidErrorCheck(TSourceLoc, const TString&, const TPublicType&);
|
||||||
void boolCheck(TSourceLoc, const TIntermTyped*);
|
void boolCheck(TSourceLoc, const TIntermTyped*);
|
||||||
void boolCheck(TSourceLoc, const TPublicType&);
|
void boolCheck(TSourceLoc, const TPublicType&);
|
||||||
@ -136,7 +135,7 @@ public:
|
|||||||
TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc);
|
TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc);
|
||||||
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
|
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
|
||||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
|
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, const TString& identifier);
|
||||||
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
|
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
|
||||||
void updateQualifierDefaults(TQualifier);
|
void updateQualifierDefaults(TQualifier);
|
||||||
@ -149,7 +148,7 @@ public:
|
|||||||
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc);
|
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc);
|
||||||
TIntermTyped* addConstStruct(TString& , TIntermTyped*, 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 requireProfile(TSourceLoc, EProfileMask profileMask, const char *featureDesc);
|
||||||
void requireStage(TSourceLoc, EShLanguageMask languageMask, const char *featureDesc);
|
void requireStage(TSourceLoc, EShLanguageMask languageMask, const char *featureDesc);
|
||||||
|
|||||||
@ -550,11 +550,12 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
if (ReservedSet->find(tokenText) != ReservedSet->end())
|
if (ReservedSet->find(tokenText) != ReservedSet->end())
|
||||||
return reservedWord();
|
return reservedWord();
|
||||||
|
|
||||||
keyword = (*KeywordMap)[tokenText];
|
std::map<std::string, int>::const_iterator it = KeywordMap->find(tokenText);
|
||||||
if (keyword == 0) {
|
if (it == KeywordMap->end()) {
|
||||||
// Should have an identifier of some sort
|
// Should have an identifier of some sort
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
}
|
}
|
||||||
|
keyword = it->second;
|
||||||
field = false;
|
field = false;
|
||||||
|
|
||||||
switch (keyword) {
|
switch (keyword) {
|
||||||
|
|||||||
@ -449,9 +449,6 @@ bool CompileDeferred(
|
|||||||
if (! symbolTable.atGlobalLevel())
|
if (! symbolTable.atGlobalLevel())
|
||||||
parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
|
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);
|
bool ret = parseContext.parseShaderStrings(ppContext, const_cast<char**>(shaderStrings), lengths, numStrings);
|
||||||
if (! ret)
|
if (! ret)
|
||||||
success = false;
|
success = false;
|
||||||
|
|||||||
@ -90,7 +90,7 @@ void TType::buildMangledName(TString& mangledName)
|
|||||||
case EbtStruct:
|
case EbtStruct:
|
||||||
mangledName += "struct-";
|
mangledName += "struct-";
|
||||||
if (typeName)
|
if (typeName)
|
||||||
mangledName += *typeName;
|
mangledName += *typeName;
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
for (unsigned int i = 0; i < structure->size(); ++i) {
|
||||||
mangledName += '-';
|
mangledName += '-';
|
||||||
(*structure)[i].type->buildMangledName(mangledName);
|
(*structure)[i].type->buildMangledName(mangledName);
|
||||||
@ -107,9 +107,9 @@ void TType::buildMangledName(TString& mangledName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arraySizes) {
|
if (arraySizes) {
|
||||||
const int maxSize = 11;
|
const int maxSize = 11;
|
||||||
char buf[maxSize];
|
char buf[maxSize];
|
||||||
snprintf(buf, maxSize, "%d", arraySizes->front());
|
snprintf(buf, maxSize, "%d", arraySizes->sizes.front());
|
||||||
mangledName += '[';
|
mangledName += '[';
|
||||||
mangledName += buf;
|
mangledName += buf;
|
||||||
mangledName += ']';
|
mangledName += ']';
|
||||||
@ -173,8 +173,8 @@ void TSymbolTable::dump(TInfoSink &infoSink) const
|
|||||||
//
|
//
|
||||||
TFunction::~TFunction()
|
TFunction::~TFunction()
|
||||||
{
|
{
|
||||||
for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
|
for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
|
||||||
delete (*i).type;
|
delete (*i).type;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -182,8 +182,8 @@ TFunction::~TFunction()
|
|||||||
//
|
//
|
||||||
TSymbolTableLevel::~TSymbolTableLevel()
|
TSymbolTableLevel::~TSymbolTableLevel()
|
||||||
{
|
{
|
||||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
|
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
|
||||||
delete (*it).second;
|
delete (*it).second;
|
||||||
|
|
||||||
delete [] defaultPrecision;
|
delete [] defaultPrecision;
|
||||||
}
|
}
|
||||||
@ -213,58 +213,59 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
|
|||||||
void TSymbolTableLevel::readOnly()
|
void TSymbolTableLevel::readOnly()
|
||||||
{
|
{
|
||||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
|
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)
|
TSymbol::TSymbol(const TSymbol& copyOf)
|
||||||
{
|
{
|
||||||
name = NewPoolTString(copyOf.name->c_str());
|
name = NewPoolTString(copyOf.name->c_str());
|
||||||
uniqueId = copyOf.uniqueId;
|
uniqueId = copyOf.uniqueId;
|
||||||
|
writable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
|
TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
|
||||||
{
|
{
|
||||||
type.copyType(copyOf.type, remapper);
|
type.deepCopy(copyOf.type, remapper);
|
||||||
userType = copyOf.userType;
|
userType = copyOf.userType;
|
||||||
// for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
|
|
||||||
assert(copyOf.arrayInformationType == 0);
|
|
||||||
arrayInformationType = 0;
|
|
||||||
|
|
||||||
if (copyOf.unionArray) {
|
if (copyOf.unionArray) {
|
||||||
assert(!copyOf.type.getStruct());
|
assert(!copyOf.type.getStruct());
|
||||||
assert(copyOf.type.getObjectSize() == 1);
|
assert(copyOf.type.getObjectSize() == 1);
|
||||||
unionArray = new TConstUnion[1];
|
unionArray = new TConstUnion[1];
|
||||||
unionArray[0] = copyOf.unionArray[0];
|
unionArray[0] = copyOf.unionArray[0];
|
||||||
} else
|
} else
|
||||||
unionArray = 0;
|
unionArray = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVariable* TVariable::clone(TStructureMap& remapper)
|
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)
|
TFunction::TFunction(const TFunction& copyOf, const TStructureMap& remapper) : TSymbol(copyOf)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
|
for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
|
||||||
TParameter param;
|
TParameter param;
|
||||||
parameters.push_back(param);
|
parameters.push_back(param);
|
||||||
parameters.back().copyParam(copyOf.parameters[i], remapper);
|
parameters.back().copyParam(copyOf.parameters[i], remapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
returnType.copyType(copyOf.returnType, remapper);
|
returnType.deepCopy(copyOf.returnType, remapper);
|
||||||
mangledName = copyOf.mangledName;
|
mangledName = copyOf.mangledName;
|
||||||
op = copyOf.op;
|
op = copyOf.op;
|
||||||
defined = copyOf.defined;
|
defined = copyOf.defined;
|
||||||
}
|
}
|
||||||
|
|
||||||
TFunction* TFunction::clone(TStructureMap& remapper)
|
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)
|
TAnonMember* TAnonMember::clone(TStructureMap& remapper)
|
||||||
@ -277,24 +278,24 @@ TAnonMember* TAnonMember::clone(TStructureMap& remapper)
|
|||||||
|
|
||||||
TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
|
TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
|
||||||
{
|
{
|
||||||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||||
symTableLevel->anonId = anonId;
|
symTableLevel->anonId = anonId;
|
||||||
tLevel::iterator iter;
|
tLevel::iterator iter;
|
||||||
for (iter = level.begin(); iter != level.end(); ++iter)
|
for (iter = level.begin(); iter != level.end(); ++iter)
|
||||||
symTableLevel->insert(*iter->second->clone(remapper));
|
symTableLevel->insert(*iter->second->clone(remapper));
|
||||||
|
|
||||||
return symTableLevel;
|
return symTableLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TSymbolTable::copyTable(const TSymbolTable& copyOf)
|
void TSymbolTable::copyTable(const TSymbolTable& copyOf)
|
||||||
{
|
{
|
||||||
assert(adoptedLevels == copyOf.adoptedLevels);
|
assert(adoptedLevels == copyOf.adoptedLevels);
|
||||||
|
|
||||||
TStructureMap remapper;
|
TStructureMap remapper;
|
||||||
uniqueId = copyOf.uniqueId;
|
uniqueId = copyOf.uniqueId;
|
||||||
noBuiltInRedeclarations = copyOf.noBuiltInRedeclarations;
|
noBuiltInRedeclarations = copyOf.noBuiltInRedeclarations;
|
||||||
for (unsigned int i = copyOf.adoptedLevels; i < copyOf.table.size(); ++i)
|
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
|
} // end namespace glslang
|
||||||
|
|||||||
@ -96,7 +96,8 @@ public:
|
|||||||
int getUniqueId() const { return uniqueId; }
|
int getUniqueId() const { return uniqueId; }
|
||||||
virtual void dump(TInfoSink &infoSink) const = 0;
|
virtual void dump(TInfoSink &infoSink) const = 0;
|
||||||
|
|
||||||
void readOnly() { writable = false; }
|
bool isReadOnly() { return ! writable; }
|
||||||
|
void makeReadOnly() { writable = false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TSymbol(const TSymbol&);
|
explicit TSymbol(const TSymbol&);
|
||||||
@ -124,7 +125,7 @@ protected:
|
|||||||
//
|
//
|
||||||
class TVariable : public TSymbol {
|
class TVariable : public TSymbol {
|
||||||
public:
|
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* clone(TStructureMap& remapper);
|
||||||
virtual ~TVariable() { }
|
virtual ~TVariable() { }
|
||||||
|
|
||||||
@ -133,12 +134,11 @@ public:
|
|||||||
TType& getWritableType() { assert(writable); return type; }
|
TType& getWritableType() { assert(writable); return type; }
|
||||||
const TType& getType() const { return type; }
|
const TType& getType() const { return type; }
|
||||||
bool isUserType() const { return userType; }
|
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;
|
virtual void dump(TInfoSink &infoSink) const;
|
||||||
|
|
||||||
TConstUnion* getConstUnionPointer() {
|
TConstUnion* getConstUnionPointer()
|
||||||
|
{
|
||||||
if (!unionArray)
|
if (!unionArray)
|
||||||
unionArray = new TConstUnion[type.getObjectSize()];
|
unionArray = new TConstUnion[type.getObjectSize()];
|
||||||
|
|
||||||
@ -154,16 +154,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TVariable(TVariable&);
|
explicit TVariable(const TVariable&);
|
||||||
TVariable(const TVariable&, TStructureMap& remapper);
|
TVariable(const TVariable&, TStructureMap& remapper);
|
||||||
TVariable& operator=(TVariable&);
|
TVariable& operator=(const TVariable&);
|
||||||
|
|
||||||
TType type;
|
TType type;
|
||||||
bool userType;
|
bool userType;
|
||||||
// we are assuming that Pool Allocator will free the memory allocated to unionArray
|
// we are assuming that Pool Allocator will free the memory allocated to unionArray
|
||||||
// when this object is destroyed
|
// when this object is destroyed
|
||||||
TConstUnion *unionArray;
|
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:
|
public:
|
||||||
explicit TFunction(TOperator o) :
|
explicit TFunction(TOperator o) :
|
||||||
TSymbol(0),
|
TSymbol(0),
|
||||||
returnType(TType(EbtVoid)),
|
|
||||||
op(o),
|
op(o),
|
||||||
defined(false) { }
|
defined(false) { }
|
||||||
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
|
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
|
||||||
TSymbol(name),
|
TSymbol(name),
|
||||||
returnType(retType),
|
|
||||||
mangledName(*name + '('),
|
mangledName(*name + '('),
|
||||||
op(tOp),
|
op(tOp),
|
||||||
defined(false) { }
|
defined(false) { returnType.shallowCopy(retType); }
|
||||||
virtual TFunction* clone(TStructureMap& remapper);
|
virtual TFunction* clone(TStructureMap& remapper);
|
||||||
virtual ~TFunction();
|
virtual ~TFunction();
|
||||||
|
|
||||||
@ -455,7 +452,20 @@ public:
|
|||||||
return table[currentLevel()]->insert(symbol);
|
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();
|
int level = currentLevel();
|
||||||
TSymbol* symbol;
|
TSymbol* symbol;
|
||||||
@ -467,9 +477,7 @@ public:
|
|||||||
if (builtIn)
|
if (builtIn)
|
||||||
*builtIn = isBuiltInLevel(level);
|
*builtIn = isBuiltInLevel(level);
|
||||||
if (currentScope)
|
if (currentScope)
|
||||||
*currentScope = level == currentLevel();
|
*currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals
|
||||||
if (sharedLevel)
|
|
||||||
*sharedLevel = isSharedLevel(level);
|
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
@ -502,6 +510,7 @@ protected:
|
|||||||
int uniqueId; // for unique identification in code generation
|
int uniqueId; // for unique identification in code generation
|
||||||
bool noBuiltInRedeclarations;
|
bool noBuiltInRedeclarations;
|
||||||
unsigned int adoptedLevels;
|
unsigned int adoptedLevels;
|
||||||
|
TStructureMap remapper; // for now, dummy for copyUp(), which is not yet used for structures
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@ -90,7 +90,7 @@ using namespace glslang;
|
|||||||
glslang::TParameter param;
|
glslang::TParameter param;
|
||||||
glslang::TTypeLoc typeLine;
|
glslang::TTypeLoc typeLine;
|
||||||
glslang::TTypeList* typeList;
|
glslang::TTypeList* typeList;
|
||||||
glslang::TArraySizes arraySizes;
|
glslang::TArraySizes* arraySizes;
|
||||||
glslang::TIdentifierList* identifierList;
|
glslang::TIdentifierList* identifierList;
|
||||||
};
|
};
|
||||||
} interm;
|
} interm;
|
||||||
@ -334,13 +334,15 @@ function_call_header_no_parameters
|
|||||||
|
|
||||||
function_call_header_with_parameters
|
function_call_header_with_parameters
|
||||||
: function_call_header assignment_expression {
|
: 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);
|
$1.function->addParameter(param);
|
||||||
$$.function = $1.function;
|
$$.function = $1.function;
|
||||||
$$.intermNode = $2;
|
$$.intermNode = $2;
|
||||||
}
|
}
|
||||||
| function_call_header_with_parameters COMMA assignment_expression {
|
| 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);
|
$1.function->addParameter(param);
|
||||||
$$.function = $1.function;
|
$$.function = $1.function;
|
||||||
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
|
$$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
|
||||||
@ -890,7 +892,7 @@ parameter_declarator
|
|||||||
if ($1.arraySizes) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "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) {
|
if ($1.basicType == EbtVoid) {
|
||||||
parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), "");
|
parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), "");
|
||||||
@ -905,11 +907,11 @@ parameter_declarator
|
|||||||
if ($1.arraySizes) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "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.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);
|
parseContext.reservedErrorCheck($2.loc, *$2.string);
|
||||||
|
|
||||||
$1.arraySizes = $3.arraySizes;
|
$1.arraySizes = $3.arraySizes;
|
||||||
@ -976,7 +978,7 @@ init_declarator_list
|
|||||||
| init_declarator_list COMMA IDENTIFIER array_specifier {
|
| init_declarator_list COMMA IDENTIFIER array_specifier {
|
||||||
parseContext.nonInitConstCheck($3.loc, *$3.string, $1.type);
|
parseContext.nonInitConstCheck($3.loc, *$3.string, $1.type);
|
||||||
if (parseContext.profile == EEsProfile)
|
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);
|
parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes);
|
||||||
|
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -1047,7 +1049,7 @@ single_declaration
|
|||||||
$$.intermAggregate = 0;
|
$$.intermAggregate = 0;
|
||||||
parseContext.nonInitConstCheck($2.loc, *$2.string, $1);
|
parseContext.nonInitConstCheck($2.loc, *$2.string, $1);
|
||||||
if (parseContext.profile == EEsProfile)
|
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);
|
parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes);
|
||||||
|
|
||||||
$$.type = $1;
|
$$.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, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
parseContext.precisionQualifierCheck($$.loc, $$);
|
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, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
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))
|
if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1))
|
||||||
@ -1391,7 +1393,7 @@ array_specifier
|
|||||||
: LEFT_BRACKET RIGHT_BRACKET {
|
: LEFT_BRACKET RIGHT_BRACKET {
|
||||||
$$.loc = $1.loc;
|
$$.loc = $1.loc;
|
||||||
$$.arraySizes = NewPoolTArraySizes();
|
$$.arraySizes = NewPoolTArraySizes();
|
||||||
$$.arraySizes->push_back(0);
|
$$.arraySizes->setSize(0);
|
||||||
}
|
}
|
||||||
| LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
| LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
||||||
$$.loc = $1.loc;
|
$$.loc = $1.loc;
|
||||||
@ -1399,18 +1401,18 @@ array_specifier
|
|||||||
|
|
||||||
int size;
|
int size;
|
||||||
parseContext.arraySizeCheck($2->getLoc(), $2, size);
|
parseContext.arraySizeCheck($2->getLoc(), $2, size);
|
||||||
$$.arraySizes->push_back(size);
|
$$.arraySizes->setSize(size);
|
||||||
}
|
}
|
||||||
| array_specifier LEFT_BRACKET RIGHT_BRACKET {
|
| array_specifier LEFT_BRACKET RIGHT_BRACKET {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.arraySizes->push_back(0);
|
$$.arraySizes->setSize(0);
|
||||||
}
|
}
|
||||||
| array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
| array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
parseContext.arraySizeCheck($3->getLoc(), $3, 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, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
@ -2132,7 +2134,7 @@ struct_declaration
|
|||||||
parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
@ -2166,7 +2168,7 @@ struct_declarator
|
|||||||
}
|
}
|
||||||
| IDENTIFIER array_specifier {
|
| IDENTIFIER array_specifier {
|
||||||
if (parseContext.profile == EEsProfile)
|
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);
|
parseContext.arrayDimCheck($1.loc, $2.arraySizes, 0);
|
||||||
|
|
||||||
$$.type = new TType(EbtVoid);
|
$$.type = new TType(EbtVoid);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user