diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/lldb/include/lldb/Breakpoint/BreakpointResolver.h --- a/lldb/include/lldb/Breakpoint/BreakpointResolver.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -204,7 +204,8 @@ /// filter the results to find the first breakpoint >= (line, column). void SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, llvm::StringRef log_ident, - uint32_t line = 0, uint32_t column = 0); + uint32_t line = 0, + llvm::Optional column = llvm::None); void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool, const char *) = delete; diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h --- a/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -10,6 +10,7 @@ #define LLDB_BREAKPOINT_BREAKPOINTRESOLVERFILELINE_H #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/SourceLocationSpec.h" namespace lldb_private { @@ -21,10 +22,8 @@ class BreakpointResolverFileLine : public BreakpointResolver { public: BreakpointResolverFileLine(const lldb::BreakpointSP &bkpt, - const FileSpec &resolver, - uint32_t line_no, uint32_t column, - lldb::addr_t m_offset, bool check_inlines, - bool skip_prologue, bool exact_match); + lldb::addr_t offset, bool skip_prologue, + const SourceLocationSpec &location_spec); static BreakpointResolver * CreateFromStructuredData(const lldb::BreakpointSP &bkpt, @@ -60,13 +59,8 @@ void FilterContexts(SymbolContextList &sc_list, bool is_relative); friend class Breakpoint; - FileSpec m_file_spec; ///< This is the file spec we are looking for. - uint32_t m_line_number; ///< This is the line number that we are looking for. - uint32_t m_column; ///< This is the column that we are looking for. - bool m_inlines; ///< This determines whether the resolver looks for inlined - ///< functions or not. + SourceLocationSpec m_location_spec; bool m_skip_prologue; - bool m_exact_match; private: BreakpointResolverFileLine(const BreakpointResolverFileLine &) = delete; diff --git a/lldb/include/lldb/Core/AddressResolverFileLine.h b/lldb/include/lldb/Core/AddressResolverFileLine.h --- a/lldb/include/lldb/Core/AddressResolverFileLine.h +++ b/lldb/include/lldb/Core/AddressResolverFileLine.h @@ -11,7 +11,7 @@ #include "lldb/Core/AddressResolver.h" #include "lldb/Core/SearchFilter.h" -#include "lldb/Utility/FileSpec.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/lldb-defines.h" #include @@ -28,8 +28,7 @@ class AddressResolverFileLine : public AddressResolver { public: - AddressResolverFileLine(const FileSpec &resolver, uint32_t line_no, - bool check_inlines); + AddressResolverFileLine(SourceLocationSpec location_spec); ~AddressResolverFileLine() override; @@ -42,10 +41,7 @@ void GetDescription(Stream *s) override; protected: - FileSpec m_file_spec; // This is the file spec we are looking for. - uint32_t m_line_number; // This is the line number that we are looking for. - bool m_inlines; // This determines whether the resolver looks for inlined - // functions or not. + SourceLocationSpec m_src_location_spec; private: AddressResolverFileLine(const AddressResolverFileLine &) = delete; diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h --- a/lldb/include/lldb/Symbol/CompileUnit.h +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -11,6 +11,7 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Core/ModuleChild.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/LineTable.h" @@ -345,29 +346,22 @@ /// Resolve symbol contexts by file and line. /// - /// Given a file in \a file_spec, and a line number, find all instances and + /// Given a file in \a src_location_spec, find all instances and /// append them to the supplied symbol context list \a sc_list. /// - /// \param[in] file_spec - /// A file specification. If \a file_spec contains no directory - /// information, only the basename will be used when matching - /// contexts. If the directory in \a file_spec is valid, a - /// complete file specification match will be performed. - /// - /// \param[in] line - /// The line number to match against the compile unit's line - /// tables. + /// \param[in] src_location_spec + /// The \a src_location_spec containing the \a file_spec, the line and the + /// column of the symbol to look for. Also hold the inlines and + /// exact_match flags. /// - /// \param[in] check_inlines - /// If \b true this function will also match any inline + /// If check_inlines is \b true, this function will also match any inline /// file and line matches. If \b false, the compile unit's /// file specification must match \a file_spec for any matches /// to be returned. /// - /// \param[in] exact - /// If true, only resolve the context if \a line exists in the line table. - /// If false, resolve the context to the closest line greater than \a line - /// in the line table. + /// If exact_match is \b true, only resolve the context if \a line and \a + /// column exists in the line table. If \b false, resolve the context to + /// the closest line greater than \a line in the line table. /// /// \param[in] resolve_scope /// For each matching line entry, this bitfield indicates what @@ -382,8 +376,7 @@ /// entries appended to. /// /// \see enum SymbolContext::Scope - void ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, - bool check_inlines, bool exact, + void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); diff --git a/lldb/include/lldb/Symbol/LineTable.h b/lldb/include/lldb/Symbol/LineTable.h --- a/lldb/include/lldb/Symbol/LineTable.h +++ b/lldb/include/lldb/Symbol/LineTable.h @@ -12,6 +12,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/Section.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Utility/RangeMap.h" #include "lldb/lldb-private.h" @@ -137,12 +138,8 @@ /// CompileUnit::GetSupportFiles() /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const /// - /// \param[in] line - /// The source line to match. - /// - /// \param[in] exact - /// If true, match only if you find a line entry exactly matching \a line. - /// If false, return the closest line entry greater than \a line. + /// \param[in] src_location_spec + /// The source location specifier to match. /// /// \param[out] line_entry_ptr /// A pointer to a line entry object that will get a copy of @@ -155,13 +152,14 @@ /// /// \see CompileUnit::GetSupportFiles() /// \see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const - uint32_t FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, - uint32_t line, bool exact, - LineEntry *line_entry_ptr); + uint32_t + FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, + const SourceLocationSpec &src_location_spec, + LineEntry *line_entry_ptr); uint32_t FindLineEntryIndexByFileIndex( uint32_t start_idx, const std::vector &file_indexes, - uint32_t line, bool exact, LineEntry *line_entry_ptr); + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr); size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append, SymbolContextList &sc_list); diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -10,6 +10,7 @@ #define LLDB_SYMBOL_SYMBOLFILE_H #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/SourceLocationSpec.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/CompilerType.h" @@ -209,10 +210,10 @@ virtual uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) = 0; - virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - lldb::SymbolContextItem resolve_scope, - SymbolContextList &sc_list); + virtual uint32_t + ResolveSymbolContext(const SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + SymbolContextList &sc_list); virtual void DumpClangAST(Stream &s) {} virtual void FindGlobalVariables(ConstString name, diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -857,12 +857,13 @@ std::vector step_over_until_addrs; const bool abort_other_plans = false; const bool stop_other_threads = false; - const bool check_inlines = true; - const bool exact = false; + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec( + step_file_spec, line, /*column=*/llvm::None, /*check_inlines=*/true, + /*exact_match=*/false); SymbolContextList sc_list; - frame_sc.comp_unit->ResolveSymbolContext(step_file_spec, line, - check_inlines, exact, + frame_sc.comp_unit->ResolveSymbolContext(location_spec, eSymbolContextLineEntry, sc_list); const uint32_t num_matches = sc_list.GetSize(); if (num_matches > 0) { diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -980,9 +980,12 @@ if (m_resolver_sp) { BreakpointResolverFileLine *resolverFileLine = dyn_cast(m_resolver_sp.get()); + + // TODO: Handle SourceLocationSpec column information if (resolverFileLine && - resolverFileLine->m_file_spec.GetFilename() == filename && - resolverFileLine->m_line_number == line_number) { + resolverFileLine->m_location_spec.GetFileSpec().GetFilename() == + filename && + resolverFileLine->m_location_spec.GetLine() == line_number) { return true; } } diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp b/lldb/source/Breakpoint/BreakpointResolver.cpp --- a/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -180,29 +180,29 @@ 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) {} + uint16_t column; + SourceLoc(uint32_t l, llvm::Optional c) + : line(l), column(c ? *c : LLDB_INVALID_COLUMN_NUMBER) {} SourceLoc(const SymbolContext &sc) : line(sc.line_entry.line), - column(sc.line_entry.column ? sc.line_entry.column : UINT32_MAX) {} + column(sc.line_entry.column ? sc.line_entry.column + : LLDB_INVALID_COLUMN_NUMBER) {} }; -bool operator<(const SourceLoc a, const SourceLoc b) { - if (a.line < b.line) +bool operator<(const SourceLoc lhs, const SourceLoc rhs) { + if (lhs.line < rhs.line) return true; - if (a.line > b.line) + if (lhs.line > rhs.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; + // uint32_t a_col = lhs.column ? lhs.column : LLDB_INVALID_COLUMN_NUMBER; + // uint32_t b_col = rhs.column ? rhs.column : LLDB_INVALID_COLUMN_NUMBER; + return lhs.column < rhs.column; } } // namespace -void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter, - SymbolContextList &sc_list, - bool skip_prologue, - llvm::StringRef log_ident, - uint32_t line, uint32_t column) { +void BreakpointResolver::SetSCMatchesByLine( + SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, + llvm::StringRef log_ident, uint32_t line, llvm::Optional column) { llvm::SmallVector all_scs; for (uint32_t i = 0; i < sc_list.GetSize(); ++i) all_scs.push_back(sc_list[i]); @@ -230,7 +230,7 @@ // 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); + SourceLoc requested(line, *column); // First, filter out all entries left of the requested column. worklist_end = std::remove_if( worklist_begin, worklist_end, diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp --- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -20,20 +20,17 @@ // BreakpointResolverFileLine: BreakpointResolverFileLine::BreakpointResolverFileLine( - const BreakpointSP &bkpt, const FileSpec &file_spec, uint32_t line_no, - uint32_t column, lldb::addr_t offset, bool check_inlines, - bool skip_prologue, bool exact_match) + const BreakpointSP &bkpt, lldb::addr_t offset, bool skip_prologue, + const SourceLocationSpec &location_spec) : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver, offset), - 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) {} + m_location_spec(location_spec), m_skip_prologue(skip_prologue) {} BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { llvm::StringRef filename; - uint32_t line_no; - uint32_t column; + uint32_t line; + uint16_t column; bool check_inlines; bool skip_prologue; bool exact_match; @@ -49,7 +46,7 @@ } success = options_dict.GetValueForKeyAsInteger( - GetKey(OptionNames::LineNumber), line_no); + GetKey(OptionNames::LineNumber), line); if (!success) { error.SetErrorString("BRFL::CFSD: Couldn't find line number entry."); return nullptr; @@ -83,11 +80,13 @@ return nullptr; } - FileSpec file_spec(filename); + SourceLocationSpec location_spec(FileSpec(filename), line, column, + check_inlines, exact_match); + if (!location_spec) + return nullptr; - return new BreakpointResolverFileLine(bkpt, file_spec, line_no, column, - offset, check_inlines, skip_prologue, - exact_match); + return new BreakpointResolverFileLine(bkpt, offset, skip_prologue, + location_spec); } StructuredData::ObjectSP @@ -95,17 +94,19 @@ StructuredData::DictionarySP options_dict_sp( new StructuredData::Dictionary()); - options_dict_sp->AddStringItem(GetKey(OptionNames::FileName), - 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); + options_dict_sp->AddStringItem(GetKey(OptionNames::FileName), + m_location_spec.GetFileSpec().GetPath()); + options_dict_sp->AddIntegerItem(GetKey(OptionNames::LineNumber), + m_location_spec.GetLine().getValueOr(0)); + options_dict_sp->AddIntegerItem( + GetKey(OptionNames::Column), + m_location_spec.GetColumn().getValueOr(LLDB_INVALID_COLUMN_NUMBER)); + options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines), + m_location_spec.GetCheckInlines()); options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch), - m_exact_match); + m_location_spec.GetExactMatch()); return WrapOptionsDict(options_dict_sp); } @@ -119,12 +120,12 @@ // inlined into. void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, bool is_relative) { - if (m_exact_match) + if (m_location_spec.GetExactMatch()) return; // Nothing to do. Contexts are precise. llvm::StringRef relative_path; if (is_relative) - relative_path = m_file_spec.GetDirectory().GetStringRef(); + relative_path = m_location_spec.GetFileSpec().GetDirectory().GetStringRef(); Log * log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); for(uint32_t i = 0; i < sc_list.GetSize(); ++i) { @@ -191,12 +192,13 @@ // But only do this calculation if the line number we found in the SC // was different from the one requested in the source file. If we actually // found an exact match it must be valid. - - if (m_line_number == sc.line_entry.line) + + if (m_location_spec.GetLine() == sc.line_entry.line) continue; const int decl_line_is_too_late_fudge = 1; - if (line && m_line_number < line - decl_line_is_too_late_fudge) { + if (line && + m_location_spec.GetLine() < line - decl_line_is_too_late_fudge) { LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line); sc_list.RemoveContextAtIndex(i); --i; @@ -224,8 +226,11 @@ // file. So we go through the match list and pull out the sets that have the // same file spec in their line_entry and treat each set separately. - FileSpec search_file_spec = m_file_spec; - const bool is_relative = m_file_spec.IsRelative(); + const uint32_t line = m_location_spec.GetLine().getValueOr(0); + const llvm::Optional column = m_location_spec.GetColumn(); + + FileSpec search_file_spec = m_location_spec.GetFileSpec(); + const bool is_relative = search_file_spec.IsRelative(); if (is_relative) search_file_spec.GetDirectory().Clear(); @@ -234,8 +239,7 @@ CompUnitSP cu_sp(context.module_sp->GetCompileUnitAtIndex(i)); if (cu_sp) { if (filter.CompUnitPasses(*cu_sp)) - cu_sp->ResolveSymbolContext(search_file_spec, m_line_number, m_inlines, - m_exact_match, eSymbolContextEverything, + cu_sp->ResolveSymbolContext(m_location_spec, eSymbolContextEverything, sc_list); } } @@ -243,11 +247,12 @@ FilterContexts(sc_list, is_relative); StreamString s; - s.Printf("for %s:%d ", m_file_spec.GetFilename().AsCString(""), - m_line_number); + s.Printf("for %s:%d ", + m_location_spec.GetFileSpec().GetFilename().AsCString(""), + line); - SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString(), - m_line_number, m_column); + SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString(), line, + column); return Searcher::eCallbackReturnContinue; } @@ -257,11 +262,13 @@ } void BreakpointResolverFileLine::GetDescription(Stream *s) { - 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); + s->Printf("file = '%s', line = %u, ", + m_location_spec.GetFileSpec().GetPath().c_str(), + m_location_spec.GetLine().getValueOr(0)); + auto column = m_location_spec.GetColumn(); + if (column) + s->Printf("column = %u, ", *column); + s->Printf("exact_match = %d", m_location_spec.GetExactMatch()); } void BreakpointResolverFileLine::Dump(Stream *s) const {} @@ -269,8 +276,7 @@ lldb::BreakpointResolverSP BreakpointResolverFileLine::CopyForBreakpoint(BreakpointSP &breakpoint) { lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine( - breakpoint, m_file_spec, m_line_number, m_column, GetOffset(), m_inlines, - m_skip_prologue, m_exact_match)); + breakpoint, GetOffset(), m_skip_prologue, m_location_spec)); return ret_sp; } diff --git a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp --- a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp @@ -107,10 +107,11 @@ uint32_t num_matches = line_matches.size(); for (uint32_t i = 0; i < num_matches; i++) { SymbolContextList sc_list; - const bool search_inlines = false; - - cu->ResolveSymbolContext(cu_file_spec, line_matches[i], search_inlines, - m_exact_match, eSymbolContextEverything, sc_list); + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(cu_file_spec, line_matches[i], + /*column=*/llvm::None, + /*search_inlines=*/false, m_exact_match); + cu->ResolveSymbolContext(location_spec, eSymbolContextEverything, sc_list); // Find all the function names: if (!m_function_names.empty()) { std::vector sc_to_remove; diff --git a/lldb/source/Core/AddressResolverFileLine.cpp b/lldb/source/Core/AddressResolverFileLine.cpp --- a/lldb/source/Core/AddressResolverFileLine.cpp +++ b/lldb/source/Core/AddressResolverFileLine.cpp @@ -28,11 +28,9 @@ using namespace lldb_private; // AddressResolverFileLine: -AddressResolverFileLine::AddressResolverFileLine(const FileSpec &file_spec, - uint32_t line_no, - bool check_inlines) - : AddressResolver(), m_file_spec(file_spec), m_line_number(line_no), - m_inlines(check_inlines) {} +AddressResolverFileLine::AddressResolverFileLine( + SourceLocationSpec location_spec) + : AddressResolver(), m_src_location_spec(location_spec) {} AddressResolverFileLine::~AddressResolverFileLine() {} @@ -44,8 +42,9 @@ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - cu->ResolveSymbolContext(m_file_spec, m_line_number, m_inlines, false, - eSymbolContextEverything, sc_list); + // TODO: Handle SourceLocationSpec column information + cu->ResolveSymbolContext(m_src_location_spec, eSymbolContextEverything, + sc_list); uint32_t sc_list_size = sc_list.GetSize(); for (uint32_t i = 0; i < sc_list_size; i++) { SymbolContext sc; @@ -55,18 +54,14 @@ if (line_start.IsValid()) { AddressRange new_range(line_start, byte_size); m_address_ranges.push_back(new_range); - if (log) { - StreamString s; - // new_bp_loc->GetDescription (&s, lldb::eDescriptionLevelVerbose); - // LLDB_LOGF(log, "Added address: %s\n", s.GetData()); - } } else { LLDB_LOGF(log, "error: Unable to resolve address at file address 0x%" PRIx64 " for %s:%d\n", line_start.GetFileAddress(), - m_file_spec.GetFilename().AsCString(""), - m_line_number); + m_src_location_spec.GetFileSpec().GetFilename().AsCString( + ""), + m_src_location_spec.GetLine().getValueOr(0)); } } } @@ -78,6 +73,8 @@ } void AddressResolverFileLine::GetDescription(Stream *s) { - s->Printf("File and line address - file: \"%s\" line: %u", - m_file_spec.GetFilename().AsCString(""), m_line_number); + s->Printf( + "File and line address - file: \"%s\" line: %u", + m_src_location_spec.GetFileSpec().GetFilename().AsCString(""), + m_src_location_spec.GetLine().getValueOr(0)); } diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -598,9 +598,13 @@ const uint32_t initial_count = sc_list.GetSize(); - if (SymbolFile *symbols = GetSymbolFile()) - symbols->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, - sc_list); + if (SymbolFile *symbols = GetSymbolFile()) { + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(file_spec, line, /*column=*/llvm::None, + check_inlines, /*exact_match=*/false); + + symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list); + } return sc_list.GetSize() - initial_count; } @@ -917,7 +921,12 @@ std::vector
&output_local, std::vector
&output_extern) { SearchFilterByModule filter(target_sp, m_file); - AddressResolverFileLine resolver(file, line, true); + + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(file, line, /*column=*/llvm::None, + /*check_inlines=*/true, + /*exact_match=*/false); + AddressResolverFileLine resolver(location_spec); resolver.ResolveAddress(filter); for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) { diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -101,8 +101,7 @@ lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override; - uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, - bool check_inlines, + uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) override; diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -278,7 +278,7 @@ } uint32_t SymbolFileBreakpad::ResolveSymbolContext( - const FileSpec &file_spec, uint32_t line, bool check_inlines, + const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); if (!(resolve_scope & eSymbolContextCompUnit)) @@ -287,8 +287,7 @@ uint32_t old_size = sc_list.GetSize(); for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) { CompileUnit &cu = *GetCompileUnitAtIndex(i); - cu.ResolveSymbolContext(file_spec, line, check_inlines, - /*exact*/ false, resolve_scope, sc_list); + cu.ResolveSymbolContext(src_location_spec, resolve_scope, sc_list); } return sc_list.GetSize() - old_size; } @@ -716,10 +715,10 @@ llvm::Optional next_addr; auto finish_sequence = [&]() { LineTable::AppendLineEntryToSequence( - line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0, - /*file_idx*/ 0, /*is_start_of_statement*/ false, - /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, - /*is_epilogue_begin*/ false, /*is_terminal_entry*/ true); + line_seq_up.get(), *next_addr, /*line=*/0, /*column=*/0, + /*file_idx=*/0, /*is_start_of_statement=*/false, + /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false, + /*is_epilogue_begin=*/false, /*is_terminal_entry=*/true); sequences.push_back(std::move(line_seq_up)); line_seq_up = LineTable::CreateLineSequenceContainer(); }; @@ -739,10 +738,10 @@ finish_sequence(); } LineTable::AppendLineEntryToSequence( - line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0, - map[record->FileNum], /*is_start_of_statement*/ true, - /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false, - /*is_epilogue_begin*/ false, /*is_terminal_entry*/ false); + line_seq_up.get(), record->Address, record->LineNum, /*column=*/0, + map[record->FileNum], /*is_start_of_statement=*/true, + /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false, + /*is_epilogue_begin=*/false, /*is_terminal_entry=*/false); next_addr = record->Address + record->Size; } if (next_addr) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -161,11 +161,10 @@ lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; - uint32_t - ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, - lldb::SymbolContextItem resolve_scope, - lldb_private::SymbolContextList &sc_list) override; + uint32_t ResolveSymbolContext( + const lldb_private::SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1959,12 +1959,11 @@ return resolved; } -uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, - bool check_inlines, - SymbolContextItem resolve_scope, - SymbolContextList &sc_list) { +uint32_t SymbolFileDWARF::ResolveSymbolContext( + const SourceLocationSpec &src_location_spec, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); + const bool check_inlines = src_location_spec.GetCheckInlines(); const uint32_t prev_size = sc_list.GetSize(); if (resolve_scope & eSymbolContextCompUnit) { for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus; @@ -1973,11 +1972,10 @@ if (!dc_cu) continue; - bool file_spec_matches_cu_file_spec = - FileSpec::Match(file_spec, dc_cu->GetPrimaryFile()); + bool file_spec_matches_cu_file_spec = FileSpec::Match( + src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile()); if (check_inlines || file_spec_matches_cu_file_spec) { - dc_cu->ResolveSymbolContext(file_spec, line, check_inlines, false, - resolve_scope, sc_list); + dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list); if (!check_inlines) break; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -97,11 +97,10 @@ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; - uint32_t - ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, - lldb::SymbolContextItem resolve_scope, - lldb_private::SymbolContextList &sc_list) override; + uint32_t ResolveSymbolContext( + const lldb_private::SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -806,7 +806,7 @@ } uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( - const FileSpec &file_spec, uint32_t line, bool check_inlines, + const SourceLocationSpec &src_location_spec, SymbolContextItem resolve_scope, SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); const uint32_t initial = sc_list.GetSize(); @@ -815,18 +815,19 @@ for (uint32_t i = 0; i < cu_count; ++i) { // If we are checking for inlines, then we need to look through all compile // units no matter if "file_spec" matches. - bool resolve = check_inlines; + bool resolve = src_location_spec.GetCheckInlines(); if (!resolve) { FileSpec so_file_spec; if (GetFileSpecForSO(i, so_file_spec)) - resolve = FileSpec::Match(file_spec, so_file_spec); + resolve = + FileSpec::Match(src_location_spec.GetFileSpec(), so_file_spec); } if (resolve) { SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i); if (oso_dwarf) - oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, - resolve_scope, sc_list); + oso_dwarf->ResolveSymbolContext(src_location_spec, resolve_scope, + sc_list); } } return sc_list.GetSize() - initial; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -120,8 +120,7 @@ uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override; - uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, - bool check_inlines, + uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) override; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1001,7 +1001,7 @@ } uint32_t SymbolFileNativePDB::ResolveSymbolContext( - const FileSpec &file_spec, uint32_t line, bool check_inlines, + const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { return 0; } diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -104,11 +104,10 @@ lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; - uint32_t - ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, - lldb::SymbolContextItem resolve_scope, - lldb_private::SymbolContextList &sc_list) override; + uint32_t ResolveSymbolContext( + const lldb_private::SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContextList &sc_list) override; void FindGlobalVariables(lldb_private::ConstString name, diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -784,10 +784,12 @@ } uint32_t SymbolFilePDB::ResolveSymbolContext( - const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, + const lldb_private::SourceLocationSpec &src_location_spec, SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) { std::lock_guard guard(GetModuleMutex()); const size_t old_size = sc_list.GetSize(); + const FileSpec &file_spec = src_location_spec.GetFileSpec(); + const uint32_t line = src_location_spec.GetLine().getValueOr(0); if (resolve_scope & lldb::eSymbolContextCompUnit) { // Locate all compilation units with line numbers referencing the specified // file. For example, if `file_spec` is , then this should return @@ -806,7 +808,7 @@ // this file unless the FileSpec matches. For inline functions, we don't // have to match the FileSpec since they could be defined in headers // other than file specified in FileSpec. - if (!check_inlines) { + if (!src_location_spec.GetCheckInlines()) { std::string source_file = compiland->getSourceFileFullPath(); if (source_file.empty()) continue; diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -224,18 +224,24 @@ if (file_indexes.empty()) return UINT32_MAX; + // TODO: Handle SourceLocationSpec column information + SourceLocationSpec location_spec(*file_spec_ptr, line, /*column=*/llvm::None, + /*check_inlines=*/false, exact); + LineTable *line_table = GetLineTable(); if (line_table) return line_table->FindLineEntryIndexByFileIndex( - start_idx, file_indexes, line, exact, line_entry_ptr); + start_idx, file_indexes, location_spec, line_entry_ptr); return UINT32_MAX; } -void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - bool exact, - SymbolContextItem resolve_scope, - SymbolContextList &sc_list) { +void CompileUnit::ResolveSymbolContext( + const SourceLocationSpec &src_location_spec, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { + const FileSpec file_spec = src_location_spec.GetFileSpec(); + const uint32_t line = src_location_spec.GetLine().getValueOr(0); + const bool check_inlines = src_location_spec.GetCheckInlines(); + // First find all of the file indexes that match our "file_spec". If // "file_spec" has an empty directory, then only compare the basenames when // finding file indexes @@ -288,21 +294,24 @@ // table function that searches for a line entries that match a single // support file index line_idx = line_table->FindLineEntryIndexByFileIndex( - 0, file_indexes.front(), line, exact, &line_entry); + 0, file_indexes.front(), src_location_spec, &line_entry); } else { // We found multiple support files that match "file_spec" so use the // line table function that searches for a line entries that match a // multiple support file indexes. - line_idx = line_table->FindLineEntryIndexByFileIndex(0, file_indexes, line, - exact, &line_entry); + line_idx = line_table->FindLineEntryIndexByFileIndex( + 0, file_indexes, src_location_spec, &line_entry); } // If "exact == true", then "found_line" will be the same as "line". If // "exact == false", the "found_line" will be the closest line entry // with a line number greater than "line" and we will use this for our // subsequent line exact matches below. - uint32_t found_line = line_entry.line; - + const bool inlines = false; + const bool exact = true; + SourceLocationSpec found_entry(line_entry.file, line_entry.line, + line_entry.column, inlines, exact); + while (line_idx != UINT32_MAX) { // If they only asked for the line entry, then we're done, we can // just copy that over. But if they wanted more than just the line @@ -317,10 +326,10 @@ sc_list.Append(sc); if (num_file_indexes == 1) line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_indexes.front(), found_line, true, &line_entry); + line_idx + 1, file_indexes.front(), found_entry, &line_entry); else line_idx = line_table->FindLineEntryIndexByFileIndex( - line_idx + 1, file_indexes, found_line, true, &line_entry); + line_idx + 1, file_indexes, found_entry, &line_entry); } } diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp --- a/lldb/source/Symbol/LineTable.cpp +++ b/lldb/source/Symbol/LineTable.cpp @@ -304,7 +304,7 @@ uint32_t LineTable::FindLineEntryIndexByFileIndex( uint32_t start_idx, const std::vector &file_indexes, - uint32_t line, bool exact, LineEntry *line_entry_ptr) { + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr) { const size_t count = m_entries.size(); size_t best_match = UINT32_MAX; @@ -324,13 +324,15 @@ // after and // if they're not in the same function, don't return a match. + uint32_t line = src_location_spec.GetLine().getValueOr(0); + if (m_entries[idx].line < line) { continue; } else if (m_entries[idx].line == line) { if (line_entry_ptr) ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); return idx; - } else if (!exact) { + } else if (!src_location_spec.GetExactMatch()) { if (best_match == UINT32_MAX) best_match = idx; else if (m_entries[idx].line < m_entries[best_match].line) @@ -346,10 +348,9 @@ return UINT32_MAX; } -uint32_t LineTable::FindLineEntryIndexByFileIndex(uint32_t start_idx, - uint32_t file_idx, - uint32_t line, bool exact, - LineEntry *line_entry_ptr) { +uint32_t LineTable::FindLineEntryIndexByFileIndex( + uint32_t start_idx, uint32_t file_idx, + const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr) { const size_t count = m_entries.size(); size_t best_match = UINT32_MAX; @@ -368,13 +369,15 @@ // after and // if they're not in the same function, don't return a match. + uint32_t line = src_location_spec.GetLine().getValueOr(0); + if (m_entries[idx].line < line) { continue; } else if (m_entries[idx].line == line) { if (line_entry_ptr) ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); return idx; - } else if (!exact) { + } else if (!src_location_spec.GetExactMatch()) { if (best_match == UINT32_MAX) best_match = idx; else if (m_entries[idx].line < m_entries[best_match].line) diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp --- a/lldb/source/Symbol/SymbolFile.cpp +++ b/lldb/source/Symbol/SymbolFile.cpp @@ -97,10 +97,10 @@ return type_system_or_err; } -uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - lldb::SymbolContextItem resolve_scope, - SymbolContextList &sc_list) { +uint32_t +SymbolFile::ResolveSymbolContext(const SourceLocationSpec &src_location_spec, + lldb::SymbolContextItem resolve_scope, + SymbolContextList &sc_list) { return 0; } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -371,9 +371,14 @@ if (move_to_nearest_code == eLazyBoolCalculate) move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; + SourceLocationSpec location_spec(remapped_file, line_no, column, + check_inlines, + !static_cast(move_to_nearest_code)); + if (!location_spec) + return nullptr; + BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine( - nullptr, remapped_file, line_no, column, offset, check_inlines, - skip_prologue, !static_cast(move_to_nearest_code))); + nullptr, offset, skip_prologue, location_spec)); return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); } diff --git a/lldb/unittests/Symbol/TestLineEntry.cpp b/lldb/unittests/Symbol/TestLineEntry.cpp --- a/lldb/unittests/Symbol/TestLineEntry.cpp +++ b/lldb/unittests/Symbol/TestLineEntry.cpp @@ -53,20 +53,23 @@ } llvm::Expected LineEntryTest::GetLineEntryForLine(uint32_t line) { - bool check_inlines = true; - bool exact = true; + // TODO: Handle SourceLocationSpec column information SymbolContextList sc_comp_units; SymbolContextList sc_line_entries; FileSpec file_spec("inlined-functions.cpp"); - m_module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, - lldb::eSymbolContextCompUnit, - sc_comp_units); + m_module_sp->ResolveSymbolContextsForFileSpec( + file_spec, line, /*check_inlines=*/true, lldb::eSymbolContextCompUnit, + sc_comp_units); if (sc_comp_units.GetSize() == 0) return llvm::createStringError(llvm::inconvertibleErrorCode(), "No comp unit found on the test object."); + + SourceLocationSpec location_spec(file_spec, line, /*column=*/llvm::None, + /*check_inlines=*/true, + /*exact_match=*/true); + sc_comp_units[0].comp_unit->ResolveSymbolContext( - file_spec, line, check_inlines, exact, eSymbolContextLineEntry, - sc_line_entries); + location_spec, eSymbolContextLineEntry, sc_line_entries); if (sc_line_entries.GetSize() == 0) return llvm::createStringError(llvm::inconvertibleErrorCode(), "No line entry found on the test object.");