diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-02-10 00:52:32 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-02-10 00:52:32 +0000 |
commit | 01fc1769779c640a8c39538050c35a31d1c4eb06 (patch) | |
tree | 54e27258a240fafca73825f7a9989354e4044257 /llvm/lib/IR | |
parent | be270c1c60f003739827576da5e34cbf3e430c83 (diff) | |
download | bcm5719-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.cpp | 87 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 271 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 575 |
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; |