//===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "CommandObjectSource.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileLineResolver.h"
#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/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
#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;

#pragma mark CommandObjectSourceInfo
//----------------------------------------------------------------------
// 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;
        }

        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();
        }

        const OptionDefinition *
        GetDefinitions () override
        {
            return g_option_table;
        }

        static OptionDefinition 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 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() override = default;

    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 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;
    }
    
    // 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;
    }
    
    // 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);
        }
        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++;
                    }
                }
            }
        }
        if (num_matches == 0)
        {
            result.AppendErrorWithFormat("Could not find function named \'%s\'.\n",
                                         m_options.symbol_name.c_str());
            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;
                }
            }
            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;
        }

        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;
            }
        }

        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;
        }

        // 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();
    }

    CommandOptions m_options;
    ModuleList m_module_list;
};

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}
};

#pragma mark CommandObjectSourceList
//-------------------------------------------------------------------------
// CommandObjectSourceList
//-------------------------------------------------------------------------

class CommandObjectSourceList : 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 '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;
            }

            return error;
        }

        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();
        }

        const OptionDefinition*
        GetDefinitions () override
        {
            return g_option_table;
        }

        static OptionDefinition 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;
    };

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)
    {
    }

    ~CommandObjectSourceList() override = default;

    Options *
    GetOptions () override
    {
        return &m_options;
    }

    const char *
    GetRepeatCommand (Args &current_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();
    }

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()
        {
        }
        
        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;
        }
    };

    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();
        }
    
        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;
            }

            // 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());
            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;
    }

    // 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);
                }
            }
        }
        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);
                }
            }
        }
        else
        {
            num_matches = target->GetImages().FindFunctionSymbols (name, eFunctionNameTypeAuto, sc_list);
        }
        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;
        }

        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 (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
                    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();
        }
        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.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
        {
            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;
            }

            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;
                }
            }
        }
        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 }
};

#pragma mark CommandObjectMultiwordSource
//-------------------------------------------------------------------------
// 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() = default;
