mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233573 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3584797a17
commit
1c13197c9f
@ -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;
|
||||
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;
|
||||
|
||||
/// \brief prints source location /path/to/file.exe:line:col @[inlined at]
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
// 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(); }
|
||||
|
||||
/// 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(); }
|
||||
|
||||
/// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
|
||||
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
|
||||
|
@ -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(); }
|
||||
|
||||
MDNode *DebugLoc::getScope() const { return DILocation(Loc).getScope(); }
|
||||
|
||||
MDNode *DebugLoc::getInlinedAt() const {
|
||||
return DILocation(Loc).getOrigLocation();
|
||||
MDLocation *DebugLoc::get() const {
|
||||
return cast_or_null<MDLocation>(Loc.get());
|
||||
}
|
||||
|
||||
/// Return both the Scope and the InlinedAt values.
|
||||
void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const {
|
||||
Scope = getScope();
|
||||
IA = getInlinedAt();
|
||||
unsigned DebugLoc::getLine() const {
|
||||
assert(get() && "Expected valid DebugLoc");
|
||||
return get()->getLine();
|
||||
}
|
||||
|
||||
MDNode *DebugLoc::getScopeNode() const {
|
||||
unsigned DebugLoc::getCol() const {
|
||||
assert(get() && "Expected valid DebugLoc");
|
||||
return get()->getColumn();
|
||||
}
|
||||
|
||||
MDNode *DebugLoc::getScope() const {
|
||||
assert(get() && "Expected valid DebugLoc");
|
||||
return get()->getScope();
|
||||
}
|
||||
|
||||
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, unsigned Col,
|
||||
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(MDNode *N) {
|
||||
|
||||
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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user