[X86, AVX] replace vextractf128 intrinsics with generic shuffles
[oota-llvm.git] / include / llvm / IR / DebugInfoMetadata.h
index 34d03568eb009b0c10500bf0a68f002822f92a7e..c09b7d0477db539d5ead4e23de5a338b9e027b32 100644 (file)
@@ -63,7 +63,7 @@ class MDLocation : public MDNode {
   }
 
   // Disallow replacing operands.
-  void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
+  void replaceOperandWith(unsigned I, Metadata *New) = delete;
 
 public:
   DEFINE_MDNODE_GET(MDLocation,
@@ -309,6 +309,8 @@ public:
   int64_t getValue() const { return Value; }
   StringRef getName() const { return getStringOperand(0); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(0); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDEnumeratorKind;
   }
@@ -328,7 +330,16 @@ protected:
   ~MDScope() {}
 
 public:
-  Metadata *getFile() const { return getOperand(0); }
+  /// \brief Return the underlying file.
+  ///
+  /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file
+  /// (it\em is the file).  If \c this is an \a MDFile, we need to return \c
+  /// this.  Otherwise, return the first operand, which is where all other
+  /// subclasses store their file pointer.
+  Metadata *getFile() const {
+    return isa<MDFile>(this) ? const_cast<MDScope *>(this)
+                             : static_cast<Metadata *>(getOperand(0));
+  }
 
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
@@ -356,29 +367,41 @@ public:
 /// TODO: Split up flags.
 class MDType : public MDScope {
   unsigned Line;
-  unsigned SizeInBits;
-  unsigned AlignInBits;
-  unsigned OffsetInBits;
   unsigned Flags;
+  uint64_t SizeInBits;
+  uint64_t AlignInBits;
+  uint64_t OffsetInBits;
 
 protected:
   MDType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
-         unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
-         unsigned OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
-      : MDScope(C, ID, Storage, Tag, Ops), Line(Line), SizeInBits(SizeInBits),
-        AlignInBits(AlignInBits), OffsetInBits(OffsetInBits), Flags(Flags) {}
+         unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+         uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+      : MDScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags),
+        SizeInBits(SizeInBits), AlignInBits(AlignInBits),
+        OffsetInBits(OffsetInBits) {}
   ~MDType() {}
 
 public:
+  TempMDType clone() const {
+    return TempMDType(cast<MDType>(MDNode::clone().release()));
+  }
+
   unsigned getLine() const { return Line; }
-  unsigned getSizeInBits() const { return SizeInBits; }
-  unsigned getAlignInBits() const { return AlignInBits; }
-  unsigned getOffsetInBits() const { return OffsetInBits; }
+  uint64_t getSizeInBits() const { return SizeInBits; }
+  uint64_t getAlignInBits() const { return AlignInBits; }
+  uint64_t getOffsetInBits() const { return OffsetInBits; }
   unsigned getFlags() const { return Flags; }
 
   Metadata *getScope() const { return getOperand(1); }
   StringRef getName() const { return getStringOperand(2); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
+  void setFlags(unsigned NewFlags) {
+    assert(!isUniqued() && "Cannot set flags on uniqued nodes");
+    Flags = NewFlags;
+  }
+
   static bool classof(const Metadata *MD) {
     switch (MD->getMetadataID()) {
     default:
@@ -403,7 +426,7 @@ class MDBasicType : public MDType {
   unsigned Encoding;
 
   MDBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
-              unsigned SizeInBits, unsigned AlignInBits, unsigned Encoding,
+              uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding,
               ArrayRef<Metadata *> Ops)
       : MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
                0, Ops),
@@ -411,15 +434,15 @@ class MDBasicType : public MDType {
   ~MDBasicType() {}
 
   static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
-                              StringRef Name, unsigned SizeInBits,
-                              unsigned AlignInBits, unsigned Encoding,
+                              StringRef Name, uint64_t SizeInBits,
+                              uint64_t AlignInBits, unsigned Encoding,
                               StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
                    SizeInBits, AlignInBits, Encoding, Storage, ShouldCreate);
   }
   static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
-                              MDString *Name, unsigned SizeInBits,
-                              unsigned AlignInBits, unsigned Encoding,
+                              MDString *Name, uint64_t SizeInBits,
+                              uint64_t AlignInBits, unsigned Encoding,
                               StorageType Storage, bool ShouldCreate = true);
 
   TempMDBasicType cloneImpl() const {
@@ -428,13 +451,15 @@ class MDBasicType : public MDType {
   }
 
 public:
+  DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name),
+                    (Tag, Name, 0, 0, 0))
   DEFINE_MDNODE_GET(MDBasicType,
-                    (unsigned Tag, StringRef Name, unsigned SizeInBits,
-                     unsigned AlignInBits, unsigned Encoding),
+                    (unsigned Tag, StringRef Name, uint64_t SizeInBits,
+                     uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
   DEFINE_MDNODE_GET(MDBasicType,
-                    (unsigned Tag, MDString *Name, unsigned SizeInBits,
-                     unsigned AlignInBits, unsigned Encoding),
+                    (unsigned Tag, MDString *Name, uint64_t SizeInBits,
+                     uint64_t AlignInBits, unsigned Encoding),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding))
 
   TempMDBasicType clone() const { return cloneImpl(); }
@@ -452,8 +477,8 @@ public:
 class MDDerivedTypeBase : public MDType {
 protected:
   MDDerivedTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
-                    unsigned Tag, unsigned Line, unsigned SizeInBits,
-                    unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+                    unsigned Tag, unsigned Line, uint64_t SizeInBits,
+                    uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
                     ArrayRef<Metadata *> Ops)
       : MDType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
                Flags, Ops) {}
@@ -480,8 +505,8 @@ class MDDerivedType : public MDDerivedTypeBase {
   friend class MDNode;
 
   MDDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
-                unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
-                unsigned OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+                unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+                uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
       : MDDerivedTypeBase(C, MDDerivedTypeKind, Storage, Tag, Line, SizeInBits,
                           AlignInBits, OffsetInBits, Flags, Ops) {}
   ~MDDerivedType() {}
@@ -489,8 +514,8 @@ class MDDerivedType : public MDDerivedTypeBase {
   static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
                                 StringRef Name, Metadata *File, unsigned Line,
                                 Metadata *Scope, Metadata *BaseType,
-                                unsigned SizeInBits, unsigned AlignInBits,
-                                unsigned OffsetInBits, unsigned Flags,
+                                uint64_t SizeInBits, uint64_t AlignInBits,
+                                uint64_t OffsetInBits, unsigned Flags,
                                 Metadata *ExtraData, StorageType Storage,
                                 bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
@@ -500,8 +525,8 @@ class MDDerivedType : public MDDerivedTypeBase {
   static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
                                 MDString *Name, Metadata *File, unsigned Line,
                                 Metadata *Scope, Metadata *BaseType,
-                                unsigned SizeInBits, unsigned AlignInBits,
-                                unsigned OffsetInBits, unsigned Flags,
+                                uint64_t SizeInBits, uint64_t AlignInBits,
+                                uint64_t OffsetInBits, unsigned Flags,
                                 Metadata *ExtraData, StorageType Storage,
                                 bool ShouldCreate = true);
 
@@ -516,16 +541,16 @@ public:
   DEFINE_MDNODE_GET(MDDerivedType,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags,
                      Metadata *ExtraData = nullptr),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, ExtraData))
   DEFINE_MDNODE_GET(MDDerivedType,
                     (unsigned Tag, StringRef Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags,
                      Metadata *ExtraData = nullptr),
                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                      AlignInBits, OffsetInBits, Flags, ExtraData))
@@ -555,8 +580,8 @@ class MDCompositeTypeBase : public MDDerivedTypeBase {
 protected:
   MDCompositeTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
                       unsigned Tag, unsigned Line, unsigned RuntimeLang,
-                      unsigned SizeInBits, unsigned AlignInBits,
-                      unsigned OffsetInBits, unsigned Flags,
+                      uint64_t SizeInBits, uint64_t AlignInBits,
+                      uint64_t OffsetInBits, unsigned Flags,
                       ArrayRef<Metadata *> Ops)
       : MDDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits,
                           OffsetInBits, Flags, Ops),
@@ -572,6 +597,29 @@ public:
 
   MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
 
+  /// \brief Replace operands.
+  ///
+  /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
+  /// this will be RAUW'ed and deleted.  Use a \a TrackingMDRef to keep track
+  /// of its movement if necessary.
+  /// @{
+  void replaceElements(MDTuple *Elements) {
+#ifndef NDEBUG
+    if (auto *Old = cast_or_null<MDTuple>(getElements()))
+      for (const auto &Op : Old->operands())
+        assert(std::find(Elements->op_begin(), Elements->op_end(), Op) &&
+               "Lost a member during member list replacement");
+#endif
+    replaceOperandWith(4, Elements);
+  }
+  void replaceVTableHolder(Metadata *VTableHolder) {
+    replaceOperandWith(5, VTableHolder);
+  }
+  void replaceTemplateParams(MDTuple *TemplateParams) {
+    replaceOperandWith(6, TemplateParams);
+  }
+  /// @}
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDCompositeTypeKind ||
            MD->getMetadataID() == MDSubroutineTypeKind;
@@ -587,8 +635,8 @@ class MDCompositeType : public MDCompositeTypeBase {
   friend class MDNode;
 
   MDCompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
-                  unsigned Line, unsigned RuntimeLang, unsigned SizeInBits,
-                  unsigned AlignInBits, unsigned OffsetInBits, unsigned Flags,
+                  unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
+                  uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
                   ArrayRef<Metadata *> Ops)
       : MDCompositeTypeBase(C, MDCompositeTypeKind, Storage, Tag, Line,
                             RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
@@ -598,8 +646,8 @@ class MDCompositeType : public MDCompositeTypeBase {
   static MDCompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
           unsigned Line, Metadata *Scope, Metadata *BaseType,
-          unsigned SizeInBits, unsigned AlignInBits, unsigned OffsetInBits,
-          unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
+          uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
+          uint64_t Flags, Metadata *Elements, unsigned RuntimeLang,
           Metadata *VTableHolder, Metadata *TemplateParams,
           StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
@@ -611,7 +659,7 @@ class MDCompositeType : public MDCompositeTypeBase {
   static MDCompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
           unsigned Line, Metadata *Scope, Metadata *BaseType,
-          unsigned SizeInBits, unsigned AlignInBits, unsigned OffsetInBits,
+          uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
           unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
           Metadata *VTableHolder, Metadata *TemplateParams,
           MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
@@ -628,8 +676,8 @@ public:
   DEFINE_MDNODE_GET(MDCompositeType,
                     (unsigned Tag, StringRef Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags, Metadata *Elements,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags, Metadata *Elements,
                      unsigned RuntimeLang, Metadata *VTableHolder,
                      Metadata *TemplateParams = nullptr,
                      StringRef Identifier = ""),
@@ -639,8 +687,8 @@ public:
   DEFINE_MDNODE_GET(MDCompositeType,
                     (unsigned Tag, MDString *Name, Metadata *File,
                      unsigned Line, Metadata *Scope, Metadata *BaseType,
-                     unsigned SizeInBits, unsigned AlignInBits,
-                     unsigned OffsetInBits, unsigned Flags, Metadata *Elements,
+                     uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags, Metadata *Elements,
                      unsigned RuntimeLang, Metadata *VTableHolder,
                      Metadata *TemplateParams = nullptr,
                      MDString *Identifier = nullptr),
@@ -726,18 +774,11 @@ public:
 
   TempMDFile clone() const { return cloneImpl(); }
 
-  MDTuple *getFileNode() const { return cast<MDTuple>(getOperand(0)); }
+  StringRef getFilename() const { return getStringOperand(0); }
+  StringRef getDirectory() const { return getStringOperand(1); }
 
-  StringRef getFilename() const {
-    if (auto *S = cast_or_null<MDString>(getFileNode()->getOperand(0)))
-      return S->getString();
-    return StringRef();
-  }
-  StringRef getDirectory() const {
-    if (auto *S = cast_or_null<MDString>(getFileNode()->getOperand(1)))
-      return S->getString();
-    return StringRef();
-  }
+  MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
+  MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
 
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDFileKind;
@@ -833,6 +874,22 @@ public:
   Metadata *getGlobalVariables() const { return getOperand(7); }
   Metadata *getImportedEntities() const { return getOperand(8); }
 
+  MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
+  MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
+  MDString *getRawSplitDebugFilename() const {
+    return getOperandAs<MDString>(3);
+  }
+
+  /// \brief Replace arrays.
+  ///
+  /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
+  /// deleted on a uniquing collision.  In practice, uniquing collisions on \a
+  /// MDCompileUnit should be fairly rare.
+  /// @{
+  void replaceSubprograms(MDTuple *N) { replaceOperandWith(6, N); }
+  void replaceGlobalVariables(MDTuple *N) { replaceOperandWith(7, N); }
+  /// @}
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDCompileUnitKind;
   }
@@ -940,6 +997,9 @@ public:
   StringRef getDisplayName() const { return getStringOperand(3); }
   StringRef getLinkageName() const { return getStringOperand(4); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(2); }
+  MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
+
   Metadata *getType() const { return getOperand(5); }
   Metadata *getContainingType() const { return getOperand(6); }
 
@@ -948,6 +1008,17 @@ public:
   Metadata *getDeclaration() const { return getOperand(9); }
   Metadata *getVariables() const { return getOperand(10); }
 
+  /// \brief Replace the function.
+  ///
+  /// If \a isUniqued() and not \a isResolved(), this could node will be
+  /// RAUW'ed and deleted out from under the caller.  Use a \a TrackingMDRef if
+  /// that's a problem.
+  /// @{
+  void replaceFunction(Function *F);
+  void replaceFunction(ConstantAsMetadata *MD) { replaceOperandWith(7, MD); }
+  void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); }
+  /// @}
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDSubprogramKind;
   }
@@ -1084,17 +1155,14 @@ public:
   Metadata *getScope() const { return getOperand(1); }
   StringRef getName() const { return getStringOperand(2); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDNamespaceKind;
   }
 };
 
 /// \brief Base class for template parameters.
-///
-/// TODO: Remove the scope.  It's always the compile unit, and never
-/// referenced.
-/// TODO: Remove File, Line and Column.  They're always 0 and never
-/// referenced.
 class MDTemplateParameter : public DebugNode {
 protected:
   MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
@@ -1103,9 +1171,10 @@ protected:
   ~MDTemplateParameter() {}
 
 public:
-  Metadata *getScope() const { return getOperand(0); }
-  StringRef getName() const { return getStringOperand(1); }
-  Metadata *getType() const { return getOperand(2); }
+  StringRef getName() const { return getStringOperand(0); }
+  Metadata *getType() const { return getOperand(1); }
+
+  MDString *getRawName() const { return getOperandAs<MDString>(0); }
 
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDTemplateTypeParameterKind ||
@@ -1123,29 +1192,25 @@ class MDTemplateTypeParameter : public MDTemplateParameter {
                             dwarf::DW_TAG_template_type_parameter, Ops) {}
   ~MDTemplateTypeParameter() {}
 
-  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, Metadata *Scope,
-                                          StringRef Name, Metadata *Type,
-                                          StorageType Storage,
+  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
+                                          Metadata *Type, StorageType Storage,
                                           bool ShouldCreate = true) {
-    return getImpl(Context, Scope, getCanonicalMDString(Context, Name), Type,
-                   Storage, ShouldCreate);
+    return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
+                   ShouldCreate);
   }
-  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, Metadata *Scope,
-                                          MDString *Name, Metadata *Type,
-                                          StorageType Storage,
+  static MDTemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
+                                          Metadata *Type, StorageType Storage,
                                           bool ShouldCreate = true);
 
   TempMDTemplateTypeParameter cloneImpl() const {
-    return getTemporary(getContext(), getScope(), getName(), getType());
+    return getTemporary(getContext(), getName(), getType());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDTemplateTypeParameter,
-                    (Metadata * Scope, StringRef Name, Metadata *Type),
-                    (Scope, Name, Type))
-  DEFINE_MDNODE_GET(MDTemplateTypeParameter,
-                    (Metadata * Scope, MDString *Name, Metadata *Type),
-                    (Scope, Name, Type))
+  DEFINE_MDNODE_GET(MDTemplateTypeParameter, (StringRef Name, Metadata *Type),
+                    (Name, Type))
+  DEFINE_MDNODE_GET(MDTemplateTypeParameter, (MDString * Name, Metadata *Type),
+                    (Name, Type))
 
   TempMDTemplateTypeParameter clone() const { return cloneImpl(); }
 
@@ -1165,35 +1230,33 @@ class MDTemplateValueParameter : public MDTemplateParameter {
   ~MDTemplateValueParameter() {}
 
   static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
-                                           Metadata *Scope, StringRef Name,
-                                           Metadata *Type, Metadata *Value,
-                                           StorageType Storage,
+                                           StringRef Name, Metadata *Type,
+                                           Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true) {
-    return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name),
-                   Type, Value, Storage, ShouldCreate);
+    return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
+                   Value, Storage, ShouldCreate);
   }
   static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
-                                           Metadata *Scope, MDString *Name,
-                                           Metadata *Type, Metadata *Value,
-                                           StorageType Storage,
+                                           MDString *Name, Metadata *Type,
+                                           Metadata *Value, StorageType Storage,
                                            bool ShouldCreate = true);
 
   TempMDTemplateValueParameter cloneImpl() const {
-    return getTemporary(getContext(), getTag(), getScope(), getName(),
-                        getType(), getValue());
+    return getTemporary(getContext(), getTag(), getName(), getType(),
+                        getValue());
   }
 
 public:
-  DEFINE_MDNODE_GET(MDTemplateValueParameter,
-                    (unsigned Tag, Metadata *Scope, StringRef Name,
-                     Metadata *Type, Metadata *Value),
-                    (Tag, Scope, Name, Type, Value))
-  DEFINE_MDNODE_GET(MDTemplateValueParameter,
-                    (unsigned Tag, Metadata *Scope, MDString *Name,
-                     Metadata *Type, Metadata *Value),
-                    (Tag, Scope, Name, Type, Value))
+  DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, StringRef Name,
+                                               Metadata *Type, Metadata *Value),
+                    (Tag, Name, Type, Value))
+  DEFINE_MDNODE_GET(MDTemplateValueParameter, (unsigned Tag, MDString *Name,
+                                               Metadata *Type, Metadata *Value),
+                    (Tag, Name, Type, Value))
+
+  TempMDTemplateValueParameter clone() const { return cloneImpl(); }
 
-  Metadata *getValue() const { return getOperand(3); }
+  Metadata *getValue() const { return getOperand(2); }
 
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDTemplateValueParameterKind;
@@ -1219,6 +1282,8 @@ public:
   Metadata *getFile() const { return getOperand(2); }
   Metadata *getType() const { return getOperand(3); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(1); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDLocalVariableKind ||
            MD->getMetadataID() == MDGlobalVariableKind;
@@ -1284,6 +1349,8 @@ public:
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
 
+  TempMDGlobalVariable clone() const { return cloneImpl(); }
+
   bool isLocalToUnit() const { return IsLocalToUnit; }
   bool isDefinition() const { return IsDefinition; }
   StringRef getDisplayName() const { return getStringOperand(4); }
@@ -1291,6 +1358,8 @@ public:
   Metadata *getVariable() const { return getOperand(6); }
   Metadata *getStaticDataMemberDeclaration() const { return getOperand(7); }
 
+  MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDGlobalVariableKind;
   }
@@ -1352,10 +1421,24 @@ public:
                      Metadata *InlinedAt = nullptr),
                     (Tag, Scope, Name, File, Line, Type, Arg, Flags, InlinedAt))
 
+  TempMDLocalVariable clone() const { return cloneImpl(); }
+
   unsigned getArg() const { return Arg; }
   unsigned getFlags() const { return Flags; }
   Metadata *getInlinedAt() const { return getOperand(4); }
 
+  /// \brief Get an inlined version of this variable.
+  ///
+  /// Returns a version of this with \a getAlinedAt() set to \c InlinedAt.
+  MDLocalVariable *withInline(MDLocation *InlinedAt) const {
+    if (InlinedAt == getInlinedAt())
+      return const_cast<MDLocalVariable *>(this);
+    auto Temp = clone();
+    Temp->replaceOperandWith(4, InlinedAt);
+    return replaceWithUniqued(std::move(Temp));
+  }
+  MDLocalVariable *withoutInline() const { return withInline(nullptr); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDLocalVariableKind;
   }
@@ -1389,6 +1472,8 @@ class MDExpression : public DebugNode {
 public:
   DEFINE_MDNODE_GET(MDExpression, (ArrayRef<uint64_t> Elements), (Elements))
 
+  TempMDExpression clone() const { return cloneImpl(); }
+
   ArrayRef<uint64_t> getElements() const { return Elements; }
 
   unsigned getNumElements() const { return Elements.size(); }
@@ -1401,6 +1486,85 @@ public:
   element_iterator elements_begin() const { return getElements().begin(); }
   element_iterator elements_end() const { return getElements().end(); }
 
+  /// \brief A lightweight wrapper around an expression operand.
+  ///
+  /// TODO: Store arguments directly and change \a MDExpression to store a
+  /// range of these.
+  class ExprOperand {
+    const uint64_t *Op;
+
+  public:
+    explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
+
+    const uint64_t *get() const { return Op; }
+
+    /// \brief Get the operand code.
+    uint64_t getOp() const { return *Op; }
+
+    /// \brief Get an argument to the operand.
+    ///
+    /// Never returns the operand itself.
+    uint64_t getArg(unsigned I) const { return Op[I + 1]; }
+
+    unsigned getNumArgs() const { return getSize() - 1; }
+
+    /// \brief Return the size of the operand.
+    ///
+    /// Return the number of elements in the operand (1 + args).
+    unsigned getSize() const;
+  };
+
+  /// \brief An iterator for expression operands.
+  class expr_op_iterator
+      : public std::iterator<std::input_iterator_tag, ExprOperand> {
+    ExprOperand Op;
+
+  public:
+    explicit expr_op_iterator(element_iterator I) : Op(I) {}
+
+    element_iterator getBase() const { return Op.get(); }
+    const ExprOperand &operator*() const { return Op; }
+    const ExprOperand *operator->() const { return &Op; }
+
+    expr_op_iterator &operator++() {
+      increment();
+      return *this;
+    }
+    expr_op_iterator operator++(int) {
+      expr_op_iterator T(*this);
+      increment();
+      return T;
+    }
+
+    bool operator==(const expr_op_iterator &X) const {
+      return getBase() == X.getBase();
+    }
+    bool operator!=(const expr_op_iterator &X) const {
+      return getBase() != X.getBase();
+    }
+
+  private:
+    void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
+  };
+
+  /// \brief Visit the elements via ExprOperand wrappers.
+  ///
+  /// These range iterators visit elements through \a ExprOperand wrappers.
+  /// This is not guaranteed to be a valid range unless \a isValid() gives \c
+  /// true.
+  ///
+  /// \pre \a isValid() gives \c true.
+  /// @{
+  expr_op_iterator expr_op_begin() const {
+    return expr_op_iterator(elements_begin());
+  }
+  expr_op_iterator expr_op_end() const {
+    return expr_op_iterator(elements_end());
+  }
+  /// @}
+
+  bool isValid() const;
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDExpressionKind;
   }
@@ -1455,6 +1619,8 @@ public:
                     (Name, File, Line, GetterName, SetterName, Attributes,
                      Type))
 
+  TempMDObjCProperty clone() const { return cloneImpl(); }
+
   unsigned getLine() const { return Line; }
   unsigned getAttributes() const { return Attributes; }
   StringRef getName() const { return getStringOperand(0); }
@@ -1463,6 +1629,10 @@ public:
   StringRef getSetterName() const { return getStringOperand(3); }
   Metadata *getType() const { return getOperand(4); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(0); }
+  MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
+  MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDObjCPropertyKind;
   }
@@ -1515,6 +1685,8 @@ public:
   Metadata *getEntity() const { return getOperand(1); }
   StringRef getName() const { return getStringOperand(2); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDImportedEntityKind;
   }