diff options
-rw-r--r-- | lldb/source/Commands/CommandObjectSource.cpp | 39 | ||||
-rw-r--r-- | lldb/test/Shell/Commands/list-header.test | 57 |
2 files changed, 85 insertions, 11 deletions
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 8c87af5..7e7d3f0 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -1108,9 +1108,15 @@ protected: } } } else { - const char *filename = m_options.file_name.c_str(); - + // const char *filename = m_options.file_name.c_str(); + FileSpec file_spec(m_options.file_name); bool check_inlines = false; + const InlineStrategy inline_strategy = target.GetInlineStrategy(); + if (inline_strategy == eInlineBreakpointsAlways || + (inline_strategy == eInlineBreakpointsHeaders && + !file_spec.IsSourceImplementationFile())) + check_inlines = true; + SymbolContextList sc_list; size_t num_matches = 0; @@ -1122,17 +1128,20 @@ protected: ModuleSpec module_spec(module_file_spec); matching_modules.Clear(); target.GetImages().FindModules(module_spec, matching_modules); - num_matches += matching_modules.ResolveSymbolContextForFilePath( - filename, 0, check_inlines, + num_matches += matching_modules.ResolveSymbolContextsForFileSpec( + file_spec, 1, check_inlines, SymbolContextItem(eSymbolContextModule | - eSymbolContextCompUnit), + eSymbolContextCompUnit | + eSymbolContextLineEntry), sc_list); } } } else { - num_matches = target.GetImages().ResolveSymbolContextForFilePath( - filename, 0, check_inlines, - eSymbolContextModule | eSymbolContextCompUnit, sc_list); + num_matches = target.GetImages().ResolveSymbolContextsForFileSpec( + file_spec, 1, check_inlines, + eSymbolContextModule | eSymbolContextCompUnit | + eSymbolContextLineEntry, + sc_list); } if (num_matches == 0) { @@ -1179,10 +1188,18 @@ protected: if (m_options.num_lines == 0) m_options.num_lines = 10; const uint32_t column = 0; + + // Headers aren't always in the DWARF but if they have + // executable code (eg., inlined-functions) then the callsite's + // file(s) will be found and assigned to + // sc.comp_unit->GetPrimarySupportFile, which is NOT what we want to + // print. Instead, we want to print the one from the line entry. + lldb::SupportFileSP found_file_sp = sc.line_entry.file_sp; + target.GetSourceManager().DisplaySourceLinesWithLineNumbers( - sc.comp_unit->GetPrimarySupportFile(), - m_options.start_line, column, 0, m_options.num_lines, "", - &result.GetOutputStream(), GetBreakpointLocations()); + found_file_sp, m_options.start_line, column, 0, + m_options.num_lines, "", &result.GetOutputStream(), + GetBreakpointLocations()); result.SetStatus(eReturnStatusSuccessFinishResult); } else { diff --git a/lldb/test/Shell/Commands/list-header.test b/lldb/test/Shell/Commands/list-header.test new file mode 100644 index 0000000..08bcedd --- /dev/null +++ b/lldb/test/Shell/Commands/list-header.test @@ -0,0 +1,57 @@ +## Test that `list header.h:<line>` works correctly when header is available. +## +# RUN: split-file %s %t + +# RUN: %clang_host -g %t/main_with_inlined.cc %t/foo.cc -o %t/main_with_inlined.out +# RUN: %clang_host -g %t/main_no_inlined.cc %t/foo.cc -o %t/main_no_inlined.out + +# RUN: %lldb %t/main_with_inlined.out -o "list foo.h:2" -o "exit" 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-INLINED + +## Would be nice if this listed the header too - but probably not something +## we want to support right now. +# RUN: echo quit | %lldb %t/main_no_inlined.out -o "list foo.h:2" -o "exit" 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-NO-INLINED + +# CHECK-INLINED: 2 extern int* ptr; +# CHECK-INLINED: 3 void f(int x); +# CHECK-INLINED: 4 +# CHECK-INLINED: 5 inline void g(int x) { +# CHECK-INLINED: 6 *ptr = x; // should crash here +# CHECK-INLINED: 7 } + +# CHECK-NO-INLINED: error: Could not find source file "foo.h". + +#--- foo.h +// foo.h +extern int* ptr; +void f(int x); + +inline void g(int x) { + *ptr = x; // should crash here +} + +#--- foo.cc +#include "foo.h" + +int* ptr; + +void f(int x) { + *ptr = x; +} + +#--- main_with_inlined.cc +#include "foo.h" + +int main() { + g(123); // Call the inlined function + return 0; +} + +#--- main_no_inlined.cc +#include "foo.h" + +int main() { + f(234); + return 0; +} |