[llvm-dwp] Add coverage for both the presence and absence of type units, and fix...
[oota-llvm.git] / include / llvm / IR / DebugInfoMetadata.h
index 97c85559ea17473e4cb2254eb861ee32a4ecf017..68a497745ae746acefeacc623bc28a02ad9ad68e 100644 (file)
 // Helper macros for defining get() overrides.
 #define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
 #define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
 // Helper macros for defining get() overrides.
 #define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
 #define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
-#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS)                                 \
-  static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) {  \
-    return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued);          \
-  }                                                                            \
-  static CLASS *getIfExists(LLVMContext &Context,                              \
-                            DEFINE_MDNODE_GET_UNPACK(FORMAL)) {                \
-    return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued,           \
-                   /* ShouldCreate */ false);                                  \
-  }                                                                            \
+#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)              \
   static CLASS *getDistinct(LLVMContext &Context,                              \
                             DEFINE_MDNODE_GET_UNPACK(FORMAL)) {                \
     return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct);         \
   static CLASS *getDistinct(LLVMContext &Context,                              \
                             DEFINE_MDNODE_GET_UNPACK(FORMAL)) {                \
     return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct);         \
     return Temp##CLASS(                                                        \
         getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary));          \
   }
     return Temp##CLASS(                                                        \
         getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary));          \
   }
+#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS)                                 \
+  static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) {  \
+    return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued);          \
+  }                                                                            \
+  static CLASS *getIfExists(LLVMContext &Context,                              \
+                            DEFINE_MDNODE_GET_UNPACK(FORMAL)) {                \
+    return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued,           \
+                   /* ShouldCreate */ false);                                  \
+  }                                                                            \
+  DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
 
 namespace llvm {
 
 
 namespace llvm {
 
-/// \brief Pointer union between a subclass of DebugNode and MDString.
+/// \brief Pointer union between a subclass of DINode and MDString.
 ///
 ///
-/// \a MDCompositeType can be referenced via an \a MDString unique identifier.
+/// \a DICompositeType can be referenced via an \a MDString unique identifier.
 /// This class allows some type safety in the face of that, requiring either a
 /// node of a particular type or an \a MDString.
 /// This class allows some type safety in the face of that, requiring either a
 /// node of a particular type or an \a MDString.
-template <class T> class TypedDebugNodeRef {
+template <class T> class TypedDINodeRef {
   const Metadata *MD = nullptr;
 
 public:
   const Metadata *MD = nullptr;
 
 public:
-  TypedDebugNodeRef() = default;
-  TypedDebugNodeRef(std::nullptr_t) {}
+  TypedDINodeRef() = default;
+  TypedDINodeRef(std::nullptr_t) {}
 
   /// \brief Construct from a raw pointer.
 
   /// \brief Construct from a raw pointer.
-  explicit TypedDebugNodeRef(const Metadata *MD) : MD(MD) {
+  explicit TypedDINodeRef(const Metadata *MD) : MD(MD) {
     assert((!MD || isa<MDString>(MD) || isa<T>(MD)) && "Expected valid ref");
   }
 
   template <class U>
     assert((!MD || isa<MDString>(MD) || isa<T>(MD)) && "Expected valid ref");
   }
 
   template <class U>
-  TypedDebugNodeRef(
-      const TypedDebugNodeRef<U> &X,
+  TypedDINodeRef(
+      const TypedDINodeRef<U> &X,
       typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
           nullptr)
       : MD(X) {}
 
   operator Metadata *() const { return const_cast<Metadata *>(MD); }
 
       typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
           nullptr)
       : MD(X) {}
 
   operator Metadata *() const { return const_cast<Metadata *>(MD); }
 
-  bool operator==(const TypedDebugNodeRef<T> &X) const { return MD == X.MD; };
-  bool operator!=(const TypedDebugNodeRef<T> &X) const { return MD != X.MD; };
+  bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; }
+  bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }
 
   /// \brief Create a reference.
   ///
   /// Get a reference to \c N, using an \a MDString reference if available.
 
   /// \brief Create a reference.
   ///
   /// Get a reference to \c N, using an \a MDString reference if available.
-  static TypedDebugNodeRef get(const T *N);
+  static TypedDINodeRef get(const T *N);
 
   template <class MapTy> T *resolve(const MapTy &Map) const {
     if (!MD)
 
   template <class MapTy> T *resolve(const MapTy &Map) const {
     if (!MD)
@@ -89,15 +91,16 @@ public:
   }
 };
 
   }
 };
 
-typedef TypedDebugNodeRef<DebugNode> DebugNodeRef;
-typedef TypedDebugNodeRef<MDScope> MDScopeRef;
-typedef TypedDebugNodeRef<MDType> MDTypeRef;
+typedef TypedDINodeRef<DINode> DINodeRef;
+typedef TypedDINodeRef<DIScope> DIScopeRef;
+typedef TypedDINodeRef<DIType> DITypeRef;
 
 
-class MDTypeRefArray {
+class DITypeRefArray {
   const MDTuple *N = nullptr;
 
 public:
   const MDTuple *N = nullptr;
 
 public:
-  MDTypeRefArray(const MDTuple *N) : N(N) {}
+  DITypeRefArray() = default;
+  DITypeRefArray(const MDTuple *N) : N(N) {}
 
   explicit operator bool() const { return get(); }
   explicit operator MDTuple *() const { return get(); }
 
   explicit operator bool() const { return get(); }
   explicit operator MDTuple *() const { return get(); }
@@ -108,16 +111,16 @@ public:
 
   // FIXME: Fix callers and remove condition on N.
   unsigned size() const { return N ? N->getNumOperands() : 0u; }
 
   // FIXME: Fix callers and remove condition on N.
   unsigned size() const { return N ? N->getNumOperands() : 0u; }
-  MDTypeRef operator[](unsigned I) const { return MDTypeRef(N->getOperand(I)); }
+  DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); }
 
 
-  class iterator : std::iterator<std::input_iterator_tag, MDTypeRef,
-                                 std::ptrdiff_t, void, MDTypeRef> {
+  class iterator : std::iterator<std::input_iterator_tag, DITypeRef,
+                                 std::ptrdiff_t, void, DITypeRef> {
     MDNode::op_iterator I = nullptr;
 
   public:
     iterator() = default;
     explicit iterator(MDNode::op_iterator I) : I(I) {}
     MDNode::op_iterator I = nullptr;
 
   public:
     iterator() = default;
     explicit iterator(MDNode::op_iterator I) : I(I) {}
-    MDTypeRef operator*() const { return MDTypeRef(*I); }
+    DITypeRef operator*() const { return DITypeRef(*I); }
     iterator &operator++() {
       ++I;
       return *this;
     iterator &operator++() {
       ++I;
       return *this;
@@ -139,20 +142,20 @@ public:
 /// \brief Tagged DWARF-like metadata node.
 ///
 /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
 /// \brief Tagged DWARF-like metadata node.
 ///
 /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
-/// defined in llvm/Support/Dwarf.h).  Called \a DebugNode because it's
+/// defined in llvm/Support/Dwarf.h).  Called \a DINode because it's
 /// potentially used for non-DWARF output.
 /// potentially used for non-DWARF output.
-class DebugNode : public MDNode {
+class DINode : public MDNode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
 protected:
   friend class LLVMContextImpl;
   friend class MDNode;
 
 protected:
-  DebugNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
-            ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
+  DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+         ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
       : MDNode(C, ID, Storage, Ops1, Ops2) {
     assert(Tag < 1u << 16);
     SubclassData16 = Tag;
   }
       : MDNode(C, ID, Storage, Ops1, Ops2) {
     assert(Tag < 1u << 16);
     SubclassData16 = Tag;
   }
-  ~DebugNode() = default;
+  ~DINode() = default;
 
   template <class Ty> Ty *getOperandAs(unsigned I) const {
     return cast_or_null<Ty>(getOperand(I));
 
   template <class Ty> Ty *getOperandAs(unsigned I) const {
     return cast_or_null<Ty>(getOperand(I));
@@ -193,47 +196,47 @@ public:
   static unsigned splitFlags(unsigned Flags,
                              SmallVectorImpl<unsigned> &SplitFlags);
 
   static unsigned splitFlags(unsigned Flags,
                              SmallVectorImpl<unsigned> &SplitFlags);
 
-  DebugNodeRef getRef() const { return DebugNodeRef::get(this); }
+  DINodeRef getRef() const { return DINodeRef::get(this); }
 
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
     default:
       return false;
 
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
     default:
       return false;
-    case GenericDebugNodeKind:
-    case MDSubrangeKind:
-    case MDEnumeratorKind:
-    case MDBasicTypeKind:
-    case MDDerivedTypeKind:
-    case MDCompositeTypeKind:
-    case MDSubroutineTypeKind:
-    case MDFileKind:
-    case MDCompileUnitKind:
-    case MDSubprogramKind:
-    case MDLexicalBlockKind:
-    case MDLexicalBlockFileKind:
-    case MDNamespaceKind:
-    case MDTemplateTypeParameterKind:
-    case MDTemplateValueParameterKind:
-    case MDGlobalVariableKind:
-    case MDLocalVariableKind:
-    case MDObjCPropertyKind:
-    case MDImportedEntityKind:
+    case GenericDINodeKind:
+    case DISubrangeKind:
+    case DIEnumeratorKind:
+    case DIBasicTypeKind:
+    case DIDerivedTypeKind:
+    case DICompositeTypeKind:
+    case DISubroutineTypeKind:
+    case DIFileKind:
+    case DICompileUnitKind:
+    case DISubprogramKind:
+    case DILexicalBlockKind:
+    case DILexicalBlockFileKind:
+    case DINamespaceKind:
+    case DITemplateTypeParameterKind:
+    case DITemplateValueParameterKind:
+    case DIGlobalVariableKind:
+    case DILocalVariableKind:
+    case DIObjCPropertyKind:
+    case DIImportedEntityKind:
+    case DIModuleKind:
       return true;
     }
   }
 };
 
       return true;
     }
   }
 };
 
-template <class T>
-struct simplify_type<const TypedDebugNodeRef<T>> {
+template <class T> struct simplify_type<const TypedDINodeRef<T>> {
   typedef Metadata *SimpleType;
   typedef Metadata *SimpleType;
-  static SimpleType getSimplifiedValue(const TypedDebugNodeRef<T> &MD) {
+  static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) {
     return MD;
   }
 };
 
 template <class T>
     return MD;
   }
 };
 
 template <class T>
-struct simplify_type<TypedDebugNodeRef<T>>
-    : simplify_type<const TypedDebugNodeRef<T>> {};
+struct simplify_type<TypedDINodeRef<T>>
+    : simplify_type<const TypedDINodeRef<T>> {};
 
 /// \brief Generic tagged DWARF-like metadata node.
 ///
 
 /// \brief Generic tagged DWARF-like metadata node.
 ///
@@ -241,37 +244,33 @@ struct simplify_type<TypedDebugNodeRef<T>>
 /// (possibly empty) null-separated \a MDString header that contains arbitrary
 /// fields.  The remaining operands are \a dwarf_operands(), and are pointers
 /// to other metadata.
 /// (possibly empty) null-separated \a MDString header that contains arbitrary
 /// fields.  The remaining operands are \a dwarf_operands(), and are pointers
 /// to other metadata.
-class GenericDebugNode : public DebugNode {
+class GenericDINode : public DINode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
-  GenericDebugNode(LLVMContext &C, StorageType Storage, unsigned Hash,
-                   unsigned Tag, ArrayRef<Metadata *> Ops1,
-                   ArrayRef<Metadata *> Ops2)
-      : DebugNode(C, GenericDebugNodeKind, Storage, Tag, Ops1, Ops2) {
+  GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
+                unsigned Tag, ArrayRef<Metadata *> Ops1,
+                ArrayRef<Metadata *> Ops2)
+      : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
     setHash(Hash);
   }
     setHash(Hash);
   }
-  ~GenericDebugNode() { dropAllReferences(); }
+  ~GenericDINode() { dropAllReferences(); }
 
   void setHash(unsigned Hash) { SubclassData32 = Hash; }
   void recalculateHash();
 
 
   void setHash(unsigned Hash) { SubclassData32 = Hash; }
   void recalculateHash();
 
-  static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag,
-                                   StringRef Header,
-                                   ArrayRef<Metadata *> DwarfOps,
-                                   StorageType Storage,
-                                   bool ShouldCreate = true) {
+  static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
+                                StringRef Header, ArrayRef<Metadata *> DwarfOps,
+                                StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
                    DwarfOps, Storage, ShouldCreate);
   }
 
     return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
                    DwarfOps, Storage, ShouldCreate);
   }
 
-  static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag,
-                                   MDString *Header,
-                                   ArrayRef<Metadata *> DwarfOps,
-                                   StorageType Storage,
-                                   bool ShouldCreate = true);
+  static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
+                                MDString *Header, ArrayRef<Metadata *> DwarfOps,
+                                StorageType Storage, bool ShouldCreate = true);
 
 
-  TempGenericDebugNode cloneImpl() const {
+  TempGenericDINode cloneImpl() const {
     return getTemporary(
         getContext(), getTag(), getHeader(),
         SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
     return getTemporary(
         getContext(), getTag(), getHeader(),
         SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
@@ -280,15 +279,15 @@ class GenericDebugNode : public DebugNode {
 public:
   unsigned getHash() const { return SubclassData32; }
 
 public:
   unsigned getHash() const { return SubclassData32; }
 
-  DEFINE_MDNODE_GET(GenericDebugNode, (unsigned Tag, StringRef Header,
-                                       ArrayRef<Metadata *> DwarfOps),
+  DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
+                                    ArrayRef<Metadata *> DwarfOps),
                     (Tag, Header, DwarfOps))
                     (Tag, Header, DwarfOps))
-  DEFINE_MDNODE_GET(GenericDebugNode, (unsigned Tag, MDString *Header,
-                                       ArrayRef<Metadata *> DwarfOps),
+  DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
+                                    ArrayRef<Metadata *> DwarfOps),
                     (Tag, Header, DwarfOps))
 
   /// \brief Return a (temporary) clone of this.
                     (Tag, Header, DwarfOps))
 
   /// \brief Return a (temporary) clone of this.
-  TempGenericDebugNode clone() const { return cloneImpl(); }
+  TempGenericDINode clone() const { return cloneImpl(); }
 
   unsigned getTag() const { return SubclassData16; }
   StringRef getHeader() const { return getStringOperand(0); }
 
   unsigned getTag() const { return SubclassData16; }
   StringRef getHeader() const { return getStringOperand(0); }
@@ -308,7 +307,7 @@ public:
   }
 
   static bool classof(const Metadata *MD) {
   }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == GenericDebugNodeKind;
+    return MD->getMetadataID() == GenericDINodeKind;
   }
 };
 
   }
 };
 
@@ -316,39 +315,38 @@ public:
 ///
 /// TODO: Merge into node for DW_TAG_array_type, which should have a custom
 /// type.
 ///
 /// TODO: Merge into node for DW_TAG_array_type, which should have a custom
 /// type.
-class MDSubrange : public DebugNode {
+class DISubrange : public DINode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   int64_t Count;
   int64_t LowerBound;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   int64_t Count;
   int64_t LowerBound;
 
-  MDSubrange(LLVMContext &C, StorageType Storage, int64_t Count,
+  DISubrange(LLVMContext &C, StorageType Storage, int64_t Count,
              int64_t LowerBound)
              int64_t LowerBound)
-      : DebugNode(C, MDSubrangeKind, Storage, dwarf::DW_TAG_subrange_type,
-                  None),
+      : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, None),
         Count(Count), LowerBound(LowerBound) {}
         Count(Count), LowerBound(LowerBound) {}
-  ~MDSubrange() = default;
+  ~DISubrange() = default;
 
 
-  static MDSubrange *getImpl(LLVMContext &Context, int64_t Count,
+  static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
                              int64_t LowerBound, StorageType Storage,
                              bool ShouldCreate = true);
 
                              int64_t LowerBound, StorageType Storage,
                              bool ShouldCreate = true);
 
-  TempMDSubrange cloneImpl() const {
+  TempDISubrange cloneImpl() const {
     return getTemporary(getContext(), getCount(), getLowerBound());
   }
 
 public:
     return getTemporary(getContext(), getCount(), getLowerBound());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDSubrange, (int64_t Count, int64_t LowerBound = 0),
+  DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
                     (Count, LowerBound))
 
                     (Count, LowerBound))
 
-  TempMDSubrange clone() const { return cloneImpl(); }
+  TempDISubrange clone() const { return cloneImpl(); }
 
   int64_t getLowerBound() const { return LowerBound; }
   int64_t getCount() const { return Count; }
 
   static bool classof(const Metadata *MD) {
 
   int64_t getLowerBound() const { return LowerBound; }
   int64_t getCount() const { return Count; }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDSubrangeKind;
+    return MD->getMetadataID() == DISubrangeKind;
   }
 };
 
   }
 };
 
@@ -356,39 +354,39 @@ public:
 ///
 /// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
 /// longer creates a type cycle.
 ///
 /// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
 /// longer creates a type cycle.
-class MDEnumerator : public DebugNode {
+class DIEnumerator : public DINode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   int64_t Value;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   int64_t Value;
 
-  MDEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
+  DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
                ArrayRef<Metadata *> Ops)
                ArrayRef<Metadata *> Ops)
-      : DebugNode(C, MDEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
+      : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
         Value(Value) {}
         Value(Value) {}
-  ~MDEnumerator() = default;
+  ~DIEnumerator() = default;
 
 
-  static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+  static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
                                StringRef Name, StorageType Storage,
                                bool ShouldCreate = true) {
     return getImpl(Context, Value, getCanonicalMDString(Context, Name), Storage,
                    ShouldCreate);
   }
                                StringRef Name, StorageType Storage,
                                bool ShouldCreate = true) {
     return getImpl(Context, Value, getCanonicalMDString(Context, Name), Storage,
                    ShouldCreate);
   }
-  static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+  static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
                                MDString *Name, StorageType Storage,
                                bool ShouldCreate = true);
 
                                MDString *Name, StorageType Storage,
                                bool ShouldCreate = true);
 
-  TempMDEnumerator cloneImpl() const {
+  TempDIEnumerator cloneImpl() const {
     return getTemporary(getContext(), getValue(), getName());
   }
 
 public:
     return getTemporary(getContext(), getValue(), getName());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDEnumerator, (int64_t Value, StringRef Name),
+  DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, StringRef Name),
                     (Value, Name))
                     (Value, Name))
-  DEFINE_MDNODE_GET(MDEnumerator, (int64_t Value, MDString *Name),
+  DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, MDString *Name),
                     (Value, Name))
 
                     (Value, Name))
 
-  TempMDEnumerator clone() const { return cloneImpl(); }
+  TempDIEnumerator clone() const { return cloneImpl(); }
 
   int64_t getValue() const { return Value; }
   StringRef getName() const { return getStringOperand(0); }
 
   int64_t getValue() const { return Value; }
   StringRef getName() const { return getStringOperand(0); }
@@ -396,7 +394,7 @@ public:
   MDString *getRawName() const { return getOperandAs<MDString>(0); }
 
   static bool classof(const Metadata *MD) {
   MDString *getRawName() const { return getOperandAs<MDString>(0); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDEnumeratorKind;
+    return MD->getMetadataID() == DIEnumeratorKind;
   }
 };
 
   }
 };
 
@@ -406,49 +404,50 @@ public:
 /// contexts).
 ///
 /// TODO: Separate the concepts of declaration contexts and lexical scopes.
 /// contexts).
 ///
 /// TODO: Separate the concepts of declaration contexts and lexical scopes.
-class MDScope : public DebugNode {
+class DIScope : public DINode {
 protected:
 protected:
-  MDScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+  DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
           ArrayRef<Metadata *> Ops)
           ArrayRef<Metadata *> Ops)
-      : DebugNode(C, ID, Storage, Tag, Ops) {}
-  ~MDScope() = default;
+      : DINode(C, ID, Storage, Tag, Ops) {}
+  ~DIScope() = default;
 
 public:
 
 public:
-  MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
+  DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
 
   inline StringRef getFilename() const;
   inline StringRef getDirectory() const;
 
   StringRef getName() const;
 
   inline StringRef getFilename() const;
   inline StringRef getDirectory() const;
 
   StringRef getName() const;
-  MDScopeRef getScope() const;
+  DIScopeRef getScope() const;
 
   /// \brief Return the raw underlying file.
   ///
 
   /// \brief Return the raw 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
+  /// An \a DIFile is an \a DIScope, but it doesn't point at a separate file
+  /// (it\em is the file).  If \c this is an \a DIFile, we need to return \c
   /// this.  Otherwise, return the first operand, which is where all other
   /// subclasses store their file pointer.
   Metadata *getRawFile() const {
   /// this.  Otherwise, return the first operand, which is where all other
   /// subclasses store their file pointer.
   Metadata *getRawFile() const {
-    return isa<MDFile>(this) ? const_cast<MDScope *>(this)
+    return isa<DIFile>(this) ? const_cast<DIScope *>(this)
                              : static_cast<Metadata *>(getOperand(0));
   }
 
                              : static_cast<Metadata *>(getOperand(0));
   }
 
-  MDScopeRef getRef() const { return MDScopeRef::get(this); }
+  DIScopeRef getRef() const { return DIScopeRef::get(this); }
 
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
     default:
       return false;
 
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
     default:
       return false;
-    case MDBasicTypeKind:
-    case MDDerivedTypeKind:
-    case MDCompositeTypeKind:
-    case MDSubroutineTypeKind:
-    case MDFileKind:
-    case MDCompileUnitKind:
-    case MDSubprogramKind:
-    case MDLexicalBlockKind:
-    case MDLexicalBlockFileKind:
-    case MDNamespaceKind:
+    case DIBasicTypeKind:
+    case DIDerivedTypeKind:
+    case DICompositeTypeKind:
+    case DISubroutineTypeKind:
+    case DIFileKind:
+    case DICompileUnitKind:
+    case DISubprogramKind:
+    case DILexicalBlockKind:
+    case DILexicalBlockFileKind:
+    case DINamespaceKind:
+    case DIModuleKind:
       return true;
     }
   }
       return true;
     }
   }
@@ -458,36 +457,36 @@ public:
 ///
 /// TODO: Merge with directory/file node (including users).
 /// TODO: Canonicalize paths on creation.
 ///
 /// TODO: Merge with directory/file node (including users).
 /// TODO: Canonicalize paths on creation.
-class MDFile : public MDScope {
+class DIFile : public DIScope {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   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() = default;
+  DIFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
+      : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
+  ~DIFile() = default;
 
 
-  static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
+  static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
                          StringRef Directory, StorageType Storage,
                          bool ShouldCreate = true) {
     return getImpl(Context, getCanonicalMDString(Context, Filename),
                    getCanonicalMDString(Context, Directory), Storage,
                    ShouldCreate);
   }
                          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,
+  static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
                          MDString *Directory, StorageType Storage,
                          bool ShouldCreate = true);
 
                          MDString *Directory, StorageType Storage,
                          bool ShouldCreate = true);
 
-  TempMDFile cloneImpl() const {
+  TempDIFile cloneImpl() const {
     return getTemporary(getContext(), getFilename(), getDirectory());
   }
 
 public:
     return getTemporary(getContext(), getFilename(), getDirectory());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory),
+  DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory),
                     (Filename, Directory))
                     (Filename, Directory))
-  DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory),
+  DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory),
                     (Filename, Directory))
 
                     (Filename, Directory))
 
-  TempMDFile clone() const { return cloneImpl(); }
+  TempDIFile clone() const { return cloneImpl(); }
 
   StringRef getFilename() const { return getStringOperand(0); }
   StringRef getDirectory() const { return getStringOperand(1); }
 
   StringRef getFilename() const { return getStringOperand(0); }
   StringRef getDirectory() const { return getStringOperand(1); }
@@ -496,17 +495,17 @@ public:
   MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
 
   static bool classof(const Metadata *MD) {
   MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDFileKind;
+    return MD->getMetadataID() == DIFileKind;
   }
 };
 
   }
 };
 
-StringRef MDScope::getFilename() const {
+StringRef DIScope::getFilename() const {
   if (auto *F = getFile())
     return F->getFilename();
   return "";
 }
 
   if (auto *F = getFile())
     return F->getFilename();
   return "";
 }
 
-StringRef MDScope::getDirectory() const {
+StringRef DIScope::getDirectory() const {
   if (auto *F = getFile())
     return F->getDirectory();
   return "";
   if (auto *F = getFile())
     return F->getDirectory();
   return "";
@@ -517,7 +516,7 @@ StringRef MDScope::getDirectory() const {
 /// TODO: Remove the hardcoded name and context, since many types don't use
 /// them.
 /// TODO: Split up flags.
 /// TODO: Remove the hardcoded name and context, since many types don't use
 /// them.
 /// TODO: Split up flags.
-class MDType : public MDScope {
+class DIType : public DIScope {
   unsigned Line;
   unsigned Flags;
   uint64_t SizeInBits;
   unsigned Line;
   unsigned Flags;
   uint64_t SizeInBits;
@@ -525,17 +524,17 @@ class MDType : public MDScope {
   uint64_t OffsetInBits;
 
 protected:
   uint64_t OffsetInBits;
 
 protected:
-  MDType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+  DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
          unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
          uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
          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),
+      : DIScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags),
         SizeInBits(SizeInBits), AlignInBits(AlignInBits),
         OffsetInBits(OffsetInBits) {}
         SizeInBits(SizeInBits), AlignInBits(AlignInBits),
         OffsetInBits(OffsetInBits) {}
-  ~MDType() = default;
+  ~DIType() = default;
 
 public:
 
 public:
-  TempMDType clone() const {
-    return TempMDType(cast<MDType>(MDNode::clone().release()));
+  TempDIType clone() const {
+    return TempDIType(cast<DIType>(MDNode::clone().release()));
   }
 
   unsigned getLine() const { return Line; }
   }
 
   unsigned getLine() const { return Line; }
@@ -544,7 +543,7 @@ public:
   uint64_t getOffsetInBits() const { return OffsetInBits; }
   unsigned getFlags() const { return Flags; }
 
   uint64_t getOffsetInBits() const { return OffsetInBits; }
   unsigned getFlags() const { return Flags; }
 
-  MDScopeRef getScope() const { return MDScopeRef(getRawScope()); }
+  DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
   StringRef getName() const { return getStringOperand(2); }
 
 
   StringRef getName() const { return getStringOperand(2); }
 
 
@@ -578,99 +577,76 @@ public:
   bool isStaticMember() const { return getFlags() & FlagStaticMember; }
   bool isLValueReference() const { return getFlags() & FlagLValueReference; }
   bool isRValueReference() const { return getFlags() & FlagRValueReference; }
   bool isStaticMember() const { return getFlags() & FlagStaticMember; }
   bool isLValueReference() const { return getFlags() & FlagLValueReference; }
   bool isRValueReference() const { return getFlags() & FlagRValueReference; }
+  bool isExternalTypeRef() const { return getFlags() & FlagExternalTypeRef; }
 
 
-  MDTypeRef getRef() const { return MDTypeRef::get(this); }
+  DITypeRef getRef() const { return DITypeRef::get(this); }
 
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
     default:
       return false;
 
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
     default:
       return false;
-    case MDBasicTypeKind:
-    case MDDerivedTypeKind:
-    case MDCompositeTypeKind:
-    case MDSubroutineTypeKind:
+    case DIBasicTypeKind:
+    case DIDerivedTypeKind:
+    case DICompositeTypeKind:
+    case DISubroutineTypeKind:
       return true;
     }
   }
 };
 
       return true;
     }
   }
 };
 
-/// \brief Basic type.
+/// \brief Basic type, like 'int' or 'float'.
 ///
 /// TODO: Split out DW_TAG_unspecified_type.
 /// TODO: Drop unused accessors.
 ///
 /// TODO: Split out DW_TAG_unspecified_type.
 /// TODO: Drop unused accessors.
-class MDBasicType : public MDType {
+class DIBasicType : public DIType {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Encoding;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Encoding;
 
-  MDBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
+  DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
               uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding,
               ArrayRef<Metadata *> Ops)
               uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding,
               ArrayRef<Metadata *> Ops)
-      : MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
+      : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
                0, Ops),
         Encoding(Encoding) {}
                0, Ops),
         Encoding(Encoding) {}
-  ~MDBasicType() = default;
+  ~DIBasicType() = default;
 
 
-  static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
+  static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
                               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);
   }
                               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,
+  static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
                               MDString *Name, uint64_t SizeInBits,
                               uint64_t AlignInBits, unsigned Encoding,
                               StorageType Storage, bool ShouldCreate = true);
 
                               MDString *Name, uint64_t SizeInBits,
                               uint64_t AlignInBits, unsigned Encoding,
                               StorageType Storage, bool ShouldCreate = true);
 
-  TempMDBasicType cloneImpl() const {
+  TempDIBasicType cloneImpl() const {
     return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
                         getAlignInBits(), getEncoding());
   }
 
 public:
     return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
                         getAlignInBits(), getEncoding());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name),
+  DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
                     (Tag, Name, 0, 0, 0))
                     (Tag, Name, 0, 0, 0))
-  DEFINE_MDNODE_GET(MDBasicType,
+  DEFINE_MDNODE_GET(DIBasicType,
                     (unsigned Tag, StringRef Name, uint64_t SizeInBits,
                      uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
                     (unsigned Tag, StringRef Name, uint64_t SizeInBits,
                      uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
-  DEFINE_MDNODE_GET(MDBasicType,
+  DEFINE_MDNODE_GET(DIBasicType,
                     (unsigned Tag, MDString *Name, uint64_t SizeInBits,
                      uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
 
                     (unsigned Tag, MDString *Name, uint64_t SizeInBits,
                      uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
 
-  TempMDBasicType clone() const { return cloneImpl(); }
+  TempDIBasicType clone() const { return cloneImpl(); }
 
   unsigned getEncoding() const { return Encoding; }
 
   static bool classof(const Metadata *MD) {
 
   unsigned getEncoding() const { return Encoding; }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDBasicTypeKind;
-  }
-};
-
-/// \brief Base class for MDDerivedType and MDCompositeType.
-///
-/// TODO: Delete; they're not really related.
-class MDDerivedTypeBase : public MDType {
-protected:
-  MDDerivedTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
-                    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) {}
-  ~MDDerivedTypeBase() = default;
-
-public:
-  MDTypeRef getBaseType() const { return MDTypeRef(getRawBaseType()); }
-  Metadata *getRawBaseType() const { return getOperand(3); }
-
-  static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDDerivedTypeKind ||
-           MD->getMetadataID() == MDCompositeTypeKind ||
-           MD->getMetadataID() == MDSubroutineTypeKind;
+    return MD->getMetadataID() == DIBasicTypeKind;
   }
 };
 
   }
 };
 
@@ -680,20 +656,20 @@ public:
 /// class members.
 ///
 /// TODO: Split out members (inheritance, fields, methods, etc.).
 /// class members.
 ///
 /// TODO: Split out members (inheritance, fields, methods, etc.).
-class MDDerivedType : public MDDerivedTypeBase {
+class DIDerivedType : public DIType {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
-  MDDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
+  DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
                 unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
                 uint64_t 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() = default;
+      : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
+               AlignInBits, OffsetInBits, Flags, Ops) {}
+  ~DIDerivedType() = default;
 
 
-  static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
-                                StringRef Name, MDFile *File, unsigned Line,
-                                MDScopeRef Scope, MDTypeRef BaseType,
+  static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
+                                StringRef Name, DIFile *File, unsigned Line,
+                                DIScopeRef Scope, DITypeRef BaseType,
                                 uint64_t SizeInBits, uint64_t AlignInBits,
                                 uint64_t OffsetInBits, unsigned Flags,
                                 Metadata *ExtraData, StorageType Storage,
                                 uint64_t SizeInBits, uint64_t AlignInBits,
                                 uint64_t OffsetInBits, unsigned Flags,
                                 Metadata *ExtraData, StorageType Storage,
@@ -702,7 +678,7 @@ class MDDerivedType : public MDDerivedTypeBase {
                    Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
                    Flags, ExtraData, Storage, ShouldCreate);
   }
                    Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
                    Flags, ExtraData, Storage, ShouldCreate);
   }
-  static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
+  static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
                                 MDString *Name, Metadata *File, unsigned Line,
                                 Metadata *Scope, Metadata *BaseType,
                                 uint64_t SizeInBits, uint64_t AlignInBits,
                                 MDString *Name, Metadata *File, unsigned Line,
                                 Metadata *Scope, Metadata *BaseType,
                                 uint64_t SizeInBits, uint64_t AlignInBits,
@@ -710,7 +686,7 @@ class MDDerivedType : public MDDerivedTypeBase {
                                 Metadata *ExtraData, StorageType Storage,
                                 bool ShouldCreate = true);
 
                                 Metadata *ExtraData, StorageType Storage,
                                 bool ShouldCreate = true);
 
-  TempMDDerivedType cloneImpl() const {
+  TempDIDerivedType cloneImpl() const {
     return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
                         getScope(), getBaseType(), getSizeInBits(),
                         getAlignInBits(), getOffsetInBits(), getFlags(),
     return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
                         getScope(), getBaseType(), getSizeInBits(),
                         getAlignInBits(), getOffsetInBits(), getFlags(),
@@ -718,7 +694,7 @@ class MDDerivedType : public MDDerivedTypeBase {
   }
 
 public:
   }
 
 public:
-  DEFINE_MDNODE_GET(MDDerivedType,
+  DEFINE_MDNODE_GET(DIDerivedType,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
                      uint64_t SizeInBits, uint64_t AlignInBits,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
                      uint64_t SizeInBits, uint64_t AlignInBits,
@@ -726,15 +702,19 @@ public:
                      Metadata *ExtraData = nullptr),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, ExtraData))
                      Metadata *ExtraData = nullptr),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, ExtraData))
-  DEFINE_MDNODE_GET(MDDerivedType,
-                    (unsigned Tag, StringRef Name, MDFile *File, unsigned Line,
-                     MDScopeRef Scope, MDTypeRef BaseType, uint64_t SizeInBits,
+  DEFINE_MDNODE_GET(DIDerivedType,
+                    (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+                     DIScopeRef Scope, DITypeRef BaseType, 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))
 
                      uint64_t AlignInBits, uint64_t OffsetInBits,
                      unsigned Flags, Metadata *ExtraData = nullptr),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, ExtraData))
 
-  TempMDDerivedType clone() const { return cloneImpl(); }
+  TempDIDerivedType clone() const { return cloneImpl(); }
+
+  //// Get the base type this is derived from.
+  DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
+  Metadata *getRawBaseType() const { return getOperand(3); }
 
   /// \brief Get extra data associated with this derived type.
   ///
 
   /// \brief Get extra data associated with this derived type.
   ///
@@ -748,12 +728,12 @@ public:
 
   /// \brief Get casted version of extra data.
   /// @{
 
   /// \brief Get casted version of extra data.
   /// @{
-  MDTypeRef getClassType() const {
+  DITypeRef getClassType() const {
     assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
     assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
-    return MDTypeRef(getExtraData());
+    return DITypeRef(getExtraData());
   }
   }
-  MDObjCProperty *getObjCProperty() const {
-    return dyn_cast_or_null<MDObjCProperty>(getExtraData());
+  DIObjCProperty *getObjCProperty() const {
+    return dyn_cast_or_null<DIObjCProperty>(getExtraData());
   }
   Constant *getConstant() const {
     assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
   }
   Constant *getConstant() const {
     assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
@@ -764,74 +744,7 @@ public:
   /// @}
 
   static bool classof(const Metadata *MD) {
   /// @}
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDDerivedTypeKind;
-  }
-};
-
-/// \brief Base class for MDCompositeType and MDSubroutineType.
-///
-/// TODO: Delete; they're not really related.
-class MDCompositeTypeBase : public MDDerivedTypeBase {
-  unsigned RuntimeLang;
-
-protected:
-  MDCompositeTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
-                      unsigned Tag, unsigned Line, unsigned RuntimeLang,
-                      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),
-        RuntimeLang(RuntimeLang) {}
-  ~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<MDSubroutineType>(this) && "no elements for DISubroutineType");
-    return cast_or_null<MDTuple>(getRawElements());
-  }
-  MDTypeRef getVTableHolder() const { return MDTypeRef(getRawVTableHolder()); }
-  MDTemplateParameterArray getTemplateParams() const {
-    return cast_or_null<MDTuple>(getRawTemplateParams());
-  }
-  StringRef getIdentifier() const { return getStringOperand(7); }
-  unsigned getRuntimeLang() const { return RuntimeLang; }
-
-  Metadata *getRawElements() const { return getOperand(4); }
-  Metadata *getRawVTableHolder() const { return getOperand(5); }
-  Metadata *getRawTemplateParams() const { return getOperand(6); }
-  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(DebugNodeArray Elements) {
-#ifndef NDEBUG
-    for (DebugNode *Op : getElements())
-      assert(std::find(Elements->op_begin(), Elements->op_end(), Op) &&
-             "Lost a member during member list replacement");
-#endif
-    replaceOperandWith(4, Elements.get());
-  }
-  void replaceVTableHolder(MDTypeRef VTableHolder) {
-    replaceOperandWith(5, VTableHolder);
-  }
-  void replaceTemplateParams(MDTemplateParameterArray TemplateParams) {
-    replaceOperandWith(6, TemplateParams.get());
-  }
-  /// @}
-
-  static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDCompositeTypeKind ||
-           MD->getMetadataID() == MDSubroutineTypeKind;
+    return MD->getMetadataID() == DIDerivedTypeKind;
   }
 };
 
   }
 };
 
@@ -839,25 +752,27 @@ public:
 ///
 /// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
 /// TODO: Create a custom, unrelated node for DW_TAG_array_type.
 ///
 /// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
 /// TODO: Create a custom, unrelated node for DW_TAG_array_type.
-class MDCompositeType : public MDCompositeTypeBase {
+class DICompositeType : public DIType {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
-  MDCompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
+  unsigned RuntimeLang;
+
+  DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
                   unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
                   uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
                   ArrayRef<Metadata *> Ops)
                   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,
-                            Flags, Ops) {}
-  ~MDCompositeType() = default;
+      : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
+               AlignInBits, OffsetInBits, Flags, Ops),
+        RuntimeLang(RuntimeLang) {}
+  ~DICompositeType() = default;
 
 
-  static MDCompositeType *
+  static DICompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
-          unsigned Line, MDScopeRef Scope, MDTypeRef BaseType,
+          unsigned Line, DIScopeRef Scope, DITypeRef BaseType,
           uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
           uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
-          uint64_t Flags, DebugNodeArray Elements, unsigned RuntimeLang,
-          MDTypeRef VTableHolder, MDTemplateParameterArray TemplateParams,
+          uint64_t Flags, DINodeArray Elements, unsigned RuntimeLang,
+          DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
           StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
     return getImpl(
         Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
           StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
     return getImpl(
         Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
@@ -865,7 +780,7 @@ class MDCompositeType : public MDCompositeTypeBase {
         RuntimeLang, VTableHolder, TemplateParams.get(),
         getCanonicalMDString(Context, Identifier), Storage, ShouldCreate);
   }
         RuntimeLang, VTableHolder, TemplateParams.get(),
         getCanonicalMDString(Context, Identifier), Storage, ShouldCreate);
   }
-  static MDCompositeType *
+  static DICompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
           unsigned Line, Metadata *Scope, Metadata *BaseType,
           uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
   getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
           unsigned Line, Metadata *Scope, Metadata *BaseType,
           uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
@@ -873,7 +788,7 @@ class MDCompositeType : public MDCompositeTypeBase {
           Metadata *VTableHolder, Metadata *TemplateParams,
           MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
 
           Metadata *VTableHolder, Metadata *TemplateParams,
           MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
 
-  TempMDCompositeType cloneImpl() const {
+  TempDICompositeType cloneImpl() const {
     return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
                         getScope(), getBaseType(), getSizeInBits(),
                         getAlignInBits(), getOffsetInBits(), getFlags(),
     return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
                         getScope(), getBaseType(), getSizeInBits(),
                         getAlignInBits(), getOffsetInBits(), getFlags(),
@@ -882,18 +797,18 @@ class MDCompositeType : public MDCompositeTypeBase {
   }
 
 public:
   }
 
 public:
-  DEFINE_MDNODE_GET(MDCompositeType,
-                    (unsigned Tag, StringRef Name, MDFile *File, unsigned Line,
-                     MDScopeRef Scope, MDTypeRef BaseType, uint64_t SizeInBits,
+  DEFINE_MDNODE_GET(DICompositeType,
+                    (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+                     DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
                      uint64_t AlignInBits, uint64_t OffsetInBits,
                      uint64_t AlignInBits, uint64_t OffsetInBits,
-                     unsigned Flags, DebugNodeArray Elements,
-                     unsigned RuntimeLang, MDTypeRef VTableHolder,
-                     MDTemplateParameterArray TemplateParams = nullptr,
+                     unsigned Flags, DINodeArray Elements, unsigned RuntimeLang,
+                     DITypeRef VTableHolder,
+                     DITemplateParameterArray TemplateParams = nullptr,
                      StringRef Identifier = ""),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
                      VTableHolder, TemplateParams, Identifier))
                      StringRef Identifier = ""),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
                      VTableHolder, TemplateParams, Identifier))
-  DEFINE_MDNODE_GET(MDCompositeType,
+  DEFINE_MDNODE_GET(DICompositeType,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
                      uint64_t SizeInBits, uint64_t AlignInBits,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
                      uint64_t SizeInBits, uint64_t AlignInBits,
@@ -905,71 +820,108 @@ public:
                      AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
                      VTableHolder, TemplateParams, Identifier))
 
                      AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
                      VTableHolder, TemplateParams, Identifier))
 
-  TempMDCompositeType clone() const { return cloneImpl(); }
+  TempDICompositeType clone() const { return cloneImpl(); }
+
+  DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
+  DINodeArray getElements() const {
+    return cast_or_null<MDTuple>(getRawElements());
+  }
+  DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); }
+  DITemplateParameterArray getTemplateParams() const {
+    return cast_or_null<MDTuple>(getRawTemplateParams());
+  }
+  StringRef getIdentifier() const { return getStringOperand(7); }
+  unsigned getRuntimeLang() const { return RuntimeLang; }
+
+  Metadata *getRawBaseType() const { return getOperand(3); }
+  Metadata *getRawElements() const { return getOperand(4); }
+  Metadata *getRawVTableHolder() const { return getOperand(5); }
+  Metadata *getRawTemplateParams() const { return getOperand(6); }
+  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(DINodeArray Elements) {
+#ifndef NDEBUG
+    for (DINode *Op : getElements())
+      assert(std::find(Elements->op_begin(), Elements->op_end(), Op) &&
+             "Lost a member during member list replacement");
+#endif
+    replaceOperandWith(4, Elements.get());
+  }
+  void replaceVTableHolder(DITypeRef VTableHolder) {
+    replaceOperandWith(5, VTableHolder);
+  }
+  void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
+    replaceOperandWith(6, TemplateParams.get());
+  }
+  /// @}
 
   static bool classof(const Metadata *MD) {
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDCompositeTypeKind;
+    return MD->getMetadataID() == DICompositeTypeKind;
   }
 };
 
   }
 };
 
-template <class T> TypedDebugNodeRef<T> TypedDebugNodeRef<T>::get(const T *N) {
+template <class T> TypedDINodeRef<T> TypedDINodeRef<T>::get(const T *N) {
   if (N)
   if (N)
-    if (auto *Composite = dyn_cast<MDCompositeType>(N))
+    if (auto *Composite = dyn_cast<DICompositeType>(N))
       if (auto *S = Composite->getRawIdentifier())
       if (auto *S = Composite->getRawIdentifier())
-        return TypedDebugNodeRef<T>(S);
-  return TypedDebugNodeRef<T>(N);
+        return TypedDINodeRef<T>(S);
+  return TypedDINodeRef<T>(N);
 }
 
 /// \brief Type array for a subprogram.
 ///
 }
 
 /// \brief Type array for a subprogram.
 ///
-/// TODO: Detach from CompositeType, and fold the array of types in directly
-/// as operands.
-class MDSubroutineType : public MDCompositeTypeBase {
+/// TODO: Fold the array of types in directly as operands.
+class DISubroutineType : public DIType {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
-  MDSubroutineType(LLVMContext &C, StorageType Storage, unsigned Flags,
+  DISubroutineType(LLVMContext &C, StorageType Storage, unsigned Flags,
                    ArrayRef<Metadata *> Ops)
                    ArrayRef<Metadata *> Ops)
-      : MDCompositeTypeBase(C, MDSubroutineTypeKind, Storage,
-                            dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags,
-                            Ops) {}
-  ~MDSubroutineType() = default;
+      : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type,
+               0, 0, 0, 0, Flags, Ops) {}
+  ~DISubroutineType() = default;
 
 
-  static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
-                                   MDTypeRefArray TypeArray,
+  static DISubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
+                                   DITypeRefArray TypeArray,
                                    StorageType Storage,
                                    bool ShouldCreate = true) {
     return getImpl(Context, Flags, TypeArray.get(), Storage, ShouldCreate);
   }
                                    StorageType Storage,
                                    bool ShouldCreate = true) {
     return getImpl(Context, Flags, TypeArray.get(), Storage, ShouldCreate);
   }
-  static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
+  static DISubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
                                    Metadata *TypeArray, StorageType Storage,
                                    bool ShouldCreate = true);
 
                                    Metadata *TypeArray, StorageType Storage,
                                    bool ShouldCreate = true);
 
-  TempMDSubroutineType cloneImpl() const {
+  TempDISubroutineType cloneImpl() const {
     return getTemporary(getContext(), getFlags(), getTypeArray());
   }
 
 public:
     return getTemporary(getContext(), getFlags(), getTypeArray());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDSubroutineType,
-                    (unsigned Flags, MDTypeRefArray TypeArray),
+  DEFINE_MDNODE_GET(DISubroutineType,
+                    (unsigned Flags, DITypeRefArray TypeArray),
                     (Flags, TypeArray))
                     (Flags, TypeArray))
-  DEFINE_MDNODE_GET(MDSubroutineType, (unsigned Flags, Metadata *TypeArray),
+  DEFINE_MDNODE_GET(DISubroutineType, (unsigned Flags, Metadata *TypeArray),
                     (Flags, TypeArray))
 
                     (Flags, TypeArray))
 
-  TempMDSubroutineType clone() const { return cloneImpl(); }
+  TempDISubroutineType clone() const { return cloneImpl(); }
 
 
-  MDTypeRefArray getTypeArray() const {
+  DITypeRefArray getTypeArray() const {
     return cast_or_null<MDTuple>(getRawTypeArray());
   }
     return cast_or_null<MDTuple>(getRawTypeArray());
   }
-  Metadata *getRawTypeArray() const { return getRawElements(); }
+  Metadata *getRawTypeArray() const { return getOperand(3); }
 
   static bool classof(const Metadata *MD) {
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDSubroutineTypeKind;
+    return MD->getMetadataID() == DISubroutineTypeKind;
   }
 };
 
 /// \brief Compile unit.
   }
 };
 
 /// \brief Compile unit.
-class MDCompileUnit : public MDScope {
+class DICompileUnit : public DIScope {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
@@ -977,74 +929,80 @@ class MDCompileUnit : public MDScope {
   bool IsOptimized;
   unsigned RuntimeVersion;
   unsigned EmissionKind;
   bool IsOptimized;
   unsigned RuntimeVersion;
   unsigned EmissionKind;
+  uint64_t DWOId;
 
 
-  MDCompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
+  DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
                 bool IsOptimized, unsigned RuntimeVersion,
                 bool IsOptimized, unsigned RuntimeVersion,
-                unsigned EmissionKind, ArrayRef<Metadata *> Ops)
-      : MDScope(C, MDCompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
+                unsigned EmissionKind, uint64_t DWOId, ArrayRef<Metadata *> Ops)
+      : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
         SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
         SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
-        RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind) {}
-  ~MDCompileUnit() = default;
+        RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
+        DWOId(DWOId) {
+    assert(Storage != Uniqued);
+  }
+  ~DICompileUnit() = default;
 
 
-  static MDCompileUnit *
-  getImpl(LLVMContext &Context, unsigned SourceLanguage, MDFile *File,
+  static DICompileUnit *
+  getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
           StringRef Producer, bool IsOptimized, StringRef Flags,
           unsigned RuntimeVersion, StringRef SplitDebugFilename,
           StringRef Producer, bool IsOptimized, StringRef Flags,
           unsigned RuntimeVersion, StringRef SplitDebugFilename,
-          unsigned EmissionKind, MDCompositeTypeArray EnumTypes,
-          MDTypeArray RetainedTypes, MDSubprogramArray Subprograms,
-          MDGlobalVariableArray GlobalVariables,
-          MDImportedEntityArray ImportedEntities, StorageType Storage,
-          bool ShouldCreate = true) {
-    return getImpl(
-        Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
-        IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
-        getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
-        EnumTypes.get(), RetainedTypes.get(), Subprograms.get(),
-        GlobalVariables.get(), ImportedEntities.get(), Storage, ShouldCreate);
-  }
-  static MDCompileUnit *
+          unsigned EmissionKind, DICompositeTypeArray EnumTypes,
+          DITypeArray RetainedTypes, DISubprogramArray Subprograms,
+          DIGlobalVariableArray GlobalVariables,
+          DIImportedEntityArray ImportedEntities, uint64_t DWOId,
+          StorageType Storage, bool ShouldCreate = true) {
+    return getImpl(Context, SourceLanguage, File,
+                   getCanonicalMDString(Context, Producer), IsOptimized,
+                   getCanonicalMDString(Context, Flags), RuntimeVersion,
+                   getCanonicalMDString(Context, SplitDebugFilename),
+                   EmissionKind, EnumTypes.get(), RetainedTypes.get(),
+                   Subprograms.get(), GlobalVariables.get(),
+                   ImportedEntities.get(), DWOId, Storage, ShouldCreate);
+  }
+  static DICompileUnit *
   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,
   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,
+          Metadata *ImportedEntities, uint64_t DWOId, StorageType Storage,
           bool ShouldCreate = true);
 
           bool ShouldCreate = true);
 
-  TempMDCompileUnit cloneImpl() const {
+  TempDICompileUnit cloneImpl() const {
     return getTemporary(
         getContext(), getSourceLanguage(), getFile(), getProducer(),
         isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
         getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(),
     return getTemporary(
         getContext(), getSourceLanguage(), getFile(), getProducer(),
         isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
         getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(),
-        getGlobalVariables(), getImportedEntities());
+        getGlobalVariables(), getImportedEntities(), DWOId);
   }
 
   }
 
+  static void get() = delete;
+  static void getIfExists() = delete;
+
 public:
 public:
-  DEFINE_MDNODE_GET(MDCompileUnit,
-                    (unsigned SourceLanguage, MDFile *File, StringRef Producer,
-                     bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
-                     StringRef SplitDebugFilename, unsigned EmissionKind,
-                     MDCompositeTypeArray EnumTypes, MDTypeArray RetainedTypes,
-                     MDSubprogramArray Subprograms,
-                     MDGlobalVariableArray GlobalVariables,
-                     MDImportedEntityArray ImportedEntities),
-                    (SourceLanguage, File, Producer, IsOptimized, Flags,
-                     RuntimeVersion, SplitDebugFilename, EmissionKind,
-                     EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
-                     ImportedEntities))
-  DEFINE_MDNODE_GET(MDCompileUnit,
-                    (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),
-                    (SourceLanguage, File, Producer, IsOptimized, Flags,
-                     RuntimeVersion, SplitDebugFilename, EmissionKind,
-                     EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
-                     ImportedEntities))
-
-  TempMDCompileUnit clone() const { return cloneImpl(); }
+  DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
+      DICompileUnit,
+      (unsigned SourceLanguage, DIFile *File, StringRef Producer,
+       bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
+       StringRef SplitDebugFilename, unsigned EmissionKind,
+       DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes,
+       DISubprogramArray Subprograms, DIGlobalVariableArray GlobalVariables,
+       DIImportedEntityArray ImportedEntities, uint64_t DWOId),
+      (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
+       SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms,
+       GlobalVariables, ImportedEntities, DWOId))
+  DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
+      DICompileUnit,
+      (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, uint64_t DWOId),
+      (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
+       SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms,
+       GlobalVariables, ImportedEntities, DWOId))
+
+  TempDICompileUnit clone() const { return cloneImpl(); }
 
   unsigned getSourceLanguage() const { return SourceLanguage; }
   bool isOptimized() const { return IsOptimized; }
 
   unsigned getSourceLanguage() const { return SourceLanguage; }
   bool isOptimized() const { return IsOptimized; }
@@ -1053,21 +1011,23 @@ public:
   StringRef getProducer() const { return getStringOperand(1); }
   StringRef getFlags() const { return getStringOperand(2); }
   StringRef getSplitDebugFilename() const { return getStringOperand(3); }
   StringRef getProducer() const { return getStringOperand(1); }
   StringRef getFlags() const { return getStringOperand(2); }
   StringRef getSplitDebugFilename() const { return getStringOperand(3); }
-  MDCompositeTypeArray getEnumTypes() const {
+  DICompositeTypeArray getEnumTypes() const {
     return cast_or_null<MDTuple>(getRawEnumTypes());
   }
     return cast_or_null<MDTuple>(getRawEnumTypes());
   }
-  MDTypeArray getRetainedTypes() const {
+  DITypeArray getRetainedTypes() const {
     return cast_or_null<MDTuple>(getRawRetainedTypes());
   }
     return cast_or_null<MDTuple>(getRawRetainedTypes());
   }
-  MDSubprogramArray getSubprograms() const {
+  DISubprogramArray getSubprograms() const {
     return cast_or_null<MDTuple>(getRawSubprograms());
   }
     return cast_or_null<MDTuple>(getRawSubprograms());
   }
-  MDGlobalVariableArray getGlobalVariables() const {
+  DIGlobalVariableArray getGlobalVariables() const {
     return cast_or_null<MDTuple>(getRawGlobalVariables());
   }
     return cast_or_null<MDTuple>(getRawGlobalVariables());
   }
-  MDImportedEntityArray getImportedEntities() const {
+  DIImportedEntityArray getImportedEntities() const {
     return cast_or_null<MDTuple>(getRawImportedEntities());
   }
     return cast_or_null<MDTuple>(getRawImportedEntities());
   }
+  uint64_t getDWOId() const { return DWOId; }
+  void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
 
   MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
   MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
 
   MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
   MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
@@ -1084,71 +1044,80 @@ public:
   ///
   /// 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
   ///
   /// 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.
+  /// DICompileUnit should be fairly rare.
   /// @{
   /// @{
-  void replaceSubprograms(MDSubprogramArray N) {
+  void replaceEnumTypes(DICompositeTypeArray N) {
+    replaceOperandWith(4, N.get());
+  }
+  void replaceRetainedTypes(DITypeArray N) {
+    replaceOperandWith(5, N.get());
+  }
+  void replaceSubprograms(DISubprogramArray N) {
     replaceOperandWith(6, N.get());
   }
     replaceOperandWith(6, N.get());
   }
-  void replaceGlobalVariables(MDGlobalVariableArray N) {
+  void replaceGlobalVariables(DIGlobalVariableArray N) {
     replaceOperandWith(7, N.get());
   }
     replaceOperandWith(7, N.get());
   }
+  void replaceImportedEntities(DIImportedEntityArray N) {
+    replaceOperandWith(8, N.get());
+  }
   /// @}
 
   static bool classof(const Metadata *MD) {
   /// @}
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDCompileUnitKind;
+    return MD->getMetadataID() == DICompileUnitKind;
   }
 };
 
 /// \brief A scope for locals.
 ///
 /// A legal scope for lexical blocks, local variables, and debug info
   }
 };
 
 /// \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 {
+/// locations.  Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
+/// DILexicalBlockFile.
+class DILocalScope : public DIScope {
 protected:
 protected:
-  MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+  DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
                ArrayRef<Metadata *> Ops)
                ArrayRef<Metadata *> Ops)
-      : MDScope(C, ID, Storage, Tag, Ops) {}
-  ~MDLocalScope() = default;
+      : DIScope(C, ID, Storage, Tag, Ops) {}
+  ~DILocalScope() = default;
 
 public:
   /// \brief Get the subprogram for this scope.
   ///
 
 public:
   /// \brief Get the subprogram for this scope.
   ///
-  /// Return this if it's an \a MDSubprogram; otherwise, look up the scope
+  /// Return this if it's an \a DISubprogram; otherwise, look up the scope
   /// chain.
   /// chain.
-  MDSubprogram *getSubprogram() const;
+  DISubprogram *getSubprogram() const;
 
   static bool classof(const Metadata *MD) {
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDSubprogramKind ||
-           MD->getMetadataID() == MDLexicalBlockKind ||
-           MD->getMetadataID() == MDLexicalBlockFileKind;
+    return MD->getMetadataID() == DISubprogramKind ||
+           MD->getMetadataID() == DILexicalBlockKind ||
+           MD->getMetadataID() == DILexicalBlockFileKind;
   }
 };
 
 /// \brief Debug location.
 ///
 /// A debug location in source code, used for debug info and otherwise.
   }
 };
 
 /// \brief Debug location.
 ///
 /// A debug location in source code, used for debug info and otherwise.
-class MDLocation : public MDNode {
+class DILocation : public MDNode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
-  MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
+  DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
              unsigned Column, ArrayRef<Metadata *> MDs);
              unsigned Column, ArrayRef<Metadata *> MDs);
-  ~MDLocation() { dropAllReferences(); }
+  ~DILocation() { dropAllReferences(); }
 
 
-  static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
+  static DILocation *getImpl(LLVMContext &Context, unsigned Line,
                              unsigned Column, Metadata *Scope,
                              Metadata *InlinedAt, StorageType Storage,
                              bool ShouldCreate = true);
                              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,
+  static DILocation *getImpl(LLVMContext &Context, unsigned Line,
+                             unsigned Column, DILocalScope *Scope,
+                             DILocation *InlinedAt, StorageType Storage,
                              bool ShouldCreate = true) {
     return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
                    static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
   }
 
                              bool ShouldCreate = true) {
     return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
                    static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
   }
 
-  TempMDLocation cloneImpl() const {
+  TempDILocation cloneImpl() const {
     return getTemporary(getContext(), getLine(), getColumn(), getScope(),
                         getInlinedAt());
   }
     return getTemporary(getContext(), getLine(), getColumn(), getScope(),
                         getInlinedAt());
   }
@@ -1157,28 +1126,26 @@ class MDLocation : public MDNode {
   void replaceOperandWith(unsigned I, Metadata *New) = delete;
 
 public:
   void replaceOperandWith(unsigned I, Metadata *New) = delete;
 
 public:
-  DEFINE_MDNODE_GET(MDLocation,
+  DEFINE_MDNODE_GET(DILocation,
                     (unsigned Line, unsigned Column, Metadata *Scope,
                      Metadata *InlinedAt = nullptr),
                     (Line, Column, Scope, InlinedAt))
                     (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),
+  DEFINE_MDNODE_GET(DILocation,
+                    (unsigned Line, unsigned Column, DILocalScope *Scope,
+                     DILocation *InlinedAt = nullptr),
                     (Line, Column, Scope, InlinedAt))
 
   /// \brief Return a (temporary) clone of this.
                     (Line, Column, Scope, InlinedAt))
 
   /// \brief Return a (temporary) clone of this.
-  TempMDLocation clone() const { return cloneImpl(); }
+  TempDILocation clone() const { return cloneImpl(); }
 
   unsigned getLine() const { return SubclassData32; }
   unsigned getColumn() const { return SubclassData16; }
 
   unsigned getLine() const { return SubclassData32; }
   unsigned getColumn() const { return SubclassData16; }
-  MDLocalScope *getScope() const {
-    return cast<MDLocalScope>(getRawScope());
-  }
-  MDLocation *getInlinedAt() const {
-    return cast_or_null<MDLocation>(getRawInlinedAt());
+  DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
+  DILocation *getInlinedAt() const {
+    return cast_or_null<DILocation>(getRawInlinedAt());
   }
 
   }
 
-  MDFile *getFile() const { return getScope()->getFile(); }
+  DIFile *getFile() const { return getScope()->getFile(); }
   StringRef getFilename() const { return getScope()->getFilename(); }
   StringRef getDirectory() const { return getScope()->getDirectory(); }
 
   StringRef getFilename() const { return getScope()->getFilename(); }
   StringRef getDirectory() const { return getScope()->getDirectory(); }
 
@@ -1186,7 +1153,7 @@ public:
   ///
   /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
   /// location.
   ///
   /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
   /// location.
-  MDLocalScope *getInlinedAtScope() const {
+  DILocalScope *getInlinedAtScope() const {
     if (auto *IA = getInlinedAt())
       return IA->getInlinedAtScope();
     return getScope();
     if (auto *IA = getInlinedAt())
       return IA->getInlinedAtScope();
     return getScope();
@@ -1205,7 +1172,7 @@ public:
   /// FIXME: Add a check for getColumn().
   /// FIXME: Change the getFilename() check to getFile() (or add one for
   /// getDirectory()).
   /// FIXME: Add a check for getColumn().
   /// FIXME: Change the getFilename() check to getFile() (or add one for
   /// getDirectory()).
-  bool canDiscriminate(const MDLocation &RHS) const {
+  bool canDiscriminate(const DILocation &RHS) const {
     return getFilename() != RHS.getFilename() || getLine() != RHS.getLine();
   }
 
     return getFilename() != RHS.getFilename() || getLine() != RHS.getLine();
   }
 
@@ -1232,7 +1199,7 @@ public:
   }
 
   static bool classof(const Metadata *MD) {
   }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDLocationKind;
+    return MD->getMetadataID() == DILocationKind;
   }
 };
 
   }
 };
 
@@ -1240,7 +1207,7 @@ public:
 ///
 /// TODO: Remove DisplayName.  It's always equal to Name.
 /// TODO: Split up flags.
 ///
 /// TODO: Remove DisplayName.  It's always equal to Name.
 /// TODO: Split up flags.
-class MDSubprogram : public MDLocalScope {
+class DISubprogram : public DILocalScope {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
@@ -1253,80 +1220,77 @@ class MDSubprogram : public MDLocalScope {
   bool IsDefinition;
   bool IsOptimized;
 
   bool IsDefinition;
   bool IsOptimized;
 
-  MDSubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
+  DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
                unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
                unsigned Flags, bool IsLocalToUnit, bool IsDefinition,
                bool IsOptimized, ArrayRef<Metadata *> Ops)
                unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
                unsigned Flags, bool IsLocalToUnit, bool IsDefinition,
                bool IsOptimized, ArrayRef<Metadata *> Ops)
-      : MDLocalScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram,
+      : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
                      Ops),
         Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
         VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
         IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
                      Ops),
         Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
         VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
         IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
-  ~MDSubprogram() = default;
+  ~DISubprogram() = default;
 
 
-  static MDSubprogram *
-  getImpl(LLVMContext &Context, MDScopeRef Scope, StringRef Name,
-          StringRef LinkageName, MDFile *File, unsigned Line,
-          MDSubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
-          unsigned ScopeLine, MDTypeRef ContainingType, unsigned Virtuality,
+  static DISubprogram *
+  getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name,
+          StringRef LinkageName, DIFile *File, unsigned Line,
+          DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
+          unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality,
           unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
           unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
-          Constant *Function, MDTemplateParameterArray TemplateParams,
-          MDSubprogram *Declaration, MDLocalVariableArray Variables,
-          StorageType Storage, bool ShouldCreate = true) {
+          DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
+          DILocalVariableArray 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,
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
                    IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
                    Virtuality, VirtualIndex, Flags, IsOptimized,
-                   Function ? ConstantAsMetadata::get(Function) : nullptr,
                    TemplateParams.get(), Declaration, Variables.get(), Storage,
                    ShouldCreate);
   }
                    TemplateParams.get(), Declaration, Variables.get(), Storage,
                    ShouldCreate);
   }
-  static MDSubprogram *
+  static DISubprogram *
   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,
   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 = true);
+          unsigned Flags, bool IsOptimized, Metadata *TemplateParams,
+          Metadata *Declaration, Metadata *Variables, StorageType Storage,
+          bool ShouldCreate = true);
 
 
-  TempMDSubprogram cloneImpl() const {
-    return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
-                        getFile(), getLine(), getType(), isLocalToUnit(),
-                        isDefinition(), getScopeLine(), getContainingType(),
-                        getVirtuality(), getVirtualIndex(), getFlags(),
-                        isOptimized(), getFunctionConstant(),
-                        getTemplateParams(), getDeclaration(), getVariables());
+  TempDISubprogram cloneImpl() const {
+    return getTemporary(
+        getContext(), getScope(), getName(), getLinkageName(), getFile(),
+        getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(),
+        getContainingType(), getVirtuality(), getVirtualIndex(), getFlags(),
+        isOptimized(), getTemplateParams(), getDeclaration(), getVariables());
   }
 
 public:
   }
 
 public:
-  DEFINE_MDNODE_GET(MDSubprogram,
-                    (MDScopeRef Scope, StringRef Name, StringRef LinkageName,
-                     MDFile *File, unsigned Line, MDSubroutineType *Type,
+  DEFINE_MDNODE_GET(DISubprogram,
+                    (DIScopeRef Scope, StringRef Name, StringRef LinkageName,
+                     DIFile *File, unsigned Line, DISubroutineType *Type,
                      bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
                      bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
-                     MDTypeRef ContainingType, unsigned Virtuality,
+                     DITypeRef ContainingType, unsigned Virtuality,
                      unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
                      unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
-                     Constant *Function = nullptr,
-                     MDTemplateParameterArray TemplateParams = nullptr,
-                     MDSubprogram *Declaration = nullptr,
-                     MDLocalVariableArray Variables = nullptr),
+                     DITemplateParameterArray TemplateParams = nullptr,
+                     DISubprogram *Declaration = nullptr,
+                     DILocalVariableArray Variables = nullptr),
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, ScopeLine, ContainingType, Virtuality,
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, ScopeLine, ContainingType, Virtuality,
-                     VirtualIndex, Flags, IsOptimized, Function, TemplateParams,
+                     VirtualIndex, Flags, IsOptimized, TemplateParams,
                      Declaration, Variables))
   DEFINE_MDNODE_GET(
                      Declaration, Variables))
   DEFINE_MDNODE_GET(
-      MDSubprogram,
+      DISubprogram,
       (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 * 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 = nullptr, Metadata *TemplateParams = nullptr,
-       Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
+       Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
+       Metadata *Variables = nullptr),
       (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
        ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized,
       (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
        ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized,
-       Function, TemplateParams, Declaration, Variables))
+       TemplateParams, Declaration, Variables))
 
 
-  TempMDSubprogram clone() const { return cloneImpl(); }
+  TempDISubprogram clone() const { return cloneImpl(); }
 
 public:
   unsigned getLine() const { return Line; }
 
 public:
   unsigned getLine() const { return Line; }
@@ -1367,7 +1331,7 @@ public:
     return getFlags() & FlagRValueReference;
   }
 
     return getFlags() & FlagRValueReference;
   }
 
-  MDScopeRef getScope() const { return MDScopeRef(getRawScope()); }
+  DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
 
   StringRef getName() const { return getStringOperand(2); }
   StringRef getDisplayName() const { return getStringOperand(3); }
 
   StringRef getName() const { return getStringOperand(2); }
   StringRef getDisplayName() const { return getStringOperand(3); }
@@ -1376,97 +1340,75 @@ public:
   MDString *getRawName() const { return getOperandAs<MDString>(2); }
   MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
 
   MDString *getRawName() const { return getOperandAs<MDString>(2); }
   MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
 
-  MDSubroutineType *getType() const {
-    return cast_or_null<MDSubroutineType>(getRawType());
+  DISubroutineType *getType() const {
+    return cast_or_null<DISubroutineType>(getRawType());
   }
   }
-  MDTypeRef getContainingType() const {
-    return MDTypeRef(getRawContainingType());
+  DITypeRef getContainingType() const {
+    return DITypeRef(getRawContainingType());
   }
 
   }
 
-  Constant *getFunctionConstant() const {
-    if (auto *C = cast_or_null<ConstantAsMetadata>(getRawFunction()))
-      return C->getValue();
-    return nullptr;
-  }
-  MDTemplateParameterArray getTemplateParams() const {
+  DITemplateParameterArray getTemplateParams() const {
     return cast_or_null<MDTuple>(getRawTemplateParams());
   }
     return cast_or_null<MDTuple>(getRawTemplateParams());
   }
-  MDSubprogram *getDeclaration() const {
-    return cast_or_null<MDSubprogram>(getRawDeclaration());
+  DISubprogram *getDeclaration() const {
+    return cast_or_null<DISubprogram>(getRawDeclaration());
   }
   }
-  MDLocalVariableArray getVariables() const {
+  DILocalVariableArray getVariables() const {
     return cast_or_null<MDTuple>(getRawVariables());
   }
 
   Metadata *getRawScope() const { return getOperand(1); }
   Metadata *getRawType() const { return getOperand(5); }
   Metadata *getRawContainingType() const { return getOperand(6); }
     return cast_or_null<MDTuple>(getRawVariables());
   }
 
   Metadata *getRawScope() const { return getOperand(1); }
   Metadata *getRawType() const { return getOperand(5); }
   Metadata *getRawContainingType() const { return getOperand(6); }
-  Metadata *getRawFunction() const { return getOperand(7); }
-  Metadata *getRawTemplateParams() const { return getOperand(8); }
-  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
-  /// 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); }
-  /// @}
+  Metadata *getRawTemplateParams() const { return getOperand(7); }
+  Metadata *getRawDeclaration() const { return getOperand(8); }
+  Metadata *getRawVariables() const { return getOperand(9); }
 
 
-  /// \brief Check if this subprogram decribes the given function.
+  /// \brief Check if this subprogram describes the given function.
   ///
   /// FIXME: Should this be looking through bitcasts?
   bool describes(const Function *F) const;
 
   static bool classof(const Metadata *MD) {
   ///
   /// FIXME: Should this be looking through bitcasts?
   bool describes(const Function *F) const;
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDSubprogramKind;
+    return MD->getMetadataID() == DISubprogramKind;
   }
 };
 
   }
 };
 
-class MDLexicalBlockBase : public MDLocalScope {
+class DILexicalBlockBase : public DILocalScope {
 protected:
 protected:
-  MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
+  DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
                      ArrayRef<Metadata *> Ops)
                      ArrayRef<Metadata *> Ops)
-      : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
-  ~MDLexicalBlockBase() = default;
+      : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
+  ~DILexicalBlockBase() = default;
 
 public:
 
 public:
-  MDLocalScope *getScope() const { return cast<MDLocalScope>(getRawScope()); }
+  DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
 
   Metadata *getRawScope() const { return getOperand(1); }
 
   static bool classof(const Metadata *MD) {
 
   Metadata *getRawScope() const { return getOperand(1); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDLexicalBlockKind ||
-           MD->getMetadataID() == MDLexicalBlockFileKind;
+    return MD->getMetadataID() == DILexicalBlockKind ||
+           MD->getMetadataID() == DILexicalBlockFileKind;
   }
 };
 
   }
 };
 
-class MDLexicalBlock : public MDLexicalBlockBase {
+class DILexicalBlock : public DILexicalBlockBase {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
-  unsigned Column;
+  uint16_t Column;
 
 
-  MDLexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
+  DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
                  unsigned Column, ArrayRef<Metadata *> Ops)
                  unsigned Column, ArrayRef<Metadata *> Ops)
-      : MDLexicalBlockBase(C, MDLexicalBlockKind, Storage, Ops), Line(Line),
-        Column(Column) {}
-  ~MDLexicalBlock() = default;
+      : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
+        Column(Column) {
+    assert(Column < (1u << 16) && "Expected 16-bit column");
+  }
+  ~DILexicalBlock() = default;
 
 
-  static MDLexicalBlock *getImpl(LLVMContext &Context, MDLocalScope *Scope,
-                                 MDFile *File, unsigned Line, unsigned Column,
+  static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
+                                 DIFile *File, unsigned Line, unsigned Column,
                                  StorageType Storage,
                                  bool ShouldCreate = true) {
     return getImpl(Context, static_cast<Metadata *>(Scope),
                                  StorageType Storage,
                                  bool ShouldCreate = true) {
     return getImpl(Context, static_cast<Metadata *>(Scope),
@@ -1474,47 +1416,47 @@ class MDLexicalBlock : public MDLexicalBlockBase {
                    ShouldCreate);
   }
 
                    ShouldCreate);
   }
 
-  static MDLexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
+  static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
                                  Metadata *File, unsigned Line, unsigned Column,
                                  StorageType Storage, bool ShouldCreate = true);
 
                                  Metadata *File, unsigned Line, unsigned Column,
                                  StorageType Storage, bool ShouldCreate = true);
 
-  TempMDLexicalBlock cloneImpl() const {
+  TempDILexicalBlock cloneImpl() const {
     return getTemporary(getContext(), getScope(), getFile(), getLine(),
                         getColumn());
   }
 
 public:
     return getTemporary(getContext(), getScope(), getFile(), getLine(),
                         getColumn());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDLexicalBlock, (MDLocalScope * Scope, MDFile *File,
+  DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
                                      unsigned Line, unsigned Column),
                     (Scope, File, Line, Column))
                                      unsigned Line, unsigned Column),
                     (Scope, File, Line, Column))
-  DEFINE_MDNODE_GET(MDLexicalBlock, (Metadata * Scope, Metadata *File,
+  DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
                                      unsigned Line, unsigned Column),
                     (Scope, File, Line, Column))
 
                                      unsigned Line, unsigned Column),
                     (Scope, File, Line, Column))
 
-  TempMDLexicalBlock clone() const { return cloneImpl(); }
+  TempDILexicalBlock clone() const { return cloneImpl(); }
 
   unsigned getLine() const { return Line; }
   unsigned getColumn() const { return Column; }
 
   static bool classof(const Metadata *MD) {
 
   unsigned getLine() const { return Line; }
   unsigned getColumn() const { return Column; }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDLexicalBlockKind;
+    return MD->getMetadataID() == DILexicalBlockKind;
   }
 };
 
   }
 };
 
-class MDLexicalBlockFile : public MDLexicalBlockBase {
+class DILexicalBlockFile : public DILexicalBlockBase {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Discriminator;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Discriminator;
 
-  MDLexicalBlockFile(LLVMContext &C, StorageType Storage,
+  DILexicalBlockFile(LLVMContext &C, StorageType Storage,
                      unsigned Discriminator, ArrayRef<Metadata *> Ops)
                      unsigned Discriminator, ArrayRef<Metadata *> Ops)
-      : MDLexicalBlockBase(C, MDLexicalBlockFileKind, Storage, Ops),
+      : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
         Discriminator(Discriminator) {}
         Discriminator(Discriminator) {}
-  ~MDLexicalBlockFile() = default;
+  ~DILexicalBlockFile() = default;
 
 
-  static MDLexicalBlockFile *getImpl(LLVMContext &Context, MDLocalScope *Scope,
-                                     MDFile *File, unsigned Discriminator,
+  static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
+                                     DIFile *File, unsigned Discriminator,
                                      StorageType Storage,
                                      bool ShouldCreate = true) {
     return getImpl(Context, static_cast<Metadata *>(Scope),
                                      StorageType Storage,
                                      bool ShouldCreate = true) {
     return getImpl(Context, static_cast<Metadata *>(Scope),
@@ -1522,209 +1464,271 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
                    ShouldCreate);
   }
 
                    ShouldCreate);
   }
 
-  static MDLexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
+  static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
                                      Metadata *File, unsigned Discriminator,
                                      StorageType Storage,
                                      bool ShouldCreate = true);
 
                                      Metadata *File, unsigned Discriminator,
                                      StorageType Storage,
                                      bool ShouldCreate = true);
 
-  TempMDLexicalBlockFile cloneImpl() const {
+  TempDILexicalBlockFile cloneImpl() const {
     return getTemporary(getContext(), getScope(), getFile(),
                         getDiscriminator());
   }
 
 public:
     return getTemporary(getContext(), getScope(), getFile(),
                         getDiscriminator());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDLexicalBlockFile, (MDLocalScope * Scope, MDFile *File,
+  DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
                                          unsigned Discriminator),
                     (Scope, File, Discriminator))
                                          unsigned Discriminator),
                     (Scope, File, Discriminator))
-  DEFINE_MDNODE_GET(MDLexicalBlockFile,
+  DEFINE_MDNODE_GET(DILexicalBlockFile,
                     (Metadata * Scope, Metadata *File, unsigned Discriminator),
                     (Scope, File, Discriminator))
 
                     (Metadata * Scope, Metadata *File, unsigned Discriminator),
                     (Scope, File, Discriminator))
 
-  TempMDLexicalBlockFile clone() const { return cloneImpl(); }
+  TempDILexicalBlockFile clone() const { return cloneImpl(); }
+
+  // TODO: Remove these once they're gone from DILexicalBlockBase.
+  unsigned getLine() const = delete;
+  unsigned getColumn() const = delete;
 
   unsigned getDiscriminator() const { return Discriminator; }
 
   static bool classof(const Metadata *MD) {
 
   unsigned getDiscriminator() const { return Discriminator; }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDLexicalBlockFileKind;
+    return MD->getMetadataID() == DILexicalBlockFileKind;
   }
 };
 
   }
 };
 
-unsigned MDLocation::getDiscriminator() const {
-  if (auto *F = dyn_cast<MDLexicalBlockFile>(getScope()))
+unsigned DILocation::getDiscriminator() const {
+  if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
     return F->getDiscriminator();
   return 0;
 }
 
     return F->getDiscriminator();
   return 0;
 }
 
-class MDNamespace : public MDScope {
+class DINamespace : public DIScope {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
 
-  MDNamespace(LLVMContext &Context, StorageType Storage, unsigned Line,
+  DINamespace(LLVMContext &Context, StorageType Storage, unsigned Line,
               ArrayRef<Metadata *> Ops)
               ArrayRef<Metadata *> Ops)
-      : MDScope(Context, MDNamespaceKind, Storage, dwarf::DW_TAG_namespace,
+      : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
                 Ops),
         Line(Line) {}
                 Ops),
         Line(Line) {}
-  ~MDNamespace() = default;
+  ~DINamespace() = default;
 
 
-  static MDNamespace *getImpl(LLVMContext &Context, MDScope *Scope,
-                              MDFile *File, StringRef Name, unsigned Line,
+  static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
+                              DIFile *File, StringRef Name, unsigned Line,
                               StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name),
                    Line, Storage, ShouldCreate);
   }
                               StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name),
                    Line, Storage, ShouldCreate);
   }
-  static MDNamespace *getImpl(LLVMContext &Context, Metadata *Scope,
+  static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
                               Metadata *File, MDString *Name, unsigned Line,
                               StorageType Storage, bool ShouldCreate = true);
 
                               Metadata *File, MDString *Name, unsigned Line,
                               StorageType Storage, bool ShouldCreate = true);
 
-  TempMDNamespace cloneImpl() const {
+  TempDINamespace cloneImpl() const {
     return getTemporary(getContext(), getScope(), getFile(), getName(),
                         getLine());
   }
 
 public:
     return getTemporary(getContext(), getScope(), getFile(), getName(),
                         getLine());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDNamespace, (MDScope * Scope, MDFile *File, StringRef Name,
+  DEFINE_MDNODE_GET(DINamespace, (DIScope * Scope, DIFile *File, StringRef Name,
                                   unsigned Line),
                     (Scope, File, Name, Line))
                                   unsigned Line),
                     (Scope, File, Name, Line))
-  DEFINE_MDNODE_GET(MDNamespace, (Metadata * Scope, Metadata *File,
+  DEFINE_MDNODE_GET(DINamespace, (Metadata * Scope, Metadata *File,
                                   MDString *Name, unsigned Line),
                     (Scope, File, Name, Line))
 
                                   MDString *Name, unsigned Line),
                     (Scope, File, Name, Line))
 
-  TempMDNamespace clone() const { return cloneImpl(); }
+  TempDINamespace clone() const { return cloneImpl(); }
 
   unsigned getLine() const { return Line; }
 
   unsigned getLine() const { return Line; }
-  MDScope *getScope() const { return cast_or_null<MDScope>(getRawScope()); }
+  DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
   StringRef getName() const { return getStringOperand(2); }
 
   Metadata *getRawScope() const { return getOperand(1); }
   MDString *getRawName() const { return getOperandAs<MDString>(2); }
 
   static bool classof(const Metadata *MD) {
   StringRef getName() const { return getStringOperand(2); }
 
   Metadata *getRawScope() const { return getOperand(1); }
   MDString *getRawName() const { return getOperandAs<MDString>(2); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDNamespaceKind;
+    return MD->getMetadataID() == DINamespaceKind;
+  }
+};
+
+/// \brief A (clang) module that has been imported by the compile unit.
+///
+class DIModule : public DIScope {
+  friend class LLVMContextImpl;
+  friend class MDNode;
+
+  DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
+      : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
+  ~DIModule() {}
+
+  static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
+                           StringRef Name, StringRef ConfigurationMacros,
+                           StringRef IncludePath, StringRef ISysRoot,
+                           StorageType Storage, bool ShouldCreate = true) {
+    return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
+                   getCanonicalMDString(Context, ConfigurationMacros),
+                   getCanonicalMDString(Context, IncludePath),
+                   getCanonicalMDString(Context, ISysRoot),
+                   Storage, ShouldCreate);
+  }
+  static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
+                           MDString *Name, MDString *ConfigurationMacros,
+                           MDString *IncludePath, MDString *ISysRoot,
+                           StorageType Storage, bool ShouldCreate = true);
+
+  TempDIModule cloneImpl() const {
+    return getTemporary(getContext(), getScope(), getName(),
+                        getConfigurationMacros(), getIncludePath(),
+                        getISysRoot());
+  }
+
+public:
+  DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
+                               StringRef ConfigurationMacros, StringRef IncludePath,
+                               StringRef ISysRoot),
+                    (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
+  DEFINE_MDNODE_GET(DIModule,
+                    (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
+                     MDString *IncludePath, MDString *ISysRoot),
+                    (Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
+
+  TempDIModule clone() const { return cloneImpl(); }
+
+  DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
+  StringRef getName() const { return getStringOperand(1); }
+  StringRef getConfigurationMacros() const { return getStringOperand(2); }
+  StringRef getIncludePath() const { return getStringOperand(3); }
+  StringRef getISysRoot() const { return getStringOperand(4); }
+
+  Metadata *getRawScope() const { return getOperand(0); }
+  MDString *getRawName() const { return getOperandAs<MDString>(1); }
+  MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
+  MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
+  MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); }
+
+  static bool classof(const Metadata *MD) {
+    return MD->getMetadataID() == DIModuleKind;
   }
 };
 
 /// \brief Base class for template parameters.
   }
 };
 
 /// \brief Base class for template parameters.
-class MDTemplateParameter : public DebugNode {
+class DITemplateParameter : public DINode {
 protected:
 protected:
-  MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
+  DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
                       unsigned Tag, ArrayRef<Metadata *> Ops)
                       unsigned Tag, ArrayRef<Metadata *> Ops)
-      : DebugNode(Context, ID, Storage, Tag, Ops) {}
-  ~MDTemplateParameter() = default;
+      : DINode(Context, ID, Storage, Tag, Ops) {}
+  ~DITemplateParameter() = default;
 
 public:
   StringRef getName() const { return getStringOperand(0); }
 
 public:
   StringRef getName() const { return getStringOperand(0); }
-  MDTypeRef getType() const { return MDTypeRef(getRawType()); }
+  DITypeRef getType() const { return DITypeRef(getRawType()); }
 
   MDString *getRawName() const { return getOperandAs<MDString>(0); }
   Metadata *getRawType() const { return getOperand(1); }
 
   static bool classof(const Metadata *MD) {
 
   MDString *getRawName() const { return getOperandAs<MDString>(0); }
   Metadata *getRawType() const { return getOperand(1); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDTemplateTypeParameterKind ||
-           MD->getMetadataID() == MDTemplateValueParameterKind;
+    return MD->getMetadataID() == DITemplateTypeParameterKind ||
+           MD->getMetadataID() == DITemplateValueParameterKind;
   }
 };
 
   }
 };
 
-class MDTemplateTypeParameter : public MDTemplateParameter {
+class DITemplateTypeParameter : public DITemplateParameter {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
-  MDTemplateTypeParameter(LLVMContext &Context, StorageType Storage,
+  DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
                           ArrayRef<Metadata *> Ops)
                           ArrayRef<Metadata *> Ops)
-      : MDTemplateParameter(Context, MDTemplateTypeParameterKind, Storage,
+      : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
                             dwarf::DW_TAG_template_type_parameter, Ops) {}
                             dwarf::DW_TAG_template_type_parameter, Ops) {}
-  ~MDTemplateTypeParameter() = default;
+  ~DITemplateTypeParameter() = default;
 
 
-  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
-                                          MDTypeRef Type, StorageType Storage,
+  static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
+                                          DITypeRef Type, StorageType Storage,
                                           bool ShouldCreate = true) {
     return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
                    ShouldCreate);
   }
                                           bool ShouldCreate = true) {
     return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
                    ShouldCreate);
   }
-  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
+  static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
                                           Metadata *Type, StorageType Storage,
                                           bool ShouldCreate = true);
 
                                           Metadata *Type, StorageType Storage,
                                           bool ShouldCreate = true);
 
-  TempMDTemplateTypeParameter cloneImpl() const {
+  TempDITemplateTypeParameter cloneImpl() const {
     return getTemporary(getContext(), getName(), getType());
   }
 
 public:
     return getTemporary(getContext(), getName(), getType());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDTemplateTypeParameter, (StringRef Name, MDTypeRef Type),
+  DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type),
                     (Name, Type))
                     (Name, Type))
-  DEFINE_MDNODE_GET(MDTemplateTypeParameter, (MDString * Name, Metadata *Type),
+  DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
                     (Name, Type))
 
                     (Name, Type))
 
-  TempMDTemplateTypeParameter clone() const { return cloneImpl(); }
+  TempDITemplateTypeParameter clone() const { return cloneImpl(); }
 
   static bool classof(const Metadata *MD) {
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDTemplateTypeParameterKind;
+    return MD->getMetadataID() == DITemplateTypeParameterKind;
   }
 };
 
   }
 };
 
-class MDTemplateValueParameter : public MDTemplateParameter {
+class DITemplateValueParameter : public DITemplateParameter {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
-  MDTemplateValueParameter(LLVMContext &Context, StorageType Storage,
+  DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
                            unsigned Tag, ArrayRef<Metadata *> Ops)
                            unsigned Tag, ArrayRef<Metadata *> Ops)
-      : MDTemplateParameter(Context, MDTemplateValueParameterKind, Storage, Tag,
+      : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
                             Ops) {}
                             Ops) {}
-  ~MDTemplateValueParameter() = default;
+  ~DITemplateValueParameter() = default;
 
 
-  static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
-                                           StringRef Name, MDTypeRef Type,
+  static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
+                                           StringRef Name, DITypeRef Type,
                                            Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
                    Value, Storage, ShouldCreate);
   }
                                            Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
                    Value, Storage, ShouldCreate);
   }
-  static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
+  static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
                                            MDString *Name, Metadata *Type,
                                            Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true);
 
                                            MDString *Name, Metadata *Type,
                                            Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true);
 
-  TempMDTemplateValueParameter cloneImpl() const {
+  TempDITemplateValueParameter cloneImpl() const {
     return getTemporary(getContext(), getTag(), getName(), getType(),
                         getValue());
   }
 
 public:
     return getTemporary(getContext(), getTag(), getName(), getType(),
                         getValue());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, StringRef Name,
-                                               MDTypeRef Type, Metadata *Value),
+  DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name,
+                                               DITypeRef Type, Metadata *Value),
                     (Tag, Name, Type, Value))
                     (Tag, Name, Type, Value))
-  DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, MDString *Name,
+  DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
                                                Metadata *Type, Metadata *Value),
                     (Tag, Name, Type, Value))
 
                                                Metadata *Type, Metadata *Value),
                     (Tag, Name, Type, Value))
 
-  TempMDTemplateValueParameter clone() const { return cloneImpl(); }
+  TempDITemplateValueParameter clone() const { return cloneImpl(); }
 
   Metadata *getValue() const { return getOperand(2); }
 
   static bool classof(const Metadata *MD) {
 
   Metadata *getValue() const { return getOperand(2); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDTemplateValueParameterKind;
+    return MD->getMetadataID() == DITemplateValueParameterKind;
   }
 };
 
 /// \brief Base class for variables.
   }
 };
 
 /// \brief Base class for variables.
-///
-/// TODO: Hardcode to DW_TAG_variable.
-class MDVariable : public DebugNode {
+class DIVariable : public DINode {
   unsigned Line;
 
 protected:
   unsigned Line;
 
 protected:
-  MDVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
-             unsigned Line, ArrayRef<Metadata *> Ops)
-      : DebugNode(C, ID, Storage, Tag, Ops), Line(Line) {}
-  ~MDVariable() = default;
+  DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
+             ArrayRef<Metadata *> Ops)
+      : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {}
+  ~DIVariable() = default;
 
 public:
   unsigned getLine() const { return Line; }
 
 public:
   unsigned getLine() const { return Line; }
-  MDScope *getScope() const { return cast_or_null<MDScope>(getRawScope()); }
+  DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
   StringRef getName() const { return getStringOperand(1); }
   StringRef getName() const { return getStringOperand(1); }
-  MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
-  MDTypeRef getType() const { return MDTypeRef(getRawType()); }
+  DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
+  DITypeRef getType() const { return DITypeRef(getRawType()); }
 
   StringRef getFilename() const {
     if (auto *F = getFile())
 
   StringRef getFilename() const {
     if (auto *F = getFile())
@@ -1743,34 +1747,33 @@ public:
   Metadata *getRawType() const { return getOperand(3); }
 
   static bool classof(const Metadata *MD) {
   Metadata *getRawType() const { return getOperand(3); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDLocalVariableKind ||
-           MD->getMetadataID() == MDGlobalVariableKind;
+    return MD->getMetadataID() == DILocalVariableKind ||
+           MD->getMetadataID() == DIGlobalVariableKind;
   }
 };
 
 /// \brief Global variables.
 ///
 /// TODO: Remove DisplayName.  It's always equal to Name.
   }
 };
 
 /// \brief Global variables.
 ///
 /// TODO: Remove DisplayName.  It's always equal to Name.
-class MDGlobalVariable : public MDVariable {
+class DIGlobalVariable : public DIVariable {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   bool IsLocalToUnit;
   bool IsDefinition;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   bool IsLocalToUnit;
   bool IsDefinition;
 
-  MDGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
+  DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
                    bool IsLocalToUnit, bool IsDefinition,
                    ArrayRef<Metadata *> Ops)
                    bool IsLocalToUnit, bool IsDefinition,
                    ArrayRef<Metadata *> Ops)
-      : MDVariable(C, MDGlobalVariableKind, Storage, dwarf::DW_TAG_variable,
-                   Line, Ops),
+      : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops),
         IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
         IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
-  ~MDGlobalVariable() = default;
+  ~DIGlobalVariable() = default;
 
 
-  static MDGlobalVariable *
-  getImpl(LLVMContext &Context, MDScope *Scope, StringRef Name,
-          StringRef LinkageName, MDFile *File, unsigned Line, MDTypeRef Type,
+  static DIGlobalVariable *
+  getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
+          StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type,
           bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
           bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
-          MDDerivedType *StaticDataMemberDeclaration, StorageType Storage,
+          DIDerivedType *StaticDataMemberDeclaration, StorageType Storage,
           bool ShouldCreate = true) {
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
           bool ShouldCreate = true) {
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
@@ -1778,14 +1781,14 @@ class MDGlobalVariable : public MDVariable {
                    Variable ? ConstantAsMetadata::get(Variable) : nullptr,
                    StaticDataMemberDeclaration, Storage, ShouldCreate);
   }
                    Variable ? ConstantAsMetadata::get(Variable) : nullptr,
                    StaticDataMemberDeclaration, Storage, ShouldCreate);
   }
-  static MDGlobalVariable *
+  static DIGlobalVariable *
   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 = true);
 
   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 = true);
 
-  TempMDGlobalVariable cloneImpl() const {
+  TempDIGlobalVariable cloneImpl() const {
     return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
                         getFile(), getLine(), getType(), isLocalToUnit(),
                         isDefinition(), getVariable(),
     return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
                         getFile(), getLine(), getType(), isLocalToUnit(),
                         isDefinition(), getVariable(),
@@ -1793,14 +1796,14 @@ class MDGlobalVariable : public MDVariable {
   }
 
 public:
   }
 
 public:
-  DEFINE_MDNODE_GET(MDGlobalVariable,
-                    (MDScope * Scope, StringRef Name, StringRef LinkageName,
-                     MDFile *File, unsigned Line, MDTypeRef Type,
+  DEFINE_MDNODE_GET(DIGlobalVariable,
+                    (DIScope * Scope, StringRef Name, StringRef LinkageName,
+                     DIFile *File, unsigned Line, DITypeRef Type,
                      bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
                      bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
-                     MDDerivedType *StaticDataMemberDeclaration),
+                     DIDerivedType *StaticDataMemberDeclaration),
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
-  DEFINE_MDNODE_GET(MDGlobalVariable,
+  DEFINE_MDNODE_GET(DIGlobalVariable,
                     (Metadata * Scope, MDString *Name, MDString *LinkageName,
                      Metadata *File, unsigned Line, Metadata *Type,
                      bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
                     (Metadata * Scope, MDString *Name, MDString *LinkageName,
                      Metadata *File, unsigned Line, Metadata *Type,
                      bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
@@ -1808,7 +1811,7 @@ public:
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
 
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
 
-  TempMDGlobalVariable clone() const { return cloneImpl(); }
+  TempDIGlobalVariable clone() const { return cloneImpl(); }
 
   bool isLocalToUnit() const { return IsLocalToUnit; }
   bool isDefinition() const { return IsDefinition; }
 
   bool isLocalToUnit() const { return IsLocalToUnit; }
   bool isDefinition() const { return IsDefinition; }
@@ -1819,8 +1822,8 @@ public:
       return dyn_cast<Constant>(C->getValue());
     return nullptr;
   }
       return dyn_cast<Constant>(C->getValue());
     return nullptr;
   }
-  MDDerivedType *getStaticDataMemberDeclaration() const {
-    return cast_or_null<MDDerivedType>(getRawStaticDataMemberDeclaration());
+  DIDerivedType *getStaticDataMemberDeclaration() const {
+    return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
   }
 
   MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
   }
 
   MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
@@ -1828,107 +1831,84 @@ public:
   Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(7); }
 
   static bool classof(const Metadata *MD) {
   Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(7); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDGlobalVariableKind;
+    return MD->getMetadataID() == DIGlobalVariableKind;
   }
 };
 
 /// \brief Local variable.
 ///
   }
 };
 
 /// \brief Local variable.
 ///
-/// TODO: Split between arguments and otherwise.
-/// TODO: Use \c DW_TAG_variable instead of fake tags.
 /// TODO: Split up flags.
 /// TODO: Split up flags.
-class MDLocalVariable : public MDVariable {
+class DILocalVariable : public DIVariable {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Arg;
   unsigned Flags;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Arg;
   unsigned Flags;
 
-  MDLocalVariable(LLVMContext &C, StorageType Storage, unsigned Tag,
-                  unsigned Line, unsigned Arg, unsigned Flags,
-                  ArrayRef<Metadata *> Ops)
-      : MDVariable(C, MDLocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg),
+  DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
+                  unsigned Arg, unsigned Flags, ArrayRef<Metadata *> Ops)
+      : DIVariable(C, DILocalVariableKind, Storage, Line, Ops), Arg(Arg),
         Flags(Flags) {}
         Flags(Flags) {}
-  ~MDLocalVariable() = default;
+  ~DILocalVariable() = default;
 
 
-  static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
-                                  MDScope *Scope, StringRef Name, MDFile *File,
-                                  unsigned Line, MDTypeRef Type, unsigned Arg,
-                                  unsigned Flags, MDLocation *InlinedAt,
+  static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
+                                  StringRef Name, DIFile *File, unsigned Line,
+                                  DITypeRef Type, unsigned Arg, unsigned Flags,
                                   StorageType Storage,
                                   bool ShouldCreate = true) {
                                   StorageType Storage,
                                   bool ShouldCreate = true) {
-    return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name),
-                   File, Line, Type, Arg, Flags, InlinedAt, Storage,
-                   ShouldCreate);
+    return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
+                   Line, Type, Arg, Flags, Storage, ShouldCreate);
   }
   }
-  static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
-                                  Metadata *Scope, MDString *Name,
-                                  Metadata *File, unsigned Line, Metadata *Type,
-                                  unsigned Arg, unsigned Flags,
-                                  Metadata *InlinedAt, StorageType Storage,
+  static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
+                                  MDString *Name, Metadata *File, unsigned Line,
+                                  Metadata *Type, unsigned Arg, unsigned Flags,
+                                  StorageType Storage,
                                   bool ShouldCreate = true);
 
                                   bool ShouldCreate = true);
 
-  TempMDLocalVariable cloneImpl() const {
-    return getTemporary(getContext(), getTag(), getScope(), getName(),
-                        getFile(), getLine(), getType(), getArg(), getFlags(),
-                        getInlinedAt());
+  TempDILocalVariable cloneImpl() const {
+    return getTemporary(getContext(), getScope(), getName(), getFile(),
+                        getLine(), getType(), getArg(), getFlags());
   }
 
 public:
   }
 
 public:
-  DEFINE_MDNODE_GET(MDLocalVariable,
-                    (unsigned Tag, MDLocalScope *Scope, StringRef Name,
-                     MDFile *File, unsigned Line, MDTypeRef Type, unsigned Arg,
-                     unsigned Flags, MDLocation *InlinedAt = nullptr),
-                    (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
-  DEFINE_MDNODE_GET(MDLocalVariable,
-                    (unsigned Tag, Metadata *Scope, MDString *Name,
-                     Metadata *File, unsigned Line, Metadata *Type,
-                     unsigned Arg, unsigned Flags,
-                     Metadata *InlinedAt = nullptr),
-                    (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
-
-  TempMDLocalVariable clone() const { return cloneImpl(); }
+  DEFINE_MDNODE_GET(DILocalVariable,
+                    (DILocalScope * Scope, StringRef Name, DIFile *File,
+                     unsigned Line, DITypeRef Type, unsigned Arg,
+                     unsigned Flags),
+                    (Scope, Name, File, Line, Type, Arg, Flags))
+  DEFINE_MDNODE_GET(DILocalVariable,
+                    (Metadata * Scope, MDString *Name, Metadata *File,
+                     unsigned Line, Metadata *Type, unsigned Arg,
+                     unsigned Flags),
+                    (Scope, Name, File, Line, Type, Arg, Flags))
+
+  TempDILocalVariable clone() const { return cloneImpl(); }
 
   /// \brief Get the local scope for this variable.
   ///
   /// Variables must be defined in a local scope.
 
   /// \brief Get the local scope for this variable.
   ///
   /// Variables must be defined in a local scope.
-  MDLocalScope *getScope() const {
-    return cast<MDLocalScope>(MDVariable::getScope());
+  DILocalScope *getScope() const {
+    return cast<DILocalScope>(DIVariable::getScope());
   }
 
   }
 
+  bool isParameter() const { return Arg; }
   unsigned getArg() const { return Arg; }
   unsigned getFlags() const { return Flags; }
   unsigned getArg() const { return Arg; }
   unsigned getFlags() const { return Flags; }
-  MDLocation *getInlinedAt() const {
-    return cast_or_null<MDLocation>(getRawInlinedAt());
-  }
-
-  Metadata *getRawInlinedAt() const { return getOperand(4); }
 
   bool isArtificial() const { return getFlags() & FlagArtificial; }
   bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
 
   /// \brief Check that a location is valid for this variable.
   ///
 
   bool isArtificial() const { return getFlags() & FlagArtificial; }
   bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
 
   /// \brief Check that a location is valid for this variable.
   ///
-  /// Check that \c DL has the same inlined-at location as this variable,
-  /// making them valid for the same \a DbgInfoIntrinsic.
-  bool isValidLocationForIntrinsic(const MDLocation *DL) const {
-    return getInlinedAt() == (DL ? DL->getInlinedAt() : nullptr);
+  /// Check that \c DL exists, is in the same subprogram, and has the same
+  /// inlined-at location as \c this.  (Otherwise, it's not a valid attachment
+  /// to a \a DbgInfoIntrinsic.)
+  bool isValidLocationForIntrinsic(const DILocation *DL) const {
+    return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
   }
 
   }
 
-  /// \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) {
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDLocalVariableKind;
+    return MD->getMetadataID() == DILocalVariableKind;
   }
 };
 
   }
 };
 
@@ -1943,29 +1923,29 @@ public:
 /// TODO: Co-allocate the expression elements.
 /// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
 /// storage types.
 /// TODO: Co-allocate the expression elements.
 /// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
 /// storage types.
-class MDExpression : public MDNode {
+class DIExpression : public MDNode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   std::vector<uint64_t> Elements;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   std::vector<uint64_t> Elements;
 
-  MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
-      : MDNode(C, MDExpressionKind, Storage, None),
+  DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
+      : MDNode(C, DIExpressionKind, Storage, None),
         Elements(Elements.begin(), Elements.end()) {}
         Elements(Elements.begin(), Elements.end()) {}
-  ~MDExpression() = default;
+  ~DIExpression() = default;
 
 
-  static MDExpression *getImpl(LLVMContext &Context,
+  static DIExpression *getImpl(LLVMContext &Context,
                                ArrayRef<uint64_t> Elements, StorageType Storage,
                                bool ShouldCreate = true);
 
                                ArrayRef<uint64_t> Elements, StorageType Storage,
                                bool ShouldCreate = true);
 
-  TempMDExpression cloneImpl() const {
+  TempDIExpression cloneImpl() const {
     return getTemporary(getContext(), getElements());
   }
 
 public:
     return getTemporary(getContext(), getElements());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDExpression, (ArrayRef<uint64_t> Elements), (Elements))
+  DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
 
 
-  TempMDExpression clone() const { return cloneImpl(); }
+  TempDIExpression clone() const { return cloneImpl(); }
 
   ArrayRef<uint64_t> getElements() const { return Elements; }
 
 
   ArrayRef<uint64_t> getElements() const { return Elements; }
 
@@ -1990,7 +1970,7 @@ public:
 
   /// \brief A lightweight wrapper around an expression operand.
   ///
 
   /// \brief A lightweight wrapper around an expression operand.
   ///
-  /// TODO: Store arguments directly and change \a MDExpression to store a
+  /// TODO: Store arguments directly and change \a DIExpression to store a
   /// range of these.
   class ExprOperand {
     const uint64_t *Op;
   /// range of these.
   class ExprOperand {
     const uint64_t *Op;
@@ -2075,73 +2055,68 @@ public:
   bool isValid() const;
 
   static bool classof(const Metadata *MD) {
   bool isValid() const;
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDExpressionKind;
+    return MD->getMetadataID() == DIExpressionKind;
   }
 };
 
   }
 };
 
-class MDObjCProperty : public DebugNode {
+class DIObjCProperty : public DINode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
   unsigned Attributes;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
   unsigned Attributes;
 
-  MDObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
+  DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
                  unsigned Attributes, ArrayRef<Metadata *> Ops)
                  unsigned Attributes, ArrayRef<Metadata *> Ops)
-      : DebugNode(C, MDObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
-                  Ops),
+      : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
+               Ops),
         Line(Line), Attributes(Attributes) {}
         Line(Line), Attributes(Attributes) {}
-  ~MDObjCProperty() = default;
+  ~DIObjCProperty() = default;
 
 
-  static MDObjCProperty *
-  getImpl(LLVMContext &Context, StringRef Name, MDFile *File, unsigned Line,
+  static DIObjCProperty *
+  getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
           StringRef GetterName, StringRef SetterName, unsigned Attributes,
           StringRef GetterName, StringRef SetterName, unsigned Attributes,
-          MDType *Type, StorageType Storage, bool ShouldCreate = true) {
+          DITypeRef Type, StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
                    getCanonicalMDString(Context, GetterName),
                    getCanonicalMDString(Context, SetterName), Attributes, Type,
                    Storage, ShouldCreate);
   }
     return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
                    getCanonicalMDString(Context, GetterName),
                    getCanonicalMDString(Context, SetterName), Attributes, Type,
                    Storage, ShouldCreate);
   }
-  static MDObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
+  static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
                                  Metadata *File, unsigned Line,
                                  MDString *GetterName, MDString *SetterName,
                                  unsigned Attributes, Metadata *Type,
                                  StorageType Storage, bool ShouldCreate = true);
 
                                  Metadata *File, unsigned Line,
                                  MDString *GetterName, MDString *SetterName,
                                  unsigned Attributes, Metadata *Type,
                                  StorageType Storage, bool ShouldCreate = true);
 
-  TempMDObjCProperty cloneImpl() const {
+  TempDIObjCProperty cloneImpl() const {
     return getTemporary(getContext(), getName(), getFile(), getLine(),
                         getGetterName(), getSetterName(), getAttributes(),
                         getType());
   }
 
 public:
     return getTemporary(getContext(), getName(), getFile(), getLine(),
                         getGetterName(), getSetterName(), getAttributes(),
                         getType());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDObjCProperty,
-                    (StringRef Name, MDFile *File, unsigned Line,
+  DEFINE_MDNODE_GET(DIObjCProperty,
+                    (StringRef Name, DIFile *File, unsigned Line,
                      StringRef GetterName, StringRef SetterName,
                      StringRef GetterName, StringRef SetterName,
-                     unsigned Attributes, MDType *Type),
+                     unsigned Attributes, DITypeRef Type),
                     (Name, File, Line, GetterName, SetterName, Attributes,
                      Type))
                     (Name, File, Line, GetterName, SetterName, Attributes,
                      Type))
-  DEFINE_MDNODE_GET(MDObjCProperty,
+  DEFINE_MDNODE_GET(DIObjCProperty,
                     (MDString * Name, Metadata *File, unsigned Line,
                      MDString *GetterName, MDString *SetterName,
                      unsigned Attributes, Metadata *Type),
                     (Name, File, Line, GetterName, SetterName, Attributes,
                      Type))
 
                     (MDString * Name, Metadata *File, unsigned Line,
                      MDString *GetterName, MDString *SetterName,
                      unsigned Attributes, Metadata *Type),
                     (Name, File, Line, GetterName, SetterName, Attributes,
                      Type))
 
-  TempMDObjCProperty clone() const { return cloneImpl(); }
+  TempDIObjCProperty clone() const { return cloneImpl(); }
 
   unsigned getLine() const { return Line; }
   unsigned getAttributes() const { return Attributes; }
   StringRef getName() const { return getStringOperand(0); }
 
   unsigned getLine() const { return Line; }
   unsigned getAttributes() const { return Attributes; }
   StringRef getName() const { return getStringOperand(0); }
-  MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
+  DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
   StringRef getGetterName() const { return getStringOperand(2); }
   StringRef getSetterName() const { return getStringOperand(3); }
   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<MDType>(getRawType()); }
+  DITypeRef getType() const { return DITypeRef(getRawType()); }
 
   StringRef getFilename() const {
     if (auto *F = getFile())
 
   StringRef getFilename() const {
     if (auto *F = getFile())
@@ -2161,56 +2136,56 @@ public:
   Metadata *getRawType() const { return getOperand(4); }
 
   static bool classof(const Metadata *MD) {
   Metadata *getRawType() const { return getOperand(4); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDObjCPropertyKind;
+    return MD->getMetadataID() == DIObjCPropertyKind;
   }
 };
 
 /// \brief An imported module (C++ using directive or similar).
   }
 };
 
 /// \brief An imported module (C++ using directive or similar).
-class MDImportedEntity : public DebugNode {
+class DIImportedEntity : public DINode {
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
 
   friend class LLVMContextImpl;
   friend class MDNode;
 
   unsigned Line;
 
-  MDImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
+  DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
                    unsigned Line, ArrayRef<Metadata *> Ops)
                    unsigned Line, ArrayRef<Metadata *> Ops)
-      : DebugNode(C, MDImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
-  ~MDImportedEntity() = default;
+      : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
+  ~DIImportedEntity() = default;
 
 
-  static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
-                                   MDScope *Scope, DebugNodeRef Entity,
+  static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
+                                   DIScope *Scope, DINodeRef Entity,
                                    unsigned Line, StringRef Name,
                                    StorageType Storage,
                                    bool ShouldCreate = true) {
     return getImpl(Context, Tag, Scope, Entity, Line,
                    getCanonicalMDString(Context, Name), Storage, ShouldCreate);
   }
                                    unsigned Line, StringRef Name,
                                    StorageType Storage,
                                    bool ShouldCreate = true) {
     return getImpl(Context, Tag, Scope, Entity, Line,
                    getCanonicalMDString(Context, Name), Storage, ShouldCreate);
   }
-  static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
+  static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
                                    Metadata *Scope, Metadata *Entity,
                                    unsigned Line, MDString *Name,
                                    StorageType Storage,
                                    bool ShouldCreate = true);
 
                                    Metadata *Scope, Metadata *Entity,
                                    unsigned Line, MDString *Name,
                                    StorageType Storage,
                                    bool ShouldCreate = true);
 
-  TempMDImportedEntity cloneImpl() const {
+  TempDIImportedEntity cloneImpl() const {
     return getTemporary(getContext(), getTag(), getScope(), getEntity(),
                         getLine(), getName());
   }
 
 public:
     return getTemporary(getContext(), getTag(), getScope(), getEntity(),
                         getLine(), getName());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDImportedEntity,
-                    (unsigned Tag, MDScope *Scope, DebugNodeRef Entity,
+  DEFINE_MDNODE_GET(DIImportedEntity,
+                    (unsigned Tag, DIScope *Scope, DINodeRef Entity,
                      unsigned Line, StringRef Name = ""),
                     (Tag, Scope, Entity, Line, Name))
                      unsigned Line, StringRef Name = ""),
                     (Tag, Scope, Entity, Line, Name))
-  DEFINE_MDNODE_GET(MDImportedEntity,
+  DEFINE_MDNODE_GET(DIImportedEntity,
                     (unsigned Tag, Metadata *Scope, Metadata *Entity,
                      unsigned Line, MDString *Name),
                     (Tag, Scope, Entity, Line, Name))
 
                     (unsigned Tag, Metadata *Scope, Metadata *Entity,
                      unsigned Line, MDString *Name),
                     (Tag, Scope, Entity, Line, Name))
 
-  TempMDImportedEntity clone() const { return cloneImpl(); }
+  TempDIImportedEntity clone() const { return cloneImpl(); }
 
   unsigned getLine() const { return Line; }
 
   unsigned getLine() const { return Line; }
-  MDScope *getScope() const { return cast_or_null<MDScope>(getRawScope()); }
-  DebugNodeRef getEntity() const { return DebugNodeRef(getRawEntity()); }
+  DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
+  DINodeRef getEntity() const { return DINodeRef(getRawEntity()); }
   StringRef getName() const { return getStringOperand(2); }
 
   Metadata *getRawScope() const { return getOperand(0); }
   StringRef getName() const { return getStringOperand(2); }
 
   Metadata *getRawScope() const { return getOperand(0); }
@@ -2218,7 +2193,7 @@ public:
   MDString *getRawName() const { return getOperandAs<MDString>(2); }
 
   static bool classof(const Metadata *MD) {
   MDString *getRawName() const { return getOperandAs<MDString>(2); }
 
   static bool classof(const Metadata *MD) {
-    return MD->getMetadataID() == MDImportedEntityKind;
+    return MD->getMetadataID() == DIImportedEntityKind;
   }
 };
 
   }
 };