X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FIR%2FDebugInfoMetadata.h;h=e16e4319aa94ec49a208ea3172e39ef7faa6567c;hp=18619f374208f11bf70aa36ef4c9f8af9fd7b30c;hb=32cb99437ef2921bcad7e62de0c3438d594997e6;hpb=2e25115e02eda8f47786bca06288917c4437c103 diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 18619f37420..e16e4319aa9 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -50,6 +50,7 @@ template class TypedDebugNodeRef { const Metadata *MD = nullptr; public: + TypedDebugNodeRef() = default; TypedDebugNodeRef(std::nullptr_t) {} /// \brief Construct from a raw pointer. @@ -151,7 +152,7 @@ protected: assert(Tag < 1u << 16); SubclassData16 = Tag; } - ~DebugNode() {} + ~DebugNode() = default; template Ty *getOperandAs(unsigned I) const { return cast_or_null(getOperand(I)); @@ -327,7 +328,7 @@ class MDSubrange : public DebugNode { : DebugNode(C, MDSubrangeKind, Storage, dwarf::DW_TAG_subrange_type, None), Count(Count), LowerBound(LowerBound) {} - ~MDSubrange() {} + ~MDSubrange() = default; static MDSubrange *getImpl(LLVMContext &Context, int64_t Count, int64_t LowerBound, StorageType Storage, @@ -365,7 +366,7 @@ class MDEnumerator : public DebugNode { ArrayRef Ops) : DebugNode(C, MDEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops), Value(Value) {} - ~MDEnumerator() {} + ~MDEnumerator() = default; static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value, StringRef Name, StorageType Storage, @@ -410,11 +411,17 @@ protected: MDScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef Ops) : DebugNode(C, ID, Storage, Tag, Ops) {} - ~MDScope() {} + ~MDScope() = default; public: MDFile *getFile() const { return cast_or_null(getRawFile()); } + inline StringRef getFilename() const; + inline StringRef getDirectory() const; + + StringRef getName() const; + MDScopeRef getScope() const; + /// \brief Return the raw underlying file. /// /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file @@ -457,7 +464,7 @@ class MDFile : public MDScope { MDFile(LLVMContext &C, StorageType Storage, ArrayRef Ops) : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {} - ~MDFile() {} + ~MDFile() = default; static MDFile *getImpl(LLVMContext &Context, StringRef Filename, StringRef Directory, StorageType Storage, @@ -493,6 +500,18 @@ public: } }; +StringRef MDScope::getFilename() const { + if (auto *F = getFile()) + return F->getFilename(); + return ""; +} + +StringRef MDScope::getDirectory() const { + if (auto *F = getFile()) + return F->getDirectory(); + return ""; +} + /// \brief Base class for types. /// /// TODO: Remove the hardcoded name and context, since many types don't use @@ -512,7 +531,7 @@ protected: : MDScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags), SizeInBits(SizeInBits), AlignInBits(AlignInBits), OffsetInBits(OffsetInBits) {} - ~MDType() {} + ~MDType() = default; public: TempMDType clone() const { @@ -591,7 +610,7 @@ class MDBasicType : public MDType { : MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0, 0, Ops), Encoding(Encoding) {} - ~MDBasicType() {} + ~MDBasicType() = default; static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, uint64_t SizeInBits, @@ -642,7 +661,7 @@ protected: ArrayRef Ops) : MDType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags, Ops) {} - ~MDDerivedTypeBase() {} + ~MDDerivedTypeBase() = default; public: MDTypeRef getBaseType() const { return MDTypeRef(getRawBaseType()); } @@ -670,7 +689,7 @@ class MDDerivedType : public MDDerivedTypeBase { uint64_t OffsetInBits, unsigned Flags, ArrayRef Ops) : MDDerivedTypeBase(C, MDDerivedTypeKind, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags, Ops) {} - ~MDDerivedType() {} + ~MDDerivedType() = default; static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, MDFile *File, unsigned Line, @@ -727,6 +746,23 @@ public: Metadata *getExtraData() const { return getRawExtraData(); } Metadata *getRawExtraData() const { return getOperand(4); } + /// \brief Get casted version of extra data. + /// @{ + MDTypeRef getClassType() const { + assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); + return MDTypeRef(getExtraData()); + } + MDObjCProperty *getObjCProperty() const { + return dyn_cast_or_null(getExtraData()); + } + Constant *getConstant() const { + assert(getTag() == dwarf::DW_TAG_member && isStaticMember()); + if (auto *C = cast_or_null(getExtraData())) + return C->getValue(); + return nullptr; + } + /// @} + static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDDerivedTypeKind; } @@ -747,10 +783,16 @@ protected: : MDDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags, Ops), RuntimeLang(RuntimeLang) {} - ~MDCompositeTypeBase() {} + ~MDCompositeTypeBase() = default; public: + /// \brief Get the elements of the composite type. + /// + /// \note Calling this is only valid for \a MDCompositeType. This assertion + /// can be removed once \a MDSubroutineType has been separated from + /// "composite types". DebugNodeArray getElements() const { + assert(!isa(this) && "no elements for DISubroutineType"); return cast_or_null(getRawElements()); } MDTypeRef getVTableHolder() const { return MDTypeRef(getRawVTableHolder()); } @@ -808,7 +850,7 @@ class MDCompositeType : public MDCompositeTypeBase { : MDCompositeTypeBase(C, MDCompositeTypeKind, Storage, Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags, Ops) {} - ~MDCompositeType() {} + ~MDCompositeType() = default; static MDCompositeType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File, @@ -891,7 +933,7 @@ class MDSubroutineType : public MDCompositeTypeBase { : MDCompositeTypeBase(C, MDSubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags, Ops) {} - ~MDSubroutineType() {} + ~MDSubroutineType() = default; static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags, MDTypeRefArray TypeArray, @@ -942,7 +984,7 @@ class MDCompileUnit : public MDScope { : MDScope(C, MDCompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind) {} - ~MDCompileUnit() {} + ~MDCompileUnit() = default; static MDCompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, MDFile *File, @@ -1067,7 +1109,7 @@ protected: MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef Ops) : MDScope(C, ID, Storage, Tag, Ops) {} - ~MDLocalScope() {} + ~MDLocalScope() = default; public: /// \brief Get the subprogram for this scope. @@ -1136,6 +1178,10 @@ public: return cast_or_null(getRawInlinedAt()); } + MDFile *getFile() const { return getScope()->getFile(); } + StringRef getFilename() const { return getScope()->getFilename(); } + StringRef getDirectory() const { return getScope()->getDirectory(); } + /// \brief Get the scope where this is inlined. /// /// Walk through \a getInlinedAt() and return \a getScope() from the deepest @@ -1146,6 +1192,38 @@ public: return getScope(); } + /// \brief Check whether this can be discriminated from another location. + /// + /// Check \c this can be discriminated from \c RHS in a linetable entry. + /// Scope and inlined-at chains are not recorded in the linetable, so they + /// cannot be used to distinguish basic blocks. + /// + /// The current implementation is weaker than it should be, since it just + /// checks filename and line. + /// + /// FIXME: Add a check for getDiscriminator(). + /// FIXME: Add a check for getColumn(). + /// FIXME: Change the getFilename() check to getFile() (or add one for + /// getDirectory()). + bool canDiscriminate(const MDLocation &RHS) const { + return getFilename() != RHS.getFilename() || getLine() != RHS.getLine(); + } + + /// \brief Get the DWARF discriminator. + /// + /// DWARF discriminators distinguish identical file locations between + /// instructions that are on different basic blocks. + inline unsigned getDiscriminator() const; + + /// \brief Compute new discriminator in the given context. + /// + /// This modifies the \a LLVMContext that \c this is in to increment the next + /// discriminator for \c this's line/filename combination. + /// + /// FIXME: Delete this. See comments in implementation and at the only call + /// site in \a AddDiscriminators::runOnFunction(). + unsigned computeNewDiscriminator() const; + Metadata *getRawScope() const { return getOperand(0); } Metadata *getRawInlinedAt() const { if (getNumOperands() == 2) @@ -1184,7 +1262,7 @@ class MDSubprogram : public MDLocalScope { Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality), VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), IsOptimized(IsOptimized) {} - ~MDSubprogram() {} + ~MDSubprogram() = default; static MDSubprogram * getImpl(LLVMContext &Context, MDScopeRef Scope, StringRef Name, @@ -1192,13 +1270,14 @@ class MDSubprogram : public MDLocalScope { MDSubroutineType *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, MDTypeRef ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - ConstantAsMetadata *Function, MDTemplateParameterArray TemplateParams, + Constant *Function, MDTemplateParameterArray TemplateParams, MDSubprogram *Declaration, MDLocalVariableArray 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, + Virtuality, VirtualIndex, Flags, IsOptimized, + Function ? ConstantAsMetadata::get(Function) : nullptr, TemplateParams.get(), Declaration, Variables.get(), Storage, ShouldCreate); } @@ -1216,8 +1295,8 @@ class MDSubprogram : public MDLocalScope { getFile(), getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(), getContainingType(), getVirtuality(), getVirtualIndex(), getFlags(), - isOptimized(), getFunction(), getTemplateParams(), - getDeclaration(), getVariables()); + isOptimized(), getFunctionConstant(), + getTemplateParams(), getDeclaration(), getVariables()); } public: @@ -1227,7 +1306,7 @@ public: bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, MDTypeRef ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - ConstantAsMetadata *Function = nullptr, + Constant *Function = nullptr, MDTemplateParameterArray TemplateParams = nullptr, MDSubprogram *Declaration = nullptr, MDLocalVariableArray Variables = nullptr), @@ -1304,8 +1383,10 @@ public: return MDTypeRef(getRawContainingType()); } - ConstantAsMetadata *getFunction() const { - return cast_or_null(getRawFunction()); + Constant *getFunctionConstant() const { + if (auto *C = cast_or_null(getRawFunction())) + return C->getValue(); + return nullptr; } MDTemplateParameterArray getTemplateParams() const { return cast_or_null(getRawTemplateParams()); @@ -1325,6 +1406,13 @@ public: Metadata *getRawDeclaration() const { return getOperand(9); } Metadata *getRawVariables() const { return getOperand(10); } + /// \brief Get a pointer to the function this subprogram describes. + /// + /// This dyn_casts \a getFunctionConstant() to \a Function. + /// + /// FIXME: Should this be looking through bitcasts? + Function *getFunction() const; + /// \brief Replace the function. /// /// If \a isUniqued() and not \a isResolved(), this could node will be @@ -1336,6 +1424,11 @@ public: void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); } /// @} + /// \brief Check if this subprogram decribes the given function. + /// + /// FIXME: Should this be looking through bitcasts? + bool describes(const Function *F) const; + static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDSubprogramKind; } @@ -1346,13 +1439,20 @@ protected: MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, ArrayRef Ops) : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {} - ~MDLexicalBlockBase() {} + ~MDLexicalBlockBase() = default; public: MDLocalScope *getScope() const { return cast(getRawScope()); } Metadata *getRawScope() const { return getOperand(1); } + /// \brief Forwarding accessors to LexicalBlock. + /// + /// TODO: Remove these and update code to use \a MDLexicalBlock directly. + /// @{ + inline unsigned getLine() const; + inline unsigned getColumn() const; + /// @} static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDLexicalBlockKind || MD->getMetadataID() == MDLexicalBlockFileKind; @@ -1370,7 +1470,7 @@ class MDLexicalBlock : public MDLexicalBlockBase { unsigned Column, ArrayRef Ops) : MDLexicalBlockBase(C, MDLexicalBlockKind, Storage, Ops), Line(Line), Column(Column) {} - ~MDLexicalBlock() {} + ~MDLexicalBlock() = default; static MDLexicalBlock *getImpl(LLVMContext &Context, MDLocalScope *Scope, MDFile *File, unsigned Line, unsigned Column, @@ -1408,6 +1508,18 @@ public: } }; +unsigned MDLexicalBlockBase::getLine() const { + if (auto *N = dyn_cast(this)) + return N->getLine(); + return 0; +} + +unsigned MDLexicalBlockBase::getColumn() const { + if (auto *N = dyn_cast(this)) + return N->getColumn(); + return 0; +} + class MDLexicalBlockFile : public MDLexicalBlockBase { friend class LLVMContextImpl; friend class MDNode; @@ -1418,7 +1530,7 @@ class MDLexicalBlockFile : public MDLexicalBlockBase { unsigned Discriminator, ArrayRef Ops) : MDLexicalBlockBase(C, MDLexicalBlockFileKind, Storage, Ops), Discriminator(Discriminator) {} - ~MDLexicalBlockFile() {} + ~MDLexicalBlockFile() = default; static MDLexicalBlockFile *getImpl(LLVMContext &Context, MDLocalScope *Scope, MDFile *File, unsigned Discriminator, @@ -1449,6 +1561,10 @@ public: TempMDLexicalBlockFile clone() const { return cloneImpl(); } + // TODO: Remove these once they're gone from MDLexicalBlockBase. + unsigned getLine() const = delete; + unsigned getColumn() const = delete; + unsigned getDiscriminator() const { return Discriminator; } static bool classof(const Metadata *MD) { @@ -1456,6 +1572,12 @@ public: } }; +unsigned MDLocation::getDiscriminator() const { + if (auto *F = dyn_cast(getScope())) + return F->getDiscriminator(); + return 0; +} + class MDNamespace : public MDScope { friend class LLVMContextImpl; friend class MDNode; @@ -1467,7 +1589,7 @@ class MDNamespace : public MDScope { : MDScope(Context, MDNamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops), Line(Line) {} - ~MDNamespace() {} + ~MDNamespace() = default; static MDNamespace *getImpl(LLVMContext &Context, MDScope *Scope, MDFile *File, StringRef Name, unsigned Line, @@ -1512,7 +1634,7 @@ protected: MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef Ops) : DebugNode(Context, ID, Storage, Tag, Ops) {} - ~MDTemplateParameter() {} + ~MDTemplateParameter() = default; public: StringRef getName() const { return getStringOperand(0); } @@ -1535,7 +1657,7 @@ class MDTemplateTypeParameter : public MDTemplateParameter { ArrayRef Ops) : MDTemplateParameter(Context, MDTemplateTypeParameterKind, Storage, dwarf::DW_TAG_template_type_parameter, Ops) {} - ~MDTemplateTypeParameter() {} + ~MDTemplateTypeParameter() = default; static MDTemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name, MDTypeRef Type, StorageType Storage, @@ -1572,7 +1694,7 @@ class MDTemplateValueParameter : public MDTemplateParameter { unsigned Tag, ArrayRef Ops) : MDTemplateParameter(Context, MDTemplateValueParameterKind, Storage, Tag, Ops) {} - ~MDTemplateValueParameter() {} + ~MDTemplateValueParameter() = default; static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, MDTypeRef Type, @@ -1618,7 +1740,7 @@ protected: MDVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, unsigned Line, ArrayRef Ops) : DebugNode(C, ID, Storage, Tag, Ops), Line(Line) {} - ~MDVariable() {} + ~MDVariable() = default; public: unsigned getLine() const { return Line; } @@ -1627,6 +1749,17 @@ public: MDFile *getFile() const { return cast_or_null(getRawFile()); } MDTypeRef getType() const { return MDTypeRef(getRawType()); } + StringRef getFilename() const { + if (auto *F = getFile()) + return F->getFilename(); + return ""; + } + StringRef getDirectory() const { + if (auto *F = getFile()) + return F->getDirectory(); + return ""; + } + Metadata *getRawScope() const { return getOperand(0); } MDString *getRawName() const { return getOperandAs(1); } Metadata *getRawFile() const { return getOperand(2); } @@ -1654,17 +1787,18 @@ class MDGlobalVariable : public MDVariable { : MDVariable(C, MDGlobalVariableKind, Storage, dwarf::DW_TAG_variable, Line, Ops), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {} - ~MDGlobalVariable() {} + ~MDGlobalVariable() = default; static MDGlobalVariable * getImpl(LLVMContext &Context, MDScope *Scope, StringRef Name, StringRef LinkageName, MDFile *File, unsigned Line, MDTypeRef Type, - bool IsLocalToUnit, bool IsDefinition, ConstantAsMetadata *Variable, + bool IsLocalToUnit, bool IsDefinition, Constant *Variable, MDDerivedType *StaticDataMemberDeclaration, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, - IsLocalToUnit, IsDefinition, Variable, + IsLocalToUnit, IsDefinition, + Variable ? ConstantAsMetadata::get(Variable) : nullptr, StaticDataMemberDeclaration, Storage, ShouldCreate); } static MDGlobalVariable * @@ -1685,8 +1819,7 @@ public: DEFINE_MDNODE_GET(MDGlobalVariable, (MDScope * Scope, StringRef Name, StringRef LinkageName, MDFile *File, unsigned Line, MDTypeRef Type, - bool IsLocalToUnit, bool IsDefinition, - ConstantAsMetadata *Variable, + bool IsLocalToUnit, bool IsDefinition, Constant *Variable, MDDerivedType *StaticDataMemberDeclaration), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, Variable, StaticDataMemberDeclaration)) @@ -1704,8 +1837,10 @@ public: bool isDefinition() const { return IsDefinition; } StringRef getDisplayName() const { return getStringOperand(4); } StringRef getLinkageName() const { return getStringOperand(5); } - ConstantAsMetadata *getVariable() const { - return cast_or_null(getRawVariable()); + Constant *getVariable() const { + if (auto *C = cast_or_null(getRawVariable())) + return dyn_cast(C->getValue()); + return nullptr; } MDDerivedType *getStaticDataMemberDeclaration() const { return cast_or_null(getRawStaticDataMemberDeclaration()); @@ -1737,7 +1872,7 @@ class MDLocalVariable : public MDVariable { ArrayRef Ops) : MDVariable(C, MDLocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg), Flags(Flags) {} - ~MDLocalVariable() {} + ~MDLocalVariable() = default; static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag, MDScope *Scope, StringRef Name, MDFile *File, @@ -1822,6 +1957,12 @@ public: /// \brief DWARF expression. /// +/// This is (almost) a DWARF expression that modifies the location of a +/// variable or (or the location of a single piece of a variable). +/// +/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const +/// and have DW_OP_plus consume the topmost elements on the stack. +/// /// TODO: Co-allocate the expression elements. /// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary /// storage types. @@ -1834,7 +1975,7 @@ class MDExpression : public MDNode { MDExpression(LLVMContext &C, StorageType Storage, ArrayRef Elements) : MDNode(C, MDExpressionKind, Storage, None), Elements(Elements.begin(), Elements.end()) {} - ~MDExpression() {} + ~MDExpression() = default; static MDExpression *getImpl(LLVMContext &Context, ArrayRef Elements, StorageType Storage, @@ -1973,7 +2114,7 @@ class MDObjCProperty : public DebugNode { : DebugNode(C, MDObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops), Line(Line), Attributes(Attributes) {} - ~MDObjCProperty() {} + ~MDObjCProperty() = default; static MDObjCProperty * getImpl(LLVMContext &Context, StringRef Name, MDFile *File, unsigned Line, @@ -2018,8 +2159,24 @@ public: MDFile *getFile() const { return cast_or_null(getRawFile()); } StringRef getGetterName() const { return getStringOperand(2); } StringRef getSetterName() const { return getStringOperand(3); } + + /// \brief Get the type. + /// + /// \note Objective-C doesn't have an ODR, so there is no benefit in storing + /// the type as a DITypeRef here. MDType *getType() const { return cast_or_null(getRawType()); } + StringRef getFilename() const { + if (auto *F = getFile()) + return F->getFilename(); + return ""; + } + StringRef getDirectory() const { + if (auto *F = getFile()) + return F->getDirectory(); + return ""; + } + MDString *getRawName() const { return getOperandAs(0); } Metadata *getRawFile() const { return getOperand(1); } MDString *getRawGetterName() const { return getOperandAs(2); } @@ -2031,6 +2188,7 @@ public: } }; +/// \brief An imported module (C++ using directive or similar). class MDImportedEntity : public DebugNode { friend class LLVMContextImpl; friend class MDNode; @@ -2040,7 +2198,7 @@ class MDImportedEntity : public DebugNode { MDImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, ArrayRef Ops) : DebugNode(C, MDImportedEntityKind, Storage, Tag, Ops), Line(Line) {} - ~MDImportedEntity() {} + ~MDImportedEntity() = default; static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag, MDScope *Scope, DebugNodeRef Entity,