//===-- SWIG Interface for SBTarget -----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

namespace lldb {


%feature("docstring",
"Represents the target program running under the debugger.

SBTarget supports module, breakpoint, and watchpoint iterations. For example,

    for m in target.module_iter():
        print m

produces:

(x86_64) /Volumes/data/lldb/svn/trunk/test/python_api/lldbutil/iter/a.out
(x86_64) /usr/lib/dyld
(x86_64) /usr/lib/libstdc++.6.dylib
(x86_64) /usr/lib/libSystem.B.dylib
(x86_64) /usr/lib/system/libmathCommon.A.dylib
(x86_64) /usr/lib/libSystem.B.dylib(__commpage)

and,

    for b in target.breakpoint_iter():
        print b

produces:

SBBreakpoint: id = 1, file ='main.cpp', line = 66, locations = 1
SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1

and,

    for wp_loc in target.watchpoint_iter():
        print wp_loc

produces:

Watchpoint 1: addr = 0x1034ca048 size = 4 state = enabled type = rw
    declare @ '/Volumes/data/lldb/svn/trunk/test/python_api/watchpoint/main.c:12'
    hw_index = 0  hit_count = 2     ignore_count = 0"
) SBTarget;
class SBTarget
{
public:
    //------------------------------------------------------------------
    // Broadcaster bits.
    //------------------------------------------------------------------
    enum
    {
        eBroadcastBitBreakpointChanged  = (1 << 0),
        eBroadcastBitModulesLoaded      = (1 << 1),
        eBroadcastBitModulesUnloaded    = (1 << 2),
        eBroadcastBitWatchpointChanged  = (1 << 3),
        eBroadcastBitSymbolsLoaded      = (1 << 4)
    };

    //------------------------------------------------------------------
    // Constructors
    //------------------------------------------------------------------
    SBTarget ();

    SBTarget (const lldb::SBTarget& rhs);

    //------------------------------------------------------------------
    // Destructor
    //------------------------------------------------------------------
    ~SBTarget();

    static const char *
    GetBroadcasterClassName ();

    bool
    IsValid() const;

    explicit operator bool() const;

    static bool
    EventIsTargetEvent (const lldb::SBEvent &event);

    static lldb::SBTarget
    GetTargetFromEvent (const lldb::SBEvent &event);

    static uint32_t
    GetNumModulesFromEvent (const lldb::SBEvent &event);

    static lldb::SBModule
    GetModuleAtIndexFromEvent (const uint32_t idx, const lldb::SBEvent &event);

    lldb::SBProcess
    GetProcess ();


    %feature("docstring", "
    Return the platform object associated with the target.

    After return, the platform object should be checked for
    validity.

    @return
        A platform object.") GetPlatform;
    lldb::SBPlatform
    GetPlatform ();

    %feature("docstring", "
    Install any binaries that need to be installed.

    This function does nothing when debugging on the host system.
    When connected to remote platforms, the target's main executable
    and any modules that have their install path set will be
    installed on the remote platform. If the main executable doesn't
    have an install location set, it will be installed in the remote
    platform's working directory.

    @return
        An error describing anything that went wrong during
        installation.") Install;
    lldb::SBError
    Install();

    %feature("docstring", "
    Launch a new process.

    Launch a new process by spawning a new process using the
    target object's executable module's file as the file to launch.
    Arguments are given in argv, and the environment variables
    are in envp. Standard input and output files can be
    optionally re-directed to stdin_path, stdout_path, and
    stderr_path.

    @param[in] listener
        An optional listener that will receive all process events.
        If listener is valid then listener will listen to all
        process events. If not valid, then this target's debugger
        (SBTarget::GetDebugger()) will listen to all process events.

    @param[in] argv
        The argument array.

    @param[in] envp
        The environment array.

    @param[in] launch_flags
        Flags to modify the launch (@see lldb::LaunchFlags)

    @param[in] stdin_path
        The path to use when re-directing the STDIN of the new
        process. If all stdXX_path arguments are NULL, a pseudo
        terminal will be used.

    @param[in] stdout_path
        The path to use when re-directing the STDOUT of the new
        process. If all stdXX_path arguments are NULL, a pseudo
        terminal will be used.

    @param[in] stderr_path
        The path to use when re-directing the STDERR of the new
        process. If all stdXX_path arguments are NULL, a pseudo
        terminal will be used.

    @param[in] working_directory
        The working directory to have the child process run in

    @param[in] launch_flags
        Some launch options specified by logical OR'ing
        lldb::LaunchFlags enumeration values together.

    @param[in] stop_at_entry
        If false do not stop the inferior at the entry point.

    @param[out]
        An error object. Contains the reason if there is some failure.

    @return
         A process object for the newly created process.

    For example,

        process = target.Launch(self.dbg.GetListener(), None, None,
                                None, '/tmp/stdout.txt', None,
                                None, 0, False, error)

    launches a new process by passing nothing for both the args and the envs
    and redirect the standard output of the inferior to the /tmp/stdout.txt
    file. It does not specify a working directory so that the debug server
    will use its idea of what the current working directory is for the
    inferior. Also, we ask the debugger not to stop the inferior at the
    entry point. If no breakpoint is specified for the inferior, it should
    run to completion if no user interaction is required.") Launch;
    lldb::SBProcess
    Launch (SBListener &listener,
            char const **argv,
            char const **envp,
            const char *stdin_path,
            const char *stdout_path,
            const char *stderr_path,
            const char *working_directory,
            uint32_t launch_flags,   // See LaunchFlags
            bool stop_at_entry,
            lldb::SBError& error);

    %feature("docstring", "
    Launch a new process with sensible defaults.

    @param[in] argv
        The argument array.

    @param[in] envp
        The environment array.

    @param[in] working_directory
        The working directory to have the child process run in

    Default: listener
        Set to the target's debugger (SBTarget::GetDebugger())

    Default: launch_flags
        Empty launch flags

    Default: stdin_path
    Default: stdout_path
    Default: stderr_path
        A pseudo terminal will be used.

    @return
         A process object for the newly created process.

    For example,

        process = target.LaunchSimple(['X', 'Y', 'Z'], None, os.getcwd())

    launches a new process by passing 'X', 'Y', 'Z' as the args to the
    executable.") LaunchSimple;
    lldb::SBProcess
    LaunchSimple (const char **argv,
                  const char **envp,
                  const char *working_directory);

    lldb::SBProcess
    Launch (lldb::SBLaunchInfo &launch_info, lldb::SBError& error);

    %feature("docstring", "
    Load a core file

    @param[in] core_file
        File path of the core dump.

    @param[out] error
        An error explaining what went wrong if the operation fails.
        (Optional)

    @return
         A process object for the newly created core file.

    For example,

        process = target.LoadCore('./a.out.core')

    loads a new core file and returns the process object.") LoadCore;
    lldb::SBProcess
    LoadCore(const char *core_file);

    lldb::SBProcess
    LoadCore(const char *core_file, lldb::SBError &error);

    lldb::SBProcess
    Attach(lldb::SBAttachInfo &attach_info, lldb::SBError& error);

    %feature("docstring", "
    Attach to process with pid.

    @param[in] listener
        An optional listener that will receive all process events.
        If listener is valid then listener will listen to all
        process events. If not valid, then this target's debugger
        (SBTarget::GetDebugger()) will listen to all process events.

    @param[in] pid
        The process ID to attach to.

    @param[out]
        An error explaining what went wrong if attach fails.

    @return
         A process object for the attached process.") AttachToProcessWithID;
    lldb::SBProcess
    AttachToProcessWithID (SBListener &listener,
                           lldb::pid_t pid,
                           lldb::SBError& error);

    %feature("docstring", "
    Attach to process with name.

    @param[in] listener
        An optional listener that will receive all process events.
        If listener is valid then listener will listen to all
        process events. If not valid, then this target's debugger
        (SBTarget::GetDebugger()) will listen to all process events.

    @param[in] name
        Basename of process to attach to.

    @param[in] wait_for
        If true wait for a new instance of 'name' to be launched.

    @param[out]
        An error explaining what went wrong if attach fails.

    @return
         A process object for the attached process.") AttachToProcessWithName;
    lldb::SBProcess
    AttachToProcessWithName (SBListener &listener,
                             const char *name,
                             bool wait_for,
                             lldb::SBError& error);

    %feature("docstring", "
    Connect to a remote debug server with url.

    @param[in] listener
        An optional listener that will receive all process events.
        If listener is valid then listener will listen to all
        process events. If not valid, then this target's debugger
        (SBTarget::GetDebugger()) will listen to all process events.

    @param[in] url
        The url to connect to, e.g., 'connect://localhost:12345'.

    @param[in] plugin_name
        The plugin name to be used; can be NULL.

    @param[out]
        An error explaining what went wrong if the connect fails.

    @return
         A process object for the connected process.") ConnectRemote;
    lldb::SBProcess
    ConnectRemote (SBListener &listener,
                   const char *url,
                   const char *plugin_name,
                   SBError& error);

    lldb::SBFileSpec
    GetExecutable ();

    %feature("docstring", "
    Append the path mapping (from -> to) to the target's paths mapping list.") AppendImageSearchPath;
    void
    AppendImageSearchPath (const char *from,
                           const char *to,
                           SBError &error);

    bool
    AddModule (lldb::SBModule &module);

    lldb::SBModule
    AddModule (const char *path,
               const char *triple,
               const char *uuid);

    lldb::SBModule
    AddModule (const char *path,
               const char *triple,
               const char *uuid_cstr,
               const char *symfile);

    lldb::SBModule
    AddModule (const SBModuleSpec &module_spec);

    uint32_t
    GetNumModules () const;

    lldb::SBModule
    GetModuleAtIndex (uint32_t idx);

    bool
    RemoveModule (lldb::SBModule module);

    lldb::SBDebugger
    GetDebugger() const;

    lldb::SBModule
    FindModule (const lldb::SBFileSpec &file_spec);

    %feature("docstring", "
    Find compile units related to *this target and passed source
    file.

    @param[in] sb_file_spec
        A lldb::SBFileSpec object that contains source file
        specification.

    @return
        A lldb::SBSymbolContextList that gets filled in with all of
        the symbol contexts for all the matches.") FindCompileUnits;
    lldb::SBSymbolContextList
    FindCompileUnits (const lldb::SBFileSpec &sb_file_spec);

    lldb::ByteOrder
    GetByteOrder ();

    uint32_t
    GetAddressByteSize();

    const char *
    GetTriple ();

    %feature("docstring", "
    Architecture data byte width accessor

    @return
    The size in 8-bit (host) bytes of a minimum addressable
    unit from the Architecture's data bus") GetDataByteSize;
    uint32_t
    GetDataByteSize ();

    %feature("docstring", "
    Architecture code byte width accessor

    @return
    The size in 8-bit (host) bytes of a minimum addressable
    unit from the Architecture's code bus") GetCodeByteSize;
    uint32_t
    GetCodeByteSize ();

    lldb::SBError
    SetSectionLoadAddress (lldb::SBSection section,
                           lldb::addr_t section_base_addr);

    lldb::SBError
    ClearSectionLoadAddress (lldb::SBSection section);

    lldb::SBError
    SetModuleLoadAddress (lldb::SBModule module,
                          int64_t sections_offset);

    lldb::SBError
    ClearModuleLoadAddress (lldb::SBModule module);

    %feature("docstring", "
    Find functions by name.

    @param[in] name
        The name of the function we are looking for.

    @param[in] name_type_mask
        A logical OR of one or more FunctionNameType enum bits that
        indicate what kind of names should be used when doing the
        lookup. Bits include fully qualified names, base names,
        C++ methods, or ObjC selectors.
        See FunctionNameType for more details.

    @return
        A lldb::SBSymbolContextList that gets filled in with all of
        the symbol contexts for all the matches.") FindFunctions;
    lldb::SBSymbolContextList
    FindFunctions (const char *name,
                   uint32_t name_type_mask = lldb::eFunctionNameTypeAny);

    lldb::SBType
    FindFirstType (const char* type);

    lldb::SBTypeList
    FindTypes (const char* type);

    lldb::SBType
    GetBasicType(lldb::BasicType type);

    lldb::SBSourceManager
    GetSourceManager ();

    %feature("docstring", "
    Find global and static variables by name.

    @param[in] name
        The name of the global or static variable we are looking
        for.

    @param[in] max_matches
        Allow the number of matches to be limited to max_matches.

    @return
        A list of matched variables in an SBValueList.") FindGlobalVariables;
    lldb::SBValueList
    FindGlobalVariables (const char *name,
                         uint32_t max_matches);

     %feature("docstring", "
    Find the first global (or static) variable by name.

    @param[in] name
        The name of the global or static variable we are looking
        for.

    @return
        An SBValue that gets filled in with the found variable (if any).") FindFirstGlobalVariable;
    lldb::SBValue
    FindFirstGlobalVariable (const char* name);


    lldb::SBValueList
    FindGlobalVariables(const char *name,
                        uint32_t max_matches,
                        MatchType matchtype);

    lldb::SBSymbolContextList
    FindGlobalFunctions(const char *name,
                        uint32_t max_matches,
                        MatchType matchtype);

    void
    Clear ();

     %feature("docstring", "
    Resolve a current file address into a section offset address.

    @param[in] file_addr

    @return
        An SBAddress which will be valid if...") ResolveFileAddress;
    lldb::SBAddress
    ResolveFileAddress (lldb::addr_t file_addr);

    lldb::SBAddress
    ResolveLoadAddress (lldb::addr_t vm_addr);

    lldb::SBAddress
    ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr);

    SBSymbolContext
    ResolveSymbolContextForAddress (const SBAddress& addr,
                                    uint32_t resolve_scope);

     %feature("docstring", "
    Read target memory. If a target process is running then memory
    is read from here. Otherwise the memory is read from the object
    files. For a target whose bytes are sized as a multiple of host
    bytes, the data read back will preserve the target's byte order.

    @param[in] addr
        A target address to read from.

    @param[out] buf
        The buffer to read memory into.

    @param[in] size
        The maximum number of host bytes to read in the buffer passed
        into this call

    @param[out] error
        Error information is written here if the memory read fails.

    @return
        The amount of data read in host bytes.") ReadMemory;
    size_t
    ReadMemory (const SBAddress addr, void *buf, size_t size, lldb::SBError &error);

    lldb::SBBreakpoint
    BreakpointCreateByLocation (const char *file, uint32_t line);

    lldb::SBBreakpoint
    BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line);

    lldb::SBBreakpoint
    BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset);

    lldb::SBBreakpoint
    BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line,
                                lldb::addr_t offset, SBFileSpecList &module_list);

    lldb::SBBreakpoint
    BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line,
                                uint32_t column, lldb::addr_t offset,
                                SBFileSpecList &module_list);

    lldb::SBBreakpoint
    BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL);

    lldb::SBBreakpoint
    BreakpointCreateByName (const char *symbol_name,
                            uint32_t func_name_type,           // Logical OR one or more FunctionNameType enum bits
                            const SBFileSpecList &module_list,
                            const SBFileSpecList &comp_unit_list);

    lldb::SBBreakpoint
    BreakpointCreateByName (const char *symbol_name,
                            uint32_t func_name_type,           // Logical OR one or more FunctionNameType enum bits
                            lldb::LanguageType symbol_language,
                            const SBFileSpecList &module_list,
                            const SBFileSpecList &comp_unit_list);

%typemap(in) (const char **symbol_name, uint32_t num_names) {
  using namespace lldb_private;
  /* Check if is a list  */
  if (PythonList::Check($input)) {
    PythonList list(PyRefType::Borrowed, $input);
    $2 = list.GetSize();
    int i = 0;
    $1 = (char**)malloc(($2+1)*sizeof(char*));
    for (i = 0; i < $2; i++) {
      PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();
      if (!py_str.IsAllocated()) {
        PyErr_SetString(PyExc_TypeError,"list must contain strings and blubby");
        free($1);
        return nullptr;
      }

      $1[i] = const_cast<char*>(py_str.GetString().data());
    }
    $1[i] = 0;
  } else if ($input == Py_None) {
    $1 =  NULL;
  } else {
    PyErr_SetString(PyExc_TypeError,"not a list");
    return NULL;
  }
}

//%typecheck(SWIG_TYPECHECK_STRING_ARRAY) (const char *symbol_name[], uint32_t num_names) {
//    $1 = 1;
//    $2 = 1;
//}

    lldb::SBBreakpoint
    BreakpointCreateByNames (const char **symbol_name,
                             uint32_t num_names,
                             uint32_t name_type_mask,           // Logical OR one or more FunctionNameType enum bits
                             const SBFileSpecList &module_list,
                             const SBFileSpecList &comp_unit_list);

    lldb::SBBreakpoint
    BreakpointCreateByNames (const char **symbol_name,
                             uint32_t num_names,
                             uint32_t name_type_mask,           // Logical OR one or more FunctionNameType enum bits
                             lldb::LanguageType symbol_language,
                             const SBFileSpecList &module_list,
                             const SBFileSpecList &comp_unit_list);

    lldb::SBBreakpoint
    BreakpointCreateByNames (const char **symbol_name,
                             uint32_t num_names,
                             uint32_t name_type_mask,           // Logical OR one or more FunctionNameType enum bits
                             lldb::LanguageType symbol_language,
                             lldb::addr_t offset,
                             const SBFileSpecList &module_list,
                             const SBFileSpecList &comp_unit_list);

    lldb::SBBreakpoint
    BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL);

    lldb::SBBreakpoint
    BreakpointCreateByRegex (const char *symbol_name_regex,
                             lldb::LanguageType symbol_language,
                             const SBFileSpecList &module_list,
                             const SBFileSpecList &comp_unit_list);

    lldb::SBBreakpoint
    BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name = NULL);

    lldb::SBBreakpoint
    BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpecList &module_list, const lldb::SBFileSpecList &file_list);

    lldb::SBBreakpoint
    BreakpointCreateBySourceRegex (const char *source_regex,
                                   const SBFileSpecList &module_list,
                                   const SBFileSpecList &source_file,
                                   const SBStringList  &func_names);

    lldb::SBBreakpoint
    BreakpointCreateForException  (lldb::LanguageType language,
                                   bool catch_bp,
                                   bool throw_bp);

    lldb::SBBreakpoint
    BreakpointCreateByAddress (addr_t address);

    lldb::SBBreakpoint
    BreakpointCreateBySBAddress (SBAddress &sb_address);

    %feature("docstring", "
    Create a breakpoint using a scripted resolver.

    @param[in] class_name
       This is the name of the class that implements a scripted resolver.
       The class should have the following signature:
       class Resolver:
           def __init__(self, bkpt, extra_args):
               # bkpt - the breakpoint for which this is the resolver.  When
               # the resolver finds an interesting address, call AddLocation
               # on this breakpoint to add it.
               #
               # extra_args - an SBStructuredData that can be used to
               # parametrize this instance.  Same as the extra_args passed
               # to BreakpointCreateFromScript.

           def __get_depth__ (self):
               # This is optional, but if defined, you should return the
               # depth at which you want the callback to be called.  The
               # available options are:
               #    lldb.eSearchDepthModule
               #    lldb.eSearchDepthCompUnit
               # The default if you don't implement this method is
               # eSearchDepthModule.

           def __callback__(self, sym_ctx):
               # sym_ctx - an SBSymbolContext that is the cursor in the
               # search through the program to resolve breakpoints.
               # The sym_ctx will be filled out to the depth requested in
               # __get_depth__.
               # Look in this sym_ctx for new breakpoint locations,
               # and if found use bkpt.AddLocation to add them.
               # Note, you will only get called for modules/compile_units that
               # pass the SearchFilter provided by the module_list & file_list
               # passed into BreakpointCreateFromScript.

           def get_short_help(self):
               # Optional, but if implemented return a short string that will
               # be printed at the beginning of the break list output for the
               # breakpoint.

    @param[in] extra_args
       This is an SBStructuredData object that will get passed to the
       constructor of the class in class_name.  You can use this to
       reuse the same class, parametrizing it with entries from this
       dictionary.

    @param module_list
       If this is non-empty, this will be used as the module filter in the
       SearchFilter created for this breakpoint.

    @param file_list
       If this is non-empty, this will be used as the comp unit filter in the
       SearchFilter created for this breakpoint.

    @return
        An SBBreakpoint that will set locations based on the logic in the
        resolver's search callback.") BreakpointCreateFromScript;
    lldb::SBBreakpoint BreakpointCreateFromScript(
      const char *class_name,
      SBStructuredData &extra_args,
      const SBFileSpecList &module_list,
      const SBFileSpecList &file_list,
      bool request_hardware = false);

    uint32_t
    GetNumBreakpoints () const;

    lldb::SBBreakpoint
    GetBreakpointAtIndex (uint32_t idx) const;

    bool
    BreakpointDelete (break_id_t break_id);

    lldb::SBBreakpoint
    FindBreakpointByID (break_id_t break_id);


    bool FindBreakpointsByName(const char *name, SBBreakpointList &bkpt_list);

    void DeleteBreakpointName(const char *name);

    void GetBreakpointNames(SBStringList &names);

    bool
    EnableAllBreakpoints ();

    bool
    DisableAllBreakpoints ();

    bool
    DeleteAllBreakpoints ();

     %feature("docstring", "
    Read breakpoints from source_file and return the newly created
    breakpoints in bkpt_list.

    @param[in] source_file
       The file from which to read the breakpoints

    @param[out] bkpt_list
       A list of the newly created breakpoints.

    @return
        An SBError detailing any errors in reading in the breakpoints.") BreakpointsCreateFromFile;
    lldb::SBError
    BreakpointsCreateFromFile(SBFileSpec &source_file,
                              SBBreakpointList &bkpt_list);

     %feature("docstring", "
    Read breakpoints from source_file and return the newly created
    breakpoints in bkpt_list.

    @param[in] source_file
       The file from which to read the breakpoints

    @param[in] matching_names
       Only read in breakpoints whose names match one of the names in this
       list.

    @param[out] bkpt_list
       A list of the newly created breakpoints.

    @return
        An SBError detailing any errors in reading in the breakpoints.") BreakpointsCreateFromFile;
    lldb::SBError BreakpointsCreateFromFile(SBFileSpec &source_file,
                                          SBStringList &matching_names,
                                          SBBreakpointList &new_bps);

     %feature("docstring", "
    Write breakpoints to dest_file.

    @param[in] dest_file
       The file to which to write the breakpoints.

    @return
        An SBError detailing any errors in writing in the breakpoints.") BreakpointsCreateFromFile;
    lldb::SBError
    BreakpointsWriteToFile(SBFileSpec &dest_file);

     %feature("docstring", "
    Write breakpoints listed in bkpt_list to dest_file.

    @param[in] dest_file
       The file to which to write the breakpoints.

    @param[in] bkpt_list
       Only write breakpoints from this list.

    @param[in] append
       If true, append the breakpoints in bkpt_list to the others
       serialized in dest_file.  If dest_file doesn't exist, then a new
       file will be created and the breakpoints in bkpt_list written to it.

    @return
        An SBError detailing any errors in writing in the breakpoints.") BreakpointsCreateFromFile;
    lldb::SBError
    BreakpointsWriteToFile(SBFileSpec &dest_file,
                           SBBreakpointList &bkpt_list,
                           bool append = false);

    uint32_t
    GetNumWatchpoints () const;

    lldb::SBWatchpoint
    GetWatchpointAtIndex (uint32_t idx) const;

    bool
    DeleteWatchpoint (lldb::watch_id_t watch_id);

    lldb::SBWatchpoint
    FindWatchpointByID (lldb::watch_id_t watch_id);

    bool
    EnableAllWatchpoints ();

    bool
    DisableAllWatchpoints ();

    bool
    DeleteAllWatchpoints ();

    lldb::SBWatchpoint
    WatchAddress (lldb::addr_t addr,
                  size_t size,
                  bool read,
                  bool write,
                  SBError &error);


    lldb::SBBroadcaster
    GetBroadcaster () const;

     %feature("docstring", "
    Create an SBValue with the given name by treating the memory starting at addr as an entity of type.

    @param[in] name
        The name of the resultant SBValue

    @param[in] addr
        The address of the start of the memory region to be used.

    @param[in] type
        The type to use to interpret the memory starting at addr.

    @return
        An SBValue of the given type, may be invalid if there was an error reading
        the underlying memory.") CreateValueFromAddress;
    lldb::SBValue
    CreateValueFromAddress (const char *name, lldb::SBAddress addr, lldb::SBType type);

    lldb::SBValue
    CreateValueFromData (const char *name, lldb::SBData data, lldb::SBType type);

    lldb::SBValue
    CreateValueFromExpression (const char *name, const char* expr);

    %feature("docstring", "
    Disassemble a specified number of instructions starting at an address.
    Parameters:
       base_addr       -- the address to start disassembly from
       count           -- the number of instructions to disassemble
       flavor_string   -- may be 'intel' or 'att' on x86 targets to specify that style of disassembly
    Returns an SBInstructionList.")
    ReadInstructions;
    lldb::SBInstructionList
    ReadInstructions (lldb::SBAddress base_addr, uint32_t count);

    lldb::SBInstructionList
    ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string);

    %feature("docstring", "
    Disassemble the bytes in a buffer and return them in an SBInstructionList.
    Parameters:
       base_addr -- used for symbolicating the offsets in the byte stream when disassembling
       buf       -- bytes to be disassembled
       size      -- (C++) size of the buffer
    Returns an SBInstructionList.")
    GetInstructions;
    lldb::SBInstructionList
    GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);

    %feature("docstring", "
    Disassemble the bytes in a buffer and return them in an SBInstructionList, with a supplied flavor.
    Parameters:
       base_addr -- used for symbolicating the offsets in the byte stream when disassembling
       flavor    -- may be 'intel' or 'att' on x86 targets to specify that style of disassembly
       buf       -- bytes to be disassembled
       size      -- (C++) size of the buffer
    Returns an SBInstructionList.")
    GetInstructionsWithFlavor;
    lldb::SBInstructionList
    GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size);

    lldb::SBSymbolContextList
    FindSymbols (const char *name, lldb::SymbolType type = eSymbolTypeAny);

    bool
    GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);

    lldb::addr_t
    GetStackRedZoneSize();

    lldb::SBLaunchInfo
    GetLaunchInfo () const;

    void
    SetLaunchInfo (const lldb::SBLaunchInfo &launch_info);

    void SetCollectingStats(bool v);

    bool GetCollectingStats();

    lldb::SBStructuredData GetStatistics();

    bool
    operator == (const lldb::SBTarget &rhs) const;

    bool
    operator != (const lldb::SBTarget &rhs) const;

    lldb::SBValue
    EvaluateExpression (const char *expr);

    lldb::SBValue
    EvaluateExpression (const char *expr, const lldb::SBExpressionOptions &options);

    %pythoncode %{
        class modules_access(object):
            '''A helper object that will lazily hand out lldb.SBModule objects for a target when supplied an index, or by full or partial path.'''
            def __init__(self, sbtarget):
                self.sbtarget = sbtarget

            def __len__(self):
                if self.sbtarget:
                    return int(self.sbtarget.GetNumModules())
                return 0

            def __getitem__(self, key):
                num_modules = self.sbtarget.GetNumModules()
                if type(key) is int:
                    if key < num_modules:
                        return self.sbtarget.GetModuleAtIndex(key)
                elif type(key) is str:
                    if key.find('/') == -1:
                        for idx in range(num_modules):
                            module = self.sbtarget.GetModuleAtIndex(idx)
                            if module.file.basename == key:
                                return module
                    else:
                        for idx in range(num_modules):
                            module = self.sbtarget.GetModuleAtIndex(idx)
                            if module.file.fullpath == key:
                                return module
                    # See if the string is a UUID
                    try:
                        the_uuid = uuid.UUID(key)
                        if the_uuid:
                            for idx in range(num_modules):
                                module = self.sbtarget.GetModuleAtIndex(idx)
                                if module.uuid == the_uuid:
                                    return module
                    except:
                        return None
                elif type(key) is uuid.UUID:
                    for idx in range(num_modules):
                        module = self.sbtarget.GetModuleAtIndex(idx)
                        if module.uuid == key:
                            return module
                elif type(key) is re.SRE_Pattern:
                    matching_modules = []
                    for idx in range(num_modules):
                        module = self.sbtarget.GetModuleAtIndex(idx)
                        re_match = key.search(module.path.fullpath)
                        if re_match:
                            matching_modules.append(module)
                    return matching_modules
                else:
                    print("error: unsupported item type: %s" % type(key))
                return None

        def get_modules_access_object(self):
            '''An accessor function that returns a modules_access() object which allows lazy module access from a lldb.SBTarget object.'''
            return self.modules_access (self)

        def get_modules_array(self):
            '''An accessor function that returns a list() that contains all modules in a lldb.SBTarget object.'''
            modules = []
            for idx in range(self.GetNumModules()):
                modules.append(self.GetModuleAtIndex(idx))
            return modules

        def module_iter(self):
            '''Returns an iterator over all modules in a lldb.SBTarget
            object.'''
            return lldb_iter(self, 'GetNumModules', 'GetModuleAtIndex')

        def breakpoint_iter(self):
            '''Returns an iterator over all breakpoints in a lldb.SBTarget
            object.'''
            return lldb_iter(self, 'GetNumBreakpoints', 'GetBreakpointAtIndex')

        def watchpoint_iter(self):
            '''Returns an iterator over all watchpoints in a lldb.SBTarget
            object.'''
            return lldb_iter(self, 'GetNumWatchpoints', 'GetWatchpointAtIndex')

        modules = property(get_modules_array, None, doc='''A read only property that returns a list() of lldb.SBModule objects contained in this target. This list is a list all modules that the target currently is tracking (the main executable and all dependent shared libraries).''')
        module = property(get_modules_access_object, None, doc=r'''A read only property that returns an object that implements python operator overloading with the square brackets().\n    target.module[<int>] allows array access to any modules.\n    target.module[<str>] allows access to modules by basename, full path, or uuid string value.\n    target.module[uuid.UUID()] allows module access by UUID.\n    target.module[re] allows module access using a regular expression that matches the module full path.''')
        process = property(GetProcess, None, doc='''A read only property that returns an lldb object that represents the process (lldb.SBProcess) that this target owns.''')
        executable = property(GetExecutable, None, doc='''A read only property that returns an lldb object that represents the main executable module (lldb.SBModule) for this target.''')
        debugger = property(GetDebugger, None, doc='''A read only property that returns an lldb object that represents the debugger (lldb.SBDebugger) that owns this target.''')
        num_breakpoints = property(GetNumBreakpoints, None, doc='''A read only property that returns the number of breakpoints that this target has as an integer.''')
        num_watchpoints = property(GetNumWatchpoints, None, doc='''A read only property that returns the number of watchpoints that this target has as an integer.''')
        broadcaster = property(GetBroadcaster, None, doc='''A read only property that an lldb object that represents the broadcaster (lldb.SBBroadcaster) for this target.''')
        byte_order = property(GetByteOrder, None, doc='''A read only property that returns an lldb enumeration value (lldb.eByteOrderLittle, lldb.eByteOrderBig, lldb.eByteOrderInvalid) that represents the byte order for this target.''')
        addr_size = property(GetAddressByteSize, None, doc='''A read only property that returns the size in bytes of an address for this target.''')
        triple = property(GetTriple, None, doc='''A read only property that returns the target triple (arch-vendor-os) for this target as a string.''')
        data_byte_size = property(GetDataByteSize, None, doc='''A read only property that returns the size in host bytes of a byte in the data address space for this target.''')
        code_byte_size = property(GetCodeByteSize, None, doc='''A read only property that returns the size in host bytes of a byte in the code address space for this target.''')
        platform = property(GetPlatform, None, doc='''A read only property that returns the platform associated with with this target.''')
    %}
};
} // namespace lldb
