diff options
Diffstat (limited to 'include/llvm/IR/DebugInfoMetadata.h')
-rw-r--r-- | include/llvm/IR/DebugInfoMetadata.h | 273 |
1 files changed, 171 insertions, 102 deletions
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 4534a14..d7563fc 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -41,53 +41,6 @@ namespace llvm { -/// \brief Debug location. -/// -/// A debug location in source code, used for debug info and otherwise. -class MDLocation : public MDNode { - friend class LLVMContextImpl; - friend class MDNode; - - MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, - unsigned Column, ArrayRef<Metadata *> MDs); - ~MDLocation() { dropAllReferences(); } - - static MDLocation *getImpl(LLVMContext &Context, unsigned Line, - unsigned Column, Metadata *Scope, - Metadata *InlinedAt, StorageType Storage, - bool ShouldCreate = true); - - TempMDLocation cloneImpl() const { - return getTemporary(getContext(), getLine(), getColumn(), getScope(), - getInlinedAt()); - } - - // Disallow replacing operands. - void replaceOperandWith(unsigned I, Metadata *New) = delete; - -public: - DEFINE_MDNODE_GET(MDLocation, - (unsigned Line, unsigned Column, Metadata *Scope, - Metadata *InlinedAt = nullptr), - (Line, Column, Scope, InlinedAt)) - - /// \brief Return a (temporary) clone of this. - TempMDLocation clone() const { return cloneImpl(); } - - unsigned getLine() const { return SubclassData32; } - unsigned getColumn() const { return SubclassData16; } - Metadata *getScope() const { return getOperand(0); } - Metadata *getInlinedAt() const { - if (getNumOperands() == 2) - return getOperand(1); - return nullptr; - } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == MDLocationKind; - } -}; - /// \brief Tagged DWARF-like metadata node. /// /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*, @@ -146,7 +99,6 @@ public: case MDTemplateValueParameterKind: case MDGlobalVariableKind: case MDLocalVariableKind: - case MDExpressionKind: case MDObjCPropertyKind: case MDImportedEntityKind: return true; @@ -330,7 +282,16 @@ protected: ~MDScope() {} public: - Metadata *getFile() const { return getOperand(0); } + /// \brief Return the underlying file. + /// + /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file + /// (it\em is the file). If \c this is an \a MDFile, we need to return \c + /// this. Otherwise, return the first operand, which is where all other + /// subclasses store their file pointer. + Metadata *getFile() const { + return isa<MDFile>(this) ? const_cast<MDScope *>(this) + : static_cast<Metadata *>(getOperand(0)); + } static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { @@ -351,6 +312,52 @@ public: } }; +/// \brief File. +/// +/// TODO: Merge with directory/file node (including users). +/// TODO: Canonicalize paths on creation. +class MDFile : public MDScope { + friend class LLVMContextImpl; + friend class MDNode; + + MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops) + : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {} + ~MDFile() {} + + static MDFile *getImpl(LLVMContext &Context, StringRef Filename, + StringRef Directory, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, getCanonicalMDString(Context, Filename), + getCanonicalMDString(Context, Directory), Storage, + ShouldCreate); + } + static MDFile *getImpl(LLVMContext &Context, MDString *Filename, + MDString *Directory, StorageType Storage, + bool ShouldCreate = true); + + TempMDFile cloneImpl() const { + return getTemporary(getContext(), getFilename(), getDirectory()); + } + +public: + DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory), + (Filename, Directory)) + DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory), + (Filename, Directory)) + + TempMDFile clone() const { return cloneImpl(); } + + StringRef getFilename() const { return getStringOperand(0); } + StringRef getDirectory() const { return getStringOperand(1); } + + MDString *getRawFilename() const { return getOperandAs<MDString>(0); } + MDString *getRawDirectory() const { return getOperandAs<MDString>(1); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDFileKind; + } +}; + /// \brief Base class for types. /// /// TODO: Remove the hardcoded name and context, since many types don't use @@ -373,6 +380,10 @@ protected: ~MDType() {} public: + TempMDType clone() const { + return TempMDType(cast<MDType>(MDNode::clone().release())); + } + unsigned getLine() const { return Line; } uint64_t getSizeInBits() const { return SizeInBits; } uint64_t getAlignInBits() const { return AlignInBits; } @@ -384,6 +395,11 @@ public: MDString *getRawName() const { return getOperandAs<MDString>(2); } + void setFlags(unsigned NewFlags) { + assert(!isUniqued() && "Cannot set flags on uniqued nodes"); + Flags = NewFlags; + } + static bool classof(const Metadata *MD) { switch (MD->getMetadataID()) { default: @@ -433,6 +449,8 @@ class MDBasicType : public MDType { } public: + DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name), + (Tag, Name, 0, 0, 0)) DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding), @@ -719,52 +737,6 @@ public: } }; -/// \brief File. -/// -/// TODO: Merge with directory/file node (including users). -/// TODO: Canonicalize paths on creation. -class MDFile : public MDScope { - friend class LLVMContextImpl; - friend class MDNode; - - MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops) - : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {} - ~MDFile() {} - - static MDFile *getImpl(LLVMContext &Context, StringRef Filename, - StringRef Directory, StorageType Storage, - bool ShouldCreate = true) { - return getImpl(Context, getCanonicalMDString(Context, Filename), - getCanonicalMDString(Context, Directory), Storage, - ShouldCreate); - } - static MDFile *getImpl(LLVMContext &Context, MDString *Filename, - MDString *Directory, StorageType Storage, - bool ShouldCreate = true); - - TempMDFile cloneImpl() const { - return getTemporary(getContext(), getFilename(), getDirectory()); - } - -public: - DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory), - (Filename, Directory)) - DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory), - (Filename, Directory)) - - TempMDFile clone() const { return cloneImpl(); } - - StringRef getFilename() const { return getStringOperand(0); } - StringRef getDirectory() const { return getStringOperand(1); } - - MDString *getRawFilename() const { return getOperandAs<MDString>(0); } - MDString *getRawDirectory() const { return getOperandAs<MDString>(1); } - - static bool classof(const Metadata *MD) { - return MD->getMetadataID() == MDFileKind; - } -}; - /// \brief Compile unit. class MDCompileUnit : public MDScope { friend class LLVMContextImpl; @@ -875,11 +847,96 @@ public: } }; +/// \brief A scope for locals. +/// +/// A legal scope for lexical blocks, local variables, and debug info +/// locations. Subclasses are \a MDSubprogram, \a MDLexicalBlock, and \a +/// MDLexicalBlockFile. +class MDLocalScope : public MDScope { +protected: + MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, + ArrayRef<Metadata *> Ops) + : MDScope(C, ID, Storage, Tag, Ops) {} + ~MDLocalScope() {} + +public: + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDSubprogramKind || + MD->getMetadataID() == MDLexicalBlockKind || + MD->getMetadataID() == MDLexicalBlockFileKind; + } +}; + +/// \brief Debug location. +/// +/// A debug location in source code, used for debug info and otherwise. +class MDLocation : public MDNode { + friend class LLVMContextImpl; + friend class MDNode; + + MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, + unsigned Column, ArrayRef<Metadata *> MDs); + ~MDLocation() { dropAllReferences(); } + + static MDLocation *getImpl(LLVMContext &Context, unsigned Line, + unsigned Column, Metadata *Scope, + Metadata *InlinedAt, StorageType Storage, + bool ShouldCreate = true); + static MDLocation *getImpl(LLVMContext &Context, unsigned Line, + unsigned Column, MDLocalScope *Scope, + MDLocation *InlinedAt, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope), + static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate); + } + + TempMDLocation cloneImpl() const { + return getTemporary(getContext(), getLine(), getColumn(), getScope(), + getInlinedAt()); + } + + // Disallow replacing operands. + void replaceOperandWith(unsigned I, Metadata *New) = delete; + +public: + DEFINE_MDNODE_GET(MDLocation, + (unsigned Line, unsigned Column, Metadata *Scope, + Metadata *InlinedAt = nullptr), + (Line, Column, Scope, InlinedAt)) + DEFINE_MDNODE_GET(MDLocation, + (unsigned Line, unsigned Column, MDLocalScope *Scope, + MDLocation *InlinedAt = nullptr), + (Line, Column, Scope, InlinedAt)) + + /// \brief Return a (temporary) clone of this. + TempMDLocation clone() const { return cloneImpl(); } + + unsigned getLine() const { return SubclassData32; } + unsigned getColumn() const { return SubclassData16; } + MDLocalScope *getScope() const { + return cast_or_null<MDLocalScope>(getRawScope()); + } + MDLocation *getInlinedAt() const { + return cast_or_null<MDLocation>(getRawInlinedAt()); + } + + Metadata *getRawScope() const { return getOperand(0); } + Metadata *getRawInlinedAt() const { + if (getNumOperands() == 2) + return getOperand(1); + return nullptr; + } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDLocationKind; + } +}; + /// \brief Subprogram description. /// /// TODO: Remove DisplayName. It's always equal to Name. /// TODO: Split up flags. -class MDSubprogram : public MDScope { +class MDSubprogram : public MDLocalScope { friend class LLVMContextImpl; friend class MDNode; @@ -896,7 +953,8 @@ class MDSubprogram : public MDScope { unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, ArrayRef<Metadata *> Ops) - : MDScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops), + : MDLocalScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram, + Ops), Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality), VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), IsOptimized(IsOptimized) {} @@ -1004,11 +1062,11 @@ public: } }; -class MDLexicalBlockBase : public MDScope { +class MDLexicalBlockBase : public MDLocalScope { protected: MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, ArrayRef<Metadata *> Ops) - : MDScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {} + : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {} ~MDLexicalBlockBase() {} public: @@ -1407,6 +1465,18 @@ public: unsigned getFlags() const { return Flags; } Metadata *getInlinedAt() const { return getOperand(4); } + /// \brief Get an inlined version of this variable. + /// + /// Returns a version of this with \a getAlinedAt() set to \c InlinedAt. + MDLocalVariable *withInline(MDLocation *InlinedAt) const { + if (InlinedAt == getInlinedAt()) + return const_cast<MDLocalVariable *>(this); + auto Temp = clone(); + Temp->replaceOperandWith(4, InlinedAt); + return replaceWithUniqued(std::move(Temp)); + } + MDLocalVariable *withoutInline() const { return withInline(nullptr); } + static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDLocalVariableKind; } @@ -1415,17 +1485,16 @@ public: /// \brief DWARF expression. /// /// TODO: Co-allocate the expression elements. -/// TODO: Drop fake DW_TAG_expression and separate from DebugNode. /// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary /// storage types. -class MDExpression : public DebugNode { +class MDExpression : public MDNode { friend class LLVMContextImpl; friend class MDNode; std::vector<uint64_t> Elements; MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements) - : DebugNode(C, MDExpressionKind, Storage, dwarf::DW_TAG_expression, None), + : MDNode(C, MDExpressionKind, Storage, None), Elements(Elements.begin(), Elements.end()) {} ~MDExpression() {} |