+/// \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;
+ }
+};
+