Restore r26192, r26240, r26241: All three about implicit-array sizing design and implementation. *Minus* test results.

r26192: Link-time sizing of implicitly-sized arrays and handling of anonymous blocks containing implicitly-sized members.  Also changed "__anon" to "anon@" and encapsulated it.

r26240: Solidify the sharing of struct and array information between nodes and variables: A single copy now allows for simultaneously setting array size for all effected nodes and symbols of a given type. This allowed removal of ioArrayNodeResizeList and makes nodes of implicitly sized arrays know the final size.

r26241: Fix g++ issue with wanting non-const iterator.


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@26218 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2014-04-14 14:59:51 +00:00
parent 078c010de7
commit 150b7acd9a
7 changed files with 222 additions and 150 deletions

View file

@ -44,6 +44,12 @@ namespace glslang {
const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded
const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed
inline bool IsAnonymous(const TString& name)
{
return name.compare(0, 5, AnonymousPrefix) == 0;
}
//
// Details within a sampler type
//
@ -174,7 +180,7 @@ typedef TVector<TString*> TIdentifierList;
struct TArraySizes {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TArraySizes() : implicitArraySize(0) { }
TArraySizes() : implicitArraySize(1) { }
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; }
@ -701,14 +707,14 @@ public:
sampler.clear();
qualifier = p.qualifier;
if (p.userDef) {
structure = p.userDef->getStruct();
structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
}
}
// to efficiently make a dereferenced type
// without ever duplicating the outer structure that will be thrown away
// and using only shallow copy
TType(const TType& type, int derefIndex)
TType(const TType& type, int derefIndex, bool rowMajor = false)
{
if (! type.isArray() && (type.basicType == EbtStruct || type.basicType == EbtBlock)) {
// do a structure dereference
@ -718,7 +724,7 @@ public:
} else {
// do an array/vector/matrix dereference
shallowCopy(type);
dereference();
dereference(rowMajor);
}
}
// for making structures, ...
@ -761,12 +767,12 @@ public:
{
shallowCopy(copyOf);
if (arraySizes) {
if (copyOf.arraySizes) {
arraySizes = new TArraySizes;
*arraySizes = *copyOf.arraySizes;
}
if (structure) {
if (copyOf.structure) {
structure = new TTypeList;
TStructureMapIterator iter;
for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
@ -778,9 +784,9 @@ public:
}
}
if (fieldName)
if (copyOf.fieldName)
fieldName = NewPoolTString(copyOf.fieldName->c_str());
if (typeName)
if (copyOf.typeName)
typeName = NewPoolTString(copyOf.typeName->c_str());
}
@ -793,47 +799,48 @@ public:
}
// Merge type from parent, where a parentType is at the beginning of a declaration,
// establishing some charastics for all subsequent names, while this type
// establishing some characteristics for all subsequent names, while this type
// is on the individual names.
void mergeType(const TPublicType& parentType)
{
// arrayness is currently the only child aspect that has to be preserved
setElementType(parentType.basicType, parentType.vectorSize, parentType.matrixCols, parentType.matrixRows, parentType.userDef);
basicType = parentType.basicType;
vectorSize = parentType.vectorSize;
matrixCols = parentType.matrixCols;
matrixRows = parentType.matrixRows;
qualifier = parentType.qualifier;
sampler = parentType.sampler;
if (parentType.arraySizes)
setArraySizes(parentType.arraySizes);
if (parentType.userDef)
if (parentType.userDef) {
structure = parentType.userDef->getWritableStruct();
setTypeName(parentType.userDef->getTypeName());
}
}
virtual void dereference()
virtual void dereference(bool rowMajor = false)
{
if (arraySizes)
arraySizes = 0;
else if (matrixCols > 0) {
vectorSize = matrixRows;
if (rowMajor)
vectorSize = matrixCols;
else
vectorSize = matrixRows;
matrixCols = 0;
matrixRows = 0;
} else if (vectorSize > 1)
vectorSize = 1;
}
virtual void setElementType(TBasicType t, int s, int mc, int mr, const TType* userDef)
{
basicType = t;
vectorSize = s;
matrixCols = mc;
matrixRows = mr;
if (userDef)
structure = userDef->getStruct();
// leave array information intact.
}
virtual void hideType() { basicType = EbtVoid; vectorSize = 1; }
virtual bool wasTypeHidden() const { return basicType == EbtVoid; }
virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
virtual const TString& getTypeName() const
{
assert(typeName);
assert(typeName);
return *typeName;
}
@ -845,17 +852,22 @@ public:
virtual TBasicType getBasicType() const { return basicType; }
virtual const TSampler& getSampler() const { return sampler; }
virtual TQualifier& getQualifier() { return qualifier; }
virtual TQualifier& getQualifier() { return qualifier; }
virtual const TQualifier& getQualifier() const { return qualifier; }
virtual int getVectorSize() const { return vectorSize; }
virtual int getMatrixCols() const { return matrixCols; }
virtual int getMatrixRows() const { return matrixRows; }
virtual int getArraySize() const { return arraySizes->sizes.front(); }
virtual int getImplicitArraySize () const { return arraySizes->implicitArraySize; }
virtual bool isScalar() const { return vectorSize == 1 && ! isStruct() && ! isArray(); }
virtual bool isVector() const { return vectorSize > 1; }
virtual bool isMatrix() const { return matrixCols ? true : false; }
virtual bool isArray() const { return arraySizes != 0; }
virtual bool isImplicitlySizedArray() const { return isArray() && ! getArraySize(); }
virtual bool isExplicitlySizedArray() const { return ! isImplicitlySizedArray(); }
virtual bool isStruct() const { return structure != 0; }
// Recursively checks if the type contains the given basic type
@ -885,28 +897,58 @@ public:
}
return false;
}
int getArraySize() const { return arraySizes->sizes.front(); }
void shareArraySizes(const TType& type)
// Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp().
virtual bool containsImplicitlySizedArray() const
{
// For when we are sharing existing array descriptors.
// This allows all references to the same array
// to be updated at once, by having all of them share the
// array description.
if (isImplicitlySizedArray())
return true;
if (! structure)
return false;
for (unsigned int i = 0; i < structure->size(); ++i) {
if ((*structure)[i].type->containsImplicitlySizedArray())
return true;
}
return false;
}
// Array editing methods. Array descriptors can be shared across
// type instances. This allows all uses of the same array
// to be updated at once. E.g., all nodes can be explicitly sized
// by tracking and correcting one implicit size. Or, all nodes
// can get the explicit size on a redeclaration that gives size.
//
// N.B.: Don't share with the shared symbol tables (symbols are
// marked as isReadOnly(). Such symbols with arrays that will be
// edited need to copyUp() on first use, so that
// A) the edits don't effect the shared symbol table, and
// B) the edits are shared across all users.
void updateArraySizes(const TType& type)
{
// For when we may already be sharing existing array descriptors,
// keeping the pointers the same, just updating the contents.
*arraySizes = *type.arraySizes;
}
void setArraySizes(TArraySizes* s)
{
// For when we don't want distinct types sharing the same descriptor.
// For setting a fresh new set of array sizes, not yet worrying about sharing.
arraySizes = new TArraySizes;
*arraySizes = *s;
}
void setArraySizes(const TType& type) { setArraySizes(type.arraySizes); }
void changeArraySize(int s) { arraySizes->sizes.front() = s; }
bool isImplicitlySizedArray() const { return isArray() && ! getArraySize(); }
bool isExplicitlySizedArray() const { return ! isImplicitlySizedArray(); }
void setImplicitArraySize (int s) { arraySizes->implicitArraySize = s; }
int getImplicitArraySize () const { return arraySizes->implicitArraySize; }
// Recursively make the implicit array size the explicit array size, through the type tree.
void adoptImplicitArraySizes()
{
if (isImplicitlySizedArray())
changeArraySize(getImplicitArraySize());
if (isStruct()) {
for (int i = 0; i < (int)structure->size(); ++i)
(*structure)[i].type->adoptImplicitArraySizes();
}
}
const char* getBasicString() const
{
@ -1044,15 +1086,15 @@ public:
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
TTypeList* getStruct() { return structure; }
TTypeList* getStruct() const { return structure; }
const TTypeList* getStruct() const { return structure; }
TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads
int computeNumComponents() const
{
int components = 0;
if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
components += ((*tl).type)->computeNumComponents();
} else if (matrixCols)
components = matrixCols * matrixRows;
@ -1158,9 +1200,8 @@ protected:
TSampler sampler;
TQualifier qualifier;
TArraySizes* arraySizes;
TTypeList* structure; // 0 unless this is a struct
TArraySizes* arraySizes; // 0 unless this is an array; can be shared across types
TTypeList* structure; // 0 unless this is a struct; can be shared across types
TString *fieldName; // for structure field names
TString *typeName; // for structure type name
};