LLDB  mainline
BlockPointer.cpp
Go to the documentation of this file.
1 //===-- BlockPointer.cpp --------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "BlockPointer.h"
10 
14 #include "lldb/Core/ValueObject.h"
17 #include "lldb/Symbol/TypeSystem.h"
18 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/Log.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 using namespace lldb_private::formatters;
25 
26 namespace lldb_private {
27 namespace formatters {
28 
30 public:
31  BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
32  : SyntheticChildrenFrontEnd(*valobj_sp), m_block_struct_type() {
33  CompilerType block_pointer_type(m_backend.GetCompilerType());
34  CompilerType function_pointer_type;
35  block_pointer_type.IsBlockPointerType(&function_pointer_type);
36 
37  TargetSP target_sp(m_backend.GetTargetSP());
38 
39  if (!target_sp) {
40  return;
41  }
42 
43  auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(
45  if (auto err = type_system_or_err.takeError()) {
48  std::move(err), "Failed to get scratch TypeSystemClang");
49  return;
50  }
51 
52  TypeSystemClang *clang_ast_context =
53  llvm::cast<TypeSystemClang>(block_pointer_type.GetTypeSystem());
54 
55  std::shared_ptr<ClangASTImporter> clang_ast_importer;
56  auto *state = target_sp->GetPersistentExpressionStateForLanguage(
58  if (state) {
59  auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
60  clang_ast_importer = persistent_vars->GetClangASTImporter();
61  }
62 
63  if (!clang_ast_importer) {
64  return;
65  }
66 
67  const char *const isa_name("__isa");
68  const CompilerType isa_type =
69  clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
70  const char *const flags_name("__flags");
71  const CompilerType flags_type =
72  clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
73  const char *const reserved_name("__reserved");
74  const CompilerType reserved_type =
75  clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
76  const char *const FuncPtr_name("__FuncPtr");
77 
78  m_block_struct_type = clang_ast_context->CreateStructForIdentifier(
79  ConstString(), {{isa_name, isa_type},
80  {flags_name, flags_type},
81  {reserved_name, reserved_type},
82  {FuncPtr_name, function_pointer_type}});
83  }
84 
85  ~BlockPointerSyntheticFrontEnd() override = default;
86 
87  size_t CalculateNumChildren() override {
88  const bool omit_empty_base_classes = false;
89  return m_block_struct_type.GetNumChildren(omit_empty_base_classes, nullptr);
90  }
91 
92  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
93  if (!m_block_struct_type.IsValid()) {
94  return lldb::ValueObjectSP();
95  }
96 
97  if (idx >= CalculateNumChildren()) {
98  return lldb::ValueObjectSP();
99  }
100 
101  const bool thread_and_frame_only_if_stopped = true;
102  ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(
103  thread_and_frame_only_if_stopped);
104  const bool transparent_pointers = false;
105  const bool omit_empty_base_classes = false;
106  const bool ignore_array_bounds = false;
107  ValueObject *value_object = nullptr;
108 
109  std::string child_name;
110  uint32_t child_byte_size = 0;
111  int32_t child_byte_offset = 0;
112  uint32_t child_bitfield_bit_size = 0;
113  uint32_t child_bitfield_bit_offset = 0;
114  bool child_is_base_class = false;
115  bool child_is_deref_of_parent = false;
116  uint64_t language_flags = 0;
117 
118  const CompilerType child_type =
119  m_block_struct_type.GetChildCompilerTypeAtIndex(
120  &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
121  ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
122  child_bitfield_bit_size, child_bitfield_bit_offset,
123  child_is_base_class, child_is_deref_of_parent, value_object,
124  language_flags);
125 
126  ValueObjectSP struct_pointer_sp =
127  m_backend.Cast(m_block_struct_type.GetPointerType());
128 
129  if (!struct_pointer_sp) {
130  return lldb::ValueObjectSP();
131  }
132 
133  Status err;
134  ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
135 
136  if (!struct_sp || !err.Success()) {
137  return lldb::ValueObjectSP();
138  }
139 
140  ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(
141  child_byte_offset, child_type, true,
142  ConstString(child_name.c_str(), child_name.size())));
143 
144  return child_sp;
145  }
146 
147  // return true if this object is now safe to use forever without ever
148  // updating again; the typical (and tested) answer here is 'false'
149  bool Update() override { return false; }
150 
151  // maybe return false if the block pointer is, say, null
152  bool MightHaveChildren() override { return true; }
153 
154  size_t GetIndexOfChildWithName(ConstString name) override {
155  if (!m_block_struct_type.IsValid())
156  return UINT32_MAX;
157 
158  const bool omit_empty_base_classes = false;
159  return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(),
160  omit_empty_base_classes);
161  }
162 
163 private:
165 };
166 
167 } // namespace formatters
168 } // namespace lldb_private
169 
171  ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
172  lldb_private::SyntheticChildrenFrontEnd *synthetic_children =
173  BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
174  if (!synthetic_children) {
175  return false;
176  }
177 
178  synthetic_children->Update();
179 
180  static const ConstString s_FuncPtr_name("__FuncPtr");
181 
182  lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(
183  synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
184 
185  if (!child_sp) {
186  return false;
187  }
188 
189  lldb::ValueObjectSP qualified_child_representation_sp =
190  child_sp->GetQualifiedRepresentationIfAvailable(
192 
193  const char *child_value =
194  qualified_child_representation_sp->GetValueAsCString();
195 
196  s.Printf("%s", child_value);
197 
198  return true;
199 }
200 
203  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
204  if (!valobj_sp)
205  return nullptr;
206  return new BlockPointerSyntheticFrontEnd(valobj_sp);
207 }
lldb_private::formatters::BlockPointerSyntheticFrontEnd::MightHaveChildren
bool MightHaveChildren() override
Definition: BlockPointer.cpp:152
lldb_private::ExecutionContext
Definition: ExecutionContext.h:291
lldb_private::formatters::BlockPointerSyntheticFrontEnd::GetIndexOfChildWithName
size_t GetIndexOfChildWithName(ConstString name) override
Definition: BlockPointer.cpp:154
CalculateNumChildren
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:169
lldb_private::SyntheticChildrenFrontEnd
Definition: TypeSynthetic.h:27
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
lldb_private::formatters::BlockPointerSyntheticFrontEnd::m_block_struct_type
CompilerType m_block_struct_type
Definition: BlockPointer.cpp:164
lldb_private::Stream
Definition: Stream.h:28
Target.h
lldb_private::TypeSystemClang::CreateStructForIdentifier
CompilerType CreateStructForIdentifier(ConstString type_name, const std::initializer_list< std::pair< const char *, CompilerType >> &type_fields, bool packed=false)
Definition: TypeSystemClang.cpp:2160
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:288
lldb::eDynamicDontRunTarget
@ eDynamicDontRunTarget
Definition: lldb-enumerations.h:497
LLDBAssert.h
Log.h
lldb_private::SyntheticChildrenFrontEnd::GetChildAtIndex
virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx)=0
TypeSystemClang.h
lldb_private::ValueObject::GetSP
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:555
lldb_private::formatters::BlockPointerSyntheticFrontEnd::BlockPointerSyntheticFrontEnd
BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: BlockPointer.cpp:31
lldb_private::CompilerType::GetChildCompilerTypeAtIndex
CompilerType GetChildCompilerTypeAtIndex(ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags) const
Definition: CompilerType.cpp:602
ClangPersistentVariables.h
lldb::eBasicTypeInt
@ eBasicTypeInt
Definition: lldb-enumerations.h:753
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::formatters::BlockPointerSummaryProvider
bool BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &)
Definition: BlockPointer.cpp:170
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:38
LIBLLDB_LOG_DATAFORMATTERS
#define LIBLLDB_LOG_DATAFORMATTERS
Definition: Logging.h:43
TypeSystem.h
lldb_private::formatters::BlockPointerSyntheticFrontEnd::Update
bool Update() override
Definition: BlockPointer.cpp:149
lldb::eBasicTypeObjCClass
@ eBasicTypeObjCClass
Definition: lldb-enumerations.h:770
CompilerType.h
lldb_private::formatters::BlockPointerSyntheticFrontEnd
Definition: BlockPointer.cpp:29
ValueObject.h
lldb_private::CompilerType::IsBlockPointerType
bool IsBlockPointerType(CompilerType *function_pointer_type_ptr=nullptr) const
Definition: CompilerType.cpp:134
lldb_private::Status
Definition: Status.h:44
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
uint32_t
lldb_private::CompilerType::GetTypeSystem
TypeSystem * GetTypeSystem() const
Accessors.
Definition: CompilerType.h:162
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb_private::formatters::BlockPointerSyntheticFrontEnd::GetChildAtIndex
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: BlockPointer.cpp:92
lldb_private::TypeSummaryOptions
Definition: TypeSummary.h:26
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::formatters
Definition: CXXFunctionPointer.h:15
lldb_private::formatters::BlockPointerSyntheticFrontEnd::CalculateNumChildren
size_t CalculateNumChildren() override
Definition: BlockPointer.cpp:87
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
BlockPointer.h
lldb_private::TypeSystemClang::GetBasicType
CompilerType GetBasicType(lldb::BasicType type)
Definition: TypeSystemClang.cpp:940
lldb_private::SyntheticChildrenFrontEnd::GetIndexOfChildWithName
virtual size_t GetIndexOfChildWithName(ConstString name)=0
lldb_private::formatters::BlockPointerSyntheticFrontEndCreator
SyntheticChildrenFrontEnd * BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: BlockPointer.cpp:202
lldb_private::TypeSystemClang
A TypeSystem implementation based on Clang.
Definition: TypeSystemClang.h:106
lldb_private::SyntheticChildrenFrontEnd::Update
virtual bool Update()=0
ClangASTImporter.h
lldb_private::CXXSyntheticChildren
Definition: TypeSynthetic.h:358
lldb_private::GetLogIfAnyCategoriesSet
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:62
FormattersHelpers.h
lldb
Definition: SBAddress.h:15
LLDB_LOG_ERROR
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:265
lldb::eLanguageTypeC_plus_plus
@ eLanguageTypeC_plus_plus
ISO C++:1998.
Definition: lldb-enumerations.h:441