Infrastructure: Generalize and broaden per-variable extension checking.
This commit is contained in:
parent
69932ab47f
commit
28be4543cd
6 changed files with 135 additions and 73 deletions
|
|
@ -79,10 +79,12 @@ class TVariable;
|
|||
class TFunction;
|
||||
class TAnonMember;
|
||||
|
||||
typedef TVector<const char*> TExtensionList;
|
||||
|
||||
class TSymbol {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
explicit TSymbol(const TString *n) : name(n), numExtensions(0), extensions(0), writable(true) { }
|
||||
explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { }
|
||||
virtual TSymbol* clone() const = 0;
|
||||
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
|
||||
|
||||
|
|
@ -104,17 +106,16 @@ public:
|
|||
virtual TType& getWritableType() = 0;
|
||||
virtual void setUniqueId(int id) { uniqueId = id; }
|
||||
virtual int getUniqueId() const { return uniqueId; }
|
||||
virtual void setExtensions(int num, const char* const exts[])
|
||||
virtual void setExtensions(int numExts, const char* const exts[])
|
||||
{
|
||||
assert(extensions == 0);
|
||||
assert(num > 0);
|
||||
numExtensions = num;
|
||||
extensions = NewPoolObject(exts[0], num);
|
||||
for (int e = 0; e < num; ++e)
|
||||
extensions[e] = exts[e];
|
||||
assert(numExts > 0);
|
||||
extensions = NewPoolObject(extensions);
|
||||
for (int e = 0; e < numExts; ++e)
|
||||
extensions->push_back(exts[e]);
|
||||
}
|
||||
virtual int getNumExtensions() const { return numExtensions; }
|
||||
virtual const char** getExtensions() const { return extensions; }
|
||||
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
||||
virtual const char** getExtensions() const { return extensions->data(); }
|
||||
virtual void dump(TInfoSink &infoSink) const = 0;
|
||||
|
||||
virtual bool isReadOnly() const { return ! writable; }
|
||||
|
|
@ -129,8 +130,7 @@ protected:
|
|||
|
||||
// For tracking what extensions must be present
|
||||
// (don't use if correct version/profile is present).
|
||||
int numExtensions;
|
||||
const char** extensions; // an array of pointers to existing constant char strings
|
||||
TExtensionList* extensions; // an array of pointers to existing constant char strings
|
||||
|
||||
//
|
||||
// N.B.: Non-const functions that will be generally used should assert on this,
|
||||
|
|
@ -155,7 +155,9 @@ public:
|
|||
: TSymbol(name),
|
||||
userType(uT),
|
||||
constSubtree(nullptr),
|
||||
anonId(-1) { type.shallowCopy(t); }
|
||||
memberExtensions(nullptr),
|
||||
anonId(-1)
|
||||
{ type.shallowCopy(t); }
|
||||
virtual TVariable* clone() const;
|
||||
virtual ~TVariable() { }
|
||||
|
||||
|
|
@ -172,6 +174,24 @@ public:
|
|||
virtual void setAnonId(int i) { anonId = i; }
|
||||
virtual int getAnonId() const { return anonId; }
|
||||
|
||||
virtual void setMemberExtensions(int member, int numExts, const char* const exts[])
|
||||
{
|
||||
assert(type.isStruct());
|
||||
assert(numExts > 0);
|
||||
if (memberExtensions == nullptr) {
|
||||
memberExtensions = NewPoolObject(memberExtensions);
|
||||
memberExtensions->resize(type.getStruct()->size());
|
||||
}
|
||||
for (int e = 0; e < numExts; ++e)
|
||||
(*memberExtensions)[member].push_back(exts[e]);
|
||||
}
|
||||
virtual bool hasMemberExtensions() const { return memberExtensions != nullptr; }
|
||||
virtual int getNumMemberExtensions(int member) const
|
||||
{
|
||||
return memberExtensions == nullptr ? 0 : (int)(*memberExtensions)[member].size();
|
||||
}
|
||||
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
|
||||
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
|
||||
protected:
|
||||
|
|
@ -180,15 +200,14 @@ protected:
|
|||
|
||||
TType type;
|
||||
bool userType;
|
||||
|
||||
// we are assuming that Pool Allocator will free the memory allocated to unionArray
|
||||
// when this object is destroyed
|
||||
|
||||
// TODO: these two should be a union
|
||||
// A variable could be a compile-time constant, or a specialization
|
||||
// constant, or neither, but never both.
|
||||
TConstUnionArray constArray; // for compile-time constant value
|
||||
TIntermTyped* constSubtree; // for specialization constant computation
|
||||
int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
|
||||
TConstUnionArray constArray; // for compile-time constant value
|
||||
TIntermTyped* constSubtree; // for specialization constant computation
|
||||
TVector<TExtensionList>* memberExtensions; // per-member extension list, allocated only when needed
|
||||
int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -325,7 +344,7 @@ protected:
|
|||
//
|
||||
class TAnonMember : public TSymbol {
|
||||
public:
|
||||
TAnonMember(const TString* n, unsigned int m, const TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
|
||||
TAnonMember(const TString* n, unsigned int m, TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
|
||||
virtual TAnonMember* clone() const;
|
||||
virtual ~TAnonMember() { }
|
||||
|
||||
|
|
@ -346,6 +365,13 @@ public:
|
|||
return *types[memberNumber].type;
|
||||
}
|
||||
|
||||
virtual void setExtensions(int numExts, const char* const exts[]) override
|
||||
{
|
||||
anonContainer.setMemberExtensions(memberNumber, numExts, exts);
|
||||
}
|
||||
virtual int getNumExtensions() const override { return anonContainer.getNumMemberExtensions(memberNumber); }
|
||||
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
|
||||
|
||||
virtual int getAnonId() const { return anonId; }
|
||||
virtual void dump(TInfoSink &infoSink) const;
|
||||
|
||||
|
|
@ -353,7 +379,7 @@ protected:
|
|||
explicit TAnonMember(const TAnonMember&);
|
||||
TAnonMember& operator=(const TAnonMember&);
|
||||
|
||||
const TVariable& anonContainer;
|
||||
TVariable& anonContainer;
|
||||
unsigned int memberNumber;
|
||||
int anonId;
|
||||
};
|
||||
|
|
@ -789,11 +815,30 @@ public:
|
|||
table[level]->setFunctionExtensions(name, num, extensions);
|
||||
}
|
||||
|
||||
void setVariableExtensions(const char* name, int num, const char* const extensions[])
|
||||
void setVariableExtensions(const char* name, int numExts, const char* const extensions[])
|
||||
{
|
||||
TSymbol* symbol = find(TString(name));
|
||||
if (symbol)
|
||||
symbol->setExtensions(num, extensions);
|
||||
if (symbol == nullptr)
|
||||
return;
|
||||
|
||||
symbol->setExtensions(numExts, extensions);
|
||||
}
|
||||
|
||||
void setVariableExtensions(const char* blockName, const char* name, int numExts, const char* const extensions[])
|
||||
{
|
||||
TSymbol* symbol = find(TString(blockName));
|
||||
if (symbol == nullptr)
|
||||
return;
|
||||
TVariable* variable = symbol->getAsVariable();
|
||||
assert(variable != nullptr);
|
||||
|
||||
const TTypeList& structure = *variable->getAsVariable()->getType().getStruct();
|
||||
for (int member = 0; member < (int)structure.size(); ++member) {
|
||||
if (structure[member].type->getFieldName().compare(name) == 0) {
|
||||
variable->setMemberExtensions(member, numExts, extensions);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getMaxSymbolId() { return uniqueId; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue