diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
| commit | 14f1b3e8826ce43b978db93a62d1166055db5394 (patch) | |
| tree | 0a00ad8d3498783fe0193f3b656bca17c4c8697d /source/Commands/CommandObjectSource.cpp | |
| parent | 4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff) | |
Notes
Diffstat (limited to 'source/Commands/CommandObjectSource.cpp')
| -rw-r--r-- | source/Commands/CommandObjectSource.cpp | 2565 | 
1 files changed, 1202 insertions, 1363 deletions
| diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp index cef9d09d0e55..6ff32080905e 100644 --- a/source/Commands/CommandObjectSource.cpp +++ b/source/Commands/CommandObjectSource.cpp @@ -18,10 +18,12 @@  #include "lldb/Core/Module.h"  #include "lldb/Core/ModuleSpec.h"  #include "lldb/Core/SourceManager.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h"  #include "lldb/Host/FileSpec.h"  #include "lldb/Host/StringConvert.h" +#include "lldb/Interpreter/CommandCompletions.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/Options.h"  #include "lldb/Symbol/CompileUnit.h"  #include "lldb/Symbol/Function.h"  #include "lldb/Symbol/Symbol.h" @@ -29,8 +31,6 @@  #include "lldb/Target/SectionLoadList.h"  #include "lldb/Target/StackFrame.h"  #include "lldb/Target/TargetList.h" -#include "lldb/Interpreter/CommandCompletions.h" -#include "lldb/Interpreter/Options.h"  using namespace lldb;  using namespace lldb_private; @@ -40,682 +40,622 @@ using namespace lldb_private;  // CommandObjectSourceInfo - debug line entries dumping command  //---------------------------------------------------------------------- -class CommandObjectSourceInfo : public CommandObjectParsed -{ -    class CommandOptions : public Options -    { -    public: -        CommandOptions (CommandInterpreter &interpreter) : Options(interpreter) {} - -        ~CommandOptions() override = default; - -        Error -        SetOptionValue (uint32_t option_idx, const char *option_arg) override -        { -            Error error; -            const int short_option = g_option_table[option_idx].short_option; -            switch (short_option) -            { -                case 'l': -                    start_line = StringConvert::ToUInt32(option_arg, 0); -                    if (start_line == 0) -                        error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg); -                    break; - -                case 'e': -                    end_line = StringConvert::ToUInt32(option_arg, 0); -                    if (end_line == 0) -                        error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg); -                    break; - -                case 'c': -                    num_lines = StringConvert::ToUInt32(option_arg, 0); -                    if (num_lines == 0) -                        error.SetErrorStringWithFormat("invalid line count: '%s'", option_arg); -                    break; - -                case 'f': -                    file_name = option_arg; -                    break; - -                case 'n': -                    symbol_name = option_arg; -                    break; - -                case 'a': -                { -                    ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); -                    address = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); -                } -                break; -                case 's': -                    modules.push_back(std::string(option_arg)); -                    break; -                default: -                    error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); -                    break; -            } - -            return error; -        } +static OptionDefinition g_source_info_options[] = { +    // clang-format off +  { LLDB_OPT_SET_ALL,                false, "count",    'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeCount,               "The number of line entries to display." }, +  { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib",    's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion,     eArgTypeShlibName,           "Look up the source in the given module or shared library (can be specified more than once)." }, +  { LLDB_OPT_SET_1,                  false, "file",     'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,            "The file from which to display source." }, +  { LLDB_OPT_SET_1,                  false, "line",     'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeLineNum,             "The line number at which to start the displaying lines." }, +  { LLDB_OPT_SET_1,                  false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeLineNum,             "The line number at which to stop displaying lines." }, +  { LLDB_OPT_SET_2,                  false, "name",     'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion,     eArgTypeSymbol,              "The name of a function whose source to display." }, +  { LLDB_OPT_SET_3,                  false, "address",  'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, +    // clang-format on +}; -        void -        OptionParsingStarting () override -        { -            file_spec.Clear(); -            file_name.clear(); -            symbol_name.clear(); -            address = LLDB_INVALID_ADDRESS; -            start_line = 0; -            end_line = 0; -            num_lines = 0; -            modules.clear(); -        } +class CommandObjectSourceInfo : public CommandObjectParsed { +  class CommandOptions : public Options { +  public: +    CommandOptions() : Options() {} + +    ~CommandOptions() override = default; + +    Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, +                         ExecutionContext *execution_context) override { +      Error error; +      const int short_option = GetDefinitions()[option_idx].short_option; +      switch (short_option) { +      case 'l': +        if (option_arg.getAsInteger(0, start_line)) +          error.SetErrorStringWithFormat("invalid line number: '%s'", +                                         option_arg.str().c_str()); +        break; + +      case 'e': +        if (option_arg.getAsInteger(0, end_line)) +          error.SetErrorStringWithFormat("invalid line number: '%s'", +                                         option_arg.str().c_str()); +        break; + +      case 'c': +        if (option_arg.getAsInteger(0, num_lines)) +          error.SetErrorStringWithFormat("invalid line count: '%s'", +                                         option_arg.str().c_str()); +        break; + +      case 'f': +        file_name = option_arg; +        break; + +      case 'n': +        symbol_name = option_arg; +        break; + +      case 'a': { +        address = Args::StringToAddress(execution_context, option_arg, +                                        LLDB_INVALID_ADDRESS, &error); +      } break; +      case 's': +        modules.push_back(std::string(option_arg)); +        break; +      default: +        error.SetErrorStringWithFormat("unrecognized short option '%c'", +                                       short_option); +        break; +      } + +      return error; +    } -        const OptionDefinition * -        GetDefinitions () override -        { -            return g_option_table; -        } +    void OptionParsingStarting(ExecutionContext *execution_context) override { +      file_spec.Clear(); +      file_name.clear(); +      symbol_name.clear(); +      address = LLDB_INVALID_ADDRESS; +      start_line = 0; +      end_line = 0; +      num_lines = 0; +      modules.clear(); +    } -        static OptionDefinition g_option_table[]; +    llvm::ArrayRef<OptionDefinition> GetDefinitions() override { +      return llvm::makeArrayRef(g_source_info_options); +    } -        // Instance variables to hold the values for command options. -        FileSpec file_spec; -        std::string file_name; -        std::string symbol_name; -        lldb::addr_t address; -        uint32_t start_line; -        uint32_t end_line; -        uint32_t num_lines; -        STLStringArray modules; -    }; +    // Instance variables to hold the values for command options. +    FileSpec file_spec; +    std::string file_name; +    std::string symbol_name; +    lldb::addr_t address; +    uint32_t start_line; +    uint32_t end_line; +    uint32_t num_lines; +    STLStringArray modules; +  };  public: -    CommandObjectSourceInfo(CommandInterpreter &interpreter) -        : CommandObjectParsed(interpreter, "source info", "Display source line information for the current target " -                                                          "process.  Defaults to instruction pointer in current stack " -                                                          "frame.", -                              nullptr, eCommandRequiresTarget), -          m_options(interpreter) -    { -    } +  CommandObjectSourceInfo(CommandInterpreter &interpreter) +      : CommandObjectParsed( +            interpreter, "source info", +            "Display source line information for the current target " +            "process.  Defaults to instruction pointer in current stack " +            "frame.", +            nullptr, eCommandRequiresTarget), +        m_options() {} -    ~CommandObjectSourceInfo() override = default; +  ~CommandObjectSourceInfo() override = default; -    Options * -    GetOptions () override -    { -        return &m_options; -    } +  Options *GetOptions() override { return &m_options; }  protected: -    // Dump the line entries in each symbol context. -    // Return the number of entries found. -    // If module_list is set, only dump lines contained in one of the modules. -    // If file_spec is set, only dump lines in the file. -    // If the start_line option was specified, don't print lines less than start_line. -    // If the end_line option was specified, don't print lines greater than end_line. -    // If the num_lines option was specified, dont print more than num_lines entries. -    uint32_t -    DumpLinesInSymbolContexts (Stream &strm, const SymbolContextList &sc_list, -                               const ModuleList &module_list, const FileSpec &file_spec) -    { -        uint32_t start_line = m_options.start_line; -        uint32_t end_line = m_options.end_line; -        uint32_t num_lines = m_options.num_lines; -        Target *target = m_exe_ctx.GetTargetPtr(); - -        uint32_t num_matches = 0; -        bool has_path = false; -        if (file_spec) -        { -            assert(file_spec.GetFilename().AsCString()); -            has_path = (file_spec.GetDirectory().AsCString() != nullptr); -        } -     -        // Dump all the line entries for the file in the list. -        ConstString last_module_file_name; -        uint32_t num_scs = sc_list.GetSize(); -        for (uint32_t i = 0; i < num_scs; ++i) -        { -            SymbolContext sc; -            sc_list.GetContextAtIndex(i, sc); -            if (sc.comp_unit) -            { -                Module *module = sc.module_sp.get(); -                CompileUnit *cu = sc.comp_unit; -                const LineEntry &line_entry = sc.line_entry; -                assert(module && cu); -     -                // Are we looking for specific modules, files or lines? -                if (module_list.GetSize() && module_list.GetIndexForModule(module) == LLDB_INVALID_INDEX32) -                    continue; -                if (file_spec && !lldb_private::FileSpec::Equal(file_spec, line_entry.file, has_path)) -                    continue; -                if (start_line > 0 && line_entry.line < start_line) -                    continue; -                if (end_line > 0 && line_entry.line > end_line) -                    continue; -                if (num_lines > 0 && num_matches > num_lines) -                    continue; -     -                // Print a new header if the module changed. -                const ConstString &module_file_name = module->GetFileSpec().GetFilename(); -                assert(module_file_name); -                if (module_file_name != last_module_file_name) -                { -                    if (num_matches > 0) -                        strm << "\n\n"; -                    strm << "Lines found in module `" << module_file_name << "\n"; -                } -                // Dump the line entry. -                line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu, -                                          target, /*show_address_only=*/false); -                strm << "\n"; -                last_module_file_name = module_file_name; -                num_matches++; -            } -        } -        return num_matches; +  // Dump the line entries in each symbol context. +  // Return the number of entries found. +  // If module_list is set, only dump lines contained in one of the modules. +  // If file_spec is set, only dump lines in the file. +  // If the start_line option was specified, don't print lines less than +  // start_line. +  // If the end_line option was specified, don't print lines greater than +  // end_line. +  // If the num_lines option was specified, dont print more than num_lines +  // entries. +  uint32_t DumpLinesInSymbolContexts(Stream &strm, +                                     const SymbolContextList &sc_list, +                                     const ModuleList &module_list, +                                     const FileSpec &file_spec) { +    uint32_t start_line = m_options.start_line; +    uint32_t end_line = m_options.end_line; +    uint32_t num_lines = m_options.num_lines; +    Target *target = m_exe_ctx.GetTargetPtr(); + +    uint32_t num_matches = 0; +    bool has_path = false; +    if (file_spec) { +      assert(file_spec.GetFilename().AsCString()); +      has_path = (file_spec.GetDirectory().AsCString() != nullptr);      } -     -    // Dump the requested line entries for the file in the compilation unit. -    // Return the number of entries found. -    // If module_list is set, only dump lines contained in one of the modules. -    // If the start_line option was specified, don't print lines less than start_line. -    // If the end_line option was specified, don't print lines greater than end_line. -    // If the num_lines option was specified, dont print more than num_lines entries. -    uint32_t -    DumpFileLinesInCompUnit (Stream &strm, Module *module, CompileUnit *cu, const FileSpec &file_spec) -    { -        uint32_t start_line = m_options.start_line; -        uint32_t end_line = m_options.end_line; -        uint32_t num_lines = m_options.num_lines; -        Target *target = m_exe_ctx.GetTargetPtr(); - -        uint32_t num_matches = 0; -        assert(module); -        if (cu) -        { -            assert(file_spec.GetFilename().AsCString()); -            bool has_path = (file_spec.GetDirectory().AsCString() != nullptr); -            const FileSpecList &cu_file_list = cu->GetSupportFiles(); -            size_t file_idx = cu_file_list.FindFileIndex(0, file_spec, has_path); -            if (file_idx != UINT32_MAX) -            { -                // Update the file to how it appears in the CU. -                const FileSpec &cu_file_spec = cu_file_list.GetFileSpecAtIndex(file_idx); -     -                // Dump all matching lines at or above start_line for the file in the CU. -                const ConstString &file_spec_name = file_spec.GetFilename(); -                const ConstString &module_file_name = module->GetFileSpec().GetFilename(); -                bool cu_header_printed = false; -                uint32_t line = start_line; -                while (true) -                { -                    LineEntry line_entry; -     -                    // Find the lowest index of a line entry with a line equal to -                    // or higher than 'line'. -                    uint32_t start_idx = 0; -                    start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec, -                                                  /*exact=*/false, &line_entry); -                    if (start_idx == UINT32_MAX) -                        // No more line entries for our file in this CU. -                        break; -     -                    if (end_line > 0 && line_entry.line > end_line) -                        break; -     -                    // Loop through to find any other entries for this line, dumping each. -                    line = line_entry.line; -                    do -                    { -                        num_matches++; -                        if (num_lines > 0 && num_matches > num_lines) -                            break; -                        assert(lldb_private::FileSpec::Equal(cu_file_spec, line_entry.file, has_path)); -                        if (!cu_header_printed) -                        { -                            if (num_matches > 0) -                                strm << "\n\n"; -                            strm << "Lines found for file " << file_spec_name -                                 << " in compilation unit " << cu->GetFilename() -                                 << " in `" << module_file_name << "\n"; -                            cu_header_printed = true; -                        } -                        line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu, -                                                  target, /*show_address_only=*/false); -                        strm << "\n"; -     -                        // Anymore after this one? -                        start_idx++; -                        start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec, -                                                      /*exact=*/true, &line_entry); -                    } while (start_idx != UINT32_MAX); -     -                    // Try the next higher line, starting over at start_idx 0. -                    line++; -                } -            } + +    // Dump all the line entries for the file in the list. +    ConstString last_module_file_name; +    uint32_t num_scs = sc_list.GetSize(); +    for (uint32_t i = 0; i < num_scs; ++i) { +      SymbolContext sc; +      sc_list.GetContextAtIndex(i, sc); +      if (sc.comp_unit) { +        Module *module = sc.module_sp.get(); +        CompileUnit *cu = sc.comp_unit; +        const LineEntry &line_entry = sc.line_entry; +        assert(module && cu); + +        // Are we looking for specific modules, files or lines? +        if (module_list.GetSize() && +            module_list.GetIndexForModule(module) == LLDB_INVALID_INDEX32) +          continue; +        if (file_spec && +            !lldb_private::FileSpec::Equal(file_spec, line_entry.file, +                                           has_path)) +          continue; +        if (start_line > 0 && line_entry.line < start_line) +          continue; +        if (end_line > 0 && line_entry.line > end_line) +          continue; +        if (num_lines > 0 && num_matches > num_lines) +          continue; + +        // Print a new header if the module changed. +        const ConstString &module_file_name = +            module->GetFileSpec().GetFilename(); +        assert(module_file_name); +        if (module_file_name != last_module_file_name) { +          if (num_matches > 0) +            strm << "\n\n"; +          strm << "Lines found in module `" << module_file_name << "\n";          } -        return num_matches; +        // Dump the line entry. +        line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu, +                                  target, /*show_address_only=*/false); +        strm << "\n"; +        last_module_file_name = module_file_name; +        num_matches++; +      }      } -     -    // Dump the requested line entries for the file in the module. -    // Return the number of entries found. -    // If module_list is set, only dump lines contained in one of the modules. -    // If the start_line option was specified, don't print lines less than start_line. -    // If the end_line option was specified, don't print lines greater than end_line. -    // If the num_lines option was specified, dont print more than num_lines entries. -    uint32_t -    DumpFileLinesInModule (Stream &strm, Module *module, const FileSpec &file_spec) -    { -        uint32_t num_matches = 0; -        if (module) -        { -            // Look through all the compilation units (CUs) in this module for ones that -            // contain lines of code from this source file. -            for (size_t i = 0; i < module->GetNumCompileUnits(); i++) -            { -                // Look for a matching source file in this CU. -                CompUnitSP cu_sp(module->GetCompileUnitAtIndex(i)); -                if (cu_sp) -                { -                    num_matches += DumpFileLinesInCompUnit(strm, module, cu_sp.get(), file_spec); -                } +    return num_matches; +  } + +  // Dump the requested line entries for the file in the compilation unit. +  // Return the number of entries found. +  // If module_list is set, only dump lines contained in one of the modules. +  // If the start_line option was specified, don't print lines less than +  // start_line. +  // If the end_line option was specified, don't print lines greater than +  // end_line. +  // If the num_lines option was specified, dont print more than num_lines +  // entries. +  uint32_t DumpFileLinesInCompUnit(Stream &strm, Module *module, +                                   CompileUnit *cu, const FileSpec &file_spec) { +    uint32_t start_line = m_options.start_line; +    uint32_t end_line = m_options.end_line; +    uint32_t num_lines = m_options.num_lines; +    Target *target = m_exe_ctx.GetTargetPtr(); + +    uint32_t num_matches = 0; +    assert(module); +    if (cu) { +      assert(file_spec.GetFilename().AsCString()); +      bool has_path = (file_spec.GetDirectory().AsCString() != nullptr); +      const FileSpecList &cu_file_list = cu->GetSupportFiles(); +      size_t file_idx = cu_file_list.FindFileIndex(0, file_spec, has_path); +      if (file_idx != UINT32_MAX) { +        // Update the file to how it appears in the CU. +        const FileSpec &cu_file_spec = +            cu_file_list.GetFileSpecAtIndex(file_idx); + +        // Dump all matching lines at or above start_line for the file in the +        // CU. +        const ConstString &file_spec_name = file_spec.GetFilename(); +        const ConstString &module_file_name = +            module->GetFileSpec().GetFilename(); +        bool cu_header_printed = false; +        uint32_t line = start_line; +        while (true) { +          LineEntry line_entry; + +          // Find the lowest index of a line entry with a line equal to +          // or higher than 'line'. +          uint32_t start_idx = 0; +          start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec, +                                        /*exact=*/false, &line_entry); +          if (start_idx == UINT32_MAX) +            // No more line entries for our file in this CU. +            break; + +          if (end_line > 0 && line_entry.line > end_line) +            break; + +          // Loop through to find any other entries for this line, dumping each. +          line = line_entry.line; +          do { +            num_matches++; +            if (num_lines > 0 && num_matches > num_lines) +              break; +            assert(lldb_private::FileSpec::Equal(cu_file_spec, line_entry.file, +                                                 has_path)); +            if (!cu_header_printed) { +              if (num_matches > 0) +                strm << "\n\n"; +              strm << "Lines found for file " << file_spec_name +                   << " in compilation unit " << cu->GetFilename() << " in `" +                   << module_file_name << "\n"; +              cu_header_printed = true;              } +            line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu, +                                      target, /*show_address_only=*/false); +            strm << "\n"; + +            // Anymore after this one? +            start_idx++; +            start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec, +                                          /*exact=*/true, &line_entry); +          } while (start_idx != UINT32_MAX); + +          // Try the next higher line, starting over at start_idx 0. +          line++;          } -        return num_matches; +      }      } -     -    // Given an address and a list of modules, append the symbol contexts of all line entries -    // containing the address found in the modules and return the count of matches.  If none -    // is found, return an error in 'error_strm'. -    size_t -    GetSymbolContextsForAddress (const ModuleList &module_list, lldb::addr_t addr, -                                 SymbolContextList &sc_list, StreamString &error_strm) -    { -        Address so_addr; -        size_t num_matches = 0; -        assert(module_list.GetSize() > 0); -        Target *target = m_exe_ctx.GetTargetPtr(); -        if (target->GetSectionLoadList().IsEmpty()) -        { -            // The target isn't loaded yet, we need to lookup the file address in -            // all modules.  Note: the module list option does not apply to addresses. -            const size_t num_modules = module_list.GetSize(); -            for (size_t i = 0; i < num_modules; ++i) -            { -                ModuleSP module_sp(module_list.GetModuleAtIndex(i)); -                if (!module_sp) -                    continue; -                if (module_sp->ResolveFileAddress(addr, so_addr)) -                { -                    SymbolContext sc; -                    sc.Clear(true); -                    if (module_sp->ResolveSymbolContextForAddress(so_addr, eSymbolContextEverything, sc) & -                        eSymbolContextLineEntry) -                    { -                        sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false); -                        ++num_matches; -                    } -                } -            } -            if (num_matches == 0) -                error_strm.Printf("Source information for file address 0x%" PRIx64 -                                  " not found in any modules.\n", addr); +    return num_matches; +  } + +  // Dump the requested line entries for the file in the module. +  // Return the number of entries found. +  // If module_list is set, only dump lines contained in one of the modules. +  // If the start_line option was specified, don't print lines less than +  // start_line. +  // If the end_line option was specified, don't print lines greater than +  // end_line. +  // If the num_lines option was specified, dont print more than num_lines +  // entries. +  uint32_t DumpFileLinesInModule(Stream &strm, Module *module, +                                 const FileSpec &file_spec) { +    uint32_t num_matches = 0; +    if (module) { +      // Look through all the compilation units (CUs) in this module for ones +      // that +      // contain lines of code from this source file. +      for (size_t i = 0; i < module->GetNumCompileUnits(); i++) { +        // Look for a matching source file in this CU. +        CompUnitSP cu_sp(module->GetCompileUnitAtIndex(i)); +        if (cu_sp) { +          num_matches += +              DumpFileLinesInCompUnit(strm, module, cu_sp.get(), file_spec);          } -        else -        { -            // The target has some things loaded, resolve this address to a -            // compile unit + file + line and display -            if (target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) -            { -                ModuleSP module_sp(so_addr.GetModule()); -                // Check to make sure this module is in our list. -                if (module_sp && -                    module_list.GetIndexForModule(module_sp.get()) != LLDB_INVALID_INDEX32) -                { -                    SymbolContext sc; -                    sc.Clear(true); -                    if (module_sp->ResolveSymbolContextForAddress(so_addr, eSymbolContextEverything, sc) & -                        eSymbolContextLineEntry) -                    { -                        sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false); -                        ++num_matches; -                    } -                    else -                    { -                        StreamString addr_strm; -                        so_addr.Dump(&addr_strm, nullptr, Address::DumpStyleModuleWithFileAddress); -                        error_strm.Printf("Address 0x%" PRIx64 " resolves to %s, but there is" -                                          " no source information available for this address.\n", -                                          addr, addr_strm.GetData()); -                    } -                } -                else -                { -                    StreamString addr_strm; -                    so_addr.Dump(&addr_strm, nullptr, Address::DumpStyleModuleWithFileAddress); -                    error_strm.Printf("Address 0x%" PRIx64 " resolves to %s, but it cannot" -                                      " be found in any modules.\n", -                                      addr, addr_strm.GetData()); -                } -            } -            else -                error_strm.Printf("Unable to resolve address 0x%" PRIx64 ".\n", addr); -        } -        return num_matches; +      }      } - -    // Dump the line entries found in functions matching the name specified in the option.  -    bool -    DumpLinesInFunctions (CommandReturnObject &result) -    { -        SymbolContextList sc_list_funcs; -        ConstString name(m_options.symbol_name.c_str()); -        SymbolContextList sc_list_lines; -        Target *target = m_exe_ctx.GetTargetPtr(); -        uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - -        // Note: module_list can't be const& because FindFunctionSymbols isn't const. -        ModuleList module_list = (m_module_list.GetSize() > 0) ? -                                 m_module_list : target->GetImages(); -        size_t num_matches = module_list.FindFunctions(name, -                                                       eFunctionNameTypeAuto, -                                                       /*include_symbols=*/false, -                                                       /*include_inlines=*/true, -                                                       /*append=*/true, -                                                       sc_list_funcs); -        if (!num_matches) -        { -            // If we didn't find any functions with that name, try searching for -            // symbols that line up exactly with function addresses. -            SymbolContextList sc_list_symbols; -            size_t num_symbol_matches = module_list.FindFunctionSymbols(name, -                                                                        eFunctionNameTypeAuto, -                                                                        sc_list_symbols); -            for (size_t i = 0; i < num_symbol_matches; i++) -            { -                SymbolContext sc; -                sc_list_symbols.GetContextAtIndex(i, sc); -                if (sc.symbol && sc.symbol->ValueIsAddress()) -                { -                    const Address &base_address = sc.symbol->GetAddressRef(); -                    Function *function = base_address.CalculateSymbolContextFunction(); -                    if (function) -                    { -                        sc_list_funcs.Append(SymbolContext(function)); -                        num_matches++; -                    } -                } -            } +    return num_matches; +  } + +  // Given an address and a list of modules, append the symbol contexts of all +  // line entries +  // containing the address found in the modules and return the count of +  // matches.  If none +  // is found, return an error in 'error_strm'. +  size_t GetSymbolContextsForAddress(const ModuleList &module_list, +                                     lldb::addr_t addr, +                                     SymbolContextList &sc_list, +                                     StreamString &error_strm) { +    Address so_addr; +    size_t num_matches = 0; +    assert(module_list.GetSize() > 0); +    Target *target = m_exe_ctx.GetTargetPtr(); +    if (target->GetSectionLoadList().IsEmpty()) { +      // The target isn't loaded yet, we need to lookup the file address in +      // all modules.  Note: the module list option does not apply to addresses. +      const size_t num_modules = module_list.GetSize(); +      for (size_t i = 0; i < num_modules; ++i) { +        ModuleSP module_sp(module_list.GetModuleAtIndex(i)); +        if (!module_sp) +          continue; +        if (module_sp->ResolveFileAddress(addr, so_addr)) { +          SymbolContext sc; +          sc.Clear(true); +          if (module_sp->ResolveSymbolContextForAddress( +                  so_addr, eSymbolContextEverything, sc) & +              eSymbolContextLineEntry) { +            sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false); +            ++num_matches; +          }          } -        if (num_matches == 0) -        { -            result.AppendErrorWithFormat("Could not find function named \'%s\'.\n", -                                         m_options.symbol_name.c_str()); -            return false; +      } +      if (num_matches == 0) +        error_strm.Printf("Source information for file address 0x%" PRIx64 +                          " not found in any modules.\n", +                          addr); +    } else { +      // The target has some things loaded, resolve this address to a +      // compile unit + file + line and display +      if (target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { +        ModuleSP module_sp(so_addr.GetModule()); +        // Check to make sure this module is in our list. +        if (module_sp && +            module_list.GetIndexForModule(module_sp.get()) != +                LLDB_INVALID_INDEX32) { +          SymbolContext sc; +          sc.Clear(true); +          if (module_sp->ResolveSymbolContextForAddress( +                  so_addr, eSymbolContextEverything, sc) & +              eSymbolContextLineEntry) { +            sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false); +            ++num_matches; +          } else { +            StreamString addr_strm; +            so_addr.Dump(&addr_strm, nullptr, +                         Address::DumpStyleModuleWithFileAddress); +            error_strm.Printf( +                "Address 0x%" PRIx64 " resolves to %s, but there is" +                " no source information available for this address.\n", +                addr, addr_strm.GetData()); +          } +        } else { +          StreamString addr_strm; +          so_addr.Dump(&addr_strm, nullptr, +                       Address::DumpStyleModuleWithFileAddress); +          error_strm.Printf("Address 0x%" PRIx64 +                            " resolves to %s, but it cannot" +                            " be found in any modules.\n", +                            addr, addr_strm.GetData());          } -        for (size_t i = 0; i < num_matches; i++) -        { -            SymbolContext sc; -            sc_list_funcs.GetContextAtIndex(i, sc); -            bool context_found_for_symbol = false; -            // Loop through all the ranges in the function. -            AddressRange range; -            for (uint32_t r = 0; -                 sc.GetAddressRange(eSymbolContextEverything, -                                    r, -                                    /*use_inline_block_range=*/true, -                                    range); -                 ++r) -            { -                // Append the symbol contexts for each address in the range to sc_list_lines. -                const Address &base_address = range.GetBaseAddress(); -                const addr_t size = range.GetByteSize(); -                lldb::addr_t start_addr = base_address.GetLoadAddress(target); -                if (start_addr == LLDB_INVALID_ADDRESS) -                    start_addr = base_address.GetFileAddress(); -                lldb::addr_t end_addr = start_addr + size; -                for (lldb::addr_t addr = start_addr; addr < end_addr; addr += addr_byte_size) -                { -                    StreamString error_strm; -                    if (!GetSymbolContextsForAddress(module_list, addr, sc_list_lines, error_strm)) -                        result.AppendWarningWithFormat("in symbol '%s': %s", -                                                       sc.GetFunctionName().AsCString(), -                                                       error_strm.GetData()); -                    else -                        context_found_for_symbol = true; -                } -            } -            if (!context_found_for_symbol) -                result.AppendWarningWithFormat("Unable to find line information" -                                               " for matching symbol '%s'.\n", -                                               sc.GetFunctionName().AsCString()); -        } -        if (sc_list_lines.GetSize() == 0) -        { -            result.AppendErrorWithFormat("No line information could be found" -                                         " for any symbols matching '%s'.\n", -                                         name.AsCString()); -            return false; -        } -        FileSpec file_spec; -        if (!DumpLinesInSymbolContexts(result.GetOutputStream(), -                                       sc_list_lines, module_list, file_spec)) -        { -            result.AppendErrorWithFormat("Unable to dump line information for symbol '%s'.\n", -                                         name.AsCString()); -            return false; -        } -        return true; +      } else +        error_strm.Printf("Unable to resolve address 0x%" PRIx64 ".\n", addr);      } - -    // Dump the line entries found for the address specified in the option.  -    bool -    DumpLinesForAddress (CommandReturnObject &result) -    { -        Target *target = m_exe_ctx.GetTargetPtr(); -        SymbolContextList sc_list; - -        StreamString error_strm; -        if (!GetSymbolContextsForAddress(target->GetImages(), m_options.address, sc_list, error_strm)) -        { -            result.AppendErrorWithFormat("%s.\n", error_strm.GetData()); -            return false; -        } -        ModuleList module_list; -        FileSpec file_spec; -        if (!DumpLinesInSymbolContexts(result.GetOutputStream(), -                                       sc_list, module_list, file_spec)) -        { -            result.AppendErrorWithFormat("No modules contain load address 0x%" PRIx64 ".\n", -                                         m_options.address); -            return false; +    return num_matches; +  } + +  // Dump the line entries found in functions matching the name specified in the +  // option. +  bool DumpLinesInFunctions(CommandReturnObject &result) { +    SymbolContextList sc_list_funcs; +    ConstString name(m_options.symbol_name.c_str()); +    SymbolContextList sc_list_lines; +    Target *target = m_exe_ctx.GetTargetPtr(); +    uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + +    // Note: module_list can't be const& because FindFunctionSymbols isn't +    // const. +    ModuleList module_list = +        (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages(); +    size_t num_matches = +        module_list.FindFunctions(name, eFunctionNameTypeAuto, +                                  /*include_symbols=*/false, +                                  /*include_inlines=*/true, +                                  /*append=*/true, sc_list_funcs); +    if (!num_matches) { +      // If we didn't find any functions with that name, try searching for +      // symbols that line up exactly with function addresses. +      SymbolContextList sc_list_symbols; +      size_t num_symbol_matches = module_list.FindFunctionSymbols( +          name, eFunctionNameTypeAuto, sc_list_symbols); +      for (size_t i = 0; i < num_symbol_matches; i++) { +        SymbolContext sc; +        sc_list_symbols.GetContextAtIndex(i, sc); +        if (sc.symbol && sc.symbol->ValueIsAddress()) { +          const Address &base_address = sc.symbol->GetAddressRef(); +          Function *function = base_address.CalculateSymbolContextFunction(); +          if (function) { +            sc_list_funcs.Append(SymbolContext(function)); +            num_matches++; +          }          } -        return true; +      }      } - -    // Dump the line entries found in the file specified in the option.  -    bool -    DumpLinesForFile (CommandReturnObject &result) -    { -        FileSpec file_spec(m_options.file_name, false); -        const char *filename = m_options.file_name.c_str(); -        Target *target = m_exe_ctx.GetTargetPtr(); -        const ModuleList &module_list = (m_module_list.GetSize() > 0) ? -                                        m_module_list : target->GetImages(); - -        bool displayed_something = false; -        const size_t num_modules = module_list.GetSize(); -        for (uint32_t i = 0; i < num_modules; ++i) -        { -            // Dump lines for this module. -            Module *module = module_list.GetModulePointerAtIndex(i); -            assert(module); -            if (DumpFileLinesInModule(result.GetOutputStream(), module, file_spec)) -                displayed_something = true; -        } -        if (!displayed_something) -        { -            result.AppendErrorWithFormat("No source filenames matched '%s'.\n", filename); -            return false; -        } -        return true; +    if (num_matches == 0) { +      result.AppendErrorWithFormat("Could not find function named \'%s\'.\n", +                                   m_options.symbol_name.c_str()); +      return false;      } - -    // Dump the line entries for the current frame. -    bool -    DumpLinesForFrame (CommandReturnObject &result) -    { -        StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); -        if (cur_frame == nullptr) -        { -            result.AppendError("No selected frame to use to find the default source."); -            return false; -        } -        else if (!cur_frame->HasDebugInformation()) -        { -            result.AppendError("No debug info for the selected frame."); -            return false; -        } -        else -        { -            const SymbolContext &sc = cur_frame->GetSymbolContext(eSymbolContextLineEntry); -            SymbolContextList sc_list; -            sc_list.Append(sc); -            ModuleList module_list; -            FileSpec file_spec; -            if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list, module_list, file_spec)) -            { -                result.AppendError("No source line info available for the selected frame."); -                return false; -            } +    for (size_t i = 0; i < num_matches; i++) { +      SymbolContext sc; +      sc_list_funcs.GetContextAtIndex(i, sc); +      bool context_found_for_symbol = false; +      // Loop through all the ranges in the function. +      AddressRange range; +      for (uint32_t r = 0; +           sc.GetAddressRange(eSymbolContextEverything, r, +                              /*use_inline_block_range=*/true, range); +           ++r) { +        // Append the symbol contexts for each address in the range to +        // sc_list_lines. +        const Address &base_address = range.GetBaseAddress(); +        const addr_t size = range.GetByteSize(); +        lldb::addr_t start_addr = base_address.GetLoadAddress(target); +        if (start_addr == LLDB_INVALID_ADDRESS) +          start_addr = base_address.GetFileAddress(); +        lldb::addr_t end_addr = start_addr + size; +        for (lldb::addr_t addr = start_addr; addr < end_addr; +             addr += addr_byte_size) { +          StreamString error_strm; +          if (!GetSymbolContextsForAddress(module_list, addr, sc_list_lines, +                                           error_strm)) +            result.AppendWarningWithFormat("in symbol '%s': %s", +                                           sc.GetFunctionName().AsCString(), +                                           error_strm.GetData()); +          else +            context_found_for_symbol = true;          } -        return true; +      } +      if (!context_found_for_symbol) +        result.AppendWarningWithFormat("Unable to find line information" +                                       " for matching symbol '%s'.\n", +                                       sc.GetFunctionName().AsCString()); +    } +    if (sc_list_lines.GetSize() == 0) { +      result.AppendErrorWithFormat("No line information could be found" +                                   " for any symbols matching '%s'.\n", +                                   name.AsCString()); +      return false; +    } +    FileSpec file_spec; +    if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list_lines, +                                   module_list, file_spec)) { +      result.AppendErrorWithFormat( +          "Unable to dump line information for symbol '%s'.\n", +          name.AsCString()); +      return false; +    } +    return true; +  } + +  // Dump the line entries found for the address specified in the option. +  bool DumpLinesForAddress(CommandReturnObject &result) { +    Target *target = m_exe_ctx.GetTargetPtr(); +    SymbolContextList sc_list; + +    StreamString error_strm; +    if (!GetSymbolContextsForAddress(target->GetImages(), m_options.address, +                                     sc_list, error_strm)) { +      result.AppendErrorWithFormat("%s.\n", error_strm.GetData()); +      return false; +    } +    ModuleList module_list; +    FileSpec file_spec; +    if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list, +                                   module_list, file_spec)) { +      result.AppendErrorWithFormat("No modules contain load address 0x%" PRIx64 +                                   ".\n", +                                   m_options.address); +      return false;      } +    return true; +  } + +  // Dump the line entries found in the file specified in the option. +  bool DumpLinesForFile(CommandReturnObject &result) { +    FileSpec file_spec(m_options.file_name, false); +    const char *filename = m_options.file_name.c_str(); +    Target *target = m_exe_ctx.GetTargetPtr(); +    const ModuleList &module_list = +        (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages(); + +    bool displayed_something = false; +    const size_t num_modules = module_list.GetSize(); +    for (uint32_t i = 0; i < num_modules; ++i) { +      // Dump lines for this module. +      Module *module = module_list.GetModulePointerAtIndex(i); +      assert(module); +      if (DumpFileLinesInModule(result.GetOutputStream(), module, file_spec)) +        displayed_something = true; +    } +    if (!displayed_something) { +      result.AppendErrorWithFormat("No source filenames matched '%s'.\n", +                                   filename); +      return false; +    } +    return true; +  } + +  // Dump the line entries for the current frame. +  bool DumpLinesForFrame(CommandReturnObject &result) { +    StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); +    if (cur_frame == nullptr) { +      result.AppendError( +          "No selected frame to use to find the default source."); +      return false; +    } else if (!cur_frame->HasDebugInformation()) { +      result.AppendError("No debug info for the selected frame."); +      return false; +    } else { +      const SymbolContext &sc = +          cur_frame->GetSymbolContext(eSymbolContextLineEntry); +      SymbolContextList sc_list; +      sc_list.Append(sc); +      ModuleList module_list; +      FileSpec file_spec; +      if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list, +                                     module_list, file_spec)) { +        result.AppendError( +            "No source line info available for the selected frame."); +        return false; +      } +    } +    return true; +  } -    bool -    DoExecute (Args &command, CommandReturnObject &result) override -    { -        const size_t argc = command.GetArgumentCount(); - -        if (argc != 0) -        { -            result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", -                                         GetCommandName()); -            result.SetStatus(eReturnStatusFailed); -            return false; -        } +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    const size_t argc = command.GetArgumentCount(); -        Target *target = m_exe_ctx.GetTargetPtr(); -        if (target == nullptr) -        { -            target = m_interpreter.GetDebugger().GetSelectedTarget().get(); -            if (target == nullptr) -            { -                result.AppendError("invalid target, create a debug target using the " -                                   "'target create' command."); -                result.SetStatus(eReturnStatusFailed); -                return false; -            } -        } +    if (argc != 0) { +      result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", +                                   GetCommandName().str().c_str()); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); -        result.GetOutputStream().SetAddressByteSize(addr_byte_size); -        result.GetErrorStream().SetAddressByteSize(addr_byte_size); - -        // Collect the list of modules to search. -        m_module_list.Clear(); -        if (!m_options.modules.empty()) -        { -            for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) -            { -                FileSpec module_file_spec(m_options.modules[i].c_str(), false); -                if (module_file_spec) -                { -                    ModuleSpec module_spec(module_file_spec); -                    if (target->GetImages().FindModules(module_spec, m_module_list) == 0) -                        result.AppendWarningWithFormat("No module found for '%s'.\n", -                                                       m_options.modules[i].c_str()); -                } -            } -            if (!m_module_list.GetSize()) -            { -                result.AppendError("No modules match the input."); -                result.SetStatus(eReturnStatusFailed); -                return false; -            } -        } -        else if (target->GetImages().GetSize() == 0) -        { -            result.AppendError("The target has no associated executable images."); -            result.SetStatus(eReturnStatusFailed); -            return false; -        } +    Target *target = m_exe_ctx.GetTargetPtr(); +    if (target == nullptr) { +      target = m_interpreter.GetDebugger().GetSelectedTarget().get(); +      if (target == nullptr) { +        result.AppendError("invalid target, create a debug target using the " +                           "'target create' command."); +        result.SetStatus(eReturnStatusFailed); +        return false; +      } +    } -        // Check the arguments to see what lines we should dump. -        if (!m_options.symbol_name.empty()) -        { -            // Print lines for symbol. -            if (DumpLinesInFunctions(result)) -                result.SetStatus(eReturnStatusSuccessFinishResult); -            else -                result.SetStatus(eReturnStatusFailed); -        } -        else if (m_options.address != LLDB_INVALID_ADDRESS) -        { -            // Print lines for an address. -            if (DumpLinesForAddress(result)) -                result.SetStatus(eReturnStatusSuccessFinishResult); -            else -                result.SetStatus(eReturnStatusFailed); -        } -        else if (!m_options.file_name.empty()) -        { -            // Dump lines for a file. -            if (DumpLinesForFile(result)) -                result.SetStatus(eReturnStatusSuccessFinishResult); -            else -                result.SetStatus(eReturnStatusFailed); -        } -        else -        { -            // Dump the line for the current frame. -            if (DumpLinesForFrame(result)) -                result.SetStatus(eReturnStatusSuccessFinishResult); -            else -                result.SetStatus(eReturnStatusFailed); +    uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); +    result.GetOutputStream().SetAddressByteSize(addr_byte_size); +    result.GetErrorStream().SetAddressByteSize(addr_byte_size); + +    // Collect the list of modules to search. +    m_module_list.Clear(); +    if (!m_options.modules.empty()) { +      for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) { +        FileSpec module_file_spec(m_options.modules[i], false); +        if (module_file_spec) { +          ModuleSpec module_spec(module_file_spec); +          if (target->GetImages().FindModules(module_spec, m_module_list) == 0) +            result.AppendWarningWithFormat("No module found for '%s'.\n", +                                           m_options.modules[i].c_str());          } -        return result.Succeeded(); +      } +      if (!m_module_list.GetSize()) { +        result.AppendError("No modules match the input."); +        result.SetStatus(eReturnStatusFailed); +        return false; +      } +    } else if (target->GetImages().GetSize() == 0) { +      result.AppendError("The target has no associated executable images."); +      result.SetStatus(eReturnStatusFailed); +      return false;      } -    CommandOptions m_options; -    ModuleList m_module_list; -}; +    // Check the arguments to see what lines we should dump. +    if (!m_options.symbol_name.empty()) { +      // Print lines for symbol. +      if (DumpLinesInFunctions(result)) +        result.SetStatus(eReturnStatusSuccessFinishResult); +      else +        result.SetStatus(eReturnStatusFailed); +    } else if (m_options.address != LLDB_INVALID_ADDRESS) { +      // Print lines for an address. +      if (DumpLinesForAddress(result)) +        result.SetStatus(eReturnStatusSuccessFinishResult); +      else +        result.SetStatus(eReturnStatusFailed); +    } else if (!m_options.file_name.empty()) { +      // Dump lines for a file. +      if (DumpLinesForFile(result)) +        result.SetStatus(eReturnStatusSuccessFinishResult); +      else +        result.SetStatus(eReturnStatusFailed); +    } else { +      // Dump the line for the current frame. +      if (DumpLinesForFrame(result)) +        result.SetStatus(eReturnStatusSuccessFinishResult); +      else +        result.SetStatus(eReturnStatusFailed); +    } +    return result.Succeeded(); +  } -OptionDefinition CommandObjectSourceInfo::CommandOptions::g_option_table[] = { -    {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, -     "The number of line entries to display."}, -    {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, -     CommandCompletions::eModuleCompletion, eArgTypeShlibName, -     "Look up the source in the given module or shared library (can be " -     "specified more than once)."}, -    {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, -     CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."}, -    {LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, -     "The line number at which to start the displaying lines."}, -    {LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, -     "The line number at which to stop displaying lines."}, -    {LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, -     CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."}, -    {LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, -     "Lookup the address and display the source information for the " -     "corresponding file and line."}, -    {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} +  CommandOptions m_options; +  ModuleList m_module_list;  };  #pragma mark CommandObjectSourceList @@ -723,754 +663,650 @@ OptionDefinition CommandObjectSourceInfo::CommandOptions::g_option_table[] = {  // CommandObjectSourceList  //------------------------------------------------------------------------- -class CommandObjectSourceList : public CommandObjectParsed -{ -    class CommandOptions : public Options -    { -    public: -        CommandOptions (CommandInterpreter &interpreter) : -            Options(interpreter) -        { -        } +static OptionDefinition g_source_list_options[] = { +    // clang-format off +  { LLDB_OPT_SET_ALL,                false, "count",            'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeCount,               "The number of source lines to display." }, +  { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib",            's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion,     eArgTypeShlibName,           "Look up the source file in the given shared library." }, +  { LLDB_OPT_SET_ALL,                false, "show-breakpoints", 'b', OptionParser::eNoArgument,       nullptr, nullptr, 0,                                         eArgTypeNone,                "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." }, +  { LLDB_OPT_SET_1,                  false, "file",             'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,            "The file from which to display source." }, +  { LLDB_OPT_SET_1,                  false, "line",             'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeLineNum,             "The line number at which to start the display source." }, +  { LLDB_OPT_SET_2,                  false, "name",             'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion,     eArgTypeSymbol,              "The name of a function whose source to display." }, +  { LLDB_OPT_SET_3,                  false, "address",          'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, +  { LLDB_OPT_SET_4,                  false, "reverse",          'r', OptionParser::eNoArgument,       nullptr, nullptr, 0,                                         eArgTypeNone,                "Reverse the listing to look backwards from the last displayed block of source." }, +    // clang-format on +}; -        ~CommandOptions() override = default; - -        Error -        SetOptionValue (uint32_t option_idx, const char *option_arg) override -        { -            Error error; -            const int short_option = g_option_table[option_idx].short_option; -            switch (short_option) -            { -            case 'l': -                start_line = StringConvert::ToUInt32 (option_arg, 0); -                if (start_line == 0) -                    error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg); -                break; - -            case 'c': -                num_lines = StringConvert::ToUInt32 (option_arg, 0); -                if (num_lines == 0) -                    error.SetErrorStringWithFormat("invalid line count: '%s'", option_arg); -                break; - -            case 'f': -                file_name = option_arg; -                break; -                 -            case 'n': -                symbol_name = option_arg; -                break; - -            case 'a': -                { -                    ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); -                    address = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); -                } -                break; -            case 's': -                modules.push_back (std::string (option_arg)); -                break; -             -            case 'b': -                show_bp_locs = true; -                break; -            case 'r': -                reverse = true; -                break; -           default: -                error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); -                break; -            } +class CommandObjectSourceList : public CommandObjectParsed { +  class CommandOptions : public Options { +  public: +    CommandOptions() : Options() {} + +    ~CommandOptions() override = default; + +    Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, +                         ExecutionContext *execution_context) override { +      Error error; +      const int short_option = GetDefinitions()[option_idx].short_option; +      switch (short_option) { +      case 'l': +        if (option_arg.getAsInteger(0, start_line)) +          error.SetErrorStringWithFormat("invalid line number: '%s'", +                                         option_arg.str().c_str()); +        break; + +      case 'c': +        if (option_arg.getAsInteger(0, num_lines)) +          error.SetErrorStringWithFormat("invalid line count: '%s'", +                                         option_arg.str().c_str()); +        break; + +      case 'f': +        file_name = option_arg; +        break; + +      case 'n': +        symbol_name = option_arg; +        break; + +      case 'a': { +        address = Args::StringToAddress(execution_context, option_arg, +                                        LLDB_INVALID_ADDRESS, &error); +      } break; +      case 's': +        modules.push_back(std::string(option_arg)); +        break; + +      case 'b': +        show_bp_locs = true; +        break; +      case 'r': +        reverse = true; +        break; +      default: +        error.SetErrorStringWithFormat("unrecognized short option '%c'", +                                       short_option); +        break; +      } + +      return error; +    } -            return error; -        } +    void OptionParsingStarting(ExecutionContext *execution_context) override { +      file_spec.Clear(); +      file_name.clear(); +      symbol_name.clear(); +      address = LLDB_INVALID_ADDRESS; +      start_line = 0; +      num_lines = 0; +      show_bp_locs = false; +      reverse = false; +      modules.clear(); +    } -        void -        OptionParsingStarting () override -        { -            file_spec.Clear(); -            file_name.clear(); -            symbol_name.clear(); -            address = LLDB_INVALID_ADDRESS; -            start_line = 0; -            num_lines = 0; -            show_bp_locs = false; -            reverse = false; -            modules.clear(); -        } +    llvm::ArrayRef<OptionDefinition> GetDefinitions() override { +      return llvm::makeArrayRef(g_source_list_options); +    } -        const OptionDefinition* -        GetDefinitions () override -        { -            return g_option_table; -        } +    // Instance variables to hold the values for command options. +    FileSpec file_spec; +    std::string file_name; +    std::string symbol_name; +    lldb::addr_t address; +    uint32_t start_line; +    uint32_t num_lines; +    STLStringArray modules; +    bool show_bp_locs; +    bool reverse; +  }; -        static OptionDefinition g_option_table[]; +public: +  CommandObjectSourceList(CommandInterpreter &interpreter) +      : CommandObjectParsed(interpreter, "source list", +                            "Display source code for the current target " +                            "process as specified by options.", +                            nullptr, eCommandRequiresTarget), +        m_options() {} + +  ~CommandObjectSourceList() override = default; + +  Options *GetOptions() override { return &m_options; } + +  const char *GetRepeatCommand(Args ¤t_command_args, +                               uint32_t index) override { +    // This is kind of gross, but the command hasn't been parsed yet so we can't +    // look at the option values for this invocation...  I have to scan the +    // arguments directly. +    auto iter = +        llvm::find_if(current_command_args, [](const Args::ArgEntry &e) { +          return e.ref == "-r" || e.ref == "--reverse"; +        }); +    if (iter == current_command_args.end()) +      return m_cmd_name.c_str(); + +    if (m_reverse_name.empty()) { +      m_reverse_name = m_cmd_name; +      m_reverse_name.append(" -r"); +    } +    return m_reverse_name.c_str(); +  } -        // Instance variables to hold the values for command options. -        FileSpec file_spec; -        std::string file_name; -        std::string symbol_name; -        lldb::addr_t address; -        uint32_t start_line; -        uint32_t num_lines; -        STLStringArray modules;         -        bool show_bp_locs; -        bool reverse; -    }; +protected: +  struct SourceInfo { +    ConstString function; +    LineEntry line_entry; -public: -    CommandObjectSourceList(CommandInterpreter &interpreter) -        : CommandObjectParsed(interpreter, "source list", -                              "Display source code for the current target process as specified by options.", nullptr, -                              eCommandRequiresTarget), -          m_options(interpreter) -    { +    SourceInfo(const ConstString &name, const LineEntry &line_entry) +        : function(name), line_entry(line_entry) {} + +    SourceInfo() : function(), line_entry() {} + +    bool IsValid() const { return (bool)function && line_entry.IsValid(); } + +    bool operator==(const SourceInfo &rhs) const { +      return function == rhs.function && +             line_entry.original_file == rhs.line_entry.original_file && +             line_entry.line == rhs.line_entry.line;      } -    ~CommandObjectSourceList() override = default; +    bool operator!=(const SourceInfo &rhs) const { +      return function != rhs.function || +             line_entry.original_file != rhs.line_entry.original_file || +             line_entry.line != rhs.line_entry.line; +    } -    Options * -    GetOptions () override -    { -        return &m_options; +    bool operator<(const SourceInfo &rhs) const { +      if (function.GetCString() < rhs.function.GetCString()) +        return true; +      if (line_entry.file.GetDirectory().GetCString() < +          rhs.line_entry.file.GetDirectory().GetCString()) +        return true; +      if (line_entry.file.GetFilename().GetCString() < +          rhs.line_entry.file.GetFilename().GetCString()) +        return true; +      if (line_entry.line < rhs.line_entry.line) +        return true; +      return false;      } +  }; -    const char * -    GetRepeatCommand (Args ¤t_command_args, uint32_t index) override -    { -        // This is kind of gross, but the command hasn't been parsed yet so we can't look at the option -        // values for this invocation...  I have to scan the arguments directly. -        size_t num_args = current_command_args.GetArgumentCount(); -        bool is_reverse = false; -        for (size_t i = 0; i < num_args; i++) -        { -            const char *arg = current_command_args.GetArgumentAtIndex(i); -            if (arg && (strcmp(arg, "-r") == 0 || strcmp(arg, "--reverse") == 0)) -            { -                is_reverse = true; -            } -        } -        if (is_reverse) -        { -            if (m_reverse_name.empty()) -            { -                m_reverse_name = m_cmd_name; -                m_reverse_name.append (" -r"); -            } -            return m_reverse_name.c_str(); -        } -        else -            return m_cmd_name.c_str(); +  size_t DisplayFunctionSource(const SymbolContext &sc, SourceInfo &source_info, +                               CommandReturnObject &result) { +    if (!source_info.IsValid()) { +      source_info.function = sc.GetFunctionName(); +      source_info.line_entry = sc.GetFunctionStartLineEntry();      } -protected: -    struct SourceInfo -    { -        ConstString function; -        LineEntry line_entry; -         -        SourceInfo (const ConstString &name, const LineEntry &line_entry) : -            function(name), -            line_entry(line_entry) -        { -        } -         -        SourceInfo () : -            function(), -            line_entry() -        { +    if (sc.function) { +      Target *target = m_exe_ctx.GetTargetPtr(); + +      FileSpec start_file; +      uint32_t start_line; +      uint32_t end_line; +      FileSpec end_file; + +      if (sc.block == nullptr) { +        // Not an inlined function +        sc.function->GetStartLineSourceInfo(start_file, start_line); +        if (start_line == 0) { +          result.AppendErrorWithFormat("Could not find line information for " +                                       "start of function: \"%s\".\n", +                                       source_info.function.GetCString()); +          result.SetStatus(eReturnStatusFailed); +          return 0;          } -         -        bool -        IsValid () const -        { -            return (bool)function && line_entry.IsValid(); -        } -         -        bool -        operator == (const SourceInfo &rhs) const -        { -            return function == rhs.function && -            line_entry.original_file == rhs.line_entry.original_file && -            line_entry.line == rhs.line_entry.line; -        } -         -        bool -        operator != (const SourceInfo &rhs) const -        { -            return function != rhs.function || -            line_entry.original_file != rhs.line_entry.original_file || -            line_entry.line != rhs.line_entry.line; -        } -         -        bool -        operator < (const SourceInfo &rhs) const -        { -            if (function.GetCString() < rhs.function.GetCString()) -                return true; -            if (line_entry.file.GetDirectory().GetCString() < rhs.line_entry.file.GetDirectory().GetCString()) -                return true; -            if (line_entry.file.GetFilename().GetCString() < rhs.line_entry.file.GetFilename().GetCString()) -                return true; -            if (line_entry.line < rhs.line_entry.line) -                return true; -            return false; +        sc.function->GetEndLineSourceInfo(end_file, end_line); +      } else { +        // We have an inlined function +        start_file = source_info.line_entry.file; +        start_line = source_info.line_entry.line; +        end_line = start_line + m_options.num_lines; +      } + +      // This is a little hacky, but the first line table entry for a function +      // points to the "{" that +      // starts the function block.  It would be nice to actually get the +      // function +      // declaration in there too.  So back up a bit, but not further than what +      // you're going to display. +      uint32_t extra_lines; +      if (m_options.num_lines >= 10) +        extra_lines = 5; +      else +        extra_lines = m_options.num_lines / 2; +      uint32_t line_no; +      if (start_line <= extra_lines) +        line_no = 1; +      else +        line_no = start_line - extra_lines; + +      // For fun, if the function is shorter than the number of lines we're +      // supposed to display, +      // only display the function... +      if (end_line != 0) { +        if (m_options.num_lines > end_line - line_no) +          m_options.num_lines = end_line - line_no + extra_lines; +      } + +      m_breakpoint_locations.Clear(); + +      if (m_options.show_bp_locs) { +        const bool show_inlines = true; +        m_breakpoint_locations.Reset(start_file, 0, show_inlines); +        SearchFilterForUnconstrainedSearches target_search_filter( +            m_exe_ctx.GetTargetSP()); +        target_search_filter.Search(m_breakpoint_locations); +      } + +      result.AppendMessageWithFormat("File: %s\n", +                                     start_file.GetPath().c_str()); +      // We don't care about the column here. +      const uint32_t column = 0; +      return target->GetSourceManager().DisplaySourceLinesWithLineNumbers( +          start_file, line_no, 0, m_options.num_lines, column, "", +          &result.GetOutputStream(), GetBreakpointLocations()); +    } else { +      result.AppendErrorWithFormat( +          "Could not find function info for: \"%s\".\n", +          m_options.symbol_name.c_str()); +    } +    return 0; +  } + +  // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols functions +  // "take a possibly empty vector of strings which are names of modules, and +  // run the two search functions on the subset of the full module list that +  // matches the strings in the input vector". If we wanted to put these +  // somewhere, +  // there should probably be a module-filter-list that can be passed to the +  // various ModuleList::Find* calls, which would either be a vector of string +  // names or a ModuleSpecList. +  size_t FindMatchingFunctions(Target *target, const ConstString &name, +                               SymbolContextList &sc_list) { +    // Displaying the source for a symbol: +    bool include_inlines = true; +    bool append = true; +    bool include_symbols = false; +    size_t num_matches = 0; + +    if (m_options.num_lines == 0) +      m_options.num_lines = 10; + +    const size_t num_modules = m_options.modules.size(); +    if (num_modules > 0) { +      ModuleList matching_modules; +      for (size_t i = 0; i < num_modules; ++i) { +        FileSpec module_file_spec(m_options.modules[i], false); +        if (module_file_spec) { +          ModuleSpec module_spec(module_file_spec); +          matching_modules.Clear(); +          target->GetImages().FindModules(module_spec, matching_modules); +          num_matches += matching_modules.FindFunctions( +              name, eFunctionNameTypeAuto, include_symbols, include_inlines, +              append, sc_list);          } -    }; - -    size_t -    DisplayFunctionSource (const SymbolContext &sc, -                           SourceInfo &source_info, -                           CommandReturnObject &result) -    { -        if (!source_info.IsValid()) -        { -            source_info.function = sc.GetFunctionName(); -            source_info.line_entry = sc.GetFunctionStartLineEntry(); +      } +    } else { +      num_matches = target->GetImages().FindFunctions( +          name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, +          sc_list); +    } +    return num_matches; +  } + +  size_t FindMatchingFunctionSymbols(Target *target, const ConstString &name, +                                     SymbolContextList &sc_list) { +    size_t num_matches = 0; +    const size_t num_modules = m_options.modules.size(); +    if (num_modules > 0) { +      ModuleList matching_modules; +      for (size_t i = 0; i < num_modules; ++i) { +        FileSpec module_file_spec(m_options.modules[i], false); +        if (module_file_spec) { +          ModuleSpec module_spec(module_file_spec); +          matching_modules.Clear(); +          target->GetImages().FindModules(module_spec, matching_modules); +          num_matches += matching_modules.FindFunctionSymbols( +              name, eFunctionNameTypeAuto, sc_list);          } -     -        if (sc.function) -        { -            Target *target = m_exe_ctx.GetTargetPtr(); - -            FileSpec start_file; -            uint32_t start_line; -            uint32_t end_line; -            FileSpec end_file; -             -            if (sc.block == nullptr) -            { -                // Not an inlined function -                sc.function->GetStartLineSourceInfo (start_file, start_line); -                if (start_line == 0) -                { -                    result.AppendErrorWithFormat("Could not find line information for start of function: \"%s\".\n", source_info.function.GetCString()); -                    result.SetStatus (eReturnStatusFailed); -                    return 0; -                } -                sc.function->GetEndLineSourceInfo (end_file, end_line); -            } -            else -            { -                // We have an inlined function -                start_file = source_info.line_entry.file; -                start_line = source_info.line_entry.line; -                end_line = start_line + m_options.num_lines; -            } +      } +    } else { +      num_matches = target->GetImages().FindFunctionSymbols( +          name, eFunctionNameTypeAuto, sc_list); +    } +    return num_matches; +  } -            // This is a little hacky, but the first line table entry for a function points to the "{" that -            // starts the function block.  It would be nice to actually get the function -            // declaration in there too.  So back up a bit, but not further than what you're going to display. -            uint32_t extra_lines; -            if (m_options.num_lines >= 10) -                extra_lines = 5; -            else -                extra_lines = m_options.num_lines/2; -            uint32_t line_no; -            if (start_line <= extra_lines) -                line_no = 1; -            else -                line_no = start_line - extra_lines; -             -            // For fun, if the function is shorter than the number of lines we're supposed to display, -            // only display the function... -            if (end_line != 0) -            { -                if (m_options.num_lines > end_line - line_no) -                    m_options.num_lines = end_line - line_no + extra_lines; -            } -             -            m_breakpoint_locations.Clear(); +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    const size_t argc = command.GetArgumentCount(); -            if (m_options.show_bp_locs) -            { -                const bool show_inlines = true; -                m_breakpoint_locations.Reset (start_file, 0, show_inlines); -                SearchFilterForUnconstrainedSearches target_search_filter (m_exe_ctx.GetTargetSP()); -                target_search_filter.Search (m_breakpoint_locations); -            } -             -            result.AppendMessageWithFormat("File: %s\n", start_file.GetPath().c_str()); -            return target->GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file, -                                                                                 line_no, -                                                                                 0, -                                                                                 m_options.num_lines, -                                                                                 "", -                                                                                 &result.GetOutputStream(), -                                                                                 GetBreakpointLocations ()); -        } -        else -        { -            result.AppendErrorWithFormat("Could not find function info for: \"%s\".\n", m_options.symbol_name.c_str()); -        } -        return 0; +    if (argc != 0) { +      result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", +                                   GetCommandName().str().c_str()); +      result.SetStatus(eReturnStatusFailed); +      return false;      } -    // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols functions  -    // "take a possibly empty vector of strings which are names of modules, and -    // run the two search functions on the subset of the full module list that -    // matches the strings in the input vector". If we wanted to put these somewhere, -    // there should probably be a module-filter-list that can be passed to the -    // various ModuleList::Find* calls, which would either be a vector of string -    // names or a ModuleSpecList. -    size_t FindMatchingFunctions (Target *target, const ConstString &name, SymbolContextList& sc_list) -    { -        // Displaying the source for a symbol: -        bool include_inlines = true; -        bool append = true; -        bool include_symbols = false; -        size_t num_matches = 0; -         -        if (m_options.num_lines == 0) -            m_options.num_lines = 10; - -        const size_t num_modules = m_options.modules.size(); -        if (num_modules > 0) -        { -            ModuleList matching_modules; -            for (size_t i = 0; i < num_modules; ++i) -            { -                FileSpec module_file_spec(m_options.modules[i].c_str(), false); -                if (module_file_spec) -                { -                    ModuleSpec module_spec (module_file_spec); -                    matching_modules.Clear(); -                    target->GetImages().FindModules (module_spec, matching_modules); -                    num_matches += matching_modules.FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list); -                } +    Target *target = m_exe_ctx.GetTargetPtr(); + +    if (!m_options.symbol_name.empty()) { +      SymbolContextList sc_list; +      ConstString name(m_options.symbol_name.c_str()); + +      // Displaying the source for a symbol. Search for function named name. +      size_t num_matches = FindMatchingFunctions(target, name, sc_list); +      if (!num_matches) { +        // If we didn't find any functions with that name, try searching for +        // symbols +        // that line up exactly with function addresses. +        SymbolContextList sc_list_symbols; +        size_t num_symbol_matches = +            FindMatchingFunctionSymbols(target, name, sc_list_symbols); +        for (size_t i = 0; i < num_symbol_matches; i++) { +          SymbolContext sc; +          sc_list_symbols.GetContextAtIndex(i, sc); +          if (sc.symbol && sc.symbol->ValueIsAddress()) { +            const Address &base_address = sc.symbol->GetAddressRef(); +            Function *function = base_address.CalculateSymbolContextFunction(); +            if (function) { +              sc_list.Append(SymbolContext(function)); +              num_matches++; +              break;              } +          }          } -        else -        { -            num_matches = target->GetImages().FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list); -        } -        return num_matches; -    } +      } -    size_t FindMatchingFunctionSymbols (Target *target, const ConstString &name, SymbolContextList& sc_list) -    { -        size_t num_matches = 0; -        const size_t num_modules = m_options.modules.size(); -        if (num_modules > 0) -        { -            ModuleList matching_modules; -            for (size_t i = 0; i < num_modules; ++i) -            { -                FileSpec module_file_spec(m_options.modules[i].c_str(), false); -                if (module_file_spec) -                { -                    ModuleSpec module_spec (module_file_spec); -                    matching_modules.Clear(); -                    target->GetImages().FindModules (module_spec, matching_modules); -                    num_matches += matching_modules.FindFunctionSymbols (name, eFunctionNameTypeAuto, sc_list); -                } +      if (num_matches == 0) { +        result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", +                                     m_options.symbol_name.c_str()); +        result.SetStatus(eReturnStatusFailed); +        return false; +      } + +      if (num_matches > 1) { +        std::set<SourceInfo> source_match_set; + +        bool displayed_something = false; +        for (size_t i = 0; i < num_matches; i++) { +          SymbolContext sc; +          sc_list.GetContextAtIndex(i, sc); +          SourceInfo source_info(sc.GetFunctionName(), +                                 sc.GetFunctionStartLineEntry()); + +          if (source_info.IsValid()) { +            if (source_match_set.find(source_info) == source_match_set.end()) { +              source_match_set.insert(source_info); +              if (DisplayFunctionSource(sc, source_info, result)) +                displayed_something = true;              } +          }          } + +        if (displayed_something) +          result.SetStatus(eReturnStatusSuccessFinishResult);          else -        { -            num_matches = target->GetImages().FindFunctionSymbols (name, eFunctionNameTypeAuto, sc_list); +          result.SetStatus(eReturnStatusFailed); +      } else { +        SymbolContext sc; +        sc_list.GetContextAtIndex(0, sc); +        SourceInfo source_info; + +        if (DisplayFunctionSource(sc, source_info, result)) { +          result.SetStatus(eReturnStatusSuccessFinishResult); +        } else { +          result.SetStatus(eReturnStatusFailed);          } -        return num_matches; -    } - -    bool -    DoExecute (Args& command, CommandReturnObject &result) override -    { -        const size_t argc = command.GetArgumentCount(); - -        if (argc != 0) -        { -            result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName()); -            result.SetStatus (eReturnStatusFailed); -            return false; +      } +      return result.Succeeded(); +    } else if (m_options.address != LLDB_INVALID_ADDRESS) { +      Address so_addr; +      StreamString error_strm; +      SymbolContextList sc_list; + +      if (target->GetSectionLoadList().IsEmpty()) { +        // The target isn't loaded yet, we need to lookup the file address +        // in all modules +        const ModuleList &module_list = target->GetImages(); +        const size_t num_modules = module_list.GetSize(); +        for (size_t i = 0; i < num_modules; ++i) { +          ModuleSP module_sp(module_list.GetModuleAtIndex(i)); +          if (module_sp && +              module_sp->ResolveFileAddress(m_options.address, so_addr)) { +            SymbolContext sc; +            sc.Clear(true); +            if (module_sp->ResolveSymbolContextForAddress( +                    so_addr, eSymbolContextEverything, sc) & +                eSymbolContextLineEntry) +              sc_list.Append(sc); +          }          } -        Target *target = m_exe_ctx.GetTargetPtr(); - -        if (!m_options.symbol_name.empty()) -        { -            SymbolContextList sc_list; -            ConstString name(m_options.symbol_name.c_str()); - -            // Displaying the source for a symbol. Search for function named name. -            size_t num_matches = FindMatchingFunctions (target, name, sc_list); -            if (!num_matches) -            { -                // If we didn't find any functions with that name, try searching for symbols -                // that line up exactly with function addresses. -                SymbolContextList sc_list_symbols; -                size_t num_symbol_matches = FindMatchingFunctionSymbols (target, name, sc_list_symbols); -                for (size_t i = 0; i < num_symbol_matches; i++) -                { -                    SymbolContext sc; -                    sc_list_symbols.GetContextAtIndex (i, sc); -                    if (sc.symbol && sc.symbol->ValueIsAddress()) -                    { -                        const Address &base_address = sc.symbol->GetAddressRef(); -                        Function *function = base_address.CalculateSymbolContextFunction(); -                        if (function) -                        { -                            sc_list.Append (SymbolContext(function)); -                            num_matches++; -                            break; -                        } -                    } -                } +        if (sc_list.GetSize() == 0) { +          result.AppendErrorWithFormat( +              "no modules have source information for file address 0x%" PRIx64 +              ".\n", +              m_options.address); +          result.SetStatus(eReturnStatusFailed); +          return false; +        } +      } else { +        // The target has some things loaded, resolve this address to a +        // compile unit + file + line and display +        if (target->GetSectionLoadList().ResolveLoadAddress(m_options.address, +                                                            so_addr)) { +          ModuleSP module_sp(so_addr.GetModule()); +          if (module_sp) { +            SymbolContext sc; +            sc.Clear(true); +            if (module_sp->ResolveSymbolContextForAddress( +                    so_addr, eSymbolContextEverything, sc) & +                eSymbolContextLineEntry) { +              sc_list.Append(sc); +            } else { +              so_addr.Dump(&error_strm, nullptr, +                           Address::DumpStyleModuleWithFileAddress); +              result.AppendErrorWithFormat("address resolves to %s, but there " +                                           "is no line table information " +                                           "available for this address.\n", +                                           error_strm.GetData()); +              result.SetStatus(eReturnStatusFailed); +              return false;              } +          } +        } -            if (num_matches == 0) -            { -                result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str()); -                result.SetStatus (eReturnStatusFailed); -                return false; -            } +        if (sc_list.GetSize() == 0) { +          result.AppendErrorWithFormat( +              "no modules contain load address 0x%" PRIx64 ".\n", +              m_options.address); +          result.SetStatus(eReturnStatusFailed); +          return false; +        } +      } +      uint32_t num_matches = sc_list.GetSize(); +      for (uint32_t i = 0; i < num_matches; ++i) { +        SymbolContext sc; +        sc_list.GetContextAtIndex(i, sc); +        if (sc.comp_unit) { +          if (m_options.show_bp_locs) { +            m_breakpoint_locations.Clear(); +            const bool show_inlines = true; +            m_breakpoint_locations.Reset(*sc.comp_unit, 0, show_inlines); +            SearchFilterForUnconstrainedSearches target_search_filter( +                target->shared_from_this()); +            target_search_filter.Search(m_breakpoint_locations); +          } + +          bool show_fullpaths = true; +          bool show_module = true; +          bool show_inlined_frames = true; +          const bool show_function_arguments = true; +          const bool show_function_name = true; +          sc.DumpStopContext(&result.GetOutputStream(), +                             m_exe_ctx.GetBestExecutionContextScope(), +                             sc.line_entry.range.GetBaseAddress(), +                             show_fullpaths, show_module, show_inlined_frames, +                             show_function_arguments, show_function_name); +          result.GetOutputStream().EOL(); + +          if (m_options.num_lines == 0) +            m_options.num_lines = 10; -            if (num_matches > 1) -            { -                std::set<SourceInfo> source_match_set; -                 -                bool displayed_something = false; -                for (size_t i = 0; i < num_matches; i++) -                { -                    SymbolContext sc; -                    sc_list.GetContextAtIndex (i, sc); -                    SourceInfo source_info (sc.GetFunctionName(), -                                            sc.GetFunctionStartLineEntry()); -                     -                    if (source_info.IsValid()) -                    { -                        if (source_match_set.find(source_info) == source_match_set.end()) -                        { -                            source_match_set.insert(source_info); -                            if (DisplayFunctionSource (sc, source_info, result)) -                                displayed_something = true; -                        } -                    } -                } -                 -                if (displayed_something) -                    result.SetStatus (eReturnStatusSuccessFinishResult); -                else -                    result.SetStatus (eReturnStatusFailed); -            } -            else -            { -                SymbolContext sc; -                sc_list.GetContextAtIndex (0, sc); -                SourceInfo source_info; -                 -                if (DisplayFunctionSource (sc, source_info, result)) -                { -                    result.SetStatus (eReturnStatusSuccessFinishResult); -                } -                else -                { -                    result.SetStatus (eReturnStatusFailed); -                } -            } -            return result.Succeeded(); +          size_t lines_to_back_up = +              m_options.num_lines >= 10 ? 5 : m_options.num_lines / 2; + +          const uint32_t column = +              (m_interpreter.GetDebugger().GetStopShowColumn() != +               eStopShowColumnNone) +                  ? sc.line_entry.column +                  : 0; +          target->GetSourceManager().DisplaySourceLinesWithLineNumbers( +              sc.comp_unit, sc.line_entry.line, lines_to_back_up, column, +              m_options.num_lines - lines_to_back_up, "->", +              &result.GetOutputStream(), GetBreakpointLocations()); +          result.SetStatus(eReturnStatusSuccessFinishResult);          } -        else if (m_options.address != LLDB_INVALID_ADDRESS) -        { -            Address so_addr; -            StreamString error_strm; -            SymbolContextList sc_list; - -            if (target->GetSectionLoadList().IsEmpty()) -            { -                // The target isn't loaded yet, we need to lookup the file address -                // in all modules -                const ModuleList &module_list = target->GetImages(); -                const size_t num_modules = module_list.GetSize(); -                for (size_t i = 0; i < num_modules; ++i) -                { -                    ModuleSP module_sp (module_list.GetModuleAtIndex(i)); -                    if (module_sp && module_sp->ResolveFileAddress(m_options.address, so_addr)) -                    { -                        SymbolContext sc; -                        sc.Clear(true); -                        if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry) -                            sc_list.Append(sc); -                    } -                } -                 -                if (sc_list.GetSize() == 0) -                { -                    result.AppendErrorWithFormat("no modules have source information for file address 0x%" PRIx64 ".\n", -                                                 m_options.address); -                    result.SetStatus (eReturnStatusFailed); -                    return false; -                } -            } -            else -            { -                // The target has some things loaded, resolve this address to a -                // compile unit + file + line and display -                if (target->GetSectionLoadList().ResolveLoadAddress (m_options.address, so_addr)) -                { -                    ModuleSP module_sp (so_addr.GetModule()); -                    if (module_sp) -                    { -                        SymbolContext sc; -                        sc.Clear(true); -                        if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry) -                        { -                            sc_list.Append(sc); -                        } -                        else -                        { -                            so_addr.Dump(&error_strm, nullptr, Address::DumpStyleModuleWithFileAddress); -                            result.AppendErrorWithFormat("address resolves to %s, but there is no line table information available for this address.\n", -                                                         error_strm.GetData()); -                            result.SetStatus (eReturnStatusFailed); -                            return false; -                        } -                    } -                } - -                if (sc_list.GetSize() == 0) -                { -                    result.AppendErrorWithFormat("no modules contain load address 0x%" PRIx64 ".\n", m_options.address); -                    result.SetStatus (eReturnStatusFailed); -                    return false; -                } -            } -            uint32_t num_matches = sc_list.GetSize(); -            for (uint32_t i = 0; i < num_matches; ++i) -            { -                SymbolContext sc; -                sc_list.GetContextAtIndex(i, sc); -                if (sc.comp_unit) -                { -                    if (m_options.show_bp_locs) -                    { -                        m_breakpoint_locations.Clear(); -                        const bool show_inlines = true; -                        m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines); -                        SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this()); -                        target_search_filter.Search (m_breakpoint_locations); -                    } -                     -                    bool show_fullpaths = true; -                    bool show_module = true; -                    bool show_inlined_frames = true; -                    const bool show_function_arguments = true; -                    const bool show_function_name = true; -                    sc.DumpStopContext(&result.GetOutputStream(), -                                       m_exe_ctx.GetBestExecutionContextScope(), -                                       sc.line_entry.range.GetBaseAddress(), -                                       show_fullpaths, -                                       show_module, -                                       show_inlined_frames, -                                       show_function_arguments, -                                       show_function_name); -                    result.GetOutputStream().EOL(); - -                    if (m_options.num_lines == 0) -                        m_options.num_lines = 10; -                     -                    size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2; - -                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit, -                                                                                  sc.line_entry.line, -                                                                                  lines_to_back_up, -                                                                                  m_options.num_lines - lines_to_back_up, -                                                                                  "->", -                                                                                  &result.GetOutputStream(), -                                                                                  GetBreakpointLocations ()); -                    result.SetStatus (eReturnStatusSuccessFinishResult); -                } -            } +      } +    } else if (m_options.file_name.empty()) { +      // Last valid source manager context, or the current frame if no +      // valid last context in source manager. +      // One little trick here, if you type the exact same list command twice in +      // a row, it is +      // more likely because you typed it once, then typed it again +      if (m_options.start_line == 0) { +        if (target->GetSourceManager().DisplayMoreWithLineNumbers( +                &result.GetOutputStream(), m_options.num_lines, +                m_options.reverse, GetBreakpointLocations())) { +          result.SetStatus(eReturnStatusSuccessFinishResult);          } -        else if (m_options.file_name.empty()) -        { -            // Last valid source manager context, or the current frame if no -            // valid last context in source manager. -            // One little trick here, if you type the exact same list command twice in a row, it is -            // more likely because you typed it once, then typed it again -            if (m_options.start_line == 0) -            { -                if (target->GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream(), -                                                                           m_options.num_lines, -                                                                           m_options.reverse, -                                                                           GetBreakpointLocations ())) -                { -                    result.SetStatus (eReturnStatusSuccessFinishResult); -                } -            } -            else -            { -                if (m_options.num_lines == 0) -                    m_options.num_lines = 10; - -                if (m_options.show_bp_locs) -                { -                    SourceManager::FileSP last_file_sp (target->GetSourceManager().GetLastFile ()); -                    if (last_file_sp) -                    { -                        const bool show_inlines = true; -                        m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines); -                        SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this()); -                        target_search_filter.Search (m_breakpoint_locations); -                    } -                } -                else -                    m_breakpoint_locations.Clear(); - -                if (target->GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile( -                            m_options.start_line,   // Line to display -                            m_options.num_lines,    // Lines after line to -                            UINT32_MAX,             // Don't mark "line" -                            "",                     // Don't mark "line" -                            &result.GetOutputStream(), -                            GetBreakpointLocations ())) -                { -                    result.SetStatus (eReturnStatusSuccessFinishResult); -                } -            } +      } else { +        if (m_options.num_lines == 0) +          m_options.num_lines = 10; + +        if (m_options.show_bp_locs) { +          SourceManager::FileSP last_file_sp( +              target->GetSourceManager().GetLastFile()); +          if (last_file_sp) { +            const bool show_inlines = true; +            m_breakpoint_locations.Reset(last_file_sp->GetFileSpec(), 0, +                                         show_inlines); +            SearchFilterForUnconstrainedSearches target_search_filter( +                target->shared_from_this()); +            target_search_filter.Search(m_breakpoint_locations); +          } +        } else +          m_breakpoint_locations.Clear(); + +        const uint32_t column = 0; +        if (target->GetSourceManager() +                .DisplaySourceLinesWithLineNumbersUsingLastFile( +                    m_options.start_line, // Line to display +                    m_options.num_lines,  // Lines after line to +                    UINT32_MAX,           // Don't mark "line" +                    column, +                    "", // Don't mark "line" +                    &result.GetOutputStream(), GetBreakpointLocations())) { +          result.SetStatus(eReturnStatusSuccessFinishResult);          } -        else -        { -            const char *filename = m_options.file_name.c_str(); - -            bool check_inlines = false; -            SymbolContextList sc_list; -            size_t num_matches = 0; -             -            if (!m_options.modules.empty()) -            { -                ModuleList matching_modules; -                for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) -                { -                    FileSpec module_file_spec(m_options.modules[i].c_str(), false); -                    if (module_file_spec) -                    { -                        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, -                                                                                         eSymbolContextModule | eSymbolContextCompUnit, -                                                                                         sc_list); -                    } -                } -            } -            else -            { -                num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename, -                                                                                   0, -                                                                                   check_inlines, -                                                                                   eSymbolContextModule | eSymbolContextCompUnit, -                                                                                   sc_list); -            } -             -            if (num_matches == 0) -            { -                result.AppendErrorWithFormat("Could not find source file \"%s\".\n",  -                                             m_options.file_name.c_str()); -                result.SetStatus (eReturnStatusFailed); -                return false; -            } +      } +    } else { +      const char *filename = m_options.file_name.c_str(); + +      bool check_inlines = false; +      SymbolContextList sc_list; +      size_t num_matches = 0; + +      if (!m_options.modules.empty()) { +        ModuleList matching_modules; +        for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) { +          FileSpec module_file_spec(m_options.modules[i], false); +          if (module_file_spec) { +            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, +                eSymbolContextModule | eSymbolContextCompUnit, sc_list); +          } +        } +      } else { +        num_matches = target->GetImages().ResolveSymbolContextForFilePath( +            filename, 0, check_inlines, +            eSymbolContextModule | eSymbolContextCompUnit, sc_list); +      } + +      if (num_matches == 0) { +        result.AppendErrorWithFormat("Could not find source file \"%s\".\n", +                                     m_options.file_name.c_str()); +        result.SetStatus(eReturnStatusFailed); +        return false; +      } + +      if (num_matches > 1) { +        bool got_multiple = false; +        FileSpec *test_cu_spec = nullptr; + +        for (unsigned i = 0; i < num_matches; i++) { +          SymbolContext sc; +          sc_list.GetContextAtIndex(i, sc); +          if (sc.comp_unit) { +            if (test_cu_spec) { +              if (test_cu_spec != static_cast<FileSpec *>(sc.comp_unit)) +                got_multiple = true; +              break; +            } else +              test_cu_spec = sc.comp_unit; +          } +        } +        if (got_multiple) { +          result.AppendErrorWithFormat( +              "Multiple source files found matching: \"%s.\"\n", +              m_options.file_name.c_str()); +          result.SetStatus(eReturnStatusFailed); +          return false; +        } +      } + +      SymbolContext sc; +      if (sc_list.GetContextAtIndex(0, sc)) { +        if (sc.comp_unit) { +          if (m_options.show_bp_locs) { +            const bool show_inlines = true; +            m_breakpoint_locations.Reset(*sc.comp_unit, 0, show_inlines); +            SearchFilterForUnconstrainedSearches target_search_filter( +                target->shared_from_this()); +            target_search_filter.Search(m_breakpoint_locations); +          } else +            m_breakpoint_locations.Clear(); -            if (num_matches > 1) -            { -                bool got_multiple = false; -                FileSpec *test_cu_spec = nullptr; - -                for (unsigned i = 0; i < num_matches; i++) -                { -                    SymbolContext sc; -                    sc_list.GetContextAtIndex(i, sc); -                    if (sc.comp_unit) -                    { -                        if (test_cu_spec) -                        { -                            if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit)) -                                got_multiple = true; -                            break; -                        } -                        else -                            test_cu_spec = sc.comp_unit; -                    } -                } -                if (got_multiple) -                { -                    result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n", -                                                 m_options.file_name.c_str()); -                    result.SetStatus (eReturnStatusFailed); -                    return false; -                } -            } -             -            SymbolContext sc; -            if (sc_list.GetContextAtIndex(0, sc)) -            { -                if (sc.comp_unit) -                { -                    if (m_options.show_bp_locs) -                    { -                        const bool show_inlines = true; -                        m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines); -                        SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this()); -                        target_search_filter.Search (m_breakpoint_locations); -                    } -                    else -                        m_breakpoint_locations.Clear(); - -                    if (m_options.num_lines == 0) -                        m_options.num_lines = 10; -                     -                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit, -                                                                                  m_options.start_line, -                                                                                  0, -                                                                                  m_options.num_lines, -                                                                                  "", -                                                                                  &result.GetOutputStream(), -                                                                                  GetBreakpointLocations ()); - -                    result.SetStatus (eReturnStatusSuccessFinishResult); -                } -                else -                { -                    result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n",  -                                                 m_options.file_name.c_str()); -                    result.SetStatus (eReturnStatusFailed); -                    return false; -                } -            } +          if (m_options.num_lines == 0) +            m_options.num_lines = 10; +          const uint32_t column = 0; +          target->GetSourceManager().DisplaySourceLinesWithLineNumbers( +              sc.comp_unit, m_options.start_line, 0, m_options.num_lines, +              column, "", &result.GetOutputStream(), GetBreakpointLocations()); + +          result.SetStatus(eReturnStatusSuccessFinishResult); +        } else { +          result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n", +                                       m_options.file_name.c_str()); +          result.SetStatus(eReturnStatusFailed); +          return false;          } -        return result.Succeeded(); -    } -     -    const SymbolContextList * -    GetBreakpointLocations () -    { -        if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0) -            return &m_breakpoint_locations.GetFileLineMatches(); -        return nullptr; +      }      } - -    CommandOptions m_options; -    FileLineResolver m_breakpoint_locations; -    std::string    m_reverse_name; -}; - -OptionDefinition -CommandObjectSourceList::CommandOptions::g_option_table[] = -{ -{ LLDB_OPT_SET_ALL, false, "count",  'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,   "The number of source lines to display."}, -{ LLDB_OPT_SET_1  | -  LLDB_OPT_SET_2  , false, "shlib",  's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."}, -{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."}, -{ LLDB_OPT_SET_1  , false, "file",   'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,    "The file from which to display source."}, -{ LLDB_OPT_SET_1  , false, "line",   'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,    "The line number at which to start the display source."}, -{ LLDB_OPT_SET_2  , false, "name",   'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeSymbol,    "The name of a function whose source to display."}, -{ LLDB_OPT_SET_3  , false, "address",'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line."}, -{ LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."}, -{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } +    return result.Succeeded(); +  } + +  const SymbolContextList *GetBreakpointLocations() { +    if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0) +      return &m_breakpoint_locations.GetFileLineMatches(); +    return nullptr; +  } + +  CommandOptions m_options; +  FileLineResolver m_breakpoint_locations; +  std::string m_reverse_name;  };  #pragma mark CommandObjectMultiwordSource @@ -1478,14 +1314,17 @@ CommandObjectSourceList::CommandOptions::g_option_table[] =  // CommandObjectMultiwordSource  //------------------------------------------------------------------------- -CommandObjectMultiwordSource::CommandObjectMultiwordSource(CommandInterpreter &interpreter) -    : CommandObjectMultiword( -          interpreter, "source", -          "Commands for examining source code described by debug information for the current target process.", -          "source <subcommand> [<subcommand-options>]") -{ -    LoadSubCommand ("info",   CommandObjectSP (new CommandObjectSourceInfo (interpreter))); -    LoadSubCommand ("list",   CommandObjectSP (new CommandObjectSourceList (interpreter))); +CommandObjectMultiwordSource::CommandObjectMultiwordSource( +    CommandInterpreter &interpreter) +    : CommandObjectMultiword(interpreter, "source", "Commands for examining " +                                                    "source code described by " +                                                    "debug information for the " +                                                    "current target process.", +                             "source <subcommand> [<subcommand-options>]") { +  LoadSubCommand("info", +                 CommandObjectSP(new CommandObjectSourceInfo(interpreter))); +  LoadSubCommand("list", +                 CommandObjectSP(new CommandObjectSourceList(interpreter)));  }  CommandObjectMultiwordSource::~CommandObjectMultiwordSource() = default; | 
