[llvm] r228640 - IR: Add specialized debug info metadata nodes
Duncan P. N. Exon Smith
dexonsmith at apple.com
Mon Feb 9 16:52:32 PST 2015
Author: dexonsmith
Date: Mon Feb 9 18:52:32 2015
New Revision: 228640
URL: http://llvm.org/viewvc/llvm-project?rev=228640&view=rev
Log:
IR: Add specialized debug info metadata nodes
Add specialized debug info metadata nodes that match the `DIDescriptor`
wrappers (used by `DIBuilder`) closely. Assembly and bitcode support to
follow soon (it'll mostly just be obvious), but this sketches in today's
schema. This is the first big commit (well, the only *big* one aside
from the testcase changes that'll come when I move this into place) for
PR22464.
I've marked a bunch of obvious changes as `TODO`s in the source; I plan
to make those changes promptly after this hierarchy is moved underneath
`DIDescriptor`, but for now I'm aiming mostly to match the status quo.
Modified:
llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
llvm/trunk/include/llvm/IR/Metadata.def
llvm/trunk/include/llvm/IR/Metadata.h
llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/trunk/lib/IR/AsmWriter.cpp
llvm/trunk/lib/IR/DebugInfoMetadata.cpp
llvm/trunk/lib/IR/LLVMContextImpl.h
llvm/trunk/unittests/IR/MetadataTest.cpp
Modified: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfoMetadata.h?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h (original)
+++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h Mon Feb 9 18:52:32 2015
@@ -15,6 +15,7 @@
#define LLVM_IR_DEBUGINFOMETADATA_H
#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Dwarf.h"
// Helper macros for defining get() overrides.
#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
@@ -125,7 +126,31 @@ public:
unsigned getTag() const { return SubclassData16; }
static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == GenericDebugNodeKind;
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+ case GenericDebugNodeKind:
+ case MDSubrangeKind:
+ case MDEnumeratorKind:
+ case MDBasicTypeKind:
+ case MDDerivedTypeKind:
+ case MDCompositeTypeKind:
+ case MDSubroutineTypeKind:
+ case MDFileKind:
+ case MDCompileUnitKind:
+ case MDSubprogramKind:
+ case MDLexicalBlockKind:
+ case MDLexicalBlockFileKind:
+ case MDNamespaceKind:
+ case MDTemplateTypeParameterKind:
+ case MDTemplateValueParameterKind:
+ case MDGlobalVariableKind:
+ case MDLocalVariableKind:
+ case MDExpressionKind:
+ case MDObjCPropertyKind:
+ case MDImportedEntityKind:
+ return true;
+ }
}
};
@@ -206,6 +231,1308 @@ public:
}
};
+/// \brief Array subrange.
+///
+/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
+/// type.
+class MDSubrange : public DebugNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ int64_t Count;
+ int64_t Lo;
+
+ MDSubrange(LLVMContext &C, StorageType Storage, int64_t Count, int64_t Lo)
+ : DebugNode(C, MDSubrangeKind, Storage, dwarf::DW_TAG_subrange_type,
+ None),
+ Count(Count), Lo(Lo) {}
+ ~MDSubrange() {}
+
+ static MDSubrange *getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempMDSubrange cloneImpl() const {
+ return getTemporary(getContext(), getCount(), getLo());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDSubrange, (int64_t Count, int64_t Lo = 0), (Count, Lo))
+
+ TempMDSubrange clone() const { return cloneImpl(); }
+
+ int64_t getLo() const { return Lo; }
+ int64_t getCount() const { return Count; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDSubrangeKind;
+ }
+};
+
+/// \brief Enumeration value.
+///
+/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
+/// longer creates a type cycle.
+class MDEnumerator : public DebugNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ int64_t Value;
+
+ MDEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
+ ArrayRef<Metadata *> Ops)
+ : DebugNode(C, MDEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
+ Value(Value) {}
+ ~MDEnumerator() {}
+
+ static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+ StringRef Name, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Value, getCanonicalMDString(Context, Name), Storage,
+ ShouldCreate);
+ }
+ static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+ MDString *Name, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDEnumerator cloneImpl() const {
+ return getTemporary(getContext(), getValue(), getName());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDEnumerator, (int64_t Value, StringRef Name),
+ (Value, Name))
+ DEFINE_MDNODE_GET(MDEnumerator, (int64_t Value, MDString *Name),
+ (Value, Name))
+
+ TempMDEnumerator clone() const { return cloneImpl(); }
+
+ int64_t getValue() const { return Value; }
+ StringRef getName() const { return getStringOperand(0); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDEnumeratorKind;
+ }
+};
+
+/// \brief Base class for scope-like contexts.
+///
+/// Base class for lexical scopes and types (which are also declaration
+/// contexts).
+///
+/// TODO: Separate the concepts of declaration contexts and lexical scopes.
+class MDScope : public DebugNode {
+protected:
+ MDScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ ArrayRef<Metadata *> Ops)
+ : DebugNode(C, ID, Storage, Tag, Ops) {}
+ ~MDScope() {}
+
+public:
+ Metadata *getFile() const { return getOperand(0); }
+
+ static bool classof(const Metadata *MD) {
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+ case MDBasicTypeKind:
+ case MDDerivedTypeKind:
+ case MDCompositeTypeKind:
+ case MDSubroutineTypeKind:
+ case MDFileKind:
+ case MDCompileUnitKind:
+ case MDSubprogramKind:
+ case MDLexicalBlockKind:
+ case MDLexicalBlockFileKind:
+ case MDNamespaceKind:
+ return true;
+ }
+ }
+};
+
+/// \brief Base class for types.
+///
+/// TODO: Remove the hardcoded name and context, since many types don't use
+/// them.
+/// TODO: Split up flags.
+class MDType : public MDScope {
+ unsigned Line;
+ unsigned SizeInBits;
+ unsigned AlignInBits;
+ unsigned OffsetInBits;
+ unsigned Flags;
+
+protected:
+ MDType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+ : MDScope(C, ID, Storage, Tag, Ops), Line(Line), SizeInBits(SizeInBits),
+ AlignInBits(AlignInBits), OffsetInBits(OffsetInBits), Flags(Flags) {}
+ ~MDType() {}
+
+public:
+ unsigned getLine() const { return Line; }
+ unsigned getSizeInBits() const { return SizeInBits; }
+ unsigned getAlignInBits() const { return AlignInBits; }
+ unsigned getOffsetInBits() const { return OffsetInBits; }
+ unsigned getFlags() const { return Flags; }
+
+ Metadata *getScope() const { return getOperand(1); }
+ StringRef getName() const { return getStringOperand(2); }
+
+ static bool classof(const Metadata *MD) {
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+ case MDBasicTypeKind:
+ case MDDerivedTypeKind:
+ case MDCompositeTypeKind:
+ case MDSubroutineTypeKind:
+ return true;
+ }
+ }
+};
+
+/// \brief Basic type.
+///
+/// TODO: Split out DW_TAG_unspecified_type.
+/// TODO: Drop unused accessors.
+class MDBasicType : public MDType {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Encoding;
+
+ MDBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned SizeInBits, unsigned AlignInBits, unsigned Encoding,
+ ArrayRef<Metadata *> Ops)
+ : MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
+ 0, Ops),
+ Encoding(Encoding) {}
+ ~MDBasicType() {}
+
+ static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Name, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
+ SizeInBits, AlignInBits, Encoding, Storage, ShouldCreate);
+ }
+ static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempMDBasicType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
+ getAlignInBits(), getEncoding());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDBasicType,
+ (unsigned Tag, StringRef Name, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned Encoding),
+ (Tag, Name, SizeInBits, AlignInBits, Encoding))
+ DEFINE_MDNODE_GET(MDBasicType,
+ (unsigned Tag, MDString *Name, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned Encoding),
+ (Tag, Name, SizeInBits, AlignInBits, Encoding))
+
+ TempMDBasicType clone() const { return cloneImpl(); }
+
+ unsigned getEncoding() const { return Encoding; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDBasicTypeKind;
+ }
+};
+
+/// \brief Base class for MDDerivedType and MDCompositeType.
+///
+/// TODO: Delete; they're not really related.
+class MDDerivedTypeBase : public MDType {
+protected:
+ MDDerivedTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
+ unsigned Tag, unsigned Line, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : MDType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Ops) {}
+ ~MDDerivedTypeBase() {}
+
+public:
+ Metadata *getBaseType() const { return getOperand(3); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDDerivedTypeKind ||
+ MD->getMetadataID() == MDCompositeTypeKind ||
+ MD->getMetadataID() == MDSubroutineTypeKind;
+ }
+};
+
+/// \brief Derived types.
+///
+/// This includes qualified types, pointers, references, friends, typedefs, and
+/// class members.
+///
+/// TODO: Split out members (inheritance, fields, methods, etc.).
+class MDDerivedType : public MDDerivedTypeBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+ : MDDerivedTypeBase(C, MDDerivedTypeKind, Storage, Tag, Line, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Ops) {}
+ ~MDDerivedType() {}
+
+ static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Name, Metadata *File, unsigned Line,
+ Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags,
+ Metadata *ExtraData, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
+ Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, ExtraData, Storage, ShouldCreate);
+ }
+ static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *File, unsigned Line,
+ Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags,
+ Metadata *ExtraData, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDDerivedType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
+ getScope(), getBaseType(), getSizeInBits(),
+ getAlignInBits(), getOffsetInBits(), getFlags(),
+ getExtraData());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDDerivedType,
+ (unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags,
+ Metadata *ExtraData = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, ExtraData))
+ DEFINE_MDNODE_GET(MDDerivedType,
+ (unsigned Tag, StringRef Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags,
+ Metadata *ExtraData = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, ExtraData))
+
+ TempMDDerivedType clone() const { return cloneImpl(); }
+
+ /// \brief Get extra data associated with this derived type.
+ ///
+ /// Class type for pointer-to-members, objective-c property node for ivars,
+ /// or global constant wrapper for static members.
+ ///
+ /// TODO: Separate out types that need this extra operand: pointer-to-member
+ /// types and member fields (static members and ivars).
+ Metadata *getExtraData() const { return getOperand(4); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDDerivedTypeKind;
+ }
+};
+
+/// \brief Base class for MDCompositeType and MDSubroutineType.
+///
+/// TODO: Delete; they're not really related.
+class MDCompositeTypeBase : public MDDerivedTypeBase {
+ unsigned RuntimeLang;
+
+protected:
+ MDCompositeTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
+ unsigned Tag, unsigned Line, unsigned RuntimeLang,
+ unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : MDDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Ops),
+ RuntimeLang(RuntimeLang) {}
+ ~MDCompositeTypeBase() {}
+
+public:
+ Metadata *getElements() const { return getOperand(4); }
+ Metadata *getVTableHolder() const { return getOperand(5); }
+ Metadata *getTemplateParams() const { return getOperand(6); }
+ StringRef getIdentifier() const { return getStringOperand(7); }
+ unsigned getRuntimeLang() const { return RuntimeLang; }
+
+ MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDCompositeTypeKind ||
+ MD->getMetadataID() == MDSubroutineTypeKind;
+ }
+};
+
+/// \brief Composite types.
+///
+/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
+/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
+class MDCompositeType : public MDCompositeTypeBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDCompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, unsigned RuntimeLang, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : MDCompositeTypeBase(C, MDCompositeTypeKind, Storage, Tag, Line,
+ RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Ops) {}
+ ~MDCompositeType() {}
+
+ static MDCompositeType *
+ getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits, unsigned OffsetInBits,
+ unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
+ Metadata *VTableHolder, Metadata *TemplateParams,
+ StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
+ Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
+ getCanonicalMDString(Context, Identifier), Storage,
+ ShouldCreate);
+ }
+ static MDCompositeType *
+ getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits, unsigned OffsetInBits,
+ unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
+ Metadata *VTableHolder, Metadata *TemplateParams,
+ MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
+
+ TempMDCompositeType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
+ getScope(), getBaseType(), getSizeInBits(),
+ getAlignInBits(), getOffsetInBits(), getFlags(),
+ getElements(), getRuntimeLang(), getVTableHolder(),
+ getTemplateParams(), getIdentifier());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDCompositeType,
+ (unsigned Tag, StringRef Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags, Metadata *Elements,
+ unsigned RuntimeLang, Metadata *VTableHolder,
+ Metadata *TemplateParams = nullptr,
+ StringRef Identifier = ""),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier))
+ DEFINE_MDNODE_GET(MDCompositeType,
+ (unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ unsigned SizeInBits, unsigned AlignInBits,
+ unsigned OffsetInBits, unsigned Flags, Metadata *Elements,
+ unsigned RuntimeLang, Metadata *VTableHolder,
+ Metadata *TemplateParams = nullptr,
+ MDString *Identifier = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier))
+
+ TempMDCompositeType clone() const { return cloneImpl(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDCompositeTypeKind;
+ }
+};
+
+/// \brief Type array for a subprogram.
+///
+/// TODO: Detach from CompositeType, and fold the array of types in directly
+/// as operands.
+class MDSubroutineType : public MDCompositeTypeBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDSubroutineType(LLVMContext &C, StorageType Storage, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : MDCompositeTypeBase(C, MDSubroutineTypeKind, Storage,
+ dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags,
+ Ops) {}
+ ~MDSubroutineType() {}
+
+ static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
+ Metadata *TypeArray, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDSubroutineType cloneImpl() const {
+ return getTemporary(getContext(), getFlags(), getTypeArray());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDSubroutineType, (unsigned Flags, Metadata *TypeArray),
+ (Flags, TypeArray))
+
+ TempMDSubroutineType clone() const { return cloneImpl(); }
+
+ Metadata *getTypeArray() const { return getElements(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDSubroutineTypeKind;
+ }
+};
+
+/// \brief File.
+///
+/// TODO: Merge with directory/file node (including users).
+/// TODO: Canonicalize paths on creation.
+class MDFile : public MDScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
+ : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
+ ~MDFile() {}
+
+ static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
+ StringRef Directory, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, getCanonicalMDString(Context, Filename),
+ getCanonicalMDString(Context, Directory), Storage,
+ ShouldCreate);
+ }
+ static MDFile *getImpl(LLVMContext &Context, MDString *Filename,
+ MDString *Directory, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDFile cloneImpl() const {
+ return getTemporary(getContext(), getFilename(), getDirectory());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory),
+ (Filename, Directory))
+ DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory),
+ (Filename, Directory))
+
+ TempMDFile clone() const { return cloneImpl(); }
+
+ MDTuple *getFileNode() const { return cast<MDTuple>(getOperand(0)); }
+
+ StringRef getFilename() const {
+ if (auto *S = cast_or_null<MDString>(getFileNode()->getOperand(0)))
+ return S->getString();
+ return StringRef();
+ }
+ StringRef getDirectory() const {
+ if (auto *S = cast_or_null<MDString>(getFileNode()->getOperand(1)))
+ return S->getString();
+ return StringRef();
+ }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDFileKind;
+ }
+};
+
+/// \brief Compile unit.
+class MDCompileUnit : public MDScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned SourceLanguage;
+ bool IsOptimized;
+ unsigned RuntimeVersion;
+ unsigned EmissionKind;
+
+ MDCompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
+ bool IsOptimized, unsigned RuntimeVersion,
+ unsigned EmissionKind, ArrayRef<Metadata *> Ops)
+ : MDScope(C, MDCompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
+ SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
+ RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind) {}
+ ~MDCompileUnit() {}
+
+ static MDCompileUnit *
+ getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
+ StringRef Producer, bool IsOptimized, StringRef Flags,
+ unsigned RuntimeVersion, StringRef SplitDebugFilename,
+ unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
+ Metadata *Subprograms, Metadata *GlobalVariables,
+ Metadata *ImportedEntities, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, SourceLanguage, File,
+ getCanonicalMDString(Context, Producer), IsOptimized,
+ getCanonicalMDString(Context, Flags), RuntimeVersion,
+ getCanonicalMDString(Context, SplitDebugFilename),
+ EmissionKind, EnumTypes, RetainedTypes, Subprograms,
+ GlobalVariables, ImportedEntities, Storage, ShouldCreate);
+ }
+ static MDCompileUnit *
+ getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
+ MDString *Producer, bool IsOptimized, MDString *Flags,
+ unsigned RuntimeVersion, MDString *SplitDebugFilename,
+ unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
+ Metadata *Subprograms, Metadata *GlobalVariables,
+ Metadata *ImportedEntities, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDCompileUnit cloneImpl() const {
+ return getTemporary(
+ getContext(), getSourceLanguage(), getFile(), getProducer(),
+ isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
+ getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(),
+ getGlobalVariables(), getImportedEntities());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDCompileUnit,
+ (unsigned SourceLanguage, Metadata *File,
+ StringRef Producer, bool IsOptimized, StringRef Flags,
+ unsigned RuntimeVersion, StringRef SplitDebugFilename,
+ unsigned EmissionKind, Metadata *EnumTypes,
+ Metadata *RetainedTypes, Metadata *Subprograms,
+ Metadata *GlobalVariables, Metadata *ImportedEntities),
+ (SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind,
+ EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities))
+ DEFINE_MDNODE_GET(MDCompileUnit,
+ (unsigned SourceLanguage, Metadata *File,
+ MDString *Producer, bool IsOptimized, MDString *Flags,
+ unsigned RuntimeVersion, MDString *SplitDebugFilename,
+ unsigned EmissionKind, Metadata *EnumTypes,
+ Metadata *RetainedTypes, Metadata *Subprograms,
+ Metadata *GlobalVariables, Metadata *ImportedEntities),
+ (SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind,
+ EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities))
+
+ TempMDCompileUnit clone() const { return cloneImpl(); }
+
+ unsigned getSourceLanguage() const { return SourceLanguage; }
+ bool isOptimized() const { return IsOptimized; }
+ unsigned getRuntimeVersion() const { return RuntimeVersion; }
+ unsigned getEmissionKind() const { return EmissionKind; }
+ StringRef getProducer() const { return getStringOperand(1); }
+ StringRef getFlags() const { return getStringOperand(2); }
+ StringRef getSplitDebugFilename() const { return getStringOperand(3); }
+ Metadata *getEnumTypes() const { return getOperand(4); }
+ Metadata *getRetainedTypes() const { return getOperand(5); }
+ Metadata *getSubprograms() const { return getOperand(6); }
+ Metadata *getGlobalVariables() const { return getOperand(7); }
+ Metadata *getImportedEntities() const { return getOperand(8); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDCompileUnitKind;
+ }
+};
+
+/// \brief Subprogram description.
+///
+/// TODO: Remove DisplayName. It's always equal to Name.
+/// TODO: Split up flags.
+class MDSubprogram : public MDScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+ unsigned ScopeLine;
+ unsigned Virtuality;
+ unsigned VirtualIndex;
+ unsigned Flags;
+ bool IsLocalToUnit;
+ bool IsDefinition;
+ bool IsOptimized;
+
+ MDSubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
+ unsigned Flags, bool IsLocalToUnit, bool IsDefinition,
+ bool IsOptimized, ArrayRef<Metadata *> Ops)
+ : MDScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
+ Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
+ VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
+ IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
+ ~MDSubprogram() {}
+
+ static MDSubprogram *
+ getImpl(LLVMContext &Context, Metadata *Scope, StringRef Name,
+ StringRef LinkageName, Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
+ Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
+ unsigned Flags, bool IsOptimized, Metadata *Function,
+ Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
+ getCanonicalMDString(Context, LinkageName), File, Line, Type,
+ IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
+ Virtuality, VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables, Storage,
+ ShouldCreate);
+ }
+ static MDSubprogram *
+ getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
+ MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
+ Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
+ unsigned Flags, bool IsOptimized, Metadata *Function,
+ Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempMDSubprogram cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
+ getFile(), getLine(), getType(), isLocalToUnit(),
+ isDefinition(), getScopeLine(), getContainingType(),
+ getVirtuality(), getVirtualIndex(), getFlags(),
+ isOptimized(), getFunction(), getTemplateParams(),
+ getDeclaration(), getVariables());
+ }
+
+public:
+ DEFINE_MDNODE_GET(
+ MDSubprogram,
+ (Metadata * Scope, StringRef Name, StringRef LinkageName, Metadata *File,
+ unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
+ unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Metadata *Function = nullptr, Metadata *TemplateParams = nullptr,
+ Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized,
+ Function, TemplateParams, Declaration, Variables))
+ DEFINE_MDNODE_GET(
+ MDSubprogram,
+ (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
+ unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
+ unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Metadata *Function = nullptr, Metadata *TemplateParams = nullptr,
+ Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized,
+ Function, TemplateParams, Declaration, Variables))
+
+ TempMDSubprogram clone() const { return cloneImpl(); }
+
+public:
+ unsigned getLine() const { return Line; }
+ unsigned getVirtuality() const { return Virtuality; }
+ unsigned getVirtualIndex() const { return VirtualIndex; }
+ unsigned getScopeLine() const { return ScopeLine; }
+ unsigned getFlags() const { return Flags; }
+ bool isLocalToUnit() const { return IsLocalToUnit; }
+ bool isDefinition() const { return IsDefinition; }
+ bool isOptimized() const { return IsOptimized; }
+
+ Metadata *getScope() const { return getOperand(1); }
+
+ StringRef getName() const { return getStringOperand(2); }
+ StringRef getDisplayName() const { return getStringOperand(3); }
+ StringRef getLinkageName() const { return getStringOperand(4); }
+
+ Metadata *getType() const { return getOperand(5); }
+ Metadata *getContainingType() const { return getOperand(6); }
+
+ Metadata *getFunction() const { return getOperand(7); }
+ Metadata *getTemplateParams() const { return getOperand(8); }
+ Metadata *getDeclaration() const { return getOperand(9); }
+ Metadata *getVariables() const { return getOperand(10); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDSubprogramKind;
+ }
+};
+
+class MDLexicalBlockBase : public MDScope {
+protected:
+ MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
+ ArrayRef<Metadata *> Ops)
+ : MDScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
+ ~MDLexicalBlockBase() {}
+
+public:
+ Metadata *getScope() const { return getOperand(1); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDLexicalBlockKind ||
+ MD->getMetadataID() == MDLexicalBlockFileKind;
+ }
+};
+
+class MDLexicalBlock : public MDLexicalBlockBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+ unsigned Column;
+
+ MDLexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Column, ArrayRef<Metadata *> Ops)
+ : MDLexicalBlockBase(C, MDLexicalBlockKind, Storage, Ops), Line(Line),
+ Column(Column) {}
+ ~MDLexicalBlock() {}
+
+ static MDLexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, unsigned Line, unsigned Column,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempMDLexicalBlock cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getFile(), getLine(),
+ getColumn());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDLexicalBlock, (Metadata * Scope, Metadata *File,
+ unsigned Line, unsigned Column),
+ (Scope, File, Line, Column))
+
+ TempMDLexicalBlock clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return Line; }
+ unsigned getColumn() const { return Column; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDLexicalBlockKind;
+ }
+};
+
+class MDLexicalBlockFile : public MDLexicalBlockBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Discriminator;
+
+ MDLexicalBlockFile(LLVMContext &C, StorageType Storage,
+ unsigned Discriminator, ArrayRef<Metadata *> Ops)
+ : MDLexicalBlockBase(C, MDLexicalBlockFileKind, Storage, Ops),
+ Discriminator(Discriminator) {}
+ ~MDLexicalBlockFile() {}
+
+ static MDLexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, unsigned Discriminator,
+ StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDLexicalBlockFile cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getFile(),
+ getDiscriminator());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDLexicalBlockFile,
+ (Metadata * Scope, Metadata *File, unsigned Discriminator),
+ (Scope, File, Discriminator))
+
+ TempMDLexicalBlockFile clone() const { return cloneImpl(); }
+
+ unsigned getDiscriminator() const { return Discriminator; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDLexicalBlockFileKind;
+ }
+};
+
+class MDNamespace : public MDScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+
+ MDNamespace(LLVMContext &Context, StorageType Storage, unsigned Line,
+ ArrayRef<Metadata *> Ops)
+ : MDScope(Context, MDNamespaceKind, Storage, dwarf::DW_TAG_namespace,
+ Ops),
+ Line(Line) {}
+ ~MDNamespace() {}
+
+ static MDNamespace *getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, StringRef Name, unsigned Line,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name),
+ Line, Storage, ShouldCreate);
+ }
+ static MDNamespace *getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, MDString *Name, unsigned Line,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempMDNamespace cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getFile(), getName(),
+ getLine());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDNamespace, (Metadata * Scope, Metadata *File,
+ StringRef Name, unsigned Line),
+ (Scope, File, Name, Line))
+ DEFINE_MDNODE_GET(MDNamespace, (Metadata * Scope, Metadata *File,
+ MDString *Name, unsigned Line),
+ (Scope, File, Name, Line))
+
+ TempMDNamespace clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return Line; }
+ Metadata *getScope() const { return getOperand(1); }
+ StringRef getName() const { return getStringOperand(2); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDNamespaceKind;
+ }
+};
+
+/// \brief Base class for template parameters.
+///
+/// TODO: Remove the scope. It's always the compile unit, and never
+/// referenced.
+/// TODO: Remove File, Line and Column. They're always 0 and never
+/// referenced.
+class MDTemplateParameter : public DebugNode {
+ unsigned Line;
+ unsigned Column;
+
+protected:
+ MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
+ unsigned Tag, unsigned Line, unsigned Column,
+ ArrayRef<Metadata *> Ops)
+ : DebugNode(Context, ID, Storage, Tag, Ops), Line(Line), Column(Column) {}
+ ~MDTemplateParameter() {}
+
+public:
+ unsigned getLine() const { return Line; }
+ unsigned getColumn() const { return Column; }
+
+ Metadata *getFile() const { return getOperand(0); }
+ Metadata *getScope() const { return getOperand(1); }
+ StringRef getName() const { return getStringOperand(2); }
+ Metadata *getType() const { return getOperand(3); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDTemplateTypeParameterKind ||
+ MD->getMetadataID() == MDTemplateValueParameterKind;
+ }
+};
+
+class MDTemplateTypeParameter : public MDTemplateParameter {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDTemplateTypeParameter(LLVMContext &Context, StorageType Storage,
+ unsigned Line, unsigned Column,
+ ArrayRef<Metadata *> Ops)
+ : MDTemplateParameter(Context, MDTemplateTypeParameterKind, Storage,
+ dwarf::DW_TAG_template_type_parameter, Line, Column,
+ Ops) {}
+ ~MDTemplateTypeParameter() {}
+
+ static MDTemplateTypeParameter *getImpl(LLVMContext &Context, Metadata *Scope,
+ StringRef Name, Metadata *Type,
+ Metadata *File, unsigned Line,
+ unsigned Column, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Scope, getCanonicalMDString(Context, Name), Type,
+ File, Line, Column, Storage, ShouldCreate);
+ }
+ static MDTemplateTypeParameter *getImpl(LLVMContext &Context, Metadata *Scope,
+ MDString *Name, Metadata *Type,
+ Metadata *File, unsigned Line,
+ unsigned Column, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDTemplateTypeParameter cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getName(), getType(),
+ getFile(), getLine(), getColumn());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDTemplateTypeParameter,
+ (Metadata * Scope, StringRef Name, Metadata *Type,
+ Metadata *File = nullptr, unsigned Line = 0,
+ unsigned Column = 0),
+ (Scope, Name, Type, File, Line, Column))
+ DEFINE_MDNODE_GET(MDTemplateTypeParameter,
+ (Metadata * Scope, MDString *Name, Metadata *Type,
+ Metadata *File = nullptr, unsigned Line = 0,
+ unsigned Column = 0),
+ (Scope, Name, Type, File, Line, Column))
+
+ TempMDTemplateTypeParameter clone() const { return cloneImpl(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDTemplateTypeParameterKind;
+ }
+};
+
+class MDTemplateValueParameter : public MDTemplateParameter {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDTemplateValueParameter(LLVMContext &Context, StorageType Storage,
+ unsigned Tag, unsigned Line, unsigned Column,
+ ArrayRef<Metadata *> Ops)
+ : MDTemplateParameter(Context, MDTemplateValueParameterKind, Storage, Tag,
+ Line, Column, Ops) {}
+ ~MDTemplateValueParameter() {}
+
+ static MDTemplateValueParameter *
+ getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, StringRef Name,
+ Metadata *Type, Metadata *Value, Metadata *File, unsigned Line,
+ unsigned Column, StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name),
+ Type, Value, File, Line, Column, Storage, ShouldCreate);
+ }
+ static MDTemplateValueParameter *
+ getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *Type, Metadata *Value, Metadata *File, unsigned Line,
+ unsigned Column, StorageType Storage, bool ShouldCreate = true);
+
+ TempMDTemplateValueParameter cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getScope(), getName(),
+ getType(), getValue(), getFile(), getLine(),
+ getColumn());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDTemplateValueParameter,
+ (unsigned Tag, Metadata *Scope, StringRef Name,
+ Metadata *Type, Metadata *Value, Metadata *File = nullptr,
+ unsigned Line = 0, unsigned Column = 0),
+ (Tag, Scope, Name, Type, Value, File, Line, Column))
+ DEFINE_MDNODE_GET(MDTemplateValueParameter,
+ (unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *Type, Metadata *Value, Metadata *File = nullptr,
+ unsigned Line = 0, unsigned Column = 0),
+ (Tag, Scope, Name, Type, Value, File, Line, Column))
+
+ Metadata *getValue() const { return getOperand(4); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDTemplateValueParameterKind;
+ }
+};
+
+/// \brief Base class for variables.
+///
+/// TODO: Hardcode to DW_TAG_variable.
+class MDVariable : public DebugNode {
+ unsigned Line;
+
+protected:
+ MDVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ unsigned Line, ArrayRef<Metadata *> Ops)
+ : DebugNode(C, ID, Storage, Tag, Ops), Line(Line) {}
+ ~MDVariable() {}
+
+public:
+ unsigned getLine() const { return Line; }
+ Metadata *getScope() const { return getOperand(0); }
+ StringRef getName() const { return getStringOperand(1); }
+ Metadata *getFile() const { return getOperand(2); }
+ Metadata *getType() const { return getOperand(3); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDLocalVariableKind ||
+ MD->getMetadataID() == MDGlobalVariableKind;
+ }
+};
+
+/// \brief Global variables.
+///
+/// TODO: Remove DisplayName. It's always equal to Name.
+class MDGlobalVariable : public MDVariable {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ bool IsLocalToUnit;
+ bool IsDefinition;
+
+ MDGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
+ bool IsLocalToUnit, bool IsDefinition,
+ ArrayRef<Metadata *> Ops)
+ : MDVariable(C, MDGlobalVariableKind, Storage, dwarf::DW_TAG_variable,
+ Line, Ops),
+ IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
+ ~MDGlobalVariable() {}
+
+ static MDGlobalVariable *
+ getImpl(LLVMContext &Context, Metadata *Scope, StringRef Name,
+ StringRef LinkageName, Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
+ getCanonicalMDString(Context, LinkageName), File, Line, Type,
+ IsLocalToUnit, IsDefinition, Variable,
+ StaticDataMemberDeclaration, Storage, ShouldCreate);
+ }
+ static MDGlobalVariable *
+ getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
+ MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDGlobalVariable cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
+ getFile(), getLine(), getType(), isLocalToUnit(),
+ isDefinition(), getVariable(),
+ getStaticDataMemberDeclaration());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDGlobalVariable,
+ (Metadata * Scope, StringRef Name, StringRef LinkageName,
+ Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, Variable, StaticDataMemberDeclaration))
+ DEFINE_MDNODE_GET(MDGlobalVariable,
+ (Metadata * Scope, MDString *Name, MDString *LinkageName,
+ Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, Variable, StaticDataMemberDeclaration))
+
+ bool isLocalToUnit() const { return IsLocalToUnit; }
+ bool isDefinition() const { return IsDefinition; }
+ StringRef getDisplayName() const { return getStringOperand(4); }
+ StringRef getLinkageName() const { return getStringOperand(5); }
+ Metadata *getVariable() const { return getOperand(6); }
+ Metadata *getStaticDataMemberDeclaration() const { return getOperand(7); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDGlobalVariableKind;
+ }
+};
+
+/// \brief Local variable.
+///
+/// TODO: Split between arguments and otherwise.
+/// TODO: Use \c DW_TAG_variable instead of fake tags.
+/// TODO: Split up flags.
+class MDLocalVariable : public MDVariable {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Arg;
+ unsigned Flags;
+
+ MDLocalVariable(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, unsigned Arg, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : MDVariable(C, MDLocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg),
+ Flags(Flags) {}
+ ~MDLocalVariable() {}
+
+ static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
+ Metadata *Scope, StringRef Name,
+ Metadata *File, unsigned Line, Metadata *Type,
+ unsigned Arg, unsigned Flags,
+ Metadata *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name),
+ File, Line, Type, Arg, Flags, InlinedAt, Storage,
+ ShouldCreate);
+ }
+ static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
+ Metadata *Scope, MDString *Name,
+ Metadata *File, unsigned Line, Metadata *Type,
+ unsigned Arg, unsigned Flags,
+ Metadata *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDLocalVariable cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getScope(), getName(),
+ getFile(), getLine(), getType(), getArg(), getFlags(),
+ getInlinedAt());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDLocalVariable,
+ (unsigned Tag, Metadata *Scope, StringRef Name,
+ Metadata *File, unsigned Line, Metadata *Type,
+ unsigned Arg, unsigned Flags,
+ Metadata *InlinedAt = nullptr),
+ (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
+ DEFINE_MDNODE_GET(MDLocalVariable,
+ (unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *File, unsigned Line, Metadata *Type,
+ unsigned Arg, unsigned Flags,
+ Metadata *InlinedAt = nullptr),
+ (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
+
+ unsigned getArg() const { return Arg; }
+ unsigned getFlags() const { return Flags; }
+ Metadata *getInlinedAt() const { return getOperand(4); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDLocalVariableKind;
+ }
+};
+
+/// \brief DWARF expression.
+///
+/// TODO: Co-allocate the expression elements.
+/// TODO: Drop fake DW_TAG_expression and separate from DebugNode.
+/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
+/// storage types.
+class MDExpression : public DebugNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ std::vector<uint64_t> Elements;
+
+ MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
+ : DebugNode(C, MDExpressionKind, Storage, dwarf::DW_TAG_expression, None),
+ Elements(Elements.begin(), Elements.end()) {}
+ ~MDExpression() {}
+
+ static MDExpression *getImpl(LLVMContext &Context,
+ ArrayRef<uint64_t> Elements, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDExpression cloneImpl() const {
+ return getTemporary(getContext(), getElements());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDExpression, (ArrayRef<uint64_t> Elements), (Elements))
+
+ ArrayRef<uint64_t> getElements() const { return Elements; }
+
+ typedef ArrayRef<uint64_t>::iterator element_iterator;
+ element_iterator elements_begin() const { return getElements().begin(); }
+ element_iterator elements_end() const { return getElements().end(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDExpressionKind;
+ }
+};
+
+class MDObjCProperty : public DebugNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+ unsigned Attributes;
+
+ MDObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Attributes, ArrayRef<Metadata *> Ops)
+ : DebugNode(C, MDObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
+ Ops),
+ Line(Line), Attributes(Attributes) {}
+ ~MDObjCProperty() {}
+
+ static MDObjCProperty *
+ getImpl(LLVMContext &Context, StringRef Name, Metadata *File, unsigned Line,
+ StringRef GetterName, StringRef SetterName, unsigned Attributes,
+ Metadata *Type, StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
+ getCanonicalMDString(Context, GetterName),
+ getCanonicalMDString(Context, SetterName), Attributes, Type,
+ Storage, ShouldCreate);
+ }
+ static MDObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
+ Metadata *File, unsigned Line,
+ MDString *GetterName, MDString *SetterName,
+ unsigned Attributes, Metadata *Type,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempMDObjCProperty cloneImpl() const {
+ return getTemporary(getContext(), getName(), getFile(), getLine(),
+ getGetterName(), getSetterName(), getAttributes(),
+ getType());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDObjCProperty,
+ (StringRef Name, Metadata *File, unsigned Line,
+ StringRef GetterName, StringRef SetterName,
+ unsigned Attributes, Metadata *Type),
+ (Name, File, Line, GetterName, SetterName, Attributes,
+ Type))
+ DEFINE_MDNODE_GET(MDObjCProperty,
+ (MDString * Name, Metadata *File, unsigned Line,
+ MDString *GetterName, MDString *SetterName,
+ unsigned Attributes, Metadata *Type),
+ (Name, File, Line, GetterName, SetterName, Attributes,
+ Type))
+
+ unsigned getLine() const { return Line; }
+ unsigned getAttributes() const { return Attributes; }
+ StringRef getName() const { return getStringOperand(0); }
+ Metadata *getFile() const { return getOperand(1); }
+ StringRef getGetterName() const { return getStringOperand(2); }
+ StringRef getSetterName() const { return getStringOperand(3); }
+ Metadata *getType() const { return getOperand(4); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDObjCPropertyKind;
+ }
+};
+
+class MDImportedEntity : public DebugNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+
+ MDImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, ArrayRef<Metadata *> Ops)
+ : DebugNode(C, MDImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
+ ~MDImportedEntity() {}
+
+ static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
+ Metadata *Scope, Metadata *Entity,
+ unsigned Line, StringRef Name,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Tag, Scope, Entity, Line,
+ getCanonicalMDString(Context, Name), Storage, ShouldCreate);
+ }
+ static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
+ Metadata *Scope, Metadata *Entity,
+ unsigned Line, MDString *Name,
+ StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDImportedEntity cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getScope(), getEntity(),
+ getLine(), getName());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDImportedEntity,
+ (unsigned Tag, Metadata *Scope, Metadata *Entity,
+ unsigned Line, StringRef Name = ""),
+ (Tag, Scope, Entity, Line, Name))
+ DEFINE_MDNODE_GET(MDImportedEntity,
+ (unsigned Tag, Metadata *Scope, Metadata *Entity,
+ unsigned Line, MDString *Name),
+ (Tag, Scope, Entity, Line, Name))
+
+ TempMDImportedEntity clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return Line; }
+ Metadata *getScope() const { return getOperand(0); }
+ Metadata *getEntity() const { return getOperand(1); }
+ StringRef getName() const { return getStringOperand(2); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDImportedEntityKind;
+ }
+};
+
} // end namespace llvm
#undef DEFINE_MDNODE_GET_UNPACK_IMPL
Modified: llvm/trunk/include/llvm/IR/Metadata.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.def?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.def (original)
+++ llvm/trunk/include/llvm/IR/Metadata.def Mon Feb 9 18:52:32 2015
@@ -51,6 +51,32 @@ HANDLE_MDNODE_LEAF(MDTuple)
HANDLE_MDNODE_LEAF(MDLocation)
HANDLE_MDNODE_BRANCH(DebugNode)
HANDLE_MDNODE_LEAF(GenericDebugNode)
+HANDLE_MDNODE_LEAF(MDSubrange)
+HANDLE_MDNODE_LEAF(MDEnumerator)
+HANDLE_MDNODE_BRANCH(MDScope)
+HANDLE_MDNODE_BRANCH(MDType)
+HANDLE_MDNODE_LEAF(MDBasicType)
+HANDLE_MDNODE_BRANCH(MDDerivedTypeBase)
+HANDLE_MDNODE_LEAF(MDDerivedType)
+HANDLE_MDNODE_BRANCH(MDCompositeTypeBase)
+HANDLE_MDNODE_LEAF(MDCompositeType)
+HANDLE_MDNODE_LEAF(MDSubroutineType)
+HANDLE_MDNODE_LEAF(MDFile)
+HANDLE_MDNODE_LEAF(MDCompileUnit)
+HANDLE_MDNODE_LEAF(MDSubprogram)
+HANDLE_MDNODE_BRANCH(MDLexicalBlockBase)
+HANDLE_MDNODE_LEAF(MDLexicalBlock)
+HANDLE_MDNODE_LEAF(MDLexicalBlockFile)
+HANDLE_MDNODE_LEAF(MDNamespace)
+HANDLE_MDNODE_BRANCH(MDTemplateParameter)
+HANDLE_MDNODE_LEAF(MDTemplateTypeParameter)
+HANDLE_MDNODE_LEAF(MDTemplateValueParameter)
+HANDLE_MDNODE_BRANCH(MDVariable)
+HANDLE_MDNODE_LEAF(MDGlobalVariable)
+HANDLE_MDNODE_LEAF(MDLocalVariable)
+HANDLE_MDNODE_LEAF(MDExpression)
+HANDLE_MDNODE_LEAF(MDObjCProperty)
+HANDLE_MDNODE_LEAF(MDImportedEntity)
#undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF
Modified: llvm/trunk/include/llvm/IR/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.h (original)
+++ llvm/trunk/include/llvm/IR/Metadata.h Mon Feb 9 18:52:32 2015
@@ -62,6 +62,25 @@ public:
MDTupleKind,
MDLocationKind,
GenericDebugNodeKind,
+ MDSubrangeKind,
+ MDEnumeratorKind,
+ MDBasicTypeKind,
+ MDDerivedTypeKind,
+ MDCompositeTypeKind,
+ MDSubroutineTypeKind,
+ MDFileKind,
+ MDCompileUnitKind,
+ MDSubprogramKind,
+ MDLexicalBlockKind,
+ MDLexicalBlockFileKind,
+ MDNamespaceKind,
+ MDTemplateTypeParameterKind,
+ MDTemplateValueParameterKind,
+ MDGlobalVariableKind,
+ MDLocalVariableKind,
+ MDExpressionKind,
+ MDObjCPropertyKind,
+ MDImportedEntityKind,
ConstantAsMetadataKind,
LocalAsMetadataKind,
MDStringKind
@@ -865,9 +884,14 @@ public:
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDTupleKind ||
- MD->getMetadataID() == MDLocationKind ||
- MD->getMetadataID() == GenericDebugNodeKind;
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ return true;
+#include "llvm/IR/Metadata.def"
+ }
}
/// \brief Check whether MDNode is a vtable access.
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Feb 9 18:52:32 2015
@@ -809,6 +809,106 @@ static void WriteGenericDebugNode(const
Record.clear();
}
+static void WriteMDSubrange(const MDSubrange *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDEnumerator(const MDEnumerator *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDBasicType(const MDBasicType *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDDerivedType(const MDDerivedType *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDCompositeType(const MDCompositeType *,
+ const ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDSubroutineType(const MDSubroutineType *,
+ const ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDFile(const MDFile *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDCompileUnit(const MDCompileUnit *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDSubprogram(const MDSubprogram *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDLexicalBlock(const MDLexicalBlock *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDLexicalBlockFile(const MDLexicalBlockFile *,
+ const ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDNamespace(const MDNamespace *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDTemplateTypeParameter(const MDTemplateTypeParameter *,
+ const ValueEnumerator &,
+ BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDTemplateValueParameter(const MDTemplateValueParameter *,
+ const ValueEnumerator &,
+ BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDGlobalVariable(const MDGlobalVariable *,
+ const ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDLocalVariable(const MDLocalVariable *,
+ const ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDExpression(const MDExpression *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDObjCProperty(const MDObjCProperty *, const ValueEnumerator &,
+ BitstreamWriter &, SmallVectorImpl<uint64_t> &,
+ unsigned) {
+ llvm_unreachable("write not implemented");
+}
+static void WriteMDImportedEntity(const MDImportedEntity *,
+ const ValueEnumerator &, BitstreamWriter &,
+ SmallVectorImpl<uint64_t> &, unsigned) {
+ llvm_unreachable("write not implemented");
+}
+
static void WriteModuleMetadata(const Module *M,
const ValueEnumerator &VE,
BitstreamWriter &Stream) {
Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Mon Feb 9 18:52:32 2015
@@ -1347,6 +1347,93 @@ static void writeMDLocation(raw_ostream
Out << ")";
}
+static void writeMDSubrange(raw_ostream &, const MDSubrange *, TypePrinting *,
+ SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDEnumerator(raw_ostream &, const MDEnumerator *,
+ TypePrinting *, SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDBasicType(raw_ostream &, const MDBasicType *, TypePrinting *,
+ SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDDerivedType(raw_ostream &, const MDDerivedType *,
+ TypePrinting *, SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDCompositeType(raw_ostream &, const MDCompositeType *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDSubroutineType(raw_ostream &, const MDSubroutineType *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDFile(raw_ostream &, const MDFile *, TypePrinting *,
+ SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDCompileUnit(raw_ostream &, const MDCompileUnit *,
+ TypePrinting *, SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDSubprogram(raw_ostream &, const MDSubprogram *,
+ TypePrinting *, SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDLexicalBlock(raw_ostream &, const MDLexicalBlock *,
+ TypePrinting *, SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDLexicalBlockFile(raw_ostream &, const MDLexicalBlockFile *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDNamespace(raw_ostream &, const MDNamespace *, TypePrinting *,
+ SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDTemplateTypeParameter(raw_ostream &,
+ const MDTemplateTypeParameter *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDTemplateValueParameter(raw_ostream &,
+ const MDTemplateValueParameter *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDGlobalVariable(raw_ostream &, const MDGlobalVariable *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDLocalVariable(raw_ostream &, const MDLocalVariable *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDExpression(raw_ostream &, const MDExpression *,
+ TypePrinting *, SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDObjCProperty(raw_ostream &, const MDObjCProperty *,
+ TypePrinting *, SlotTracker *, const Module *) {
+ llvm_unreachable("write not implemented");
+}
+static void writeMDImportedEntity(raw_ostream &, const MDImportedEntity *,
+ TypePrinting *, SlotTracker *,
+ const Module *) {
+ llvm_unreachable("write not implemented");
+}
+
static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
TypePrinting *TypePrinter,
SlotTracker *Machine,
Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Mon Feb 9 18:52:32 2015
@@ -103,3 +103,274 @@ GenericDebugNode *GenericDebugNode::getI
void GenericDebugNode::recalculateHash() {
setHash(GenericDebugNodeInfo::KeyTy::calculateHash(this));
}
+
+#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__
+#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS
+#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \
+ do { \
+ if (Storage == Uniqued) { \
+ if (auto *N = getUniqued(Context.pImpl->CLASS##s, \
+ CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \
+ return N; \
+ if (!ShouldCreate) \
+ return nullptr; \
+ } else { \
+ assert(ShouldCreate && \
+ "Expected non-uniqued nodes to always be created"); \
+ } \
+ } while (false)
+#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \
+ return storeImpl(new (ArrayRef<Metadata *>(OPS).size()) \
+ CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
+ Storage, Context.pImpl->CLASS##s)
+#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \
+ return storeImpl(new (0u) CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \
+ Storage, Context.pImpl->CLASS##s)
+
+MDSubrange *MDSubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
+ StorageType Storage, bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(MDSubrange, (Count, Lo));
+ DEFINE_GETIMPL_STORE_NO_OPS(MDSubrange, (Count, Lo));
+}
+
+MDEnumerator *MDEnumerator::getImpl(LLVMContext &Context, int64_t Value,
+ MDString *Name, StorageType Storage,
+ bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDEnumerator, (Value, getString(Name)));
+ Metadata *Ops[] = {Name};
+ DEFINE_GETIMPL_STORE(MDEnumerator, (Value), Ops);
+}
+
+MDBasicType *MDBasicType::getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(
+ MDBasicType, (Tag, getString(Name), SizeInBits, AlignInBits, Encoding));
+ Metadata *Ops[] = {nullptr, nullptr, Name};
+ DEFINE_GETIMPL_STORE(MDBasicType, (Tag, SizeInBits, AlignInBits, Encoding),
+ Ops);
+}
+
+MDDerivedType *MDDerivedType::getImpl(
+ LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+ Metadata *ExtraData, StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDDerivedType, (Tag, getString(Name), File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, ExtraData));
+ Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData};
+ DEFINE_GETIMPL_STORE(
+ MDDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags),
+ Ops);
+}
+
+MDCompositeType *MDCompositeType::getImpl(
+ LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+ Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
+ Metadata *TemplateParams, MDString *Identifier, StorageType Storage,
+ bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDCompositeType,
+ (Tag, getString(Name), File, Line, Scope, BaseType,
+ SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
+ RuntimeLang, VTableHolder, TemplateParams,
+ getString(Identifier)));
+ Metadata *Ops[] = {File, Scope, Name, BaseType,
+ Elements, VTableHolder, TemplateParams, Identifier};
+ DEFINE_GETIMPL_STORE(MDCompositeType, (Tag, Line, RuntimeLang, SizeInBits,
+ AlignInBits, OffsetInBits, Flags),
+ Ops);
+}
+
+MDSubroutineType *MDSubroutineType::getImpl(LLVMContext &Context,
+ unsigned Flags, Metadata *TypeArray,
+ StorageType Storage,
+ bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(MDSubroutineType, (Flags, TypeArray));
+ Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr,
+ TypeArray, nullptr, nullptr};
+ DEFINE_GETIMPL_STORE(MDSubroutineType, (Flags), Ops);
+}
+
+MDFile *MDFile::getImpl(LLVMContext &Context, MDString *Filename,
+ MDString *Directory, StorageType Storage,
+ bool ShouldCreate) {
+ assert(isCanonical(Filename) && "Expected canonical MDString");
+ assert(isCanonical(Directory) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDFile, (getString(Filename), getString(Directory)));
+ Metadata *NodeOps[] = {Filename, Directory};
+ Metadata *Ops[] = {MDTuple::get(Context, NodeOps)};
+ return storeImpl(new (ArrayRef<Metadata *>(Ops).size())
+ MDFile(Context, Storage, Ops),
+ Storage, Context.pImpl->MDFiles);
+}
+
+MDCompileUnit *MDCompileUnit::getImpl(
+ LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
+ MDString *Producer, bool IsOptimized, MDString *Flags,
+ unsigned RuntimeVersion, MDString *SplitDebugFilename,
+ unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
+ Metadata *Subprograms, Metadata *GlobalVariables,
+ Metadata *ImportedEntities, StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Producer) && "Expected canonical MDString");
+ assert(isCanonical(Flags) && "Expected canonical MDString");
+ assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(
+ MDCompileUnit,
+ (SourceLanguage, File, getString(Producer), IsOptimized, getString(Flags),
+ RuntimeVersion, getString(SplitDebugFilename), EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables, ImportedEntities));
+ Metadata *Ops[] = {File, Producer, Flags, SplitDebugFilename, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities};
+ DEFINE_GETIMPL_STORE(
+ MDCompileUnit,
+ (SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind), Ops);
+}
+
+MDSubprogram *MDSubprogram::getImpl(
+ LLVMContext &Context, Metadata *Scope, MDString *Name,
+ MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
+ Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
+ unsigned Flags, bool IsOptimized, Metadata *Function,
+ Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
+ StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ assert(isCanonical(LinkageName) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDSubprogram,
+ (Scope, getString(Name), getString(LinkageName), File,
+ Line, Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex, Flags,
+ IsOptimized, Function, TemplateParams, Declaration,
+ Variables));
+ Metadata *Ops[] = {File, Scope, Name, Name,
+ LinkageName, Type, ContainingType, Function,
+ TemplateParams, Declaration, Variables};
+ DEFINE_GETIMPL_STORE(MDSubprogram,
+ (Line, ScopeLine, Virtuality, VirtualIndex, Flags,
+ IsLocalToUnit, IsDefinition, IsOptimized),
+ Ops);
+}
+
+MDLexicalBlock *MDLexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, unsigned Line,
+ unsigned Column, StorageType Storage,
+ bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(MDLexicalBlock, (Scope, File, Line, Column));
+ Metadata *Ops[] = {File, Scope};
+ DEFINE_GETIMPL_STORE(MDLexicalBlock, (Line, Column), Ops);
+}
+
+MDLexicalBlockFile *MDLexicalBlockFile::getImpl(LLVMContext &Context,
+ Metadata *Scope, Metadata *File,
+ unsigned Discriminator,
+ StorageType Storage,
+ bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(MDLexicalBlockFile, (Scope, File, Discriminator));
+ Metadata *Ops[] = {File, Scope};
+ DEFINE_GETIMPL_STORE(MDLexicalBlockFile, (Discriminator), Ops);
+}
+
+MDNamespace *MDNamespace::getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, MDString *Name, unsigned Line,
+ StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDNamespace, (Scope, File, getString(Name), Line));
+ Metadata *Ops[] = {File, Scope, Name};
+ DEFINE_GETIMPL_STORE(MDNamespace, (Line), Ops);
+}
+
+MDTemplateTypeParameter *
+MDTemplateTypeParameter::getImpl(LLVMContext &Context, Metadata *Scope,
+ MDString *Name, Metadata *Type, Metadata *File,
+ unsigned Line, unsigned Column,
+ StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDTemplateTypeParameter,
+ (Scope, getString(Name), Type, File, Line, Column));
+ Metadata *Ops[] = {File, Scope, Name, Type};
+ DEFINE_GETIMPL_STORE(MDTemplateTypeParameter, (Line, Column), Ops);
+}
+
+MDTemplateValueParameter *MDTemplateValueParameter::getImpl(
+ LLVMContext &Context, unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *Type, Metadata *Value, Metadata *File, unsigned Line,
+ unsigned Column, StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(
+ MDTemplateValueParameter,
+ (Tag, Scope, getString(Name), Type, Value, File, Line, Column));
+ Metadata *Ops[] = {File, Scope, Name, Type, Value};
+ DEFINE_GETIMPL_STORE(MDTemplateValueParameter, (Tag, Line, Column), Ops);
+}
+
+MDGlobalVariable *
+MDGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
+ MDString *LinkageName, Metadata *File, unsigned Line,
+ Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
+ Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration,
+ StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ assert(isCanonical(LinkageName) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDGlobalVariable,
+ (Scope, getString(Name), getString(LinkageName), File,
+ Line, Type, IsLocalToUnit, IsDefinition, Variable,
+ StaticDataMemberDeclaration));
+ Metadata *Ops[] = {Scope, Name, File, Type,
+ Name, LinkageName, Variable, StaticDataMemberDeclaration};
+ DEFINE_GETIMPL_STORE(MDGlobalVariable, (Line, IsLocalToUnit, IsDefinition),
+ Ops);
+}
+
+MDLocalVariable *MDLocalVariable::getImpl(
+ LLVMContext &Context, unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags,
+ Metadata *InlinedAt, StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDLocalVariable, (Tag, Scope, getString(Name), File,
+ Line, Type, Arg, Flags, InlinedAt));
+ Metadata *Ops[] = {Scope, Name, File, Type, InlinedAt};
+ DEFINE_GETIMPL_STORE(MDLocalVariable, (Tag, Line, Arg, Flags), Ops);
+}
+
+MDExpression *MDExpression::getImpl(LLVMContext &Context,
+ ArrayRef<uint64_t> Elements,
+ StorageType Storage, bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(MDExpression, (Elements));
+ DEFINE_GETIMPL_STORE_NO_OPS(MDExpression, (Elements));
+}
+
+MDObjCProperty *MDObjCProperty::getImpl(
+ LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
+ MDString *GetterName, MDString *SetterName, unsigned Attributes,
+ Metadata *Type, StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ assert(isCanonical(GetterName) && "Expected canonical MDString");
+ assert(isCanonical(SetterName) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDObjCProperty,
+ (getString(Name), File, Line, getString(GetterName),
+ getString(SetterName), Attributes, Type));
+ Metadata *Ops[] = {Name, File, GetterName, SetterName, Type};
+ DEFINE_GETIMPL_STORE(MDObjCProperty, (Line, Attributes), Ops);
+}
+
+MDImportedEntity *MDImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
+ Metadata *Scope, Metadata *Entity,
+ unsigned Line, MDString *Name,
+ StorageType Storage,
+ bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(MDImportedEntity,
+ (Tag, Scope, Entity, Line, getString(Name)));
+ Metadata *Ops[] = {Scope, Entity, Name};
+ DEFINE_GETIMPL_STORE(MDImportedEntity, (Tag, Line), Ops);
+}
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Mon Feb 9 18:52:32 2015
@@ -273,6 +273,581 @@ template <> struct MDNodeKeyImpl<Generic
}
};
+template <> struct MDNodeKeyImpl<MDSubrange> {
+ int64_t Count;
+ int64_t Lo;
+
+ MDNodeKeyImpl(int64_t Count, int64_t Lo) : Count(Count), Lo(Lo) {}
+ MDNodeKeyImpl(const MDSubrange *N) : Count(N->getCount()), Lo(N->getLo()) {}
+
+ bool isKeyOf(const MDSubrange *RHS) const {
+ return Count == RHS->getCount() && Lo == RHS->getLo();
+ }
+ unsigned getHashValue() const { return hash_combine(Count, Lo); }
+};
+
+template <> struct MDNodeKeyImpl<MDEnumerator> {
+ int64_t Value;
+ StringRef Name;
+
+ MDNodeKeyImpl(int64_t Value, StringRef Name) : Value(Value), Name(Name) {}
+ MDNodeKeyImpl(const MDEnumerator *N)
+ : Value(N->getValue()), Name(N->getName()) {}
+
+ bool isKeyOf(const MDEnumerator *RHS) const {
+ return Value == RHS->getValue() && Name == RHS->getName();
+ }
+ unsigned getHashValue() const { return hash_combine(Value, Name); }
+};
+
+template <> struct MDNodeKeyImpl<MDBasicType> {
+ unsigned Tag;
+ StringRef Name;
+ unsigned SizeInBits;
+ unsigned AlignInBits;
+ unsigned Encoding;
+
+ MDNodeKeyImpl(unsigned Tag, StringRef Name, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned Encoding)
+ : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
+ Encoding(Encoding) {}
+ MDNodeKeyImpl(const MDBasicType *N)
+ : Tag(N->getTag()), Name(N->getName()), SizeInBits(N->getSizeInBits()),
+ AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()) {}
+
+ bool isKeyOf(const MDBasicType *RHS) const {
+ return Tag == RHS->getTag() && Name == RHS->getName() &&
+ SizeInBits == RHS->getSizeInBits() &&
+ AlignInBits == RHS->getAlignInBits() &&
+ Encoding == RHS->getEncoding();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDDerivedType> {
+ unsigned Tag;
+ StringRef Name;
+ Metadata *File;
+ unsigned Line;
+ Metadata *Scope;
+ Metadata *BaseType;
+ unsigned SizeInBits;
+ unsigned AlignInBits;
+ unsigned OffsetInBits;
+ unsigned Flags;
+ Metadata *ExtraData;
+
+ MDNodeKeyImpl(unsigned Tag, StringRef Name, Metadata *File, unsigned Line,
+ Metadata *Scope, Metadata *BaseType, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+ Metadata *ExtraData)
+ : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
+ BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
+ OffsetInBits(OffsetInBits), Flags(Flags), ExtraData(ExtraData) {}
+ MDNodeKeyImpl(const MDDerivedType *N)
+ : Tag(N->getTag()), Name(N->getName()), File(N->getFile()),
+ Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()),
+ SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
+ OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()),
+ ExtraData(N->getExtraData()) {}
+
+ bool isKeyOf(const MDDerivedType *RHS) const {
+ return Tag == RHS->getTag() && Name == RHS->getName() &&
+ File == RHS->getFile() && Line == RHS->getLine() &&
+ Scope == RHS->getScope() && BaseType == RHS->getBaseType() &&
+ SizeInBits == RHS->getSizeInBits() &&
+ AlignInBits == RHS->getAlignInBits() &&
+ OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
+ ExtraData == RHS->getExtraData();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, ExtraData);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDCompositeType> {
+ unsigned Tag;
+ StringRef Name;
+ Metadata *File;
+ unsigned Line;
+ Metadata *Scope;
+ Metadata *BaseType;
+ unsigned SizeInBits;
+ unsigned AlignInBits;
+ unsigned OffsetInBits;
+ unsigned Flags;
+ Metadata *Elements;
+ unsigned RuntimeLang;
+ Metadata *VTableHolder;
+ Metadata *TemplateParams;
+ StringRef Identifier;
+
+ MDNodeKeyImpl(unsigned Tag, StringRef Name, Metadata *File, unsigned Line,
+ Metadata *Scope, Metadata *BaseType, unsigned SizeInBits,
+ unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+ Metadata *Elements, unsigned RuntimeLang,
+ Metadata *VTableHolder, Metadata *TemplateParams,
+ StringRef Identifier)
+ : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
+ BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
+ OffsetInBits(OffsetInBits), Flags(Flags), Elements(Elements),
+ RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
+ TemplateParams(TemplateParams), Identifier(Identifier) {}
+ MDNodeKeyImpl(const MDCompositeType *N)
+ : Tag(N->getTag()), Name(N->getName()), File(N->getFile()),
+ Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()),
+ SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
+ OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()),
+ Elements(N->getElements()), RuntimeLang(N->getRuntimeLang()),
+ VTableHolder(N->getVTableHolder()),
+ TemplateParams(N->getTemplateParams()), Identifier(N->getIdentifier()) {
+ }
+
+ bool isKeyOf(const MDCompositeType *RHS) const {
+ return Tag == RHS->getTag() && Name == RHS->getName() &&
+ File == RHS->getFile() && Line == RHS->getLine() &&
+ Scope == RHS->getScope() && BaseType == RHS->getBaseType() &&
+ SizeInBits == RHS->getSizeInBits() &&
+ AlignInBits == RHS->getAlignInBits() &&
+ OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
+ Elements == RHS->getElements() &&
+ RuntimeLang == RHS->getRuntimeLang() &&
+ VTableHolder == RHS->getVTableHolder() &&
+ TemplateParams == RHS->getTemplateParams() &&
+ Identifier == RHS->getIdentifier();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDSubroutineType> {
+ unsigned Flags;
+ Metadata *TypeArray;
+
+ MDNodeKeyImpl(int64_t Flags, Metadata *TypeArray)
+ : Flags(Flags), TypeArray(TypeArray) {}
+ MDNodeKeyImpl(const MDSubroutineType *N)
+ : Flags(N->getFlags()), TypeArray(N->getTypeArray()) {}
+
+ bool isKeyOf(const MDSubroutineType *RHS) const {
+ return Flags == RHS->getFlags() && TypeArray == RHS->getTypeArray();
+ }
+ unsigned getHashValue() const { return hash_combine(Flags, TypeArray); }
+};
+
+template <> struct MDNodeKeyImpl<MDFile> {
+ StringRef Filename;
+ StringRef Directory;
+
+ MDNodeKeyImpl(StringRef Filename, StringRef Directory)
+ : Filename(Filename), Directory(Directory) {}
+ MDNodeKeyImpl(const MDFile *N)
+ : Filename(N->getFilename()), Directory(N->getDirectory()) {}
+
+ bool isKeyOf(const MDFile *RHS) const {
+ return Filename == RHS->getFilename() && Directory == RHS->getDirectory();
+ }
+ unsigned getHashValue() const { return hash_combine(Filename, Directory); }
+};
+
+template <> struct MDNodeKeyImpl<MDCompileUnit> {
+ unsigned SourceLanguage;
+ Metadata *File;
+ StringRef Producer;
+ bool IsOptimized;
+ StringRef Flags;
+ unsigned RuntimeVersion;
+ StringRef SplitDebugFilename;
+ unsigned EmissionKind;
+ Metadata *EnumTypes;
+ Metadata *RetainedTypes;
+ Metadata *Subprograms;
+ Metadata *GlobalVariables;
+ Metadata *ImportedEntities;
+
+ MDNodeKeyImpl(unsigned SourceLanguage, Metadata *File, StringRef Producer,
+ bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
+ StringRef SplitDebugFilename, unsigned EmissionKind,
+ Metadata *EnumTypes, Metadata *RetainedTypes,
+ Metadata *Subprograms, Metadata *GlobalVariables,
+ Metadata *ImportedEntities)
+ : SourceLanguage(SourceLanguage), File(File), Producer(Producer),
+ IsOptimized(IsOptimized), Flags(Flags), RuntimeVersion(RuntimeVersion),
+ SplitDebugFilename(SplitDebugFilename), EmissionKind(EmissionKind),
+ EnumTypes(EnumTypes), RetainedTypes(RetainedTypes),
+ Subprograms(Subprograms), GlobalVariables(GlobalVariables),
+ ImportedEntities(ImportedEntities) {}
+ MDNodeKeyImpl(const MDCompileUnit *N)
+ : SourceLanguage(N->getSourceLanguage()), File(N->getFile()),
+ Producer(N->getProducer()), IsOptimized(N->isOptimized()),
+ Flags(N->getFlags()), RuntimeVersion(N->getRuntimeVersion()),
+ SplitDebugFilename(N->getSplitDebugFilename()),
+ EmissionKind(N->getEmissionKind()), EnumTypes(N->getEnumTypes()),
+ RetainedTypes(N->getRetainedTypes()), Subprograms(N->getSubprograms()),
+ GlobalVariables(N->getGlobalVariables()),
+ ImportedEntities(N->getImportedEntities()) {}
+
+ bool isKeyOf(const MDCompileUnit *RHS) const {
+ return SourceLanguage == RHS->getSourceLanguage() &&
+ File == RHS->getFile() && Producer == RHS->getProducer() &&
+ IsOptimized == RHS->isOptimized() && Flags == RHS->getFlags() &&
+ RuntimeVersion == RHS->getRuntimeVersion() &&
+ SplitDebugFilename == RHS->getSplitDebugFilename() &&
+ EmissionKind == RHS->getEmissionKind() &&
+ EnumTypes == RHS->getEnumTypes() &&
+ RetainedTypes == RHS->getRetainedTypes() &&
+ Subprograms == RHS->getSubprograms() &&
+ GlobalVariables == RHS->getGlobalVariables() &&
+ ImportedEntities == RHS->getImportedEntities();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind,
+ EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDSubprogram> {
+ Metadata *Scope;
+ StringRef Name;
+ StringRef LinkageName;
+ Metadata *File;
+ unsigned Line;
+ Metadata *Type;
+ bool IsLocalToUnit;
+ bool IsDefinition;
+ unsigned ScopeLine;
+ Metadata *ContainingType;
+ unsigned Virtuality;
+ unsigned VirtualIndex;
+ unsigned Flags;
+ bool IsOptimized;
+ Metadata *Function;
+ Metadata *TemplateParams;
+ Metadata *Declaration;
+ Metadata *Variables;
+
+ MDNodeKeyImpl(Metadata *Scope, StringRef Name, StringRef LinkageName,
+ Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
+ Metadata *ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Metadata *Function, Metadata *TemplateParams,
+ Metadata *Declaration, Metadata *Variables)
+ : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
+ Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
+ IsDefinition(IsDefinition), ScopeLine(ScopeLine),
+ ContainingType(ContainingType), Virtuality(Virtuality),
+ VirtualIndex(VirtualIndex), Flags(Flags), IsOptimized(IsOptimized),
+ Function(Function), TemplateParams(TemplateParams),
+ Declaration(Declaration), Variables(Variables) {}
+ MDNodeKeyImpl(const MDSubprogram *N)
+ : Scope(N->getScope()), Name(N->getName()),
+ LinkageName(N->getLinkageName()), File(N->getFile()),
+ Line(N->getLine()), Type(N->getType()),
+ IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
+ ScopeLine(N->getScopeLine()), ContainingType(N->getContainingType()),
+ Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()),
+ Flags(N->getFlags()), IsOptimized(N->isOptimized()),
+ Function(N->getFunction()), TemplateParams(N->getTemplateParams()),
+ Declaration(N->getDeclaration()), Variables(N->getVariables()) {}
+
+ bool isKeyOf(const MDSubprogram *RHS) const {
+ return Scope == RHS->getScope() && Name == RHS->getName() &&
+ LinkageName == RHS->getLinkageName() && File == RHS->getFile() &&
+ Line == RHS->getLine() && Type == RHS->getType() &&
+ IsLocalToUnit == RHS->isLocalToUnit() &&
+ IsDefinition == RHS->isDefinition() &&
+ ScopeLine == RHS->getScopeLine() &&
+ ContainingType == RHS->getContainingType() &&
+ Virtuality == RHS->getVirtuality() &&
+ VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() &&
+ IsOptimized == RHS->isOptimized() &&
+ Function == RHS->getFunction() &&
+ TemplateParams == RHS->getTemplateParams() &&
+ Declaration == RHS->getDeclaration() &&
+ Variables == RHS->getVariables();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Scope, Name, LinkageName, File, Line, Type,
+ IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
+ Virtuality, VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDLexicalBlock> {
+ Metadata *Scope;
+ Metadata *File;
+ unsigned Line;
+ unsigned Column;
+
+ MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
+ : Scope(Scope), File(File), Line(Line), Column(Column) {}
+ MDNodeKeyImpl(const MDLexicalBlock *N)
+ : Scope(N->getScope()), File(N->getFile()), Line(N->getLine()),
+ Column(N->getColumn()) {}
+
+ bool isKeyOf(const MDLexicalBlock *RHS) const {
+ return Scope == RHS->getScope() && File == RHS->getFile() &&
+ Line == RHS->getLine() && Column == RHS->getColumn();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Scope, File, Line, Column);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDLexicalBlockFile> {
+ Metadata *Scope;
+ Metadata *File;
+ unsigned Discriminator;
+
+ MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
+ : Scope(Scope), File(File), Discriminator(Discriminator) {}
+ MDNodeKeyImpl(const MDLexicalBlockFile *N)
+ : Scope(N->getScope()), File(N->getFile()),
+ Discriminator(N->getDiscriminator()) {}
+
+ bool isKeyOf(const MDLexicalBlockFile *RHS) const {
+ return Scope == RHS->getScope() && File == RHS->getFile() &&
+ Discriminator == RHS->getDiscriminator();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Scope, File, Discriminator);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDNamespace> {
+ Metadata *Scope;
+ Metadata *File;
+ StringRef Name;
+ unsigned Line;
+
+ MDNodeKeyImpl(Metadata *Scope, Metadata *File, StringRef Name, unsigned Line)
+ : Scope(Scope), File(File), Name(Name), Line(Line) {}
+ MDNodeKeyImpl(const MDNamespace *N)
+ : Scope(N->getScope()), File(N->getFile()), Name(N->getName()),
+ Line(N->getLine()) {}
+
+ bool isKeyOf(const MDNamespace *RHS) const {
+ return Scope == RHS->getScope() && File == RHS->getFile() &&
+ Name == RHS->getName() && Line == RHS->getLine();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Scope, File, Name, Line);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDTemplateTypeParameter> {
+ Metadata *Scope;
+ StringRef Name;
+ Metadata *Type;
+ Metadata *File;
+ unsigned Line;
+ unsigned Column;
+
+ MDNodeKeyImpl(Metadata *Scope, StringRef Name, Metadata *Type, Metadata *File,
+ unsigned Line, unsigned Column)
+ : Scope(Scope), Name(Name), Type(Type), File(File), Line(Line),
+ Column(Column) {}
+ MDNodeKeyImpl(const MDTemplateTypeParameter *N)
+ : Scope(N->getScope()), Name(N->getName()), Type(N->getType()),
+ File(N->getFile()), Line(N->getLine()), Column(N->getColumn()) {}
+
+ bool isKeyOf(const MDTemplateTypeParameter *RHS) const {
+ return Scope == RHS->getScope() && Name == RHS->getName() &&
+ Type == RHS->getType() && File == RHS->getFile() &&
+ Line == RHS->getLine() && Column == RHS->getColumn();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Scope, Name, Type, File, Line, Column);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDTemplateValueParameter> {
+ unsigned Tag;
+ Metadata *Scope;
+ StringRef Name;
+ Metadata *Type;
+ Metadata *Value;
+ Metadata *File;
+ unsigned Line;
+ unsigned Column;
+
+ MDNodeKeyImpl(unsigned Tag, Metadata *Scope, StringRef Name, Metadata *Type,
+ Metadata *Value, Metadata *File, unsigned Line, unsigned Column)
+ : Tag(Tag), Scope(Scope), Name(Name), Type(Type), Value(Value),
+ File(File), Line(Line), Column(Column) {}
+ MDNodeKeyImpl(const MDTemplateValueParameter *N)
+ : Tag(N->getTag()), Scope(N->getScope()), Name(N->getName()),
+ Type(N->getType()), Value(N->getValue()), File(N->getFile()),
+ Line(N->getLine()), Column(N->getColumn()) {}
+
+ bool isKeyOf(const MDTemplateValueParameter *RHS) const {
+ return Tag == RHS->getTag() && Scope == RHS->getScope() &&
+ Name == RHS->getName() && Type == RHS->getType() &&
+ Value == RHS->getValue() && File == RHS->getFile() &&
+ Line == RHS->getLine() && Column == RHS->getColumn();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Tag, Scope, Name, Type, Value, File, Line, Column);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDGlobalVariable> {
+ Metadata *Scope;
+ StringRef Name;
+ StringRef LinkageName;
+ Metadata *File;
+ unsigned Line;
+ Metadata *Type;
+ bool IsLocalToUnit;
+ bool IsDefinition;
+ Metadata *Variable;
+ Metadata *StaticDataMemberDeclaration;
+
+ MDNodeKeyImpl(Metadata *Scope, StringRef Name, StringRef LinkageName,
+ Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration)
+ : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
+ Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
+ IsDefinition(IsDefinition), Variable(Variable),
+ StaticDataMemberDeclaration(StaticDataMemberDeclaration) {}
+ MDNodeKeyImpl(const MDGlobalVariable *N)
+ : Scope(N->getScope()), Name(N->getName()),
+ LinkageName(N->getLinkageName()), File(N->getFile()),
+ Line(N->getLine()), Type(N->getType()),
+ IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
+ Variable(N->getVariable()),
+ StaticDataMemberDeclaration(N->getStaticDataMemberDeclaration()) {}
+
+ bool isKeyOf(const MDGlobalVariable *RHS) const {
+ return Scope == RHS->getScope() && Name == RHS->getName() &&
+ LinkageName == RHS->getLinkageName() && File == RHS->getFile() &&
+ Line == RHS->getLine() && Type == RHS->getType() &&
+ IsLocalToUnit == RHS->isLocalToUnit() &&
+ IsDefinition == RHS->isDefinition() &&
+ Variable == RHS->getVariable() &&
+ StaticDataMemberDeclaration == RHS->getStaticDataMemberDeclaration();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Scope, Name, LinkageName, File, Line, Type,
+ IsLocalToUnit, IsDefinition, Variable,
+ StaticDataMemberDeclaration);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDLocalVariable> {
+ unsigned Tag;
+ Metadata *Scope;
+ StringRef Name;
+ Metadata *File;
+ unsigned Line;
+ Metadata *Type;
+ unsigned Arg;
+ unsigned Flags;
+ Metadata *InlinedAt;
+
+ MDNodeKeyImpl(unsigned Tag, Metadata *Scope, StringRef Name, Metadata *File,
+ unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags,
+ Metadata *InlinedAt)
+ : Tag(Tag), Scope(Scope), Name(Name), File(File), Line(Line), Type(Type),
+ Arg(Arg), Flags(Flags), InlinedAt(InlinedAt) {}
+ MDNodeKeyImpl(const MDLocalVariable *N)
+ : Tag(N->getTag()), Scope(N->getScope()), Name(N->getName()),
+ File(N->getFile()), Line(N->getLine()), Type(N->getType()),
+ Arg(N->getArg()), Flags(N->getFlags()), InlinedAt(N->getInlinedAt()) {}
+
+ bool isKeyOf(const MDLocalVariable *RHS) const {
+ return Tag == RHS->getTag() && Scope == RHS->getScope() &&
+ Name == RHS->getName() && File == RHS->getFile() &&
+ Line == RHS->getLine() && Type == RHS->getType() &&
+ Arg == RHS->getArg() && Flags == RHS->getFlags() &&
+ InlinedAt == RHS->getInlinedAt();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Tag, Scope, Name, File, Line, Type, Arg, Flags,
+ InlinedAt);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDExpression> {
+ ArrayRef<uint64_t> Elements;
+
+ MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
+ MDNodeKeyImpl(const MDExpression *N) : Elements(N->getElements()) {}
+
+ bool isKeyOf(const MDExpression *RHS) const {
+ return Elements == RHS->getElements();
+ }
+ unsigned getHashValue() const {
+ return hash_combine_range(Elements.begin(), Elements.end());
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDObjCProperty> {
+ StringRef Name;
+ Metadata *File;
+ unsigned Line;
+ StringRef GetterName;
+ StringRef SetterName;
+ unsigned Attributes;
+ Metadata *Type;
+
+ MDNodeKeyImpl(StringRef Name, Metadata *File, unsigned Line,
+ StringRef GetterName, StringRef SetterName, unsigned Attributes,
+ Metadata *Type)
+ : Name(Name), File(File), Line(Line), GetterName(GetterName),
+ SetterName(SetterName), Attributes(Attributes), Type(Type) {}
+ MDNodeKeyImpl(const MDObjCProperty *N)
+ : Name(N->getName()), File(N->getFile()), Line(N->getLine()),
+ GetterName(N->getGetterName()), SetterName(N->getSetterName()),
+ Attributes(N->getAttributes()), Type(N->getType()) {}
+
+ bool isKeyOf(const MDObjCProperty *RHS) const {
+ return Name == RHS->getName() && File == RHS->getFile() &&
+ Line == RHS->getLine() && GetterName == RHS->getGetterName() &&
+ SetterName == RHS->getSetterName() &&
+ Attributes == RHS->getAttributes() && Type == RHS->getType();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
+ Type);
+ }
+};
+
+template <> struct MDNodeKeyImpl<MDImportedEntity> {
+ unsigned Tag;
+ Metadata *Scope;
+ Metadata *Entity;
+ unsigned Line;
+ StringRef Name;
+
+ MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, unsigned Line,
+ StringRef Name)
+ : Tag(Tag), Scope(Scope), Entity(Entity), Line(Line), Name(Name) {}
+ MDNodeKeyImpl(const MDImportedEntity *N)
+ : Tag(N->getTag()), Scope(N->getScope()), Entity(N->getEntity()),
+ Line(N->getLine()), Name(N->getName()) {}
+
+ bool isKeyOf(const MDImportedEntity *RHS) const {
+ return Tag == RHS->getTag() && Scope == RHS->getScope() &&
+ Entity == RHS->getEntity() && Line == RHS->getLine() &&
+ Name == RHS->getName();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Tag, Scope, Entity, Line, Name);
+ }
+};
+
/// \brief DenseMapInfo for MDNode subclasses.
template <class NodeTy> struct MDNodeInfo {
typedef MDNodeKeyImpl<NodeTy> KeyTy;
Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=228640&r1=228639&r2=228640&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
+++ llvm/trunk/unittests/IR/MetadataTest.cpp Mon Feb 9 18:52:32 2015
@@ -614,6 +614,853 @@ TEST_F(GenericDebugNodeTest, getEmptyHea
EXPECT_EQ(nullptr, N->getOperand(0));
}
+typedef MetadataTest MDSubrangeTest;
+
+TEST_F(MDSubrangeTest, get) {
+ auto *N = MDSubrange::get(Context, 5, 7);
+ EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
+ EXPECT_EQ(5, N->getCount());
+ EXPECT_EQ(7, N->getLo());
+ EXPECT_EQ(N, MDSubrange::get(Context, 5, 7));
+ EXPECT_EQ(MDSubrange::get(Context, 5, 0), MDSubrange::get(Context, 5));
+}
+
+typedef MetadataTest MDEnumeratorTest;
+
+TEST_F(MDEnumeratorTest, get) {
+ auto *N = MDEnumerator::get(Context, 7, "name");
+ EXPECT_EQ(dwarf::DW_TAG_enumerator, N->getTag());
+ EXPECT_EQ(7, N->getValue());
+ EXPECT_EQ("name", N->getName());
+ EXPECT_EQ(N, MDEnumerator::get(Context, 7, "name"));
+
+ EXPECT_NE(N, MDEnumerator::get(Context, 8, "name"));
+ EXPECT_NE(N, MDEnumerator::get(Context, 7, "nam"));
+}
+
+typedef MetadataTest MDBasicTypeTest;
+
+TEST_F(MDBasicTypeTest, get) {
+ auto *N =
+ MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7);
+ EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag());
+ EXPECT_EQ("special", N->getName());
+ EXPECT_EQ(33u, N->getSizeInBits());
+ EXPECT_EQ(26u, N->getAlignInBits());
+ EXPECT_EQ(7u, N->getEncoding());
+ EXPECT_EQ(0u, N->getLine());
+ EXPECT_EQ(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 26, 7));
+
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_unspecified_type,
+ "special", 33, 26, 7));
+ EXPECT_NE(N,
+ MDBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7));
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32,
+ 26, 7));
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 25, 7));
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 26, 6));
+}
+
+typedef MetadataTest MDDerivedTypeTest;
+
+TEST_F(MDDerivedTypeTest, get) {
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *BaseType = MDTuple::getDistinct(Context, None);
+ Metadata *ExtraData = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, Scope, BaseType, 2, 3, 4, 5, ExtraData);
+ EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag());
+ EXPECT_EQ("something", N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(1u, N->getLine());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(BaseType, N->getBaseType());
+ EXPECT_EQ(2u, N->getSizeInBits());
+ EXPECT_EQ(3u, N->getAlignInBits());
+ EXPECT_EQ(4u, N->getOffsetInBits());
+ EXPECT_EQ(5u, N->getFlags());
+ EXPECT_EQ(ExtraData, N->getExtraData());
+ EXPECT_EQ(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_reference_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else",
+ File, 1, Scope, BaseType, 2, 3, 4, 5,
+ ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", Scope, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 2, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N,
+ MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, File, BaseType, 2, 3, 4, 5, ExtraData));
+ EXPECT_NE(N,
+ MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, Scope, File, 2, 3, 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 3, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 2,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 5, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 4, ExtraData));
+ EXPECT_NE(N,
+ MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, Scope, BaseType, 2, 3, 4, 5, File));
+}
+
+typedef MetadataTest MDCompositeTypeTest;
+
+TEST_F(MDCompositeTypeTest, get) {
+ unsigned Tag = dwarf::DW_TAG_structure_type;
+ StringRef Name = "some name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 1;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *BaseType = MDTuple::getDistinct(Context, None);
+ unsigned SizeInBits = 2;
+ unsigned AlignInBits = 3;
+ unsigned OffsetInBits = 4;
+ unsigned Flags = 5;
+ Metadata *Elements = MDTuple::getDistinct(Context, None);
+ unsigned RuntimeLang = 6;
+ Metadata *VTableHolder = MDTuple::getDistinct(Context, None);
+ Metadata *TemplateParams = MDTuple::getDistinct(Context, None);
+ StringRef Identifier = "some id";
+
+ auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier);
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(BaseType, N->getBaseType());
+ EXPECT_EQ(SizeInBits, N->getSizeInBits());
+ EXPECT_EQ(AlignInBits, N->getAlignInBits());
+ EXPECT_EQ(OffsetInBits, N->getOffsetInBits());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(Elements, N->getElements());
+ EXPECT_EQ(RuntimeLang, N->getRuntimeLang());
+ EXPECT_EQ(VTableHolder, N->getVTableHolder());
+ EXPECT_EQ(TemplateParams, N->getTemplateParams());
+ EXPECT_EQ(Identifier, N->getIdentifier());
+
+ EXPECT_EQ(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag + 1, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, "abc", File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, Scope, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line + 1, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, File,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope, File,
+ SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Elements, RuntimeLang, VTableHolder,
+ TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits + 1, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits + 1,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits + 1, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags + 1, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, File, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ File, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, File, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, "other"));
+
+ // Be sure that missing identifiers get null pointers.
+ EXPECT_FALSE(MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, "")->getRawIdentifier());
+ EXPECT_FALSE(MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams)->getRawIdentifier());
+}
+
+typedef MetadataTest MDSubroutineTypeTest;
+
+TEST_F(MDSubroutineTypeTest, get) {
+ unsigned Flags = 1;
+ Metadata *TypeArray = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDSubroutineType::get(Context, Flags, TypeArray);
+ EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(TypeArray, N->getTypeArray());
+ EXPECT_EQ(N, MDSubroutineType::get(Context, Flags, TypeArray));
+
+ EXPECT_NE(N, MDSubroutineType::get(Context, Flags + 1, TypeArray));
+ EXPECT_NE(N, MDSubroutineType::get(Context, Flags,
+ MDTuple::getDistinct(Context, None)));
+}
+
+typedef MetadataTest MDFileTest;
+
+TEST_F(MDFileTest, get) {
+ StringRef Filename = "file";
+ StringRef Directory = "dir";
+ auto *N = MDFile::get(Context, Filename, Directory);
+
+ EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag());
+ EXPECT_EQ(Filename, N->getFilename());
+ EXPECT_EQ(Directory, N->getDirectory());
+ EXPECT_EQ(N, MDFile::get(Context, Filename, Directory));
+
+ EXPECT_NE(N, MDFile::get(Context, "other", Directory));
+ EXPECT_NE(N, MDFile::get(Context, Filename, "other"));
+}
+
+typedef MetadataTest MDCompileUnitTest;
+
+TEST_F(MDCompileUnitTest, get) {
+ unsigned SourceLanguage = 1;
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ StringRef Producer = "some producer";
+ bool IsOptimized = false;
+ StringRef Flags = "flag after flag";
+ unsigned RuntimeVersion = 2;
+ StringRef SplitDebugFilename = "another/file";
+ unsigned EmissionKind = 3;
+ Metadata *EnumTypes = MDTuple::getDistinct(Context, None);
+ Metadata *RetainedTypes = MDTuple::getDistinct(Context, None);
+ Metadata *Subprograms = MDTuple::getDistinct(Context, None);
+ Metadata *GlobalVariables = MDTuple::getDistinct(Context, None);
+ Metadata *ImportedEntities = MDTuple::getDistinct(Context, None);
+ auto *N = MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables, ImportedEntities);
+
+ EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag());
+ EXPECT_EQ(SourceLanguage, N->getSourceLanguage());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Producer, N->getProducer());
+ EXPECT_EQ(IsOptimized, N->isOptimized());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(RuntimeVersion, N->getRuntimeVersion());
+ EXPECT_EQ(SplitDebugFilename, N->getSplitDebugFilename());
+ EXPECT_EQ(EmissionKind, N->getEmissionKind());
+ EXPECT_EQ(EnumTypes, N->getEnumTypes());
+ EXPECT_EQ(RetainedTypes, N->getRetainedTypes());
+ EXPECT_EQ(Subprograms, N->getSubprograms());
+ EXPECT_EQ(GlobalVariables, N->getGlobalVariables());
+ EXPECT_EQ(ImportedEntities, N->getImportedEntities());
+ EXPECT_EQ(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage + 1, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, EnumTypes, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, "other",
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ !IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, "other", RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion + 1,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N,
+ MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion, "other",
+ EmissionKind, EnumTypes, RetainedTypes,
+ Subprograms, GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind + 1,
+ EnumTypes, RetainedTypes, Subprograms,
+ GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, File,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ File, Subprograms, GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, File, GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, File, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables, File));
+}
+
+typedef MetadataTest MDSubprogramTest;
+
+TEST_F(MDSubprogramTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 2;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ unsigned ScopeLine = 3;
+ Metadata *ContainingType = MDTuple::getDistinct(Context, None);
+ unsigned Virtuality = 4;
+ unsigned VirtualIndex = 5;
+ unsigned Flags = 6;
+ bool IsOptimized = false;
+ Metadata *Function = MDTuple::getDistinct(Context, None);
+ Metadata *TemplateParams = MDTuple::getDistinct(Context, None);
+ Metadata *Declaration = MDTuple::getDistinct(Context, None);
+ Metadata *Variables = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDSubprogram::get(
+ Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags,
+ IsOptimized, Function, TemplateParams, Declaration, Variables);
+
+ EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(LinkageName, N->getLinkageName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit());
+ EXPECT_EQ(IsDefinition, N->isDefinition());
+ EXPECT_EQ(ScopeLine, N->getScopeLine());
+ EXPECT_EQ(ContainingType, N->getContainingType());
+ EXPECT_EQ(Virtuality, N->getVirtuality());
+ EXPECT_EQ(VirtualIndex, N->getVirtualIndex());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(IsOptimized, N->isOptimized());
+ EXPECT_EQ(Function, N->getFunction());
+ EXPECT_EQ(TemplateParams, N->getTemplateParams());
+ EXPECT_EQ(Declaration, N->getDeclaration());
+ EXPECT_EQ(Variables, N->getVariables());
+ EXPECT_EQ(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+
+ EXPECT_NE(N, MDSubprogram::get(Context, File, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, "other", LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, "other", File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, Scope, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File,
+ Line + 1, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Scope, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, !IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, !IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ ScopeLine + 1, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ Type, Virtuality, VirtualIndex, Flags,
+ IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality + 1, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex + 1,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ ~Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, !IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Type, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, Type,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Type, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Type));
+}
+
+typedef MetadataTest MDLexicalBlockTest;
+
+TEST_F(MDLexicalBlockTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ unsigned Column = 8;
+
+ auto *N = MDLexicalBlock::get(Context, Scope, File, Line, Column);
+
+ EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Column, N->getColumn());
+ EXPECT_EQ(N, MDLexicalBlock::get(Context, Scope, File, Line, Column));
+
+ EXPECT_NE(N, MDLexicalBlock::get(Context, File, File, Line, Column));
+ EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, Scope, Line, Column));
+ EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line + 1, Column));
+ EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line, Column + 1));
+}
+
+typedef MetadataTest MDLexicalBlockFileTest;
+
+TEST_F(MDLexicalBlockFileTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Discriminator = 5;
+
+ auto *N = MDLexicalBlockFile::get(Context, Scope, File, Discriminator);
+
+ EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Discriminator, N->getDiscriminator());
+ EXPECT_EQ(N, MDLexicalBlockFile::get(Context, Scope, File, Discriminator));
+
+ EXPECT_NE(N, MDLexicalBlockFile::get(Context, File, File, Discriminator));
+ EXPECT_NE(N, MDLexicalBlockFile::get(Context, Scope, Scope, Discriminator));
+ EXPECT_NE(N,
+ MDLexicalBlockFile::get(Context, Scope, File, Discriminator + 1));
+}
+
+typedef MetadataTest MDNamespaceTest;
+
+TEST_F(MDNamespaceTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ StringRef Name = "namespace";
+ unsigned Line = 5;
+
+ auto *N = MDNamespace::get(Context, Scope, File, Name, Line);
+
+ EXPECT_EQ(dwarf::DW_TAG_namespace, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(N, MDNamespace::get(Context, Scope, File, Name, Line));
+
+ EXPECT_NE(N, MDNamespace::get(Context, File, File, Name, Line));
+ EXPECT_NE(N, MDNamespace::get(Context, Scope, Scope, Name, Line));
+ EXPECT_NE(N, MDNamespace::get(Context, Scope, File, "other", Line));
+ EXPECT_NE(N, MDNamespace::get(Context, Scope, File, Name, Line + 1));
+}
+
+typedef MetadataTest MDTemplateTypeParameterTest;
+
+TEST_F(MDTemplateTypeParameterTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "template";
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ unsigned Column = 7;
+
+ auto *N = MDTemplateTypeParameter::get(Context, Scope, Name, Type, File, Line,
+ Column);
+
+ EXPECT_EQ(dwarf::DW_TAG_template_type_parameter, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Column, N->getColumn());
+ EXPECT_EQ(N, MDTemplateTypeParameter::get(Context, Scope, Name, Type, File,
+ Line, Column));
+
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, Type, Name, Type, File,
+ Line, Column));
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, Scope, "other", Type, File,
+ Line, Column));
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, Scope, Name, Scope, File,
+ Line, Column));
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, Scope, Name, Type, Scope,
+ Line, Column));
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, Scope, Name, Type, File,
+ Line + 1, Column));
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, Scope, Name, Type, File,
+ Line, Column + 1));
+}
+
+typedef MetadataTest MDTemplateValueParameterTest;
+
+TEST_F(MDTemplateValueParameterTest, get) {
+ unsigned Tag = dwarf::DW_TAG_template_value_parameter;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "template";
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ Metadata *Value = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ unsigned Column = 7;
+
+ auto *N = MDTemplateValueParameter::get(Context, Tag, Scope, Name, Type,
+ Value, File, Line, Column);
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(Value, N->getValue());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Column, N->getColumn());
+ EXPECT_EQ(N, MDTemplateValueParameter::get(Context, Tag, Scope, Name, Type,
+ Value, File, Line, Column));
+
+ EXPECT_NE(N, MDTemplateValueParameter::get(
+ Context, dwarf::DW_TAG_GNU_template_template_param, Scope,
+ Name, Type, Value, File, Line, Column));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Type, Name, Type,
+ Value, File, Line, Column));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Scope, "other", Type,
+ Value, File, Line, Column));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Scope, Name, Scope,
+ Value, File, Line, Column));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Scope, Name, Type,
+ Scope, File, Line, Column));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Scope, Name, Type,
+ Value, Scope, Line, Column));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Scope, Name, Type,
+ Value, File, Line + 1, Column));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Scope, Name, Type,
+ Value, File, Line, Column + 1));
+}
+
+typedef MetadataTest MDGlobalVariableTest;
+
+TEST_F(MDGlobalVariableTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ Metadata *Variable = MDTuple::getDistinct(Context, None);
+ Metadata *StaticDataMemberDeclaration = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, Variable,
+ StaticDataMemberDeclaration);
+ EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(LinkageName, N->getLinkageName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit());
+ EXPECT_EQ(IsDefinition, N->isDefinition());
+ EXPECT_EQ(Variable, N->getVariable());
+ EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration());
+ EXPECT_EQ(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+
+ EXPECT_NE(N, MDGlobalVariable::get(Context, File, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, "other", LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, "other", File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, Scope,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N,
+ MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line + 1, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Scope, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, !IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, !IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Type, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, Type));
+}
+
+typedef MetadataTest MDLocalVariableTest;
+
+TEST_F(MDLocalVariableTest, get) {
+ unsigned Tag = dwarf::DW_TAG_arg_variable;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ unsigned Arg = 6;
+ unsigned Flags = 7;
+ Metadata *InlinedAt = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags, InlinedAt);
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(Arg, N->getArg());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(InlinedAt, N->getInlinedAt());
+ EXPECT_EQ(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags, InlinedAt));
+
+ EXPECT_NE(N, MDLocalVariable::get(Context, dwarf::DW_TAG_auto_variable, Scope,
+ Name, File, Line, Type, Arg, Flags,
+ InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, File, Name, File, Line,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, "other", File, Line,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, Scope, Line,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line + 1,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line,
+ Scope, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg + 1, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, ~Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags, Scope));
+}
+
+typedef MetadataTest MDExpressionTest;
+
+TEST_F(MDExpressionTest, get) {
+ uint64_t Elements[] = {2, 6, 9, 78, 0};
+ auto *N = MDExpression::get(Context, Elements);
+ EXPECT_EQ(makeArrayRef(Elements), N->getElements());
+ EXPECT_EQ(N, MDExpression::get(Context, Elements));
+}
+
+typedef MetadataTest MDObjCPropertyTest;
+
+TEST_F(MDObjCPropertyTest, get) {
+ StringRef Name = "name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ StringRef GetterName = "getter";
+ StringRef SetterName = "setter";
+ unsigned Attributes = 7;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes, Type);
+
+ EXPECT_EQ(dwarf::DW_TAG_APPLE_property, N->getTag());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(GetterName, N->getGetterName());
+ EXPECT_EQ(SetterName, N->getSetterName());
+ EXPECT_EQ(Attributes, N->getAttributes());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes, Type));
+
+ EXPECT_NE(N, MDObjCProperty::get(Context, "other", File, Line, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, Type, Line, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line + 1, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, "other",
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ "other", Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes + 1, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes, File));
+}
+
+typedef MetadataTest MDImportedEntityTest;
+
+TEST_F(MDImportedEntityTest, get) {
+ unsigned Tag = dwarf::DW_TAG_imported_module;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *Entity = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ StringRef Name = "name";
+
+ auto *N = MDImportedEntity::get(Context, Tag, Scope, Entity, Line, Name);
+
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Entity, N->getEntity());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(N, MDImportedEntity::get(Context, Tag, Scope, Entity, Line, Name));
+
+ EXPECT_NE(N,
+ MDImportedEntity::get(Context, dwarf::DW_TAG_imported_declaration,
+ Scope, Entity, Line, Name));
+ EXPECT_NE(N, MDImportedEntity::get(Context, Tag, Entity, Entity, Line, Name));
+ EXPECT_NE(N, MDImportedEntity::get(Context, Tag, Scope, Scope, Line, Name));
+ EXPECT_NE(N,
+ MDImportedEntity::get(Context, Tag, Scope, Entity, Line + 1, Name));
+ EXPECT_NE(N,
+ MDImportedEntity::get(Context, Tag, Scope, Entity, Line, "other"));
+}
+
typedef MetadataTest MetadataAsValueTest;
TEST_F(MetadataAsValueTest, MDNode) {
More information about the llvm-commits
mailing list