//===-- SBFrame.cpp -------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include <algorithm>
#include <set>
#include <string>

#include "lldb/API/SBFrame.h"

#include "lldb/lldb-types.h"

#include "SBReproducerPrivate.h"
#include "Utils.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/StackID.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Stream.h"

#include "lldb/API/SBAddress.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBValue.h"
#include "lldb/API/SBVariablesOptions.h"

#include "llvm/Support/PrettyStackTrace.h"

using namespace lldb;
using namespace lldb_private;

SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFrame);
}

SBFrame::SBFrame(const StackFrameSP &lldb_object_sp)
    : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
  LLDB_RECORD_CONSTRUCTOR(SBFrame, (const lldb::StackFrameSP &),
                          lldb_object_sp);
}

SBFrame::SBFrame(const SBFrame &rhs) : m_opaque_sp() {
  LLDB_RECORD_CONSTRUCTOR(SBFrame, (const lldb::SBFrame &), rhs);

  m_opaque_sp = clone(rhs.m_opaque_sp);
}

SBFrame::~SBFrame() = default;

const SBFrame &SBFrame::operator=(const SBFrame &rhs) {
  LLDB_RECORD_METHOD(const lldb::SBFrame &,
                     SBFrame, operator=,(const lldb::SBFrame &), rhs);

  if (this != &rhs)
    m_opaque_sp = clone(rhs.m_opaque_sp);
  return LLDB_RECORD_RESULT(*this);
}

StackFrameSP SBFrame::GetFrameSP() const {
  return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());
}

void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {
  return m_opaque_sp->SetFrameSP(lldb_object_sp);
}

bool SBFrame::IsValid() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFrame, IsValid);
  return this->operator bool();
}
SBFrame::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFrame, operator bool);

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock()))
      return GetFrameSP().get() != nullptr;
  }

  // Without a target & process we can't have a valid stack frame.
  return false;
}

SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
  LLDB_RECORD_METHOD_CONST(lldb::SBSymbolContext, SBFrame, GetSymbolContext,
                           (uint32_t), resolve_scope);

  SBSymbolContext sb_sym_ctx;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
  SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame)
        sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext(scope));
    }
  }

  return LLDB_RECORD_RESULT(sb_sym_ctx);
}

SBModule SBFrame::GetModule() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBModule, SBFrame, GetModule);

  SBModule sb_module;
  ModuleSP module_sp;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
        sb_module.SetSP(module_sp);
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_module);
}

SBCompileUnit SBFrame::GetCompileUnit() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBCompileUnit, SBFrame,
                                   GetCompileUnit);

  SBCompileUnit sb_comp_unit;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        sb_comp_unit.reset(
            frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_comp_unit);
}

SBFunction SBFrame::GetFunction() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBFunction, SBFrame, GetFunction);

  SBFunction sb_function;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        sb_function.reset(
            frame->GetSymbolContext(eSymbolContextFunction).function);
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_function);
}

SBSymbol SBFrame::GetSymbol() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBSymbol, SBFrame, GetSymbol);

  SBSymbol sb_symbol;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_symbol);
}

SBBlock SBFrame::GetBlock() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBBlock, SBFrame, GetBlock);

  SBBlock sb_block;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame)
        sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
    }
  }
  return LLDB_RECORD_RESULT(sb_block);
}

SBBlock SBFrame::GetFrameBlock() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBBlock, SBFrame, GetFrameBlock);

  SBBlock sb_block;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame)
        sb_block.SetPtr(frame->GetFrameBlock());
    }
  }
  return LLDB_RECORD_RESULT(sb_block);
}

SBLineEntry SBFrame::GetLineEntry() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBLineEntry, SBFrame, GetLineEntry);

  SBLineEntry sb_line_entry;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        sb_line_entry.SetLineEntry(
            frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
      }
    }
  }
  return LLDB_RECORD_RESULT(sb_line_entry);
}

uint32_t SBFrame::GetFrameID() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBFrame, GetFrameID);

  uint32_t frame_idx = UINT32_MAX;

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  if (frame)
    frame_idx = frame->GetFrameIndex();

  return frame_idx;
}

lldb::addr_t SBFrame::GetCFA() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::addr_t, SBFrame, GetCFA);

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  if (frame)
    return frame->GetStackID().GetCallFrameAddress();
  return LLDB_INVALID_ADDRESS;
}

addr_t SBFrame::GetPC() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::addr_t, SBFrame, GetPC);

  addr_t addr = LLDB_INVALID_ADDRESS;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
            target, AddressClass::eCode);
      }
    }
  }

  return addr;
}

bool SBFrame::SetPC(addr_t new_pc) {
  LLDB_RECORD_METHOD(bool, SBFrame, SetPC, (lldb::addr_t), new_pc);

  bool ret_val = false;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
          ret_val = reg_ctx_sp->SetPC(new_pc);
        }
      }
    }
  }

  return ret_val;
}

addr_t SBFrame::GetSP() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::addr_t, SBFrame, GetSP);

  addr_t addr = LLDB_INVALID_ADDRESS;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
          addr = reg_ctx_sp->GetSP();
        }
      }
    }
  }

  return addr;
}

addr_t SBFrame::GetFP() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::addr_t, SBFrame, GetFP);

  addr_t addr = LLDB_INVALID_ADDRESS;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      if (StackFrame *frame = exe_ctx.GetFramePtr()) {
        if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
          addr = reg_ctx_sp->GetFP();
        }
      }
    }
  }

  return addr;
}

SBAddress SBFrame::GetPCAddress() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBAddress, SBFrame, GetPCAddress);

  SBAddress sb_addr;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame)
        sb_addr.SetAddress(frame->GetFrameCodeAddress());
    }
  }
  return LLDB_RECORD_RESULT(sb_addr);
}

void SBFrame::Clear() {
  LLDB_RECORD_METHOD_NO_ARGS(void, SBFrame, Clear);

  m_opaque_sp->Clear();
}

lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, GetValueForVariablePath,
                     (const char *), var_path);

  SBValue sb_value;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  if (frame && target) {
    lldb::DynamicValueType use_dynamic =
        frame->CalculateTarget()->GetPreferDynamicValue();
    sb_value = GetValueForVariablePath(var_path, use_dynamic);
  }
  return LLDB_RECORD_RESULT(sb_value);
}

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

  SBValue sb_value;
  if (var_path == nullptr || var_path[0] == '\0') {
    return LLDB_RECORD_RESULT(sb_value);
  }

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        VariableSP var_sp;
        Status error;
        ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
            var_path, eNoDynamicValues,
            StackFrame::eExpressionPathOptionCheckPtrVsMember |
                StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
            var_sp, error));
        sb_value.SetSP(value_sp, use_dynamic);
      }
    }
  }
  return LLDB_RECORD_RESULT(sb_value);
}

SBValue SBFrame::FindVariable(const char *name) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, FindVariable, (const char *),
                     name);

  SBValue value;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  if (frame && target) {
    lldb::DynamicValueType use_dynamic =
        frame->CalculateTarget()->GetPreferDynamicValue();
    value = FindVariable(name, use_dynamic);
  }
  return LLDB_RECORD_RESULT(value);
}

SBValue SBFrame::FindVariable(const char *name,
                              lldb::DynamicValueType use_dynamic) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, FindVariable,
                     (const char *, lldb::DynamicValueType), name, use_dynamic);

  VariableSP var_sp;
  SBValue sb_value;

  if (name == nullptr || name[0] == '\0') {
    return LLDB_RECORD_RESULT(sb_value);
  }

  ValueObjectSP value_sp;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        value_sp = frame->FindVariable(ConstString(name));

        if (value_sp)
          sb_value.SetSP(value_sp, use_dynamic);
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_value);
}

SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, FindValue,
                     (const char *, lldb::ValueType), name, value_type);

  SBValue value;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  if (frame && target) {
    lldb::DynamicValueType use_dynamic =
        frame->CalculateTarget()->GetPreferDynamicValue();
    value = FindValue(name, value_type, use_dynamic);
  }
  return LLDB_RECORD_RESULT(value);
}

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

  SBValue sb_value;

  if (name == nullptr || name[0] == '\0') {
    return LLDB_RECORD_RESULT(sb_value);
  }

  ValueObjectSP value_sp;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        VariableList variable_list;

        switch (value_type) {
        case eValueTypeVariableGlobal:      // global variable
        case eValueTypeVariableStatic:      // static variable
        case eValueTypeVariableArgument:    // function argument variables
        case eValueTypeVariableLocal:       // function local variables
        case eValueTypeVariableThreadLocal: // thread local variables
        {
          SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));

          const bool can_create = true;
          const bool get_parent_variables = true;
          const bool stop_if_block_is_inlined_function = true;

          if (sc.block)
            sc.block->AppendVariables(
                can_create, get_parent_variables,
                stop_if_block_is_inlined_function,
                [frame](Variable *v) { return v->IsInScope(frame); },
                &variable_list);
          if (value_type == eValueTypeVariableGlobal) {
            const bool get_file_globals = true;
            VariableList *frame_vars = frame->GetVariableList(get_file_globals);
            if (frame_vars)
              frame_vars->AppendVariablesIfUnique(variable_list);
          }
          ConstString const_name(name);
          VariableSP variable_sp(
              variable_list.FindVariable(const_name, value_type));
          if (variable_sp) {
            value_sp = frame->GetValueObjectForFrameVariable(variable_sp,
                                                             eNoDynamicValues);
            sb_value.SetSP(value_sp, use_dynamic);
          }
        } break;

        case eValueTypeRegister: // stack frame register value
        {
          RegisterContextSP reg_ctx(frame->GetRegisterContext());
          if (reg_ctx) {
            const uint32_t num_regs = reg_ctx->GetRegisterCount();
            for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
              const RegisterInfo *reg_info =
                  reg_ctx->GetRegisterInfoAtIndex(reg_idx);
              if (reg_info &&
                  ((reg_info->name && strcasecmp(reg_info->name, name) == 0) ||
                   (reg_info->alt_name &&
                    strcasecmp(reg_info->alt_name, name) == 0))) {
                value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_idx);
                sb_value.SetSP(value_sp);
                break;
              }
            }
          }
        } break;

        case eValueTypeRegisterSet: // A collection of stack frame register
                                    // values
        {
          RegisterContextSP reg_ctx(frame->GetRegisterContext());
          if (reg_ctx) {
            const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
            for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
              const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx);
              if (reg_set &&
                  ((reg_set->name && strcasecmp(reg_set->name, name) == 0) ||
                   (reg_set->short_name &&
                    strcasecmp(reg_set->short_name, name) == 0))) {
                value_sp =
                    ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx);
                sb_value.SetSP(value_sp);
                break;
              }
            }
          }
        } break;

        case eValueTypeConstResult: // constant result variables
        {
          ConstString const_name(name);
          ExpressionVariableSP expr_var_sp(
              target->GetPersistentVariable(const_name));
          if (expr_var_sp) {
            value_sp = expr_var_sp->GetValueObject();
            sb_value.SetSP(value_sp, use_dynamic);
          }
        } break;

        default:
          break;
        }
      }
    }
  }

  return LLDB_RECORD_RESULT(sb_value);
}

bool SBFrame::IsEqual(const SBFrame &that) const {
  LLDB_RECORD_METHOD_CONST(bool, SBFrame, IsEqual, (const lldb::SBFrame &),
                           that);

  lldb::StackFrameSP this_sp = GetFrameSP();
  lldb::StackFrameSP that_sp = that.GetFrameSP();
  return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID());
}

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

  return IsEqual(rhs);
}

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

  return !IsEqual(rhs);
}

SBThread SBFrame::GetThread() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBThread, SBFrame, GetThread);

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  ThreadSP thread_sp(exe_ctx.GetThreadSP());
  SBThread sb_thread(thread_sp);

  return LLDB_RECORD_RESULT(sb_thread);
}

const char *SBFrame::Disassemble() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFrame, Disassemble);

  const char *disassembly = nullptr;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        disassembly = frame->Disassemble();
      }
    }
  }

  return disassembly;
}

SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
                                  bool in_scope_only) {
  LLDB_RECORD_METHOD(lldb::SBValueList, SBFrame, GetVariables,
                     (bool, bool, bool, bool), arguments, locals, statics,
                     in_scope_only);

  SBValueList value_list;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  if (frame && target) {
    lldb::DynamicValueType use_dynamic =
        frame->CalculateTarget()->GetPreferDynamicValue();
    const bool include_runtime_support_values =
        target ? target->GetDisplayRuntimeSupportValues() : false;

    SBVariablesOptions options;
    options.SetIncludeArguments(arguments);
    options.SetIncludeLocals(locals);
    options.SetIncludeStatics(statics);
    options.SetInScopeOnly(in_scope_only);
    options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
    options.SetUseDynamic(use_dynamic);

    value_list = GetVariables(options);
  }
  return LLDB_RECORD_RESULT(value_list);
}

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

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  Target *target = exe_ctx.GetTargetPtr();
  const bool include_runtime_support_values =
      target ? target->GetDisplayRuntimeSupportValues() : false;
  SBVariablesOptions options;
  options.SetIncludeArguments(arguments);
  options.SetIncludeLocals(locals);
  options.SetIncludeStatics(statics);
  options.SetInScopeOnly(in_scope_only);
  options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
  options.SetUseDynamic(use_dynamic);
  return LLDB_RECORD_RESULT(GetVariables(options));
}

SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
  LLDB_RECORD_METHOD(lldb::SBValueList, SBFrame, GetVariables,
                     (const lldb::SBVariablesOptions &), options);

  SBValueList value_list;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();

  const bool statics = options.GetIncludeStatics();
  const bool arguments = options.GetIncludeArguments();
  const bool recognized_arguments =
        options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
  const bool locals = options.GetIncludeLocals();
  const bool in_scope_only = options.GetInScopeOnly();
  const bool include_runtime_support_values =
      options.GetIncludeRuntimeSupportValues();
  const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();


  std::set<VariableSP> variable_set;
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        VariableList *variable_list = nullptr;
        variable_list = frame->GetVariableList(true);
        if (variable_list) {
          const size_t num_variables = variable_list->GetSize();
          if (num_variables) {
            for (const VariableSP &variable_sp : *variable_list) {
              if (variable_sp) {
                bool add_variable = false;
                switch (variable_sp->GetScope()) {
                case eValueTypeVariableGlobal:
                case eValueTypeVariableStatic:
                case eValueTypeVariableThreadLocal:
                  add_variable = statics;
                  break;

                case eValueTypeVariableArgument:
                  add_variable = arguments;
                  break;

                case eValueTypeVariableLocal:
                  add_variable = locals;
                  break;

                default:
                  break;
                }
                if (add_variable) {
                  // Only add variables once so we don't end up with duplicates
                  if (variable_set.find(variable_sp) == variable_set.end())
                    variable_set.insert(variable_sp);
                  else
                    continue;

                  if (in_scope_only && !variable_sp->IsInScope(frame))
                    continue;

                  ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable(
                      variable_sp, eNoDynamicValues));

                  if (!include_runtime_support_values && valobj_sp != nullptr &&
                      valobj_sp->IsRuntimeSupportValue())
                    continue;

                  SBValue value_sb;
                  value_sb.SetSP(valobj_sp, use_dynamic);
                  value_list.Append(value_sb);
                }
              }
            }
          }
        }
        if (recognized_arguments) {
          auto recognized_frame = frame->GetRecognizedFrame();
          if (recognized_frame) {
            ValueObjectListSP recognized_arg_list =
                recognized_frame->GetRecognizedArguments();
            if (recognized_arg_list) {
              for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
                SBValue value_sb;
                value_sb.SetSP(rec_value_sp, use_dynamic);
                value_list.Append(value_sb);
              }
            }
          }
        }
      }
    }
  }

  return LLDB_RECORD_RESULT(value_list);
}

SBValueList SBFrame::GetRegisters() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValueList, SBFrame, GetRegisters);

  SBValueList value_list;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        RegisterContextSP reg_ctx(frame->GetRegisterContext());
        if (reg_ctx) {
          const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
          for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
            value_list.Append(
                ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));
          }
        }
      }
    }
  }

  return LLDB_RECORD_RESULT(value_list);
}

SBValue SBFrame::FindRegister(const char *name) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, FindRegister, (const char *),
                     name);

  SBValue result;
  ValueObjectSP value_sp;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        RegisterContextSP reg_ctx(frame->GetRegisterContext());
        if (reg_ctx) {
          const uint32_t num_regs = reg_ctx->GetRegisterCount();
          for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
            const RegisterInfo *reg_info =
                reg_ctx->GetRegisterInfoAtIndex(reg_idx);
            if (reg_info &&
                ((reg_info->name && strcasecmp(reg_info->name, name) == 0) ||
                 (reg_info->alt_name &&
                  strcasecmp(reg_info->alt_name, name) == 0))) {
              value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_idx);
              result.SetSP(value_sp);
              break;
            }
          }
        }
      }
    }
  }

  return LLDB_RECORD_RESULT(result);
}

bool SBFrame::GetDescription(SBStream &description) {
  LLDB_RECORD_METHOD(bool, SBFrame, GetDescription, (lldb::SBStream &),
                     description);

  Stream &strm = description.ref();

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        frame->DumpUsingSettingsFormat(&strm);
      }
    }

  } else
    strm.PutCString("No value");

  return true;
}

SBValue SBFrame::EvaluateExpression(const char *expr) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, EvaluateExpression, (const char *),
                     expr);

  SBValue result;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  if (frame && target) {
    SBExpressionOptions options;
    lldb::DynamicValueType fetch_dynamic_value =
        frame->CalculateTarget()->GetPreferDynamicValue();
    options.SetFetchDynamicValue(fetch_dynamic_value);
    options.SetUnwindOnError(true);
    options.SetIgnoreBreakpoints(true);
    if (target->GetLanguage() != eLanguageTypeUnknown)
      options.SetLanguage(target->GetLanguage());
    else
      options.SetLanguage(frame->GetLanguage());
    return LLDB_RECORD_RESULT(EvaluateExpression(expr, options));
  }
  return LLDB_RECORD_RESULT(result);
}

SBValue
SBFrame::EvaluateExpression(const char *expr,
                            lldb::DynamicValueType fetch_dynamic_value) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, EvaluateExpression,
                     (const char *, lldb::DynamicValueType), expr,
                     fetch_dynamic_value);

  SBExpressionOptions options;
  options.SetFetchDynamicValue(fetch_dynamic_value);
  options.SetUnwindOnError(true);
  options.SetIgnoreBreakpoints(true);
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  if (target && target->GetLanguage() != eLanguageTypeUnknown)
    options.SetLanguage(target->GetLanguage());
  else if (frame)
    options.SetLanguage(frame->GetLanguage());
  return LLDB_RECORD_RESULT(EvaluateExpression(expr, options));
}

SBValue SBFrame::EvaluateExpression(const char *expr,
                                    lldb::DynamicValueType fetch_dynamic_value,
                                    bool unwind_on_error) {
  LLDB_RECORD_METHOD(lldb::SBValue, SBFrame, EvaluateExpression,
                     (const char *, lldb::DynamicValueType, bool), expr,
                     fetch_dynamic_value, unwind_on_error);

  SBExpressionOptions options;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  options.SetFetchDynamicValue(fetch_dynamic_value);
  options.SetUnwindOnError(unwind_on_error);
  options.SetIgnoreBreakpoints(true);
  StackFrame *frame = exe_ctx.GetFramePtr();
  Target *target = exe_ctx.GetTargetPtr();
  if (target && target->GetLanguage() != eLanguageTypeUnknown)
    options.SetLanguage(target->GetLanguage());
  else if (frame)
    options.SetLanguage(frame->GetLanguage());
  return LLDB_RECORD_RESULT(EvaluateExpression(expr, options));
}

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

  Log *expr_log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  SBValue expr_result;

  if (expr == nullptr || expr[0] == '\0') {
    return LLDB_RECORD_RESULT(expr_result);
  }

  ValueObjectSP expr_value_sp;

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);


  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();

  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
        if (target->GetDisplayExpressionsInCrashlogs()) {
          StreamString frame_description;
          frame->DumpUsingSettingsFormat(&frame_description);
          stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
              "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
              "= %u) %s",
              expr, options.GetFetchDynamicValue(),
              frame_description.GetData());
        }

        target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
        expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
      }
    }
  }

  LLDB_LOGF(expr_log,
            "** [SBFrame::EvaluateExpression] Expression result is "
            "%s, summary %s **",
            expr_result.GetValue(), expr_result.GetSummary());

  return LLDB_RECORD_RESULT(expr_result);
}

bool SBFrame::IsInlined() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBFrame, IsInlined);

  return static_cast<const SBFrame *>(this)->IsInlined();
}

bool SBFrame::IsInlined() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFrame, IsInlined);

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {

        Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
        if (block)
          return block->GetContainingInlinedBlock() != nullptr;
      }
    }
  }
  return false;
}

bool SBFrame::IsArtificial() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBFrame, IsArtificial);

  return static_cast<const SBFrame *>(this)->IsArtificial();
}

bool SBFrame::IsArtificial() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFrame, IsArtificial);

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = exe_ctx.GetFramePtr();
  if (frame)
    return frame->IsArtificial();

  return false;
}

const char *SBFrame::GetFunctionName() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBFrame, GetFunctionName);

  return static_cast<const SBFrame *>(this)->GetFunctionName();
}

lldb::LanguageType SBFrame::GuessLanguage() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::LanguageType, SBFrame, GuessLanguage);

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        return frame->GuessLanguage();
      }
    }
  }
  return eLanguageTypeUnknown;
}

const char *SBFrame::GetFunctionName() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFrame, GetFunctionName);

  const char *name = nullptr;
  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
                                                 eSymbolContextBlock |
                                                 eSymbolContextSymbol));
        if (sc.block) {
          Block *inlined_block = sc.block->GetContainingInlinedBlock();
          if (inlined_block) {
            const InlineFunctionInfo *inlined_info =
                inlined_block->GetInlinedFunctionInfo();
            name = inlined_info->GetName().AsCString();
          }
        }

        if (name == nullptr) {
          if (sc.function)
            name = sc.function->GetName().GetCString();
        }

        if (name == nullptr) {
          if (sc.symbol)
            name = sc.symbol->GetName().GetCString();
        }
      }
    }
  }
  return name;
}

const char *SBFrame::GetDisplayFunctionName() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBFrame, GetDisplayFunctionName);

  const char *name = nullptr;

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  StackFrame *frame = nullptr;
  Target *target = exe_ctx.GetTargetPtr();
  Process *process = exe_ctx.GetProcessPtr();
  if (target && process) {
    Process::StopLocker stop_locker;
    if (stop_locker.TryLock(&process->GetRunLock())) {
      frame = exe_ctx.GetFramePtr();
      if (frame) {
        SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
                                                 eSymbolContextBlock |
                                                 eSymbolContextSymbol));
        if (sc.block) {
          Block *inlined_block = sc.block->GetContainingInlinedBlock();
          if (inlined_block) {
            const InlineFunctionInfo *inlined_info =
                inlined_block->GetInlinedFunctionInfo();
            name = inlined_info->GetDisplayName().AsCString();
          }
        }

        if (name == nullptr) {
          if (sc.function)
            name = sc.function->GetDisplayName().GetCString();
        }

        if (name == nullptr) {
          if (sc.symbol)
            name = sc.symbol->GetDisplayName().GetCString();
        }
      }
    }
  }
  return name;
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBFrame>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBFrame, ());
  LLDB_REGISTER_CONSTRUCTOR(SBFrame, (const lldb::StackFrameSP &));
  LLDB_REGISTER_CONSTRUCTOR(SBFrame, (const lldb::SBFrame &));
  LLDB_REGISTER_METHOD(const lldb::SBFrame &,
                       SBFrame, operator=,(const lldb::SBFrame &));
  LLDB_REGISTER_METHOD_CONST(bool, SBFrame, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBFrame, operator bool, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBSymbolContext, SBFrame, GetSymbolContext,
                             (uint32_t));
  LLDB_REGISTER_METHOD_CONST(lldb::SBModule, SBFrame, GetModule, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBCompileUnit, SBFrame, GetCompileUnit,
                             ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBFunction, SBFrame, GetFunction, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBSymbol, SBFrame, GetSymbol, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBBlock, SBFrame, GetBlock, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBBlock, SBFrame, GetFrameBlock, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBLineEntry, SBFrame, GetLineEntry, ());
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBFrame, GetFrameID, ());
  LLDB_REGISTER_METHOD_CONST(lldb::addr_t, SBFrame, GetCFA, ());
  LLDB_REGISTER_METHOD_CONST(lldb::addr_t, SBFrame, GetPC, ());
  LLDB_REGISTER_METHOD(bool, SBFrame, SetPC, (lldb::addr_t));
  LLDB_REGISTER_METHOD_CONST(lldb::addr_t, SBFrame, GetSP, ());
  LLDB_REGISTER_METHOD_CONST(lldb::addr_t, SBFrame, GetFP, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBFrame, GetPCAddress, ());
  LLDB_REGISTER_METHOD(void, SBFrame, Clear, ());
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, GetValueForVariablePath,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, GetValueForVariablePath,
                       (const char *, lldb::DynamicValueType));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, FindVariable, (const char *));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, FindVariable,
                       (const char *, lldb::DynamicValueType));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, FindValue,
                       (const char *, lldb::ValueType));
  LLDB_REGISTER_METHOD(
      lldb::SBValue, SBFrame, FindValue,
      (const char *, lldb::ValueType, lldb::DynamicValueType));
  LLDB_REGISTER_METHOD_CONST(bool, SBFrame, IsEqual, (const lldb::SBFrame &));
  LLDB_REGISTER_METHOD_CONST(bool,
                             SBFrame, operator==,(const lldb::SBFrame &));
  LLDB_REGISTER_METHOD_CONST(bool,
                             SBFrame, operator!=,(const lldb::SBFrame &));
  LLDB_REGISTER_METHOD_CONST(lldb::SBThread, SBFrame, GetThread, ());
  LLDB_REGISTER_METHOD_CONST(const char *, SBFrame, Disassemble, ());
  LLDB_REGISTER_METHOD(lldb::SBValueList, SBFrame, GetVariables,
                       (bool, bool, bool, bool));
  LLDB_REGISTER_METHOD(lldb::SBValueList, SBFrame, GetVariables,
                       (bool, bool, bool, bool, lldb::DynamicValueType));
  LLDB_REGISTER_METHOD(lldb::SBValueList, SBFrame, GetVariables,
                       (const lldb::SBVariablesOptions &));
  LLDB_REGISTER_METHOD(lldb::SBValueList, SBFrame, GetRegisters, ());
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, FindRegister, (const char *));
  LLDB_REGISTER_METHOD(bool, SBFrame, GetDescription, (lldb::SBStream &));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, EvaluateExpression,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, EvaluateExpression,
                       (const char *, lldb::DynamicValueType));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, EvaluateExpression,
                       (const char *, lldb::DynamicValueType, bool));
  LLDB_REGISTER_METHOD(lldb::SBValue, SBFrame, EvaluateExpression,
                       (const char *, const lldb::SBExpressionOptions &));
  LLDB_REGISTER_METHOD(bool, SBFrame, IsInlined, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBFrame, IsInlined, ());
  LLDB_REGISTER_METHOD(bool, SBFrame, IsArtificial, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBFrame, IsArtificial, ());
  LLDB_REGISTER_METHOD(const char *, SBFrame, GetFunctionName, ());
  LLDB_REGISTER_METHOD_CONST(lldb::LanguageType, SBFrame, GuessLanguage, ());
  LLDB_REGISTER_METHOD_CONST(const char *, SBFrame, GetFunctionName, ());
  LLDB_REGISTER_METHOD(const char *, SBFrame, GetDisplayFunctionName, ());
}

}
}
