//===-- SWIG Interface for SBFrame ------------------------------*- 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 one of the stack frames associated with a thread.
SBThread contains SBFrame(s). For example (from test/lldbutil.py),

def print_stacktrace(thread, string_buffer = False):
    '''Prints a simple stack trace of this thread.'''

    ...

    for i in range(depth):
        frame = thread.GetFrameAtIndex(i)
        function = frame.GetFunction()

        load_addr = addrs[i].GetLoadAddress(target)
        if not function:
            file_addr = addrs[i].GetFileAddress()
            start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
            symbol_offset = file_addr - start_addr
            print >> output, '  frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}'.format(
                num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset)
        else:
            print >> output, '  frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}'.format(
                num=i, addr=load_addr, mod=mods[i],
                func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
                file=files[i], line=lines[i],
                args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')

    ...

And,

    for frame in thread:
        print frame

See also SBThread."
) SBFrame;
class SBFrame
{
public:
    SBFrame ();

    SBFrame (const lldb::SBFrame &rhs);

   ~SBFrame();

    bool
    IsEqual (const lldb::SBFrame &rhs) const;

    bool
    IsValid() const;

    explicit operator bool() const;

    uint32_t
    GetFrameID () const;

    %feature("docstring", "
    Get the Canonical Frame Address for this stack frame.
    This is the DWARF standard's definition of a CFA, a stack address
    that remains constant throughout the lifetime of the function.
    Returns an lldb::addr_t stack address, or LLDB_INVALID_ADDRESS if
    the CFA cannot be determined.") GetCFA;
    lldb::addr_t
    GetCFA () const;

    lldb::addr_t
    GetPC () const;

    bool
    SetPC (lldb::addr_t new_pc);

    lldb::addr_t
    GetSP () const;

    lldb::addr_t
    GetFP () const;

    lldb::SBAddress
    GetPCAddress () const;

    lldb::SBSymbolContext
    GetSymbolContext (uint32_t resolve_scope) const;

    lldb::SBModule
    GetModule () const;

    lldb::SBCompileUnit
    GetCompileUnit () const;

    lldb::SBFunction
    GetFunction () const;

    lldb::SBSymbol
    GetSymbol () const;

    %feature("docstring", "
    Gets the deepest block that contains the frame PC.

    See also GetFrameBlock().") GetBlock;
    lldb::SBBlock
    GetBlock () const;

    %feature("docstring", "
    Get the appropriate function name for this frame. Inlined functions in
    LLDB are represented by Blocks that have inlined function information, so
    just looking at the SBFunction or SBSymbol for a frame isn't enough.
    This function will return the appropriate function, symbol or inlined
    function name for the frame.

    This function returns:
    - the name of the inlined function (if there is one)
    - the name of the concrete function (if there is one)
    - the name of the symbol (if there is one)
    - NULL

    See also IsInlined().") GetFunctionName;
    const char *
    GetFunctionName();

     const char *
     GetDisplayFunctionName ();

    const char *
    GetFunctionName() const;

    %feature("docstring", "
    Returns the language of the frame's SBFunction, or if there.
    is no SBFunction, guess the language from the mangled name.
    .") GuessLanguage;
    lldb::LanguageType
    GuessLanguage() const;

    %feature("docstring", "
    Return true if this frame represents an inlined function.

    See also GetFunctionName().") IsInlined;
    bool
    IsInlined();

    bool
    IsInlined() const;

    %feature("docstring", "
    Return true if this frame is artificial (e.g a frame synthesized to
    capture a tail call). Local variables may not be available in an artificial
    frame.") IsArtificial;
    bool
    IsArtificial();

    bool
    IsArtificial() const;

    %feature("docstring", "
    The version that doesn't supply a 'use_dynamic' value will use the
    target's default.") EvaluateExpression;
    lldb::SBValue
    EvaluateExpression (const char *expr);

    lldb::SBValue
    EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic);

    lldb::SBValue
    EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic, bool unwind_on_error);

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

    %feature("docstring", "
    Gets the lexical block that defines the stack frame. Another way to think
    of this is it will return the block that contains all of the variables
    for a stack frame. Inlined functions are represented as SBBlock objects
    that have inlined function information: the name of the inlined function,
    where it was called from. The block that is returned will be the first
    block at or above the block for the PC (SBFrame::GetBlock()) that defines
    the scope of the frame. When a function contains no inlined functions,
    this will be the top most lexical block that defines the function.
    When a function has inlined functions and the PC is currently
    in one of those inlined functions, this method will return the inlined
    block that defines this frame. If the PC isn't currently in an inlined
    function, the lexical block that defines the function is returned.") GetFrameBlock;
    lldb::SBBlock
    GetFrameBlock () const;

    lldb::SBLineEntry
    GetLineEntry () const;

    lldb::SBThread
    GetThread () const;

    const char *
    Disassemble () const;

    void
    Clear();

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

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

    %feature("docstring", "
    The version that doesn't supply a 'use_dynamic' value will use the
    target's default.") GetVariables;
    lldb::SBValueList
    GetVariables (bool arguments,
                  bool locals,
                  bool statics,
                  bool in_scope_only);

    lldb::SBValueList
    GetVariables (bool arguments,
                  bool locals,
                  bool statics,
                  bool in_scope_only,
                  lldb::DynamicValueType  use_dynamic);

    lldb::SBValueList
    GetVariables (const lldb::SBVariablesOptions& options);

    lldb::SBValueList
    GetRegisters ();

    %feature("docstring", "
    The version that doesn't supply a 'use_dynamic' value will use the
    target's default.") FindVariable;
    lldb::SBValue
    FindVariable (const char *var_name);

    lldb::SBValue
    FindVariable (const char *var_name, lldb::DynamicValueType use_dynamic);

    lldb::SBValue
    FindRegister (const char *name);

    %feature("docstring", "
    Get a lldb.SBValue for a variable path.

    Variable paths can include access to pointer or instance members:
        rect_ptr->origin.y
        pt.x
    Pointer dereferences:
        *this->foo_ptr
        **argv
    Address of:
        &pt
        &my_array[3].x
    Array accesses and treating pointers as arrays:
        int_array[1]
        pt_ptr[22].x

    Unlike EvaluateExpression() which returns lldb.SBValue objects
    with constant copies of the values at the time of evaluation,
    the result of this function is a value that will continue to
    track the current value of the value as execution progresses
    in the current frame.") GetValueForVariablePath;
    lldb::SBValue
    GetValueForVariablePath (const char *var_path);

    lldb::SBValue
    GetValueForVariablePath (const char *var_path, lldb::DynamicValueType use_dynamic);

    %feature("docstring", "
    Find variables, register sets, registers, or persistent variables using
    the frame as the scope.

    The version that doesn't supply a 'use_dynamic' value will use the
    target's default.") FindValue;
    lldb::SBValue
    FindValue (const char *name, ValueType value_type);

    lldb::SBValue
    FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic);

    bool
    GetDescription (lldb::SBStream &description);

    %pythoncode %{
        def get_all_variables(self):
            return self.GetVariables(True,True,True,True)

        def get_parent_frame(self):
            parent_idx = self.idx + 1
            if parent_idx >= 0 and parent_idx < len(self.thread.frame):
                return self.thread.frame[parent_idx]
            else:
                return SBFrame()

        def get_arguments(self):
            return self.GetVariables(True,False,False,False)

        def get_locals(self):
            return self.GetVariables(False,True,False,False)

        def get_statics(self):
            return self.GetVariables(False,False,True,False)

        def var(self, var_expr_path):
            '''Calls through to lldb.SBFrame.GetValueForVariablePath() and returns
            a value that represents the variable expression path'''
            return self.GetValueForVariablePath(var_expr_path)

        def get_registers_access(self):
            class registers_access(object):
                '''A helper object that exposes a flattened view of registers, masking away the notion of register sets for easy scripting.'''
                def __init__(self, regs):
                    self.regs = regs

                def __getitem__(self, key):
                    if type(key) is str:
                        for i in range(0,len(self.regs)):
                            rs = self.regs[i]
                            for j in range (0,rs.num_children):
                                reg = rs.GetChildAtIndex(j)
                                if reg.name == key: return reg
                    else:
                        return lldb.SBValue()

            return registers_access(self.registers)

        pc = property(GetPC, SetPC)
        addr = property(GetPCAddress, None, doc='''A read only property that returns the program counter (PC) as a section offset address (lldb.SBAddress).''')
        fp = property(GetFP, None, doc='''A read only property that returns the frame pointer (FP) as an unsigned integer.''')
        sp = property(GetSP, None, doc='''A read only property that returns the stack pointer (SP) as an unsigned integer.''')
        module = property(GetModule, None, doc='''A read only property that returns an lldb object that represents the module (lldb.SBModule) for this stack frame.''')
        compile_unit = property(GetCompileUnit, None, doc='''A read only property that returns an lldb object that represents the compile unit (lldb.SBCompileUnit) for this stack frame.''')
        function = property(GetFunction, None, doc='''A read only property that returns an lldb object that represents the function (lldb.SBFunction) for this stack frame.''')
        symbol = property(GetSymbol, None, doc='''A read only property that returns an lldb object that represents the symbol (lldb.SBSymbol) for this stack frame.''')
        block = property(GetBlock, None, doc='''A read only property that returns an lldb object that represents the block (lldb.SBBlock) for this stack frame.''')
        is_inlined = property(IsInlined, None, doc='''A read only property that returns an boolean that indicates if the block frame is an inlined function.''')
        name = property(GetFunctionName, None, doc='''A read only property that retuns the name for the function that this frame represents. Inlined stack frame might have a concrete function that differs from the name of the inlined function (a named lldb.SBBlock).''')
        line_entry = property(GetLineEntry, None, doc='''A read only property that returns an lldb object that represents the line table entry (lldb.SBLineEntry) for this stack frame.''')
        thread = property(GetThread, None, doc='''A read only property that returns an lldb object that represents the thread (lldb.SBThread) for this stack frame.''')
        disassembly = property(Disassemble, None, doc='''A read only property that returns the disassembly for this stack frame as a python string.''')
        idx = property(GetFrameID, None, doc='''A read only property that returns the zero based stack frame index.''')
        variables = property(get_all_variables, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the variables in this stack frame.''')
        vars = property(get_all_variables, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the variables in this stack frame.''')
        locals = property(get_locals, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the local variables in this stack frame.''')
        args = property(get_arguments, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the argument variables in this stack frame.''')
        arguments = property(get_arguments, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the argument variables in this stack frame.''')
        statics = property(get_statics, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the static variables in this stack frame.''')
        registers = property(GetRegisters, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the CPU registers for this stack frame.''')
        regs = property(GetRegisters, None, doc='''A read only property that returns a list() that contains a collection of lldb.SBValue objects that represent the CPU registers for this stack frame.''')
        register = property(get_registers_access, None, doc='''A read only property that returns an helper object providing a flattened indexable view of the CPU registers for this stack frame.''')
        reg = property(get_registers_access, None, doc='''A read only property that returns an helper object providing a flattened indexable view of the CPU registers for this stack frame''')
        parent = property(get_parent_frame, None, doc='''A read only property that returns the parent (caller) frame of the current frame.''')
    %}
};

} // namespace lldb
