[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