summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-10 00:52:32 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-10 00:52:32 +0000
commit01fc1769779c640a8c39538050c35a31d1c4eb06 (patch)
tree54e27258a240fafca73825f7a9989354e4044257 /llvm/lib/IR
parentbe270c1c60f003739827576da5e34cbf3e430c83 (diff)
downloadbcm5719-llvm-01fc1769779c640a8c39538050c35a31d1c4eb06.tar.gz
bcm5719-llvm-01fc1769779c640a8c39538050c35a31d1c4eb06.zip
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. llvm-svn: 228640
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp87
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp271
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h575
3 files changed, 933 insertions, 0 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 43ae3feb363..d1beb166a18 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1347,6 +1347,93 @@ static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
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,
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index c540cc45a61..68f6bf843d8 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -103,3 +103,274 @@ GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag,
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);
+}
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 3640495dd97..6a3d59289f4 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -273,6 +273,581 @@ template <> struct MDNodeKeyImpl<GenericDebugNode> : MDNodeOpsKey {
}
};
+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;
OpenPOWER on IntegriCloud