summaryrefslogtreecommitdiffstats
path: root/lldb/source/Breakpoint
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2018-08-30 15:11:00 +0000
committerAdrian Prantl <aprantl@apple.com>2018-08-30 15:11:00 +0000
commit431b158400320fdeac946799d2087257e2bdc26c (patch)
tree30f2861f026750ed636d0d975b1ab52728b8c257 /lldb/source/Breakpoint
parent5e98c2b69db07905348e8d5b1778bbba94c56531 (diff)
downloadbcm5719-llvm-431b158400320fdeac946799d2087257e2bdc26c.tar.gz
bcm5719-llvm-431b158400320fdeac946799d2087257e2bdc26c.zip
Support setting a breakpoint by FileSpec+Line+Column in the SBAPI.
This patch extends the SBAPI to allow for setting a breakpoint not only at a specific line, but also at a specific (minimum) column. When a column is specified, it will try to find an exact match or the closest match on the same line that comes after the specified location. Differential Revision: https://reviews.llvm.org/D51461 llvm-svn: 341078
Diffstat (limited to 'lldb/source/Breakpoint')
-rw-r--r--lldb/source/Breakpoint/BreakpointResolver.cpp74
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverFileLine.cpp35
2 files changed, 86 insertions, 23 deletions
diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp b/lldb/source/Breakpoint/BreakpointResolver.cpp
index a8a3c820d53..de8032d2359 100644
--- a/lldb/source/Breakpoint/BreakpointResolver.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolver.cpp
@@ -44,9 +44,9 @@ const char *BreakpointResolver::g_ty_to_name[] = {"FileAndLine", "Address",
const char *BreakpointResolver::g_option_names[static_cast<uint32_t>(
BreakpointResolver::OptionNames::LastOptionName)] = {
- "AddressOffset", "Exact", "FileName", "Inlines", "Language",
- "LineNumber", "ModuleName", "NameMask", "Offset", "Regex",
- "SectionName", "SkipPrologue", "SymbolNames"};
+ "AddressOffset", "Exact", "FileName", "Inlines", "Language",
+ "LineNumber", "Column", "ModuleName", "NameMask", "Offset",
+ "Regex", "SectionName", "SkipPrologue", "SymbolNames"};
const char *BreakpointResolver::ResolverTyToName(enum ResolverTy type) {
if (type > LastKnownResolverType)
@@ -176,18 +176,37 @@ void BreakpointResolver::ResolveBreakpoint(SearchFilter &filter) {
filter.Search(*this);
}
+namespace {
+struct SourceLoc {
+ uint32_t line = UINT32_MAX;
+ uint32_t column;
+ SourceLoc(uint32_t l, uint32_t c) : line(l), column(c ? c : UINT32_MAX) {}
+ SourceLoc(const SymbolContext &sc)
+ : line(sc.line_entry.line),
+ column(sc.line_entry.column ? sc.line_entry.column : UINT32_MAX) {}
+};
+
+bool operator<(const SourceLoc a, const SourceLoc b) {
+ if (a.line < b.line)
+ return true;
+ if (a.line > b.line)
+ return false;
+ uint32_t a_col = a.column ? a.column : UINT32_MAX;
+ uint32_t b_col = b.column ? b.column : UINT32_MAX;
+ return a_col < b_col;
+}
+} // namespace
+
void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter,
SymbolContextList &sc_list,
bool skip_prologue,
- llvm::StringRef log_ident) {
+ llvm::StringRef log_ident,
+ uint32_t line, uint32_t column) {
llvm::SmallVector<SymbolContext, 16> all_scs;
for (uint32_t i = 0; i < sc_list.GetSize(); ++i)
all_scs.push_back(sc_list[i]);
while (all_scs.size()) {
- // ResolveSymbolContext will always return a number that is >= the
- // line number you pass in. So the smaller line number is always
- // better.
uint32_t closest_line = UINT32_MAX;
// Move all the elements with a matching file spec to the end.
@@ -202,12 +221,41 @@ void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter,
}
return true;
});
-
- // Within, remove all entries with a larger line number.
- auto worklist_end = std::remove_if(
- worklist_begin, all_scs.end(), [&](const SymbolContext &sc) {
- return closest_line != sc.line_entry.line;
- });
+
+ // (worklist_begin, worklist_end) now contains all entries for one filespec.
+ auto worklist_end = all_scs.end();
+
+ if (column) {
+ // If a column was requested, do a more precise match and only
+ // return the first location that comes after or at the
+ // requested location.
+ SourceLoc requested(line, column);
+ // First, filter out all entries left of the requested column.
+ worklist_end = std::remove_if(
+ worklist_begin, worklist_end,
+ [&](const SymbolContext &sc) { return SourceLoc(sc) < requested; });
+ // Sort the remaining entries by (line, column).
+ std::sort(worklist_begin, worklist_end,
+ [](const SymbolContext &a, const SymbolContext &b) {
+ return SourceLoc(a) < SourceLoc(b);
+ });
+
+ // Filter out all locations with a source location after the closest match.
+ if (worklist_begin != worklist_end)
+ worklist_end = std::remove_if(
+ worklist_begin, worklist_end, [&](const SymbolContext &sc) {
+ return SourceLoc(*worklist_begin) < SourceLoc(sc);
+ });
+ } else {
+ // Remove all entries with a larger line number.
+ // ResolveSymbolContext will always return a number that is >=
+ // the line number you pass in. So the smaller line number is
+ // always better.
+ worklist_end = std::remove_if(worklist_begin, worklist_end,
+ [&](const SymbolContext &sc) {
+ return closest_line != sc.line_entry.line;
+ });
+ }
// Sort by file address.
std::sort(worklist_begin, worklist_end,
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
index a846f5bf912..76223f25790 100644
--- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -28,11 +28,12 @@ using namespace lldb_private;
//----------------------------------------------------------------------
BreakpointResolverFileLine::BreakpointResolverFileLine(
Breakpoint *bkpt, const FileSpec &file_spec, uint32_t line_no,
- lldb::addr_t offset, bool check_inlines, bool skip_prologue,
- bool exact_match)
+ uint32_t column, lldb::addr_t offset, bool check_inlines,
+ bool skip_prologue, bool exact_match)
: BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver, offset),
- m_file_spec(file_spec), m_line_number(line_no), m_inlines(check_inlines),
- m_skip_prologue(skip_prologue), m_exact_match(exact_match) {}
+ m_file_spec(file_spec), m_line_number(line_no), m_column(column),
+ m_inlines(check_inlines), m_skip_prologue(skip_prologue),
+ m_exact_match(exact_match) {}
BreakpointResolverFileLine::~BreakpointResolverFileLine() {}
@@ -41,6 +42,7 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData(
Status &error) {
llvm::StringRef filename;
uint32_t line_no;
+ uint32_t column;
bool check_inlines;
bool skip_prologue;
bool exact_match;
@@ -62,6 +64,13 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData(
return nullptr;
}
+ success =
+ options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Column), column);
+ if (!success) {
+ // Backwards compatibility.
+ column = 0;
+ }
+
success = options_dict.GetValueForKeyAsBoolean(GetKey(OptionNames::Inlines),
check_inlines);
if (!success) {
@@ -85,8 +94,8 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData(
FileSpec file_spec(filename, false);
- return new BreakpointResolverFileLine(bkpt, file_spec, line_no, offset,
- check_inlines, skip_prologue,
+ return new BreakpointResolverFileLine(bkpt, file_spec, line_no, column,
+ offset, check_inlines, skip_prologue,
exact_match);
}
@@ -99,6 +108,8 @@ BreakpointResolverFileLine::SerializeToStructuredData() {
m_file_spec.GetPath());
options_dict_sp->AddIntegerItem(GetKey(OptionNames::LineNumber),
m_line_number);
+ options_dict_sp->AddIntegerItem(GetKey(OptionNames::Column),
+ m_column);
options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines), m_inlines);
options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue),
m_skip_prologue);
@@ -240,7 +251,8 @@ BreakpointResolverFileLine::SearchCallback(SearchFilter &filter,
s.Printf("for %s:%d ", m_file_spec.GetFilename().AsCString("<Unknown>"),
m_line_number);
- SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString());
+ SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString(),
+ m_line_number, m_column);
return Searcher::eCallbackReturnContinue;
}
@@ -250,8 +262,11 @@ Searcher::Depth BreakpointResolverFileLine::GetDepth() {
}
void BreakpointResolverFileLine::GetDescription(Stream *s) {
- s->Printf("file = '%s', line = %u, exact_match = %d",
- m_file_spec.GetPath().c_str(), m_line_number, m_exact_match);
+ s->Printf("file = '%s', line = %u, ", m_file_spec.GetPath().c_str(),
+ m_line_number);
+ if (m_column)
+ s->Printf("column = %u, ", m_column);
+ s->Printf("exact_match = %d", m_exact_match);
}
void BreakpointResolverFileLine::Dump(Stream *s) const {}
@@ -259,7 +274,7 @@ void BreakpointResolverFileLine::Dump(Stream *s) const {}
lldb::BreakpointResolverSP
BreakpointResolverFileLine::CopyForBreakpoint(Breakpoint &breakpoint) {
lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine(
- &breakpoint, m_file_spec, m_line_number, m_offset, m_inlines,
+ &breakpoint, m_file_spec, m_line_number, m_column, m_offset, m_inlines,
m_skip_prologue, m_exact_match));
return ret_sp;
OpenPOWER on IntegriCloud