[llvm] r233573 - DebugInfo: Write new DebugLoc API

Duncan P. N. Exon Smith dexonsmith at apple.com
Mon Mar 30 11:07:40 PDT 2015


Author: dexonsmith
Date: Mon Mar 30 13:07:40 2015
New Revision: 233573

URL: http://llvm.org/viewvc/llvm-project?rev=233573&view=rev
Log:
DebugInfo: Write new DebugLoc API

Rewrite `DebugLoc` with a cleaner API that reflects its current status
as a wrapper around an `MDLocation` pointer.

  - Add accessors/constructors to/from `MDLocation`.
  - Simplify construction from `MDNode`.
  - Remove unnecessary `LLVMContext` from APIs.
  - Drop some API that isn't useful any more.
  - Rewrite documentation.

Actually, I've left the old API behind temporarily at the bottom of the
class so that I can update callers in separate commits.  I'll remove it
once the callers are updated.

Modified:
    llvm/trunk/include/llvm/IR/DebugLoc.h
    llvm/trunk/lib/IR/DebugLoc.cpp

Modified: llvm/trunk/include/llvm/IR/DebugLoc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugLoc.h?rev=233573&r1=233572&r2=233573&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugLoc.h (original)
+++ llvm/trunk/include/llvm/IR/DebugLoc.h Mon Mar 30 13:07:40 2015
@@ -22,11 +22,15 @@ namespace llvm {
 
   class LLVMContext;
   class raw_ostream;
-  class MDNode;
+  class MDLocation;
 
-  /// DebugLoc - Debug location id.  This is carried by Instruction, SDNode,
-  /// and MachineInstr to compactly encode file/line/scope information for an
-  /// operation.
+  /// \brief A debug info location.
+  ///
+  /// This class is a wrapper around a tracking reference to an \a MDLocation
+  /// pointer.
+  ///
+  /// To avoid extra includes, \a DebugLoc doubles the \a MDLocation API with a
+  /// one based on relatively opaque \a MDNode pointers.
   class DebugLoc {
     TrackingMDNodeRef Loc;
 
@@ -43,66 +47,89 @@ namespace llvm {
       return *this;
     }
 
+    /// \brief Construct from an \a MDLocation.
+    DebugLoc(MDLocation *L);
+
+    /// \brief Construct from an \a MDNode.
+    ///
+    /// Note: if \c N is not an \a MDLocation, a verifier check will fail, and
+    /// accessors will crash.  However, construction from other nodes is
+    /// supported in order to handle forward references when reading textual
+    /// IR.
+    explicit DebugLoc(MDNode *N);
+
+    MDLocation *get() const;
+    operator MDLocation *() const { return get(); }
+    MDLocation *operator->() const { return get(); }
+    MDLocation &operator*() const { return *get(); }
+
     /// \brief Check whether this has a trivial destructor.
     bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); }
 
-    /// get - Get a new DebugLoc that corresponds to the specified line/col
-    /// scope/inline location.
+    /// \brief Create a new DebugLoc.
+    ///
+    /// Create a new DebugLoc at the specified line/col and scope/inline.  This
+    /// forwards to \a MDLocation::get().
+    ///
+    /// If \c !Scope, returns a default-constructed \a DebugLoc.
+    ///
+    /// FIXME: Remove this.  Users should use MDLocation::get().
     static DebugLoc get(unsigned Line, unsigned Col, MDNode *Scope,
                         MDNode *InlinedAt = nullptr);
 
-    /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
-    static DebugLoc getFromDILocation(MDNode *N);
-
-    /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
+    /// \brief Translate the DILexicalBlock into a DebugLoc.
+    ///
+    /// FIXME: Remove this.  It has only one user, and the user just wants to
+    /// pass an \a MDScope around.
     static DebugLoc getFromDILexicalBlock(MDNode *N);
 
-    /// isUnknown - Return true if this is an unknown location.
-    bool isUnknown() const { return !Loc; }
-
     unsigned getLine() const;
     unsigned getCol() const;
-
-    /// getScope - This returns the scope pointer for this DebugLoc, or null if
-    /// invalid.
     MDNode *getScope() const;
-    MDNode *getScope(const LLVMContext &) const { return getScope(); }
+    MDLocation *getInlinedAt() const;
+
+    /// \brief Get the fully inlined-at scope for a DebugLoc.
+    ///
+    /// Gets the inlined-at scope for a DebugLoc.
+    MDNode *getInlinedAtScope() const;
+
+    /// \brief Find the debug info location for the start of the function.
+    ///
+    /// Walk up the scope chain of given debug loc and find line number info
+    /// for the function.
+    ///
+    /// FIXME: Remove this.  Users should use MDLocation/MDLocalScope API to
+    /// find the subprogram, and then MDLocation::get().
+    DebugLoc getFnDebugLoc() const;
+
+    /// \brief Return \c this as a bar \a MDNode.
+    MDNode *getAsMDNode() const { return Loc; }
+
+    bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }
+    bool operator!=(const DebugLoc &DL) const { return Loc != DL.Loc; }
+
+    void dump() const;
 
-    /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
-    /// null if invalid or not present.
-    MDNode *getInlinedAt() const;
-    MDNode *getInlinedAt(const LLVMContext &) const { return getInlinedAt(); }
+    /// \brief prints source location /path/to/file.exe:line:col @[inlined at]
+    void print(raw_ostream &OS) const;
 
-    /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
+    // FIXME: Remove this old API once callers have been updated.
+    static DebugLoc getFromDILocation(MDNode *N) { return DebugLoc(N); }
+    bool isUnknown() const { return !Loc; }
+    MDNode *getScope(const LLVMContext &) const { return getScope(); }
+    MDNode *getInlinedAt(const LLVMContext &) const;
     void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const;
     void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
                               const LLVMContext &) const {
       return getScopeAndInlinedAt(Scope, IA);
     }
-
-    /// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid.
-    MDNode *getScopeNode() const;
+    MDNode *getScopeNode() const { return getInlinedAtScope(); }
     MDNode *getScopeNode(const LLVMContext &) const { return getScopeNode(); }
-
-    // getFnDebugLoc - Walk up the scope chain of given debug loc and find line
-    // number info for the function.
-    DebugLoc getFnDebugLoc() const;
     DebugLoc getFnDebugLoc(const LLVMContext &) const {
       return getFnDebugLoc();
     }
-
-    /// getAsMDNode - This method converts the compressed DebugLoc node into a
-    /// DILocation compatible MDNode.
-    MDNode *getAsMDNode() const;
     MDNode *getAsMDNode(LLVMContext &) const { return getAsMDNode(); }
-
-    bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }
-    bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
-
-    void dump() const;
     void dump(const LLVMContext &) const { dump(); }
-    /// \brief prints source location /path/to/file.exe:line:col @[inlined at]
-    void print(raw_ostream &OS) const;
   };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/IR/DebugLoc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugLoc.cpp?rev=233573&r1=233572&r2=233573&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugLoc.cpp (original)
+++ llvm/trunk/lib/IR/DebugLoc.cpp Mon Mar 30 13:07:40 2015
@@ -16,28 +16,40 @@ using namespace llvm;
 //===----------------------------------------------------------------------===//
 // DebugLoc Implementation
 //===----------------------------------------------------------------------===//
+DebugLoc::DebugLoc(MDLocation *L) : Loc(L) {}
+DebugLoc::DebugLoc(MDNode *L) : Loc(L) {}
 
-unsigned DebugLoc::getLine() const { return DILocation(Loc).getLineNumber(); }
-unsigned DebugLoc::getCol() const { return DILocation(Loc).getColumnNumber(); }
+MDLocation *DebugLoc::get() const {
+  return cast_or_null<MDLocation>(Loc.get());
+}
 
-MDNode *DebugLoc::getScope() const { return DILocation(Loc).getScope(); }
+unsigned DebugLoc::getLine() const {
+  assert(get() && "Expected valid DebugLoc");
+  return get()->getLine();
+}
 
-MDNode *DebugLoc::getInlinedAt() const {
-  return DILocation(Loc).getOrigLocation();
+unsigned DebugLoc::getCol() const {
+  assert(get() && "Expected valid DebugLoc");
+  return get()->getColumn();
 }
 
-/// Return both the Scope and the InlinedAt values.
-void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const {
-  Scope = getScope();
-  IA = getInlinedAt();
+MDNode *DebugLoc::getScope() const {
+  assert(get() && "Expected valid DebugLoc");
+  return get()->getScope();
 }
 
-MDNode *DebugLoc::getScopeNode() const {
+MDLocation *DebugLoc::getInlinedAt() const {
+  assert(get() && "Expected valid DebugLoc");
+  return get()->getInlinedAt();
+}
+
+MDNode *DebugLoc::getInlinedAtScope() const {
   return cast<MDLocation>(Loc)->getInlinedAtScope();
 }
 
 DebugLoc DebugLoc::getFnDebugLoc() const {
-  const MDNode *Scope = getScopeNode();
+  // FIXME: Add a method on \a MDLocation that does this work.
+  const MDNode *Scope = getInlinedAtScope();
   DISubprogram SP = getDISubprogram(Scope);
   if (SP.isSubprogram())
     return DebugLoc::get(SP.getScopeLineNumber(), 0, SP);
@@ -51,19 +63,7 @@ DebugLoc DebugLoc::get(unsigned Line, un
   if (!Scope)
     return DebugLoc();
 
-  return getFromDILocation(
-      MDLocation::get(Scope->getContext(), Line, Col, Scope, InlinedAt));
-}
-
-/// getAsMDNode - This method converts the compressed DebugLoc node into a
-/// DILocation-compatible MDNode.
-MDNode *DebugLoc::getAsMDNode() const { return Loc; }
-
-/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
-DebugLoc DebugLoc::getFromDILocation(MDNode *N) {
-  DebugLoc Loc;
-  Loc.Loc.reset(N);
-  return Loc;
+  return MDLocation::get(Scope->getContext(), Line, Col, Scope, InlinedAt);
 }
 
 /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
@@ -77,38 +77,48 @@ DebugLoc DebugLoc::getFromDILexicalBlock
 
 void DebugLoc::dump() const {
 #ifndef NDEBUG
-  if (!isUnknown()) {
-    dbgs() << getLine();
-    if (getCol() != 0)
-      dbgs() << ',' << getCol();
-    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt());
-    if (!InlinedAtDL.isUnknown()) {
-      dbgs() << " @ ";
-      InlinedAtDL.dump();
-    } else
-      dbgs() << "\n";
-  }
+  if (!Loc)
+    return;
+
+  dbgs() << getLine();
+  if (getCol() != 0)
+    dbgs() << ',' << getCol();
+  if (DebugLoc InlinedAtDL = DebugLoc(getInlinedAt())) {
+    dbgs() << " @ ";
+    InlinedAtDL.dump();
+  } else
+    dbgs() << "\n";
 #endif
 }
 
 void DebugLoc::print(raw_ostream &OS) const {
-  if (!isUnknown()) {
-    // Print source line info.
-    DIScope Scope(getScope());
-    assert((!Scope || Scope.isScope()) &&
-           "Scope of a DebugLoc should be null or a DIScope.");
-    if (Scope)
-      OS << Scope.getFilename();
-    else
-      OS << "<unknown>";
-    OS << ':' << getLine();
-    if (getCol() != 0)
-      OS << ':' << getCol();
-    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt());
-    if (!InlinedAtDL.isUnknown()) {
-      OS << " @[ ";
-      InlinedAtDL.print(OS);
-      OS << " ]";
-    }
+  if (!Loc)
+    return;
+
+  // Print source line info.
+  DIScope Scope(getScope());
+  assert((!Scope || Scope.isScope()) &&
+         "Scope of a DebugLoc should be null or a DIScope.");
+  if (Scope)
+    OS << Scope.getFilename();
+  else
+    OS << "<unknown>";
+  OS << ':' << getLine();
+  if (getCol() != 0)
+    OS << ':' << getCol();
+
+  if (DebugLoc InlinedAtDL = getInlinedAt()) {
+    OS << " @[ ";
+    InlinedAtDL.print(OS);
+    OS << " ]";
   }
 }
+
+// FIXME: Remove this old API once callers have been updated.
+MDNode *DebugLoc::getInlinedAt(const LLVMContext &) const {
+  return getInlinedAt();
+}
+void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const {
+  Scope = getScope();
+  IA = getInlinedAt();
+}





More information about the llvm-commits mailing list