DebugInfo: Add MDLexicalBlockBase::getLine(), etc.
[oota-llvm.git] / include / llvm / IR / DebugInfoMetadata.h
index 18619f374208f11bf70aa36ef4c9f8af9fd7b30c..e16e4319aa94ec49a208ea3172e39ef7faa6567c 100644 (file)
@@ -50,6 +50,7 @@ template <class T> class TypedDebugNodeRef {
   const Metadata *MD = nullptr;
 
 public:
   const Metadata *MD = nullptr;
 
 public:
+  TypedDebugNodeRef() = default;
   TypedDebugNodeRef(std::nullptr_t) {}
 
   /// \brief Construct from a raw pointer.
   TypedDebugNodeRef(std::nullptr_t) {}
 
   /// \brief Construct from a raw pointer.
@@ -151,7 +152,7 @@ protected:
     assert(Tag < 1u << 16);
     SubclassData16 = Tag;
   }
     assert(Tag < 1u << 16);
     SubclassData16 = Tag;
   }
-  ~DebugNode() {}
+  ~DebugNode() = 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));
@@ -327,7 +328,7 @@ class MDSubrange : public DebugNode {
       : DebugNode(C, MDSubrangeKind, Storage, dwarf::DW_TAG_subrange_type,
                   None),
         Count(Count), LowerBound(LowerBound) {}
       : DebugNode(C, MDSubrangeKind, Storage, dwarf::DW_TAG_subrange_type,
                   None),
         Count(Count), LowerBound(LowerBound) {}
-  ~MDSubrange() {}
+  ~MDSubrange() = default;
 
   static MDSubrange *getImpl(LLVMContext &Context, int64_t Count,
                              int64_t LowerBound, StorageType Storage,
 
   static MDSubrange *getImpl(LLVMContext &Context, int64_t Count,
                              int64_t LowerBound, StorageType Storage,
@@ -365,7 +366,7 @@ class MDEnumerator : public DebugNode {
                ArrayRef<Metadata *> Ops)
       : DebugNode(C, MDEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
         Value(Value) {}
                ArrayRef<Metadata *> Ops)
       : DebugNode(C, MDEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
         Value(Value) {}
-  ~MDEnumerator() {}
+  ~MDEnumerator() = default;
 
   static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value,
                                StringRef Name, StorageType Storage,
 
   static MDEnumerator *getImpl(LLVMContext &Context, int64_t Value,
                                StringRef Name, StorageType Storage,
@@ -410,11 +411,17 @@ protected:
   MDScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
           ArrayRef<Metadata *> Ops)
       : DebugNode(C, ID, Storage, Tag, Ops) {}
   MDScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
           ArrayRef<Metadata *> Ops)
       : DebugNode(C, ID, Storage, Tag, Ops) {}
-  ~MDScope() {}
+  ~MDScope() = default;
 
 public:
   MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
 
 
 public:
   MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
 
+  inline StringRef getFilename() const;
+  inline StringRef getDirectory() const;
+
+  StringRef getName() const;
+  MDScopeRef getScope() const;
+
   /// \brief Return the raw underlying file.
   ///
   /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file
   /// \brief Return the raw underlying file.
   ///
   /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file
@@ -457,7 +464,7 @@ class MDFile : public MDScope {
 
   MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
       : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
 
   MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
       : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
-  ~MDFile() {}
+  ~MDFile() = default;
 
   static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
                          StringRef Directory, StorageType Storage,
 
   static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
                          StringRef Directory, StorageType Storage,
@@ -493,6 +500,18 @@ public:
   }
 };
 
   }
 };
 
+StringRef MDScope::getFilename() const {
+  if (auto *F = getFile())
+    return F->getFilename();
+  return "";
+}
+
+StringRef MDScope::getDirectory() const {
+  if (auto *F = getFile())
+    return F->getDirectory();
+  return "";
+}
+
 /// \brief Base class for types.
 ///
 /// TODO: Remove the hardcoded name and context, since many types don't use
 /// \brief Base class for types.
 ///
 /// TODO: Remove the hardcoded name and context, since many types don't use
@@ -512,7 +531,7 @@ protected:
       : MDScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags),
         SizeInBits(SizeInBits), AlignInBits(AlignInBits),
         OffsetInBits(OffsetInBits) {}
       : MDScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags),
         SizeInBits(SizeInBits), AlignInBits(AlignInBits),
         OffsetInBits(OffsetInBits) {}
-  ~MDType() {}
+  ~MDType() = default;
 
 public:
   TempMDType clone() const {
 
 public:
   TempMDType clone() const {
@@ -591,7 +610,7 @@ class MDBasicType : public MDType {
       : MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
                0, Ops),
         Encoding(Encoding) {}
       : MDType(C, MDBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
                0, Ops),
         Encoding(Encoding) {}
-  ~MDBasicType() {}
+  ~MDBasicType() = default;
 
   static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
                               StringRef Name, uint64_t SizeInBits,
 
   static MDBasicType *getImpl(LLVMContext &Context, unsigned Tag,
                               StringRef Name, uint64_t SizeInBits,
@@ -642,7 +661,7 @@ protected:
                     ArrayRef<Metadata *> Ops)
       : MDType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
                Flags, Ops) {}
                     ArrayRef<Metadata *> Ops)
       : MDType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
                Flags, Ops) {}
-  ~MDDerivedTypeBase() {}
+  ~MDDerivedTypeBase() = default;
 
 public:
   MDTypeRef getBaseType() const { return MDTypeRef(getRawBaseType()); }
 
 public:
   MDTypeRef getBaseType() const { return MDTypeRef(getRawBaseType()); }
@@ -670,7 +689,7 @@ class MDDerivedType : public MDDerivedTypeBase {
                 uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
       : MDDerivedTypeBase(C, MDDerivedTypeKind, Storage, Tag, Line, SizeInBits,
                           AlignInBits, OffsetInBits, Flags, Ops) {}
                 uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
       : MDDerivedTypeBase(C, MDDerivedTypeKind, Storage, Tag, Line, SizeInBits,
                           AlignInBits, OffsetInBits, Flags, Ops) {}
-  ~MDDerivedType() {}
+  ~MDDerivedType() = default;
 
   static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
                                 StringRef Name, MDFile *File, unsigned Line,
 
   static MDDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
                                 StringRef Name, MDFile *File, unsigned Line,
@@ -727,6 +746,23 @@ public:
   Metadata *getExtraData() const { return getRawExtraData(); }
   Metadata *getRawExtraData() const { return getOperand(4); }
 
   Metadata *getExtraData() const { return getRawExtraData(); }
   Metadata *getRawExtraData() const { return getOperand(4); }
 
+  /// \brief Get casted version of extra data.
+  /// @{
+  MDTypeRef getClassType() const {
+    assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
+    return MDTypeRef(getExtraData());
+  }
+  MDObjCProperty *getObjCProperty() const {
+    return dyn_cast_or_null<MDObjCProperty>(getExtraData());
+  }
+  Constant *getConstant() const {
+    assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
+    if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
+      return C->getValue();
+    return nullptr;
+  }
+  /// @}
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDDerivedTypeKind;
   }
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDDerivedTypeKind;
   }
@@ -747,10 +783,16 @@ protected:
       : MDDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits,
                           OffsetInBits, Flags, Ops),
         RuntimeLang(RuntimeLang) {}
       : MDDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits,
                           OffsetInBits, Flags, Ops),
         RuntimeLang(RuntimeLang) {}
-  ~MDCompositeTypeBase() {}
+  ~MDCompositeTypeBase() = default;
 
 public:
 
 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 {
   DebugNodeArray getElements() const {
+    assert(!isa<MDSubroutineType>(this) && "no elements for DISubroutineType");
     return cast_or_null<MDTuple>(getRawElements());
   }
   MDTypeRef getVTableHolder() const { return MDTypeRef(getRawVTableHolder()); }
     return cast_or_null<MDTuple>(getRawElements());
   }
   MDTypeRef getVTableHolder() const { return MDTypeRef(getRawVTableHolder()); }
@@ -808,7 +850,7 @@ class MDCompositeType : public MDCompositeTypeBase {
       : MDCompositeTypeBase(C, MDCompositeTypeKind, Storage, Tag, Line,
                             RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
                             Flags, Ops) {}
       : MDCompositeTypeBase(C, MDCompositeTypeKind, Storage, Tag, Line,
                             RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
                             Flags, Ops) {}
-  ~MDCompositeType() {}
+  ~MDCompositeType() = default;
 
   static MDCompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
 
   static MDCompositeType *
   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
@@ -891,7 +933,7 @@ class MDSubroutineType : public MDCompositeTypeBase {
       : MDCompositeTypeBase(C, MDSubroutineTypeKind, Storage,
                             dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags,
                             Ops) {}
       : MDCompositeTypeBase(C, MDSubroutineTypeKind, Storage,
                             dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags,
                             Ops) {}
-  ~MDSubroutineType() {}
+  ~MDSubroutineType() = default;
 
   static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
                                    MDTypeRefArray TypeArray,
 
   static MDSubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
                                    MDTypeRefArray TypeArray,
@@ -942,7 +984,7 @@ class MDCompileUnit : public MDScope {
       : MDScope(C, MDCompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
         SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
         RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind) {}
       : MDScope(C, MDCompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
         SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
         RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind) {}
-  ~MDCompileUnit() {}
+  ~MDCompileUnit() = default;
 
   static MDCompileUnit *
   getImpl(LLVMContext &Context, unsigned SourceLanguage, MDFile *File,
 
   static MDCompileUnit *
   getImpl(LLVMContext &Context, unsigned SourceLanguage, MDFile *File,
@@ -1067,7 +1109,7 @@ protected:
   MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
                ArrayRef<Metadata *> Ops)
       : MDScope(C, ID, Storage, Tag, Ops) {}
   MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
                ArrayRef<Metadata *> Ops)
       : MDScope(C, ID, Storage, Tag, Ops) {}
-  ~MDLocalScope() {}
+  ~MDLocalScope() = default;
 
 public:
   /// \brief Get the subprogram for this scope.
 
 public:
   /// \brief Get the subprogram for this scope.
@@ -1136,6 +1178,10 @@ public:
     return cast_or_null<MDLocation>(getRawInlinedAt());
   }
 
     return cast_or_null<MDLocation>(getRawInlinedAt());
   }
 
+  MDFile *getFile() const { return getScope()->getFile(); }
+  StringRef getFilename() const { return getScope()->getFilename(); }
+  StringRef getDirectory() const { return getScope()->getDirectory(); }
+
   /// \brief Get the scope where this is inlined.
   ///
   /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
   /// \brief Get the scope where this is inlined.
   ///
   /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
@@ -1146,6 +1192,38 @@ public:
     return getScope();
   }
 
     return getScope();
   }
 
+  /// \brief Check whether this can be discriminated from another location.
+  ///
+  /// Check \c this can be discriminated from \c RHS in a linetable entry.
+  /// Scope and inlined-at chains are not recorded in the linetable, so they
+  /// cannot be used to distinguish basic blocks.
+  ///
+  /// The current implementation is weaker than it should be, since it just
+  /// checks filename and line.
+  ///
+  /// FIXME: Add a check for getDiscriminator().
+  /// FIXME: Add a check for getColumn().
+  /// FIXME: Change the getFilename() check to getFile() (or add one for
+  /// getDirectory()).
+  bool canDiscriminate(const MDLocation &RHS) const {
+    return getFilename() != RHS.getFilename() || getLine() != RHS.getLine();
+  }
+
+  /// \brief Get the DWARF discriminator.
+  ///
+  /// DWARF discriminators distinguish identical file locations between
+  /// instructions that are on different basic blocks.
+  inline unsigned getDiscriminator() const;
+
+  /// \brief Compute new discriminator in the given context.
+  ///
+  /// This modifies the \a LLVMContext that \c this is in to increment the next
+  /// discriminator for \c this's line/filename combination.
+  ///
+  /// FIXME: Delete this.  See comments in implementation and at the only call
+  /// site in \a AddDiscriminators::runOnFunction().
+  unsigned computeNewDiscriminator() const;
+
   Metadata *getRawScope() const { return getOperand(0); }
   Metadata *getRawInlinedAt() const {
     if (getNumOperands() == 2)
   Metadata *getRawScope() const { return getOperand(0); }
   Metadata *getRawInlinedAt() const {
     if (getNumOperands() == 2)
@@ -1184,7 +1262,7 @@ class MDSubprogram : public MDLocalScope {
         Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
         VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
         IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
         Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
         VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
         IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
-  ~MDSubprogram() {}
+  ~MDSubprogram() = default;
 
   static MDSubprogram *
   getImpl(LLVMContext &Context, MDScopeRef Scope, StringRef Name,
 
   static MDSubprogram *
   getImpl(LLVMContext &Context, MDScopeRef Scope, StringRef Name,
@@ -1192,13 +1270,14 @@ class MDSubprogram : public MDLocalScope {
           MDSubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
           unsigned ScopeLine, MDTypeRef ContainingType, unsigned Virtuality,
           unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
           MDSubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
           unsigned ScopeLine, MDTypeRef ContainingType, unsigned Virtuality,
           unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
-          ConstantAsMetadata *Function, MDTemplateParameterArray TemplateParams,
+          Constant *Function, MDTemplateParameterArray TemplateParams,
           MDSubprogram *Declaration, MDLocalVariableArray Variables,
           StorageType Storage, bool ShouldCreate = true) {
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
                    IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
           MDSubprogram *Declaration, MDLocalVariableArray 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, Function,
+                   Virtuality, VirtualIndex, Flags, IsOptimized,
+                   Function ? ConstantAsMetadata::get(Function) : nullptr,
                    TemplateParams.get(), Declaration, Variables.get(), Storage,
                    ShouldCreate);
   }
                    TemplateParams.get(), Declaration, Variables.get(), Storage,
                    ShouldCreate);
   }
@@ -1216,8 +1295,8 @@ class MDSubprogram : public MDLocalScope {
                         getFile(), getLine(), getType(), isLocalToUnit(),
                         isDefinition(), getScopeLine(), getContainingType(),
                         getVirtuality(), getVirtualIndex(), getFlags(),
                         getFile(), getLine(), getType(), isLocalToUnit(),
                         isDefinition(), getScopeLine(), getContainingType(),
                         getVirtuality(), getVirtualIndex(), getFlags(),
-                        isOptimized(), getFunction(), getTemplateParams(),
-                        getDeclaration(), getVariables());
+                        isOptimized(), getFunctionConstant(),
+                        getTemplateParams(), getDeclaration(), getVariables());
   }
 
 public:
   }
 
 public:
@@ -1227,7 +1306,7 @@ public:
                      bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
                      MDTypeRef ContainingType, unsigned Virtuality,
                      unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
                      bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
                      MDTypeRef ContainingType, unsigned Virtuality,
                      unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
-                     ConstantAsMetadata *Function = nullptr,
+                     Constant *Function = nullptr,
                      MDTemplateParameterArray TemplateParams = nullptr,
                      MDSubprogram *Declaration = nullptr,
                      MDLocalVariableArray Variables = nullptr),
                      MDTemplateParameterArray TemplateParams = nullptr,
                      MDSubprogram *Declaration = nullptr,
                      MDLocalVariableArray Variables = nullptr),
@@ -1304,8 +1383,10 @@ public:
     return MDTypeRef(getRawContainingType());
   }
 
     return MDTypeRef(getRawContainingType());
   }
 
-  ConstantAsMetadata *getFunction() const {
-    return cast_or_null<ConstantAsMetadata>(getRawFunction());
+  Constant *getFunctionConstant() const {
+    if (auto *C = cast_or_null<ConstantAsMetadata>(getRawFunction()))
+      return C->getValue();
+    return nullptr;
   }
   MDTemplateParameterArray getTemplateParams() const {
     return cast_or_null<MDTuple>(getRawTemplateParams());
   }
   MDTemplateParameterArray getTemplateParams() const {
     return cast_or_null<MDTuple>(getRawTemplateParams());
@@ -1325,6 +1406,13 @@ public:
   Metadata *getRawDeclaration() const { return getOperand(9); }
   Metadata *getRawVariables() const { return getOperand(10); }
 
   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
   /// \brief Replace the function.
   ///
   /// If \a isUniqued() and not \a isResolved(), this could node will be
@@ -1336,6 +1424,11 @@ public:
   void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); }
   /// @}
 
   void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); }
   /// @}
 
+  /// \brief Check if this subprogram decribes the given function.
+  ///
+  /// FIXME: Should this be looking through bitcasts?
+  bool describes(const Function *F) const;
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDSubprogramKind;
   }
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDSubprogramKind;
   }
@@ -1346,13 +1439,20 @@ protected:
   MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
                      ArrayRef<Metadata *> Ops)
       : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
   MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
                      ArrayRef<Metadata *> Ops)
       : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
-  ~MDLexicalBlockBase() {}
+  ~MDLexicalBlockBase() = default;
 
 public:
   MDLocalScope *getScope() const { return cast<MDLocalScope>(getRawScope()); }
 
   Metadata *getRawScope() const { return getOperand(1); }
 
 
 public:
   MDLocalScope *getScope() const { return cast<MDLocalScope>(getRawScope()); }
 
   Metadata *getRawScope() const { return getOperand(1); }
 
+  /// \brief Forwarding accessors to LexicalBlock.
+  ///
+  /// TODO: Remove these and update code to use \a MDLexicalBlock directly.
+  /// @{
+  inline unsigned getLine() const;
+  inline unsigned getColumn() const;
+  /// @}
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDLexicalBlockKind ||
            MD->getMetadataID() == MDLexicalBlockFileKind;
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDLexicalBlockKind ||
            MD->getMetadataID() == MDLexicalBlockFileKind;
@@ -1370,7 +1470,7 @@ class MDLexicalBlock : public MDLexicalBlockBase {
                  unsigned Column, ArrayRef<Metadata *> Ops)
       : MDLexicalBlockBase(C, MDLexicalBlockKind, Storage, Ops), Line(Line),
         Column(Column) {}
                  unsigned Column, ArrayRef<Metadata *> Ops)
       : MDLexicalBlockBase(C, MDLexicalBlockKind, Storage, Ops), Line(Line),
         Column(Column) {}
-  ~MDLexicalBlock() {}
+  ~MDLexicalBlock() = default;
 
   static MDLexicalBlock *getImpl(LLVMContext &Context, MDLocalScope *Scope,
                                  MDFile *File, unsigned Line, unsigned Column,
 
   static MDLexicalBlock *getImpl(LLVMContext &Context, MDLocalScope *Scope,
                                  MDFile *File, unsigned Line, unsigned Column,
@@ -1408,6 +1508,18 @@ public:
   }
 };
 
   }
 };
 
+unsigned MDLexicalBlockBase::getLine() const {
+  if (auto *N = dyn_cast<MDLexicalBlock>(this))
+    return N->getLine();
+  return 0;
+}
+
+unsigned MDLexicalBlockBase::getColumn() const {
+  if (auto *N = dyn_cast<MDLexicalBlock>(this))
+    return N->getColumn();
+  return 0;
+}
+
 class MDLexicalBlockFile : public MDLexicalBlockBase {
   friend class LLVMContextImpl;
   friend class MDNode;
 class MDLexicalBlockFile : public MDLexicalBlockBase {
   friend class LLVMContextImpl;
   friend class MDNode;
@@ -1418,7 +1530,7 @@ class MDLexicalBlockFile : public MDLexicalBlockBase {
                      unsigned Discriminator, ArrayRef<Metadata *> Ops)
       : MDLexicalBlockBase(C, MDLexicalBlockFileKind, Storage, Ops),
         Discriminator(Discriminator) {}
                      unsigned Discriminator, ArrayRef<Metadata *> Ops)
       : MDLexicalBlockBase(C, MDLexicalBlockFileKind, Storage, Ops),
         Discriminator(Discriminator) {}
-  ~MDLexicalBlockFile() {}
+  ~MDLexicalBlockFile() = default;
 
   static MDLexicalBlockFile *getImpl(LLVMContext &Context, MDLocalScope *Scope,
                                      MDFile *File, unsigned Discriminator,
 
   static MDLexicalBlockFile *getImpl(LLVMContext &Context, MDLocalScope *Scope,
                                      MDFile *File, unsigned Discriminator,
@@ -1449,6 +1561,10 @@ public:
 
   TempMDLexicalBlockFile clone() const { return cloneImpl(); }
 
 
   TempMDLexicalBlockFile clone() const { return cloneImpl(); }
 
+  // TODO: Remove these once they're gone from MDLexicalBlockBase.
+  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) {
@@ -1456,6 +1572,12 @@ public:
   }
 };
 
   }
 };
 
+unsigned MDLocation::getDiscriminator() const {
+  if (auto *F = dyn_cast<MDLexicalBlockFile>(getScope()))
+    return F->getDiscriminator();
+  return 0;
+}
+
 class MDNamespace : public MDScope {
   friend class LLVMContextImpl;
   friend class MDNode;
 class MDNamespace : public MDScope {
   friend class LLVMContextImpl;
   friend class MDNode;
@@ -1467,7 +1589,7 @@ class MDNamespace : public MDScope {
       : MDScope(Context, MDNamespaceKind, Storage, dwarf::DW_TAG_namespace,
                 Ops),
         Line(Line) {}
       : MDScope(Context, MDNamespaceKind, Storage, dwarf::DW_TAG_namespace,
                 Ops),
         Line(Line) {}
-  ~MDNamespace() {}
+  ~MDNamespace() = default;
 
   static MDNamespace *getImpl(LLVMContext &Context, MDScope *Scope,
                               MDFile *File, StringRef Name, unsigned Line,
 
   static MDNamespace *getImpl(LLVMContext &Context, MDScope *Scope,
                               MDFile *File, StringRef Name, unsigned Line,
@@ -1512,7 +1634,7 @@ protected:
   MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
                       unsigned Tag, ArrayRef<Metadata *> Ops)
       : DebugNode(Context, ID, Storage, Tag, Ops) {}
   MDTemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
                       unsigned Tag, ArrayRef<Metadata *> Ops)
       : DebugNode(Context, ID, Storage, Tag, Ops) {}
-  ~MDTemplateParameter() {}
+  ~MDTemplateParameter() = default;
 
 public:
   StringRef getName() const { return getStringOperand(0); }
 
 public:
   StringRef getName() const { return getStringOperand(0); }
@@ -1535,7 +1657,7 @@ class MDTemplateTypeParameter : public MDTemplateParameter {
                           ArrayRef<Metadata *> Ops)
       : MDTemplateParameter(Context, MDTemplateTypeParameterKind, Storage,
                             dwarf::DW_TAG_template_type_parameter, Ops) {}
                           ArrayRef<Metadata *> Ops)
       : MDTemplateParameter(Context, MDTemplateTypeParameterKind, Storage,
                             dwarf::DW_TAG_template_type_parameter, Ops) {}
-  ~MDTemplateTypeParameter() {}
+  ~MDTemplateTypeParameter() = default;
 
   static MDTemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
                                           MDTypeRef Type, StorageType Storage,
 
   static MDTemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
                                           MDTypeRef Type, StorageType Storage,
@@ -1572,7 +1694,7 @@ class MDTemplateValueParameter : public MDTemplateParameter {
                            unsigned Tag, ArrayRef<Metadata *> Ops)
       : MDTemplateParameter(Context, MDTemplateValueParameterKind, Storage, Tag,
                             Ops) {}
                            unsigned Tag, ArrayRef<Metadata *> Ops)
       : MDTemplateParameter(Context, MDTemplateValueParameterKind, Storage, Tag,
                             Ops) {}
-  ~MDTemplateValueParameter() {}
+  ~MDTemplateValueParameter() = default;
 
   static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
                                            StringRef Name, MDTypeRef Type,
 
   static MDTemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
                                            StringRef Name, MDTypeRef Type,
@@ -1618,7 +1740,7 @@ protected:
   MDVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
              unsigned Line, ArrayRef<Metadata *> Ops)
       : DebugNode(C, ID, Storage, Tag, Ops), Line(Line) {}
   MDVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
              unsigned Line, ArrayRef<Metadata *> Ops)
       : DebugNode(C, ID, Storage, Tag, Ops), Line(Line) {}
-  ~MDVariable() {}
+  ~MDVariable() = default;
 
 public:
   unsigned getLine() const { return Line; }
 
 public:
   unsigned getLine() const { return Line; }
@@ -1627,6 +1749,17 @@ public:
   MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
   MDTypeRef getType() const { return MDTypeRef(getRawType()); }
 
   MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
   MDTypeRef getType() const { return MDTypeRef(getRawType()); }
 
+  StringRef getFilename() const {
+    if (auto *F = getFile())
+      return F->getFilename();
+    return "";
+  }
+  StringRef getDirectory() const {
+    if (auto *F = getFile())
+      return F->getDirectory();
+    return "";
+  }
+
   Metadata *getRawScope() const { return getOperand(0); }
   MDString *getRawName() const { return getOperandAs<MDString>(1); }
   Metadata *getRawFile() const { return getOperand(2); }
   Metadata *getRawScope() const { return getOperand(0); }
   MDString *getRawName() const { return getOperandAs<MDString>(1); }
   Metadata *getRawFile() const { return getOperand(2); }
@@ -1654,17 +1787,18 @@ class MDGlobalVariable : public MDVariable {
       : MDVariable(C, MDGlobalVariableKind, Storage, dwarf::DW_TAG_variable,
                    Line, Ops),
         IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
       : MDVariable(C, MDGlobalVariableKind, Storage, dwarf::DW_TAG_variable,
                    Line, Ops),
         IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
-  ~MDGlobalVariable() {}
+  ~MDGlobalVariable() = default;
 
   static MDGlobalVariable *
   getImpl(LLVMContext &Context, MDScope *Scope, StringRef Name,
           StringRef LinkageName, MDFile *File, unsigned Line, MDTypeRef Type,
 
   static MDGlobalVariable *
   getImpl(LLVMContext &Context, MDScope *Scope, StringRef Name,
           StringRef LinkageName, MDFile *File, unsigned Line, MDTypeRef Type,
-          bool IsLocalToUnit, bool IsDefinition, ConstantAsMetadata *Variable,
+          bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
           MDDerivedType *StaticDataMemberDeclaration, StorageType Storage,
           bool ShouldCreate = true) {
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
           MDDerivedType *StaticDataMemberDeclaration, StorageType Storage,
           bool ShouldCreate = true) {
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
-                   IsLocalToUnit, IsDefinition, Variable,
+                   IsLocalToUnit, IsDefinition,
+                   Variable ? ConstantAsMetadata::get(Variable) : nullptr,
                    StaticDataMemberDeclaration, Storage, ShouldCreate);
   }
   static MDGlobalVariable *
                    StaticDataMemberDeclaration, Storage, ShouldCreate);
   }
   static MDGlobalVariable *
@@ -1685,8 +1819,7 @@ public:
   DEFINE_MDNODE_GET(MDGlobalVariable,
                     (MDScope * Scope, StringRef Name, StringRef LinkageName,
                      MDFile *File, unsigned Line, MDTypeRef Type,
   DEFINE_MDNODE_GET(MDGlobalVariable,
                     (MDScope * Scope, StringRef Name, StringRef LinkageName,
                      MDFile *File, unsigned Line, MDTypeRef Type,
-                     bool IsLocalToUnit, bool IsDefinition,
-                     ConstantAsMetadata *Variable,
+                     bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
                      MDDerivedType *StaticDataMemberDeclaration),
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
                      MDDerivedType *StaticDataMemberDeclaration),
                     (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
                      IsDefinition, Variable, StaticDataMemberDeclaration))
@@ -1704,8 +1837,10 @@ public:
   bool isDefinition() const { return IsDefinition; }
   StringRef getDisplayName() const { return getStringOperand(4); }
   StringRef getLinkageName() const { return getStringOperand(5); }
   bool isDefinition() const { return IsDefinition; }
   StringRef getDisplayName() const { return getStringOperand(4); }
   StringRef getLinkageName() const { return getStringOperand(5); }
-  ConstantAsMetadata *getVariable() const {
-    return cast_or_null<ConstantAsMetadata>(getRawVariable());
+  Constant *getVariable() const {
+    if (auto *C = cast_or_null<ConstantAsMetadata>(getRawVariable()))
+      return dyn_cast<Constant>(C->getValue());
+    return nullptr;
   }
   MDDerivedType *getStaticDataMemberDeclaration() const {
     return cast_or_null<MDDerivedType>(getRawStaticDataMemberDeclaration());
   }
   MDDerivedType *getStaticDataMemberDeclaration() const {
     return cast_or_null<MDDerivedType>(getRawStaticDataMemberDeclaration());
@@ -1737,7 +1872,7 @@ class MDLocalVariable : public MDVariable {
                   ArrayRef<Metadata *> Ops)
       : MDVariable(C, MDLocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg),
         Flags(Flags) {}
                   ArrayRef<Metadata *> Ops)
       : MDVariable(C, MDLocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg),
         Flags(Flags) {}
-  ~MDLocalVariable() {}
+  ~MDLocalVariable() = default;
 
   static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
                                   MDScope *Scope, StringRef Name, MDFile *File,
 
   static MDLocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
                                   MDScope *Scope, StringRef Name, MDFile *File,
@@ -1822,6 +1957,12 @@ public:
 
 /// \brief DWARF expression.
 ///
 
 /// \brief DWARF expression.
 ///
+/// This is (almost) a DWARF expression that modifies the location of a
+/// variable or (or the location of a single piece of a variable).
+///
+/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
+/// and have DW_OP_plus consume the topmost elements on the stack.
+///
 /// 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.
@@ -1834,7 +1975,7 @@ class MDExpression : public MDNode {
   MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
       : MDNode(C, MDExpressionKind, Storage, None),
         Elements(Elements.begin(), Elements.end()) {}
   MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
       : MDNode(C, MDExpressionKind, Storage, None),
         Elements(Elements.begin(), Elements.end()) {}
-  ~MDExpression() {}
+  ~MDExpression() = default;
 
   static MDExpression *getImpl(LLVMContext &Context,
                                ArrayRef<uint64_t> Elements, StorageType Storage,
 
   static MDExpression *getImpl(LLVMContext &Context,
                                ArrayRef<uint64_t> Elements, StorageType Storage,
@@ -1973,7 +2114,7 @@ class MDObjCProperty : public DebugNode {
       : DebugNode(C, MDObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
                   Ops),
         Line(Line), Attributes(Attributes) {}
       : DebugNode(C, MDObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
                   Ops),
         Line(Line), Attributes(Attributes) {}
-  ~MDObjCProperty() {}
+  ~MDObjCProperty() = default;
 
   static MDObjCProperty *
   getImpl(LLVMContext &Context, StringRef Name, MDFile *File, unsigned Line,
 
   static MDObjCProperty *
   getImpl(LLVMContext &Context, StringRef Name, MDFile *File, unsigned Line,
@@ -2018,8 +2159,24 @@ public:
   MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
   StringRef getGetterName() const { return getStringOperand(2); }
   StringRef getSetterName() const { return getStringOperand(3); }
   MDFile *getFile() const { return cast_or_null<MDFile>(getRawFile()); }
   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()); }
 
   MDType *getType() const { return cast_or_null<MDType>(getRawType()); }
 
+  StringRef getFilename() const {
+    if (auto *F = getFile())
+      return F->getFilename();
+    return "";
+  }
+  StringRef getDirectory() const {
+    if (auto *F = getFile())
+      return F->getDirectory();
+    return "";
+  }
+
   MDString *getRawName() const { return getOperandAs<MDString>(0); }
   Metadata *getRawFile() const { return getOperand(1); }
   MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
   MDString *getRawName() const { return getOperandAs<MDString>(0); }
   Metadata *getRawFile() const { return getOperand(1); }
   MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
@@ -2031,6 +2188,7 @@ public:
   }
 };
 
   }
 };
 
+/// \brief An imported module (C++ using directive or similar).
 class MDImportedEntity : public DebugNode {
   friend class LLVMContextImpl;
   friend class MDNode;
 class MDImportedEntity : public DebugNode {
   friend class LLVMContextImpl;
   friend class MDNode;
@@ -2040,7 +2198,7 @@ class MDImportedEntity : public DebugNode {
   MDImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
                    unsigned Line, ArrayRef<Metadata *> Ops)
       : DebugNode(C, MDImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
   MDImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
                    unsigned Line, ArrayRef<Metadata *> Ops)
       : DebugNode(C, MDImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
-  ~MDImportedEntity() {}
+  ~MDImportedEntity() = default;
 
   static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
                                    MDScope *Scope, DebugNodeRef Entity,
 
   static MDImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
                                    MDScope *Scope, DebugNodeRef Entity,