bool isDerivedType() const;
bool isCompositeType() const;
+ bool isSubroutineType() const;
bool isBasicType() const;
bool isTrivialType() const;
bool isVariable() const;
bool Verify() const;
};
-/// DIArray - This descriptor holds an array of descriptors.
-class DIArray : public DIDescriptor {
+/// DITypedArray - This descriptor holds an array of nodes with type T.
+template <typename T> class DITypedArray : public DIDescriptor {
public:
- explicit DIArray(const MDNode *N = nullptr) : DIDescriptor(N) {}
-
- unsigned getNumElements() const;
- DIDescriptor getElement(unsigned Idx) const {
- return getDescriptorField(Idx);
+ explicit DITypedArray(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ unsigned getNumElements() const {
+ return DbgNode ? DbgNode->getNumOperands() : 0;
+ }
+ T getElement(unsigned Idx) const {
+ return getFieldAs<T>(Idx);
}
};
+typedef DITypedArray<DIDescriptor> DIArray;
+
/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
/// FIXME: it seems strange that this doesn't have either a reference to the
/// type/precision or a file/line pair for location info.
template <typename T> class DIRef;
typedef DIRef<DIScope> DIScopeRef;
typedef DIRef<DIType> DITypeRef;
+typedef DITypedArray<DITypeRef> DITypeArray;
/// DIScope - A base class for various scopes.
///
class DICompositeType : public DIDerivedType {
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
+ void setArraysHelper(MDNode *Elements, MDNode *TParams);
public:
explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {}
- DIArray getElements() const { return getFieldAs<DIArray>(10); }
- void setArrays(DIArray Elements, DIArray TParams = DIArray());
+ DIArray getElements() const {
+ assert(!isSubroutineType() && "no elements for DISubroutineType");
+ return getFieldAs<DIArray>(10);
+ }
+ template <typename T>
+ void setArrays(DITypedArray<T> Elements, DIArray TParams = DIArray()) {
+ assert((!TParams || DbgNode->getNumOperands() == 15) &&
+ "If you're setting the template parameters this should include a slot "
+ "for that!");
+ setArraysHelper(Elements, TParams);
+ }
unsigned getRunTimeLang() const { return getUnsignedField(11); }
DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
void setContainingType(DICompositeType ContainingType);
bool Verify() const;
};
+class DISubroutineType : public DICompositeType {
+public:
+ explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {}
+ DITypedArray<DITypeRef> getTypeArray() const {
+ return getFieldAs<DITypedArray<DITypeRef>>(10);
+ }
+};
+
/// DIFile - This is a wrapper for a file.
class DIFile : public DIScope {
friend class DIDescriptor;
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
unsigned getLineNumber() const { return getUnsignedField(6); }
- DICompositeType getType() const { return getFieldAs<DICompositeType>(7); }
+ DISubroutineType getType() const { return getFieldAs<DISubroutineType>(7); }
/// isLocalToUnit - Return true if this subprogram is local to the current
/// compile unit, like 'static' in C.