/// This should not be stored in a container, because the underlying MDNode may
/// change in certain situations.
class DIDescriptor {
- // Befriends DIRef so DIRef can befriend the protected member
- // function: getFieldAs<DIRef>.
- template <typename T> friend class DIRef;
-
public:
/// \brief Duplicated debug info flags.
///
protected:
const MDNode *DbgNode;
- DIDescriptor getDescriptorField(unsigned Elt) const;
- template <typename DescTy> DescTy getFieldAs(unsigned Elt) const {
- return DescTy(getDescriptorField(Elt));
- }
-
public:
explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {}
+ DIDescriptor(const DebugNode *N) : DbgNode(N) {}
MDNode *get() const { return const_cast<MDNode *>(DbgNode); }
operator MDNode *() const { return get(); }
MDNode *operator->() const { return get(); }
- MDNode &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDNode &operator*() const { return *get(); }
// An explicit operator bool so that we can do testing of DI values
// easily.
void print(raw_ostream &OS) const;
void dump() const;
-
- /// \brief Replace all uses of debug info referenced by this descriptor.
- void replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D);
- void replaceAllUsesWith(MDNode *D);
};
#define DECLARE_SIMPLIFY_DESCRIPTOR(DESC) \
DECLARE_SIMPLIFY_DESCRIPTOR(DIImportedEntity)
#undef DECLARE_SIMPLIFY_DESCRIPTOR
+typedef DebugNodeArray DIArray;
+typedef MDTypeRefArray DITypeArray;
+
/// \brief This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
public:
}
operator MDSubrange *() const { return get(); }
MDSubrange *operator->() const { return get(); }
- MDSubrange &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDSubrange &operator*() const { return *get(); }
int64_t getLo() const { return get()->getLowerBound(); }
int64_t getCount() const { return get()->getCount(); }
};
-/// \brief This descriptor holds an array of nodes with type T.
-template <typename T> class DITypedArray : public DIDescriptor {
-public:
- explicit DITypedArray(const MDNode *N = nullptr) : DIDescriptor(N) {}
- operator MDTuple *() const {
- return const_cast<MDTuple *>(cast_or_null<MDTuple>(DbgNode));
- }
- unsigned getNumElements() const {
- return DbgNode ? DbgNode->getNumOperands() : 0;
- }
- T getElement(unsigned Idx) const { return getFieldAs<T>(Idx); }
-};
-
-typedef DITypedArray<DIDescriptor> DIArray;
-
/// \brief 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
}
operator MDEnumerator *() const { return get(); }
MDEnumerator *operator->() const { return get(); }
- MDEnumerator &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDEnumerator &operator*() const { return *get(); }
StringRef getName() const { return get()->getName(); }
int64_t getEnumValue() const { return get()->getValue(); }
typedef DIRef<DIDescriptor> DIDescriptorRef;
typedef DIRef<DIScope> DIScopeRef;
typedef DIRef<DIType> DITypeRef;
-typedef DITypedArray<DITypeRef> DITypeArray;
/// \brief A base class for various scopes.
///
MDScope *get() const { return cast_or_null<MDScope>(DIDescriptor::get()); }
operator MDScope *() const { return get(); }
MDScope *operator->() const { return get(); }
- MDScope &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDScope &operator*() const { return *get(); }
- /// \brief Get the parent scope.
- ///
- /// Gets the parent scope for this scope node or returns a default
- /// constructed scope.
- DIScopeRef getContext() const;
- /// \brief Get the scope name.
- ///
- /// If the scope node has a name, return that, else return an empty string.
- StringRef getName() const;
- StringRef getFilename() const;
- StringRef getDirectory() const;
+ inline DIScopeRef getContext() const;
+ StringRef getName() const { return get()->getName(); }
+ StringRef getFilename() const { return get()->getFilename(); }
+ StringRef getDirectory() const { return get()->getDirectory(); }
/// \brief Generate a reference to this DIScope.
///
///
/// Abstracts over direct and identifier-based metadata references.
template <typename T> class DIRef {
- template <typename DescTy>
- friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
- friend DIScopeRef DIScope::getContext() const;
- friend DIScopeRef DIScope::getRef() const;
- friend class DIType;
-
/// \brief Val can be either a MDNode or a MDString.
///
/// In the latter, MDString specifies the type identifier.
const Metadata *Val;
- explicit DIRef(const Metadata *V);
public:
template <class U>
T resolve(const DITypeIdentifierMap &Map) const;
operator Metadata *() const { return const_cast<Metadata *>(Val); }
-
- static DIRef get(const Metadata *MD) { return DIRef(MD); }
};
template <>
DIScope DIRef<DIScope>::resolve(const DITypeIdentifierMap &Map) const;
template <> DIType DIRef<DIType>::resolve(const DITypeIdentifierMap &Map) const;
-/// \brief Handle fields that are references to DIDescriptors.
-template <>
-DIDescriptorRef DIDescriptor::getFieldAs<DIDescriptorRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DIDescriptorRef.
-template <> DIRef<DIDescriptor>::DIRef(const Metadata *V);
-
-/// \brief Handle fields that are references to DIScopes.
-template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DIScopeRef.
-template <> DIRef<DIScope>::DIRef(const Metadata *V);
-
-/// \brief Handle fields that are references to DITypes.
-template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DITypeRef.
-template <> DIRef<DIType>::DIRef(const Metadata *V);
+DIScopeRef DIScope::getContext() const { return get()->getScope(); }
/// \brief This is a wrapper for a type.
///
MDType *get() const { return cast_or_null<MDType>(DIDescriptor::get()); }
operator MDType *() const { return get(); }
MDType *operator->() const { return get(); }
- MDType &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDType &operator*() const { return *get(); }
- DIScopeRef getContext() const { return DIScopeRef::get(get()->getScope()); }
+ DIScopeRef getContext() const { return get()->getScope(); }
StringRef getName() const { return get()->getName(); }
unsigned getLineNumber() const { return get()->getLine(); }
uint64_t getSizeInBits() const { return get()->getSizeInBits(); }
}
operator MDBasicType *() const { return get(); }
MDBasicType *operator->() const { return get(); }
- MDBasicType &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDBasicType &operator*() const { return *get(); }
unsigned getEncoding() const { return get()->getEncoding(); }
};
}
operator MDDerivedTypeBase *() const { return get(); }
MDDerivedTypeBase *operator->() const { return get(); }
- MDDerivedTypeBase &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDDerivedTypeBase &operator*() const { return *get(); }
- DITypeRef getTypeDerivedFrom() const {
- return DITypeRef::get(get()->getBaseType());
- }
+ DITypeRef getTypeDerivedFrom() const { return get()->getBaseType(); }
/// \brief Return property node, if this ivar is associated with one.
- MDNode *getObjCProperty() const {
- if (auto *N = dyn_cast<MDDerivedType>(get()))
- return dyn_cast_or_null<MDNode>(N->getExtraData());
- return nullptr;
+ MDObjCProperty *getObjCProperty() const {
+ return cast<MDDerivedType>(get())->getObjCProperty();
}
DITypeRef getClassType() const {
- assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
- if (auto *N = dyn_cast<MDDerivedType>(get()))
- return DITypeRef::get(N->getExtraData());
- return DITypeRef::get(nullptr);
+ return cast<MDDerivedType>(get())->getClassType();
}
Constant *getConstant() const {
- assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
- if (auto *N = dyn_cast<MDDerivedType>(get()))
- if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getExtraData()))
- return C->getValue();
-
- return nullptr;
+ return cast<MDDerivedType>(get())->getConstant();
}
};
class DICompositeType : public DIDerivedType {
friend class DIBuilder;
- /// \brief Set the array of member DITypes.
- void setArraysHelper(MDNode *Elements, MDNode *TParams);
-
public:
DICompositeType() = default;
DICompositeType(const MDCompositeTypeBase *N) : DIDerivedType(N) {}
}
operator MDCompositeTypeBase *() const { return get(); }
MDCompositeTypeBase *operator->() const { return get(); }
- MDCompositeTypeBase &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDCompositeTypeBase &operator*() const { return *get(); }
- DIArray getElements() const {
- assert(!isa<MDSubroutineType>(*this) && "no elements for DISubroutineType");
- return DIArray(get()->getElements());
- }
-
-private:
- template <typename T>
- void setArrays(DITypedArray<T> Elements, DIArray TParams = DIArray()) {
- assert(
- (!TParams || DbgNode->getNumOperands() == 8) &&
- "If you're setting the template parameters this should include a slot "
- "for that!");
- setArraysHelper(Elements, TParams);
- }
+ DIArray getElements() const { return get()->getElements(); }
-public:
unsigned getRunTimeLang() const { return get()->getRuntimeLang(); }
- DITypeRef getContainingType() const {
- return DITypeRef::get(get()->getVTableHolder());
- }
+ DITypeRef getContainingType() const { return get()->getVTableHolder(); }
-private:
- /// \brief Set the containing type.
- void setContainingType(DICompositeType ContainingType);
-
-public:
- DIArray getTemplateParams() const {
- return DIArray(get()->getTemplateParams());
- }
+ DIArray getTemplateParams() const { return get()->getTemplateParams(); }
MDString *getIdentifier() const { return get()->getRawIdentifier(); }
};
}
operator MDSubroutineType *() const { return get(); }
MDSubroutineType *operator->() const { return get(); }
- MDSubroutineType &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ MDSubroutineType &operator*() const { return *get(); }
- DITypedArray<DITypeRef> getTypeArray() const {
- return DITypedArray<DITypeRef>(get()->getTypeArray());
- }
+ MDTypeRefArray getTypeArray() const { return get()->getTypeArray(); }
};
-/// \brief This is a wrapper for a file.
-class DIFile : public DIScope {
-public:
- DIFile() = default;
- DIFile(const MDFile *N) : DIScope(N) {}
-
- MDFile *get() const { return cast_or_null<MDFile>(DIDescriptor::get()); }
- operator MDFile *() const { return get(); }
- MDFile *operator->() const { return get(); }
- MDFile &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+class DIFile {
+ MDFile *N;
- /// \brief Retrieve the MDNode for the directory/file pair.
- MDNode *getFileNode() const { return get(); }
-};
-
-/// \brief A wrapper for a compile unit.
-class DICompileUnit : public DIScope {
public:
- DICompileUnit() = default;
- DICompileUnit(const MDCompileUnit *N) : DIScope(N) {}
+ DIFile(const MDFile *N = nullptr) : N(const_cast<MDFile *>(N)) {}
- MDCompileUnit *get() const {
- return cast_or_null<MDCompileUnit>(DIDescriptor::get());
- }
- operator MDCompileUnit *() const { return get(); }
- MDCompileUnit *operator->() const { return get(); }
- MDCompileUnit &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- dwarf::SourceLanguage getLanguage() const {
- return static_cast<dwarf::SourceLanguage>(get()->getSourceLanguage());
- }
- StringRef getProducer() const { return get()->getProducer(); }
- bool isOptimized() const { return get()->isOptimized(); }
- StringRef getFlags() const { return get()->getFlags(); }
- unsigned getRunTimeVersion() const { return get()->getRuntimeVersion(); }
-
- DIArray getEnumTypes() const { return DIArray(get()->getEnumTypes()); }
- DIArray getRetainedTypes() const {
- return DIArray(get()->getRetainedTypes());
- }
- DIArray getSubprograms() const { return DIArray(get()->getSubprograms()); }
- DIArray getGlobalVariables() const {
- return DIArray(get()->getGlobalVariables());
- }
- DIArray getImportedEntities() const {
- return DIArray(get()->getImportedEntities());
- }
-
- void replaceSubprograms(DIArray Subprograms);
- void replaceGlobalVariables(DIArray GlobalVariables);
-
- StringRef getSplitDebugFilename() const {
- return get()->getSplitDebugFilename();
- }
- unsigned getEmissionKind() const { return get()->getEmissionKind(); }
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDFile *() const { return N; }
+ MDFile *operator->() const { return N; }
+ MDFile &operator*() const { return *N; }
};
-/// \brief This is a wrapper for a subprogram (e.g. a function).
-class DISubprogram : public DIScope {
-public:
- DISubprogram() = default;
- DISubprogram(const MDSubprogram *N) : DIScope(N) {}
-
- MDSubprogram *get() const {
- return cast_or_null<MDSubprogram>(DIDescriptor::get());
- }
- operator MDSubprogram *() const { return get(); }
- MDSubprogram *operator->() const { return get(); }
- MDSubprogram &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { return get()->getName(); }
- StringRef getDisplayName() const { return get()->getDisplayName(); }
- StringRef getLinkageName() const { return get()->getLinkageName(); }
- unsigned getLineNumber() const { return get()->getLine(); }
-
- /// \brief Check if this is local (like 'static' in C).
- unsigned isLocalToUnit() const { return get()->isLocalToUnit(); }
- unsigned isDefinition() const { return get()->isDefinition(); }
-
- unsigned getVirtuality() const { return get()->getVirtuality(); }
- unsigned getVirtualIndex() const { return get()->getVirtualIndex(); }
-
- unsigned getFlags() const { return get()->getFlags(); }
-
- unsigned isOptimized() const { return get()->isOptimized(); }
-
- /// \brief Get the beginning of the scope of the function (not the name).
- unsigned getScopeLineNumber() const { return get()->getScopeLine(); }
-
- DIScopeRef getContext() const { return DIScopeRef::get(get()->getScope()); }
- DISubroutineType getType() const {
- return DISubroutineType(get()->getType());
- }
-
- DITypeRef getContainingType() const {
- return DITypeRef::get(get()->getContainingType());
- }
-
- /// \brief Check if this provides debugging information for the function F.
- bool describes(const Function *F);
-
- Function *getFunction() const;
-
- void replaceFunction(Function *F) {
- if (auto *N = get())
- N->replaceFunction(F);
- }
- DIArray getTemplateParams() const {
- return DIArray(get()->getTemplateParams());
- }
- DISubprogram getFunctionDeclaration() const {
- return DISubprogram(get()->getDeclaration());
- }
- MDNode *getVariablesNodes() const { return getVariables(); }
- DIArray getVariables() const { return DIArray(get()->getVariables()); }
+class DICompileUnit {
+ MDCompileUnit *N;
- unsigned isArtificial() const { return get()->isArtificial(); }
- bool isPrivate() const { return get()->isPrivate(); }
- bool isProtected() const { return get()->isProtected(); }
- bool isPublic() const { return get()->isPublic(); }
- bool isExplicit() const { return get()->isExplicit(); }
- bool isPrototyped() const { return get()->isPrototyped(); }
- unsigned isLValueReference() const { return get()->isLValueReference(); }
- unsigned isRValueReference() const { return get()->isRValueReference(); }
-};
-
-/// \brief This is a wrapper for a lexical block.
-class DILexicalBlock : public DIScope {
public:
- DILexicalBlock() = default;
- DILexicalBlock(const MDLexicalBlockBase *N) : DIScope(N) {}
-
- MDLexicalBlockBase *get() const {
- return cast_or_null<MDLexicalBlockBase>(DIDescriptor::get());
- }
- operator MDLexicalBlockBase *() const { return get(); }
- MDLexicalBlockBase *operator->() const { return get(); }
- MDLexicalBlockBase &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- DIScope getContext() const { return DIScope(get()->getScope()); }
- unsigned getLineNumber() const {
- if (auto *N = dyn_cast<MDLexicalBlock>(get()))
- return N->getLine();
- return 0;
- }
- unsigned getColumnNumber() const {
- if (auto *N = dyn_cast<MDLexicalBlock>(get()))
- return N->getColumn();
- return 0;
- }
+ DICompileUnit(const MDCompileUnit *N = nullptr)
+ : N(const_cast<MDCompileUnit *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDCompileUnit *() const { return N; }
+ MDCompileUnit *operator->() const { return N; }
+ MDCompileUnit &operator*() const { return *N; }
};
-/// \brief This is a wrapper for a lexical block with a filename change.
-class DILexicalBlockFile : public DIScope {
-public:
- DILexicalBlockFile() = default;
- DILexicalBlockFile(const MDLexicalBlockFile *N) : DIScope(N) {}
+class DISubprogram {
+ MDSubprogram *N;
- MDLexicalBlockFile *get() const {
- return cast_or_null<MDLexicalBlockFile>(DIDescriptor::get());
- }
- operator MDLexicalBlockFile *() const { return get(); }
- MDLexicalBlockFile *operator->() const { return get(); }
- MDLexicalBlockFile &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- DIScope getContext() const { return get()->getScope(); }
- unsigned getDiscriminator() const { return get()->getDiscriminator(); }
-};
-
-/// \brief A wrapper for a C++ style name space.
-class DINameSpace : public DIScope {
public:
- DINameSpace() = default;
- DINameSpace(const MDNamespace *N) : DIScope(N) {}
-
- MDNamespace *get() const {
- return cast_or_null<MDNamespace>(DIDescriptor::get());
- }
- operator MDNamespace *() const { return get(); }
- MDNamespace *operator->() const { return get(); }
- MDNamespace &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { return get()->getName(); }
- unsigned getLineNumber() const { return get()->getLine(); }
- DIScope getContext() const { return DIScope(get()->getScope()); }
+ DISubprogram(const MDSubprogram *N = nullptr)
+ : N(const_cast<MDSubprogram *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDSubprogram *() const { return N; }
+ MDSubprogram *operator->() const { return N; }
+ MDSubprogram &operator*() const { return *N; }
};
-/// \brief This is a wrapper for template type parameter.
-class DITemplateTypeParameter : public DIDescriptor {
-public:
- DITemplateTypeParameter() = default;
- DITemplateTypeParameter(const MDTemplateTypeParameter *N) : DIDescriptor(N) {}
+class DILexicalBlock {
+ MDLexicalBlockBase *N;
- MDTemplateTypeParameter *get() const {
- return cast_or_null<MDTemplateTypeParameter>(DIDescriptor::get());
- }
- operator MDTemplateTypeParameter *() const { return get(); }
- MDTemplateTypeParameter *operator->() const { return get(); }
- MDTemplateTypeParameter &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { return get()->getName(); }
-
- DITypeRef getType() const { return DITypeRef::get(get()->getType()); }
-};
-
-/// \brief This is a wrapper for template value parameter.
-class DITemplateValueParameter : public DIDescriptor {
public:
- DITemplateValueParameter() = default;
- DITemplateValueParameter(const MDTemplateValueParameter *N)
- : DIDescriptor(N) {}
+ DILexicalBlock(const MDLexicalBlockBase *N = nullptr)
+ : N(const_cast<MDLexicalBlockBase *>(N)) {}
- MDTemplateValueParameter *get() const {
- return cast_or_null<MDTemplateValueParameter>(DIDescriptor::get());
- }
- operator MDTemplateValueParameter *() const { return get(); }
- MDTemplateValueParameter *operator->() const { return get(); }
- MDTemplateValueParameter &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { return get()->getName(); }
- DITypeRef getType() const { return DITypeRef::get(get()->getType()); }
- Metadata *getValue() const { return get()->getValue(); }
+ operator DIDescriptor() const { return N; }
+ operator MDLexicalBlockBase *() const { return N; }
+ MDLexicalBlockBase *operator->() const { return N; }
+ MDLexicalBlockBase &operator*() const { return *N; }
};
-/// \brief This is a wrapper for a global variable.
-class DIGlobalVariable : public DIDescriptor {
- DIFile getFile() const { return DIFile(get()->getFile()); }
+class DILexicalBlockFile {
+ MDLexicalBlockFile *N;
public:
- DIGlobalVariable() = default;
- DIGlobalVariable(const MDGlobalVariable *N) : DIDescriptor(N) {}
+ DILexicalBlockFile(const MDLexicalBlockFile *N = nullptr)
+ : N(const_cast<MDLexicalBlockFile *>(N)) {}
- MDGlobalVariable *get() const {
- return cast_or_null<MDGlobalVariable>(DIDescriptor::get());
- }
- operator MDGlobalVariable *() const { return get(); }
- MDGlobalVariable *operator->() const { return get(); }
- MDGlobalVariable &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { return get()->getName(); }
- StringRef getDisplayName() const { return get()->getDisplayName(); }
- StringRef getLinkageName() const { return get()->getLinkageName(); }
- unsigned getLineNumber() const { return get()->getLine(); }
- unsigned isLocalToUnit() const { return get()->isLocalToUnit(); }
- unsigned isDefinition() const { return get()->isDefinition(); }
-
- DIScope getContext() const { return DIScope(get()->getScope()); }
- StringRef getFilename() const { return getFile().getFilename(); }
- StringRef getDirectory() const { return getFile().getDirectory(); }
- DITypeRef getType() const { return DITypeRef::get(get()->getType()); }
-
- GlobalVariable *getGlobal() const;
- Constant *getConstant() const {
- if (auto *N = get())
- if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getVariable()))
- return C->getValue();
- return nullptr;
- }
- DIDerivedType getStaticDataMemberDeclaration() const {
- return DIDerivedType(get()->getStaticDataMemberDeclaration());
- }
+ operator DIDescriptor() const { return N; }
+ operator MDLexicalBlockFile *() const { return N; }
+ MDLexicalBlockFile *operator->() const { return N; }
+ MDLexicalBlockFile &operator*() const { return *N; }
};
-/// \brief This is a wrapper for a variable (e.g. parameter, local, global etc).
-class DIVariable : public DIDescriptor {
- unsigned getFlags() const { return get()->getFlags(); }
+class DINameSpace {
+ MDNamespace *N;
public:
- DIVariable() = default;
- DIVariable(const MDLocalVariable *N) : DIDescriptor(N) {}
-
- MDLocalVariable *get() const {
- return cast_or_null<MDLocalVariable>(DIDescriptor::get());
- }
- operator MDLocalVariable *() const { return get(); }
- MDLocalVariable *operator->() const { return get(); }
- MDLocalVariable &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
-
- StringRef getName() const { return get()->getName(); }
- unsigned getLineNumber() const { return get()->getLine(); }
- unsigned getArgNumber() const { return get()->getArg(); }
-
- DIScope getContext() const { return DIScope(get()->getScope()); }
- DIFile getFile() const { return DIFile(get()->getFile()); }
- DITypeRef getType() const { return DITypeRef::get(get()->getType()); }
-
- /// \brief Return true if this variable is marked as "artificial".
- bool isArtificial() const {
- return (getFlags() & FlagArtificial) != 0;
- }
-
- bool isObjectPointer() const {
- return (getFlags() & FlagObjectPointer) != 0;
- }
-
- /// \brief If this variable is inlined then return inline location.
- MDNode *getInlinedAt() const { return DIDescriptor(get()->getInlinedAt()); }
-
- /// \brief Check if this is a "__block" variable (Apple Blocks).
- bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const {
- return (getType().resolve(Map)).isBlockByrefStruct();
- }
+ DINameSpace(const MDNamespace *N = nullptr)
+ : N(const_cast<MDNamespace *>(N)) {}
+
+ operator DIDescriptor() const { return N; }
+ operator DIScope() const { return N; }
+ operator MDNamespace *() const { return N; }
+ MDNamespace *operator->() const { return N; }
+ MDNamespace &operator*() const { return *N; }
+};
- /// \brief Check if this is an inlined function argument.
- bool isInlinedFnArgument(const Function *CurFn);
+class DITemplateTypeParameter {
+ MDTemplateTypeParameter *N;
- /// \brief Return the size reported by the variable's type.
- unsigned getSizeInBits(const DITypeIdentifierMap &Map);
+public:
+ DITemplateTypeParameter(const MDTemplateTypeParameter *N = nullptr)
+ : N(const_cast<MDTemplateTypeParameter *>(N)) {}
- void printExtendedName(raw_ostream &OS) const;
+ operator MDTemplateTypeParameter *() const { return N; }
+ MDTemplateTypeParameter *operator->() const { return N; }
+ MDTemplateTypeParameter &operator*() const { return *N; }
};
-/// \brief A complex location expression in postfix notation.
-///
-/// This is (almost) a DWARF expression that modifies the location of a
-/// variable or (or the location of a single piece of a variable).
-///
-/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
-/// and have DW_OP_plus consume the topmost elements on the stack.
-class DIExpression : public DIDescriptor {
+class DITemplateValueParameter {
+ MDTemplateValueParameter *N;
+
public:
- DIExpression() = default;
- DIExpression(const MDExpression *N) : DIDescriptor(N) {}
+ DITemplateValueParameter(const MDTemplateValueParameter *N = nullptr)
+ : N(const_cast<MDTemplateValueParameter *>(N)) {}
- MDExpression *get() const {
- return cast_or_null<MDExpression>(DIDescriptor::get());
- }
- operator MDExpression *() const { return get(); }
- MDExpression *operator->() const { return get(); }
- MDExpression &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ operator MDTemplateValueParameter *() const { return N; }
+ MDTemplateValueParameter *operator->() const { return N; }
+ MDTemplateValueParameter &operator*() const { return *N; }
+};
- /// \brief Return the number of elements in the complex expression.
- unsigned getNumElements() const { return get()->getNumElements(); }
+class DIGlobalVariable {
+ MDGlobalVariable *N;
- /// \brief return the Idx'th complex address element.
- uint64_t getElement(unsigned I) const { return get()->getElement(I); }
+public:
+ DIGlobalVariable(const MDGlobalVariable *N = nullptr)
+ : N(const_cast<MDGlobalVariable *>(N)) {}
- /// \brief Return whether this is a piece of an aggregate variable.
- bool isBitPiece() const;
- /// \brief Return the offset of this piece in bits.
- uint64_t getBitPieceOffset() const;
- /// \brief Return the size of this piece in bits.
- uint64_t getBitPieceSize() const;
+ operator DIDescriptor() const { return N; }
+ operator MDGlobalVariable *() const { return N; }
+ MDGlobalVariable *operator->() const { return N; }
+ MDGlobalVariable &operator*() const { return *N; }
};
-/// \brief This object holds location information.
-///
-/// This object is not associated with any DWARF tag.
-class DILocation : public DIDescriptor {
+class DIVariable {
+ MDLocalVariable *N;
+
public:
- DILocation() = default;
- DILocation(const MDLocation *N) : DIDescriptor(N) {}
+ DIVariable(const MDLocalVariable *N = nullptr)
+ : N(const_cast<MDLocalVariable *>(N)) {}
- MDLocation *get() const {
- return cast_or_null<MDLocation>(DIDescriptor::get());
- }
- operator MDLocation *() const { return get(); }
- MDLocation *operator->() const { return get(); }
- MDLocation &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ operator MDLocalVariable *() const { return N; }
+ MDLocalVariable *operator->() const { return N; }
+ MDLocalVariable &operator*() const { return *N; }
+};
- unsigned getLineNumber() const { return get()->getLine(); }
- unsigned getColumnNumber() const { return get()->getColumn(); }
- DIScope getScope() const { return DIScope(get()->getScope()); }
- DILocation getOrigLocation() const {
- return DILocation(get()->getInlinedAt());
- }
- StringRef getFilename() const { return getScope().getFilename(); }
- StringRef getDirectory() const { return getScope().getDirectory(); }
- bool atSameLineAs(const DILocation &Other) const {
- return (getLineNumber() == Other.getLineNumber() &&
- getFilename() == Other.getFilename());
- }
- /// \brief Get the DWAF discriminator.
- ///
- /// DWARF discriminators are used to distinguish identical file locations for
- /// instructions that are on different basic blocks. If two instructions are
- /// inside the same lexical block and are in different basic blocks, we
- /// create a new lexical block with identical location as the original but
- /// with a different discriminator value
- /// (lib/Transforms/Util/AddDiscriminators.cpp for details).
- unsigned getDiscriminator() const {
- // Since discriminators are associated with lexical blocks, make
- // sure this location is a lexical block before retrieving its
- // value.
- if (auto *F = dyn_cast<MDLexicalBlockFile>(get()->getScope()))
- return F->getDiscriminator();
- return 0;
- }
+class DIExpression {
+ MDExpression *N;
- /// \brief Generate a new discriminator value for this location.
- unsigned computeNewDiscriminator(LLVMContext &Ctx);
+public:
+ DIExpression(const MDExpression *N = nullptr)
+ : N(const_cast<MDExpression *>(N)) {}
- /// \brief Return a copy of this location with a different scope.
- DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlockFile NewScope);
+ operator MDExpression *() const { return N; }
+ MDExpression *operator->() const { return N; }
+ MDExpression &operator*() const { return *N; }
};
-class DIObjCProperty : public DIDescriptor {
+class DILocation {
+ MDLocation *N;
+
public:
- DIObjCProperty() = default;
- DIObjCProperty(const MDObjCProperty *N) : DIDescriptor(N) {}
+ DILocation(const MDLocation *N = nullptr) : N(const_cast<MDLocation *>(N)) {}
- MDObjCProperty *get() const {
- return cast_or_null<MDObjCProperty>(DIDescriptor::get());
- }
- operator MDObjCProperty *() const { return get(); }
- MDObjCProperty *operator->() const { return get(); }
- MDObjCProperty &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+ operator MDLocation *() const { return N; }
+ MDLocation *operator->() const { return N; }
+ MDLocation &operator*() const { return *N; }
+};
- StringRef getObjCPropertyName() const { return get()->getName(); }
- DIFile getFile() const { return DIFile(get()->getFile()); }
- unsigned getLineNumber() const { return get()->getLine(); }
+class DIObjCProperty {
+ MDObjCProperty *N;
- StringRef getObjCPropertyGetterName() const { return get()->getGetterName(); }
- StringRef getObjCPropertySetterName() const { return get()->getSetterName(); }
- unsigned getAttributes() const { return get()->getAttributes(); }
- bool isReadOnlyObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
- }
- bool isReadWriteObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
- }
- bool isAssignObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_assign) != 0;
- }
- bool isRetainObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_retain) != 0;
- }
- bool isCopyObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_copy) != 0;
- }
- bool isNonAtomicObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
- }
+public:
+ DIObjCProperty(const MDObjCProperty *N = nullptr)
+ : N(const_cast<MDObjCProperty *>(N)) {}
- /// \brief Get the type.
- ///
- /// \note Objective-C doesn't have an ODR, so there is no benefit in storing
- /// the type as a DITypeRef here.
- DIType getType() const { return DIType(get()->getType()); }
+ operator MDObjCProperty *() const { return N; }
+ MDObjCProperty *operator->() const { return N; }
+ MDObjCProperty &operator*() const { return *N; }
};
-/// \brief An imported module (C++ using directive or similar).
-class DIImportedEntity : public DIDescriptor {
-public:
- DIImportedEntity() = default;
- DIImportedEntity(const MDImportedEntity *N) : DIDescriptor(N) {}
+class DIImportedEntity {
+ MDImportedEntity *N;
- MDImportedEntity *get() const {
- return cast_or_null<MDImportedEntity>(DIDescriptor::get());
- }
- operator MDImportedEntity *() const { return get(); }
- MDImportedEntity *operator->() const { return get(); }
- MDImportedEntity &operator*() const {
- assert(get() && "Expected valid pointer");
- return *get();
- }
+public:
+ DIImportedEntity(const MDImportedEntity *N = nullptr)
+ : N(const_cast<MDImportedEntity *>(N)) {}
- DIScope getContext() const { return DIScope(get()->getScope()); }
- DIDescriptorRef getEntity() const {
- return DIDescriptorRef::get(get()->getEntity());
- }
- unsigned getLineNumber() const { return get()->getLine(); }
- StringRef getName() const { return get()->getName(); }
+ operator DIDescriptor() const { return N; }
+ operator MDImportedEntity *() const { return N; }
+ MDImportedEntity *operator->() const { return N; }
+ MDImportedEntity &operator*() const { return *N; }
};
#define SIMPLIFY_DESCRIPTOR(DESC) \
/// \brief Find underlying composite type.
DICompositeType getDICompositeType(DIType T);
-/// \brief Create a new inlined variable based on current variable.
-///
-/// @param DV Current Variable.
-/// @param InlinedScope Location at current variable is inlined.
-DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
- LLVMContext &VMContext);
-
-/// \brief Remove inlined scope from the variable.
-DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
-
/// \brief Generate map by visiting all retained types.
DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);