diff options
| author | Adrian Prantl <aprantl@apple.com> | 2018-08-30 15:11:00 +0000 |
|---|---|---|
| committer | Adrian Prantl <aprantl@apple.com> | 2018-08-30 15:11:00 +0000 |
| commit | 431b158400320fdeac946799d2087257e2bdc26c (patch) | |
| tree | 30f2861f026750ed636d0d975b1ab52728b8c257 /lldb/source/Breakpoint | |
| parent | 5e98c2b69db07905348e8d5b1778bbba94c56531 (diff) | |
| download | bcm5719-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.cpp | 74 | ||||
| -rw-r--r-- | lldb/source/Breakpoint/BreakpointResolverFileLine.cpp | 35 |
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; |

