Verifier: Check accessors of MDLocation
[oota-llvm.git] / include / llvm / IR / DebugInfoMetadata.h
index 9a0546ae17b1f65272f1261f8af6438f7ec4b053..d7563fce940a21851929154dc370712abf53ac91 100644 (file)
 
 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) LLVM_DELETED_FUNCTION;
-
-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
@@ -358,24 +365,29 @@ public:
 /// TODO: Split up flags.
 class MDType : public MDScope {
   unsigned Line;
-  unsigned SizeInBits;
-  unsigned AlignInBits;
-  unsigned OffsetInBits;
   unsigned Flags;
+  uint64_t SizeInBits;
+  uint64_t AlignInBits;
+  uint64_t OffsetInBits;
 
 protected:
   MDType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
-         unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
-         unsigned OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
-      : MDScope(C, ID, Storage, Tag, Ops), Line(Line), SizeInBits(SizeInBits),
-        AlignInBits(AlignInBits), OffsetInBits(OffsetInBits), Flags(Flags) {}
+         unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+         uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+      : MDScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags),
+        SizeInBits(SizeInBits), AlignInBits(AlignInBits),
+        OffsetInBits(OffsetInBits) {}
   ~MDType() {}
 
 public:
+  TempMDType clone() const {
+    return TempMDType(cast<MDType>(MDNode::clone().release()));
+  }
+
   unsigned getLine() const { return Line; }
-  unsigned getSizeInBits() const { return SizeInBits; }
-  unsigned getAlignInBits() const { return AlignInBits; }
-  unsigned getOffsetInBits() const { return OffsetInBits; }
+  uint64_t getSizeInBits() const { return SizeInBits; }
+  uint64_t getAlignInBits() const { return AlignInBits; }
+  uint64_t getOffsetInBits() const { return OffsetInBits; }
   unsigned getFlags() const { return Flags; }
 
   Metadata *getScope() const { return getOperand(1); }
@@ -383,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:
@@ -407,7 +424,7 @@ class MDBasicType : public MDType {
   unsigned Encoding;
 
   MDBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
-              unsigned SizeInBits, unsigned AlignInBits, unsigned Encoding,
+              uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding,
               ArrayRef<Metadata *> Ops)
       : MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
                0, Ops),
@@ -415,15 +432,15 @@ class MDBasicType : public MDType {
   ~MDBasicType() {}
 
   static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
-                              StringRef Name, unsigned SizeInBits,
-                              unsigned AlignInBits, unsigned Encoding,
+                              StringRef Name, uint64_t SizeInBits,
+                              uint64_t AlignInBits, unsigned Encoding,
                               StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
                    SizeInBits, AlignInBits, Encoding, Storage, ShouldCreate);
   }
   static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
-                              MDString *Name, unsigned SizeInBits,
-                              unsigned AlignInBits, unsigned Encoding,
+                              MDString *Name, uint64_t SizeInBits,
+                              uint64_t AlignInBits, unsigned Encoding,
                               StorageType Storage, bool ShouldCreate = true);
 
   TempMDBasicType cloneImpl() const {
@@ -432,13 +449,15 @@ 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, unsigned SizeInBits,
-                     unsigned AlignInBits, unsigned Encoding),
+                    (unsigned Tag, StringRef Name, uint64_t SizeInBits,
+                     uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
   DEFINE_MDNODE_GET(MDBasicType,
-                    (unsigned Tag, MDString *Name, unsigned SizeInBits,
-                     unsigned AlignInBits, unsigned Encoding),
+                    (unsigned Tag, MDString *Name, uint64_t SizeInBits,
+                     uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
 
   TempMDBasicType clone() const { return cloneImpl(); }
@@ -456,8 +475,8 @@ public:
 class MDDerivedTypeBase : public MDType {
 protected:
   MDDerivedTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
-                    unsigned Tag, unsigned Line, unsigned SizeInBits,
-                    unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+                    unsigned Tag, unsigned Line, uint64_t SizeInBits,
+                    uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
                     ArrayRef<Metadata *> Ops)
       : MDType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
                Flags, Ops) {}
@@ -484,8 +503,8 @@ class MDDerivedType : public MDDerivedTypeBase {
   friend class MDNode;
 
   MDDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
-                unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
-                unsigned OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+                unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+                uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
       : MDDerivedTypeBase(C, MDDerivedTypeKind, Storage, Tag, Line, SizeInBits,
                           AlignInBits, OffsetInBits, Flags, Ops) {}
   ~MDDerivedType() {}
@@ -493,8 +512,8 @@ class MDDerivedType : public MDDerivedTypeBase {
   static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
                                 StringRef Name, Metadata *File, unsigned Line,
                                 Metadata *Scope, Metadata *BaseType,
-                                unsigned SizeInBits, unsigned AlignInBits,
-                                unsigned OffsetInBits, unsigned Flags,
+                                uint64_t SizeInBits, uint64_t AlignInBits,
+                                uint64_t OffsetInBits, unsigned Flags,
                                 Metadata *ExtraData, StorageType Storage,
                                 bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
@@ -504,8 +523,8 @@ class MDDerivedType : public MDDerivedTypeBase {
   static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
                                 MDString *Name, Metadata *File, unsigned Line,
                                 Metadata *Scope, Metadata *BaseType,
-                                unsigned SizeInBits, unsigned AlignInBits,
-                                unsigned OffsetInBits, unsigned Flags,
+                                uint64_t SizeInBits, uint64_t AlignInBits,
+                                uint64_t OffsetInBits, unsigned Flags,
                                 Metadata *ExtraData, StorageType Storage,
                                 bool ShouldCreate = true);
 
@@ -520,16 +539,16 @@ public:
   DEFINE_MDNODE_GET(MDDerivedType,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags,
                      Metadata *ExtraData = nullptr),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, ExtraData))
   DEFINE_MDNODE_GET(MDDerivedType,
                     (unsigned Tag, StringRef Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags,
                      Metadata *ExtraData = nullptr),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, ExtraData))
@@ -559,8 +578,8 @@ class MDCompositeTypeBase : public MDDerivedTypeBase {
 protected:
   MDCompositeTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
                       unsigned Tag, unsigned Line, unsigned RuntimeLang,
-                      unsigned SizeInBits, unsigned AlignInBits,
-                      unsigned OffsetInBits, unsigned Flags,
+                      uint64_t SizeInBits, uint64_t AlignInBits,
+                      uint64_t OffsetInBits, unsigned Flags,
                       ArrayRef<Metadata *> Ops)
       : MDDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits,
                           OffsetInBits, Flags, Ops),
@@ -576,6 +595,29 @@ public:
 
   MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
 
+  /// \brief Replace operands.
+  ///
+  /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
+  /// this will be RAUW'ed and deleted.  Use a \a TrackingMDRef to keep track
+  /// of its movement if necessary.
+  /// @{
+  void replaceElements(MDTuple *Elements) {
+#ifndef NDEBUG
+    if (auto *Old = cast_or_null<MDTuple>(getElements()))
+      for (const auto &Op : Old->operands())
+        assert(std::find(Elements->op_begin(), Elements->op_end(), Op) &&
+               "Lost a member during member list replacement");
+#endif
+    replaceOperandWith(4, Elements);
+  }
+  void replaceVTableHolder(Metadata *VTableHolder) {
+    replaceOperandWith(5, VTableHolder);
+  }
+  void replaceTemplateParams(MDTuple *TemplateParams) {
+    replaceOperandWith(6, TemplateParams);
+  }
+  /// @}
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDCompositeTypeKind ||
            MD->getMetadataID() == MDSubroutineTypeKind;
@@ -591,8 +633,8 @@ class MDCompositeType : public MDCompositeTypeBase {
   friend class MDNode;
 
   MDCompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
-                  unsigned Line, unsigned RuntimeLang, unsigned SizeInBits,
-                  unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+                  unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
+                  uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
                   ArrayRef<Metadata *> Ops)
       : MDCompositeTypeBase(C, MDCompositeTypeKind, Storage, Tag, Line,
                             RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
@@ -602,8 +644,8 @@ class MDCompositeType : public MDCompositeTypeBase {
   static MDCompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
           unsigned Line, Metadata *Scope, Metadata *BaseType,
-          unsigned SizeInBits, unsigned AlignInBits, unsigned OffsetInBits,
-          unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
+          uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
+          uint64_t Flags, Metadata *Elements, unsigned RuntimeLang,
           Metadata *VTableHolder, Metadata *TemplateParams,
           StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
@@ -615,7 +657,7 @@ class MDCompositeType : public MDCompositeTypeBase {
   static MDCompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
           unsigned Line, Metadata *Scope, Metadata *BaseType,
-          unsigned SizeInBits, unsigned AlignInBits, unsigned OffsetInBits,
+          uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
           unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
           Metadata *VTableHolder, Metadata *TemplateParams,
           MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
@@ -632,8 +674,8 @@ public:
   DEFINE_MDNODE_GET(MDCompositeType,
                     (unsigned Tag, StringRef Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags, Metadata *Elements,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags, Metadata *Elements,
                      unsigned RuntimeLang, Metadata *VTableHolder,
                      Metadata *TemplateParams = nullptr,
                      StringRef Identifier = ""),
@@ -643,8 +685,8 @@ public:
   DEFINE_MDNODE_GET(MDCompositeType,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags, Metadata *Elements,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags, Metadata *Elements,
                      unsigned RuntimeLang, Metadata *VTableHolder,
                      Metadata *TemplateParams = nullptr,
                      MDString *Identifier = nullptr),
@@ -695,66 +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(); }
-
-  MDTuple *getFileNode() const { return cast<MDTuple>(getOperand(0)); }
-
-  StringRef getFilename() const {
-    if (auto *S = getRawFilename())
-      return S->getString();
-    return StringRef();
-  }
-  StringRef getDirectory() const {
-    if (auto *S = getRawDirectory())
-      return S->getString();
-    return StringRef();
-  }
-
-  MDString *getRawFilename() const {
-    return cast_or_null<MDString>(getFileNode()->getOperand(0));
-  }
-  MDString *getRawDirectory() const {
-    return cast_or_null<MDString>(getFileNode()->getOperand(1));
-  }
-
-  static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDFileKind;
-  }
-};
-
 /// \brief Compile unit.
 class MDCompileUnit : public MDScope {
   friend class LLVMContextImpl;
@@ -844,16 +826,117 @@ public:
   Metadata *getGlobalVariables() const { return getOperand(7); }
   Metadata *getImportedEntities() const { return getOperand(8); }
 
+  MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
+  MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
+  MDString *getRawSplitDebugFilename() const {
+    return getOperandAs<MDString>(3);
+  }
+
+  /// \brief Replace arrays.
+  ///
+  /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
+  /// deleted on a uniquing collision.  In practice, uniquing collisions on \a
+  /// MDCompileUnit should be fairly rare.
+  /// @{
+  void replaceSubprograms(MDTuple *N) { replaceOperandWith(6, N); }
+  void replaceGlobalVariables(MDTuple *N) { replaceOperandWith(7, N); }
+  /// @}
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDCompileUnitKind;
   }
 };
 
+/// \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;
 
@@ -870,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) {}
@@ -951,6 +1035,9 @@ public:
   StringRef getDisplayName() const { return getStringOperand(3); }
   StringRef getLinkageName() const { return getStringOperand(4); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(2); }
+  MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
+
   Metadata *getType() const { return getOperand(5); }
   Metadata *getContainingType() const { return getOperand(6); }
 
@@ -959,16 +1046,27 @@ public:
   Metadata *getDeclaration() const { return getOperand(9); }
   Metadata *getVariables() const { return getOperand(10); }
 
+  /// \brief Replace the function.
+  ///
+  /// If \a isUniqued() and not \a isResolved(), this could node will be
+  /// RAUW'ed and deleted out from under the caller.  Use a \a TrackingMDRef if
+  /// that's a problem.
+  /// @{
+  void replaceFunction(Function *F);
+  void replaceFunction(ConstantAsMetadata *MD) { replaceOperandWith(7, MD); }
+  void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); }
+  /// @}
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDSubprogramKind;
   }
 };
 
-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:
@@ -1095,17 +1193,14 @@ public:
   Metadata *getScope() const { return getOperand(1); }
   StringRef getName() const { return getStringOperand(2); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDNamespaceKind;
   }
 };
 
 /// \brief Base class for template parameters.
-///
-/// TODO: Remove the scope.  It's always the compile unit, and never
-/// referenced.
-/// TODO: Remove File, Line and Column.  They're always 0 and never
-/// referenced.
 class MDTemplateParameter : public DebugNode {
 protected:
   MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
@@ -1114,9 +1209,10 @@ protected:
   ~MDTemplateParameter() {}
 
 public:
-  Metadata *getScope() const { return getOperand(0); }
-  StringRef getName() const { return getStringOperand(1); }
-  Metadata *getType() const { return getOperand(2); }
+  StringRef getName() const { return getStringOperand(0); }
+  Metadata *getType() const { return getOperand(1); }
+
+  MDString *getRawName() const { return getOperandAs<MDString>(0); }
 
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDTemplateTypeParameterKind ||
@@ -1134,29 +1230,25 @@ class MDTemplateTypeParameter : public MDTemplateParameter {
                             dwarf::DW_TAG_template_type_parameter, Ops) {}
   ~MDTemplateTypeParameter() {}
 
-  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, Metadata *Scope,
-                                          StringRef Name, Metadata *Type,
-                                          StorageType Storage,
+  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
+                                          Metadata *Type, StorageType Storage,
                                           bool ShouldCreate = true) {
-    return getImpl(Context, Scope, getCanonicalMDString(Context, Name), Type,
-                   Storage, ShouldCreate);
+    return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
+                   ShouldCreate);
   }
-  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, Metadata *Scope,
-                                          MDString *Name, Metadata *Type,
-                                          StorageType Storage,
+  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
+                                          Metadata *Type, StorageType Storage,
                                           bool ShouldCreate = true);
 
   TempMDTemplateTypeParameter cloneImpl() const {
-    return getTemporary(getContext(), getScope(), getName(), getType());
+    return getTemporary(getContext(), getName(), getType());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDTemplateTypeParameter,
-                    (Metadata * Scope, StringRef Name, Metadata *Type),
-                    (Scope, Name, Type))
-  DEFINE_MDNODE_GET(MDTemplateTypeParameter,
-                    (Metadata * Scope, MDString *Name, Metadata *Type),
-                    (Scope, Name, Type))
+  DEFINE_MDNODE_GET(MDTemplateTypeParameter, (StringRef Name, Metadata *Type),
+                    (Name, Type))
+  DEFINE_MDNODE_GET(MDTemplateTypeParameter, (MDString * Name, Metadata *Type),
+                    (Name, Type))
 
   TempMDTemplateTypeParameter clone() const { return cloneImpl(); }
 
@@ -1176,35 +1268,33 @@ class MDTemplateValueParameter : public MDTemplateParameter {
   ~MDTemplateValueParameter() {}
 
   static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
-                                           Metadata *Scope, StringRef Name,
-                                           Metadata *Type, Metadata *Value,
-                                           StorageType Storage,
+                                           StringRef Name, Metadata *Type,
+                                           Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true) {
-    return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name),
-                   Type, Value, Storage, ShouldCreate);
+    return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
+                   Value, Storage, ShouldCreate);
   }
   static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
-                                           Metadata *Scope, MDString *Name,
-                                           Metadata *Type, Metadata *Value,
-                                           StorageType Storage,
+                                           MDString *Name, Metadata *Type,
+                                           Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true);
 
   TempMDTemplateValueParameter cloneImpl() const {
-    return getTemporary(getContext(), getTag(), getScope(), getName(),
-                        getType(), getValue());
+    return getTemporary(getContext(), getTag(), getName(), getType(),
+                        getValue());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDTemplateValueParameter,
-                    (unsigned Tag, Metadata *Scope, StringRef Name,
-                     Metadata *Type, Metadata *Value),
-                    (Tag, Scope, Name, Type, Value))
-  DEFINE_MDNODE_GET(MDTemplateValueParameter,
-                    (unsigned Tag, Metadata *Scope, MDString *Name,
-                     Metadata *Type, Metadata *Value),
-                    (Tag, Scope, Name, Type, Value))
+  DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, StringRef Name,
+                                               Metadata *Type, Metadata *Value),
+                    (Tag, Name, Type, Value))
+  DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, MDString *Name,
+                                               Metadata *Type, Metadata *Value),
+                    (Tag, Name, Type, Value))
+
+  TempMDTemplateValueParameter clone() const { return cloneImpl(); }
 
-  Metadata *getValue() const { return getOperand(3); }
+  Metadata *getValue() const { return getOperand(2); }
 
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDTemplateValueParameterKind;
@@ -1230,6 +1320,8 @@ public:
   Metadata *getFile() const { return getOperand(2); }
   Metadata *getType() const { return getOperand(3); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(1); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDLocalVariableKind ||
            MD->getMetadataID() == MDGlobalVariableKind;
@@ -1295,6 +1387,8 @@ public:
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
 
+  TempMDGlobalVariable clone() const { return cloneImpl(); }
+
   bool isLocalToUnit() const { return IsLocalToUnit; }
   bool isDefinition() const { return IsDefinition; }
   StringRef getDisplayName() const { return getStringOperand(4); }
@@ -1302,6 +1396,8 @@ public:
   Metadata *getVariable() const { return getOperand(6); }
   Metadata *getStaticDataMemberDeclaration() const { return getOperand(7); }
 
+  MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDGlobalVariableKind;
   }
@@ -1363,10 +1459,24 @@ public:
                      Metadata *InlinedAt = nullptr),
                     (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
 
+  TempMDLocalVariable clone() const { return cloneImpl(); }
+
   unsigned getArg() const { return Arg; }
   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;
   }
@@ -1375,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() {}
 
@@ -1400,6 +1509,8 @@ class MDExpression : public DebugNode {
 public:
   DEFINE_MDNODE_GET(MDExpression, (ArrayRef<uint64_t> Elements), (Elements))
 
+  TempMDExpression clone() const { return cloneImpl(); }
+
   ArrayRef<uint64_t> getElements() const { return Elements; }
 
   unsigned getNumElements() const { return Elements.size(); }
@@ -1545,6 +1656,8 @@ public:
                     (Name, File, Line, GetterName, SetterName, Attributes,
                      Type))
 
+  TempMDObjCProperty clone() const { return cloneImpl(); }
+
   unsigned getLine() const { return Line; }
   unsigned getAttributes() const { return Attributes; }
   StringRef getName() const { return getStringOperand(0); }
@@ -1553,6 +1666,10 @@ public:
   StringRef getSetterName() const { return getStringOperand(3); }
   Metadata *getType() const { return getOperand(4); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(0); }
+  MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
+  MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDObjCPropertyKind;
   }
@@ -1605,6 +1722,8 @@ public:
   Metadata *getEntity() const { return getOperand(1); }
   StringRef getName() const { return getStringOperand(2); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDImportedEntityKind;
   }