summaryrefslogtreecommitdiff
path: root/lldb/source/API/SBBlock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/API/SBBlock.cpp')
-rw-r--r--lldb/source/API/SBBlock.cpp392
1 files changed, 392 insertions, 0 deletions
diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp
new file mode 100644
index 000000000000..f333d1d7b5f3
--- /dev/null
+++ b/lldb/source/API/SBBlock.cpp
@@ -0,0 +1,392 @@
+//===-- SBBlock.cpp ---------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBBlock.h"
+#include "SBReproducerPrivate.h"
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBValue.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBBlock::SBBlock() : m_opaque_ptr(nullptr) {
+ LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBlock);
+}
+
+SBBlock::SBBlock(lldb_private::Block *lldb_object_ptr)
+ : m_opaque_ptr(lldb_object_ptr) {}
+
+SBBlock::SBBlock(const SBBlock &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {
+ LLDB_RECORD_CONSTRUCTOR(SBBlock, (const lldb::SBBlock &), rhs);
+}
+
+const SBBlock &SBBlock::operator=(const SBBlock &rhs) {
+ LLDB_RECORD_METHOD(const lldb::SBBlock &,
+ SBBlock, operator=,(const lldb::SBBlock &), rhs);
+
+ m_opaque_ptr = rhs.m_opaque_ptr;
+ return LLDB_RECORD_RESULT(*this);
+}
+
+SBBlock::~SBBlock() { m_opaque_ptr = nullptr; }
+
+bool SBBlock::IsValid() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBlock, IsValid);
+ return this->operator bool();
+}
+SBBlock::operator bool() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBlock, operator bool);
+
+ return m_opaque_ptr != nullptr;
+}
+
+bool SBBlock::IsInlined() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBlock, IsInlined);
+
+ if (m_opaque_ptr)
+ return m_opaque_ptr->GetInlinedFunctionInfo() != nullptr;
+ return false;
+}
+
+const char *SBBlock::GetInlinedName() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBlock, GetInlinedName);
+
+ if (m_opaque_ptr) {
+ const InlineFunctionInfo *inlined_info =
+ m_opaque_ptr->GetInlinedFunctionInfo();
+ if (inlined_info) {
+ Function *function = m_opaque_ptr->CalculateSymbolContextFunction();
+ LanguageType language;
+ if (function)
+ language = function->GetLanguage();
+ else
+ language = lldb::eLanguageTypeUnknown;
+ return inlined_info->GetName(language).AsCString(nullptr);
+ }
+ }
+ return nullptr;
+}
+
+SBFileSpec SBBlock::GetInlinedCallSiteFile() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBFileSpec, SBBlock,
+ GetInlinedCallSiteFile);
+
+ SBFileSpec sb_file;
+ if (m_opaque_ptr) {
+ const InlineFunctionInfo *inlined_info =
+ m_opaque_ptr->GetInlinedFunctionInfo();
+ if (inlined_info)
+ sb_file.SetFileSpec(inlined_info->GetCallSite().GetFile());
+ }
+ return LLDB_RECORD_RESULT(sb_file);
+}
+
+uint32_t SBBlock::GetInlinedCallSiteLine() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBlock, GetInlinedCallSiteLine);
+
+ if (m_opaque_ptr) {
+ const InlineFunctionInfo *inlined_info =
+ m_opaque_ptr->GetInlinedFunctionInfo();
+ if (inlined_info)
+ return inlined_info->GetCallSite().GetLine();
+ }
+ return 0;
+}
+
+uint32_t SBBlock::GetInlinedCallSiteColumn() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBlock, GetInlinedCallSiteColumn);
+
+ if (m_opaque_ptr) {
+ const InlineFunctionInfo *inlined_info =
+ m_opaque_ptr->GetInlinedFunctionInfo();
+ if (inlined_info)
+ return inlined_info->GetCallSite().GetColumn();
+ }
+ return 0;
+}
+
+void SBBlock::AppendVariables(bool can_create, bool get_parent_variables,
+ lldb_private::VariableList *var_list) {
+ if (IsValid()) {
+ bool show_inline = true;
+ m_opaque_ptr->AppendVariables(can_create, get_parent_variables, show_inline,
+ [](Variable *) { return true; }, var_list);
+ }
+}
+
+SBBlock SBBlock::GetParent() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBBlock, GetParent);
+
+ SBBlock sb_block;
+ if (m_opaque_ptr)
+ sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
+ return LLDB_RECORD_RESULT(sb_block);
+}
+
+lldb::SBBlock SBBlock::GetContainingInlinedBlock() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBBlock, GetContainingInlinedBlock);
+
+ SBBlock sb_block;
+ if (m_opaque_ptr)
+ sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock();
+ return LLDB_RECORD_RESULT(sb_block);
+}
+
+SBBlock SBBlock::GetSibling() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBBlock, GetSibling);
+
+ SBBlock sb_block;
+ if (m_opaque_ptr)
+ sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
+ return LLDB_RECORD_RESULT(sb_block);
+}
+
+SBBlock SBBlock::GetFirstChild() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBBlock, GetFirstChild);
+
+ SBBlock sb_block;
+ if (m_opaque_ptr)
+ sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
+ return LLDB_RECORD_RESULT(sb_block);
+}
+
+lldb_private::Block *SBBlock::GetPtr() { return m_opaque_ptr; }
+
+void SBBlock::SetPtr(lldb_private::Block *block) { m_opaque_ptr = block; }
+
+bool SBBlock::GetDescription(SBStream &description) {
+ LLDB_RECORD_METHOD(bool, SBBlock, GetDescription, (lldb::SBStream &),
+ description);
+
+ Stream &strm = description.ref();
+
+ if (m_opaque_ptr) {
+ lldb::user_id_t id = m_opaque_ptr->GetID();
+ strm.Printf("Block: {id: %" PRIu64 "} ", id);
+ if (IsInlined()) {
+ strm.Printf(" (inlined, '%s') ", GetInlinedName());
+ }
+ lldb_private::SymbolContext sc;
+ m_opaque_ptr->CalculateSymbolContext(&sc);
+ if (sc.function) {
+ m_opaque_ptr->DumpAddressRanges(
+ &strm,
+ sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
+ }
+ } else
+ strm.PutCString("No value");
+
+ return true;
+}
+
+uint32_t SBBlock::GetNumRanges() {
+ LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBlock, GetNumRanges);
+
+ if (m_opaque_ptr)
+ return m_opaque_ptr->GetNumRanges();
+ return 0;
+}
+
+lldb::SBAddress SBBlock::GetRangeStartAddress(uint32_t idx) {
+ LLDB_RECORD_METHOD(lldb::SBAddress, SBBlock, GetRangeStartAddress, (uint32_t),
+ idx);
+
+ lldb::SBAddress sb_addr;
+ if (m_opaque_ptr) {
+ AddressRange range;
+ if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
+ sb_addr.ref() = range.GetBaseAddress();
+ }
+ }
+ return LLDB_RECORD_RESULT(sb_addr);
+}
+
+lldb::SBAddress SBBlock::GetRangeEndAddress(uint32_t idx) {
+ LLDB_RECORD_METHOD(lldb::SBAddress, SBBlock, GetRangeEndAddress, (uint32_t),
+ idx);
+
+ lldb::SBAddress sb_addr;
+ if (m_opaque_ptr) {
+ AddressRange range;
+ if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
+ sb_addr.ref() = range.GetBaseAddress();
+ sb_addr.ref().Slide(range.GetByteSize());
+ }
+ }
+ return LLDB_RECORD_RESULT(sb_addr);
+}
+
+uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr) {
+ LLDB_RECORD_METHOD(uint32_t, SBBlock, GetRangeIndexForBlockAddress,
+ (lldb::SBAddress), block_addr);
+
+ if (m_opaque_ptr && block_addr.IsValid()) {
+ return m_opaque_ptr->GetRangeIndexContainingAddress(block_addr.ref());
+ }
+
+ return UINT32_MAX;
+}
+
+lldb::SBValueList SBBlock::GetVariables(lldb::SBFrame &frame, bool arguments,
+ bool locals, bool statics,
+ lldb::DynamicValueType use_dynamic) {
+ LLDB_RECORD_METHOD(
+ lldb::SBValueList, SBBlock, GetVariables,
+ (lldb::SBFrame &, bool, bool, bool, lldb::DynamicValueType), frame,
+ arguments, locals, statics, use_dynamic);
+
+ Block *block = GetPtr();
+ SBValueList value_list;
+ if (block) {
+ StackFrameSP frame_sp(frame.GetFrameSP());
+ VariableListSP variable_list_sp(block->GetBlockVariableList(true));
+
+ if (variable_list_sp) {
+ const size_t num_variables = variable_list_sp->GetSize();
+ if (num_variables) {
+ for (size_t i = 0; i < num_variables; ++i) {
+ VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
+ 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) {
+ if (frame_sp) {
+ lldb::ValueObjectSP valobj_sp(
+ frame_sp->GetValueObjectForFrameVariable(variable_sp,
+ eNoDynamicValues));
+ SBValue value_sb;
+ value_sb.SetSP(valobj_sp, use_dynamic);
+ value_list.Append(value_sb);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return LLDB_RECORD_RESULT(value_list);
+}
+
+lldb::SBValueList SBBlock::GetVariables(lldb::SBTarget &target, bool arguments,
+ bool locals, bool statics) {
+ LLDB_RECORD_METHOD(lldb::SBValueList, SBBlock, GetVariables,
+ (lldb::SBTarget &, bool, bool, bool), target, arguments,
+ locals, statics);
+
+ Block *block = GetPtr();
+
+ SBValueList value_list;
+ if (block) {
+ TargetSP target_sp(target.GetSP());
+
+ VariableListSP variable_list_sp(block->GetBlockVariableList(true));
+
+ if (variable_list_sp) {
+ const size_t num_variables = variable_list_sp->GetSize();
+ if (num_variables) {
+ for (size_t i = 0; i < num_variables; ++i) {
+ VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
+ 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) {
+ if (target_sp)
+ value_list.Append(
+ ValueObjectVariable::Create(target_sp.get(), variable_sp));
+ }
+ }
+ }
+ }
+ }
+ }
+ return LLDB_RECORD_RESULT(value_list);
+}
+
+namespace lldb_private {
+namespace repro {
+
+template <>
+void RegisterMethods<SBBlock>(Registry &R) {
+ LLDB_REGISTER_CONSTRUCTOR(SBBlock, ());
+ LLDB_REGISTER_CONSTRUCTOR(SBBlock, (const lldb::SBBlock &));
+ LLDB_REGISTER_METHOD(const lldb::SBBlock &,
+ SBBlock, operator=,(const lldb::SBBlock &));
+ LLDB_REGISTER_METHOD_CONST(bool, SBBlock, IsValid, ());
+ LLDB_REGISTER_METHOD_CONST(bool, SBBlock, operator bool, ());
+ LLDB_REGISTER_METHOD_CONST(bool, SBBlock, IsInlined, ());
+ LLDB_REGISTER_METHOD_CONST(const char *, SBBlock, GetInlinedName, ());
+ LLDB_REGISTER_METHOD_CONST(lldb::SBFileSpec, SBBlock,
+ GetInlinedCallSiteFile, ());
+ LLDB_REGISTER_METHOD_CONST(uint32_t, SBBlock, GetInlinedCallSiteLine, ());
+ LLDB_REGISTER_METHOD_CONST(uint32_t, SBBlock, GetInlinedCallSiteColumn, ());
+ LLDB_REGISTER_METHOD(lldb::SBBlock, SBBlock, GetParent, ());
+ LLDB_REGISTER_METHOD(lldb::SBBlock, SBBlock, GetContainingInlinedBlock, ());
+ LLDB_REGISTER_METHOD(lldb::SBBlock, SBBlock, GetSibling, ());
+ LLDB_REGISTER_METHOD(lldb::SBBlock, SBBlock, GetFirstChild, ());
+ LLDB_REGISTER_METHOD(bool, SBBlock, GetDescription, (lldb::SBStream &));
+ LLDB_REGISTER_METHOD(uint32_t, SBBlock, GetNumRanges, ());
+ LLDB_REGISTER_METHOD(lldb::SBAddress, SBBlock, GetRangeStartAddress,
+ (uint32_t));
+ LLDB_REGISTER_METHOD(lldb::SBAddress, SBBlock, GetRangeEndAddress,
+ (uint32_t));
+ LLDB_REGISTER_METHOD(uint32_t, SBBlock, GetRangeIndexForBlockAddress,
+ (lldb::SBAddress));
+ LLDB_REGISTER_METHOD(
+ lldb::SBValueList, SBBlock, GetVariables,
+ (lldb::SBFrame &, bool, bool, bool, lldb::DynamicValueType));
+ LLDB_REGISTER_METHOD(lldb::SBValueList, SBBlock, GetVariables,
+ (lldb::SBTarget &, bool, bool, bool));
+}
+
+}
+}