LLDB  mainline
BlockPointer.cpp
Go to the documentation of this file.
1 //===-- BlockPointer.cpp ----------------------------------------*- C++ -*-===//
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 
11 #include "lldb/Core/ValueObject.h"
16 #include "lldb/Symbol/TypeSystem.h"
17 #include "lldb/Target/Target.h"
18 
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 using namespace lldb_private::formatters;
24 
25 namespace lldb_private {
26 namespace formatters {
27 
29 public:
30  BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
31  : SyntheticChildrenFrontEnd(*valobj_sp), m_block_struct_type() {
32  CompilerType block_pointer_type(m_backend.GetCompilerType());
33  CompilerType function_pointer_type;
34  block_pointer_type.IsBlockPointerType(&function_pointer_type);
35 
36  TargetSP target_sp(m_backend.GetTargetSP());
37 
38  if (!target_sp) {
39  return;
40  }
41 
42  Status err;
43  TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(
45 
46  if (!err.Success() || !type_system) {
47  return;
48  }
49 
50  ClangASTContext *clang_ast_context =
51  llvm::dyn_cast<ClangASTContext>(type_system);
52 
53  if (!clang_ast_context) {
54  return;
55  }
56 
57  ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter();
58 
59  if (!clang_ast_importer) {
60  return;
61  }
62 
63  const char *const isa_name("__isa");
64  const CompilerType isa_type =
65  clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
66  const char *const flags_name("__flags");
67  const CompilerType flags_type =
68  clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
69  const char *const reserved_name("__reserved");
70  const CompilerType reserved_type =
71  clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
72  const char *const FuncPtr_name("__FuncPtr");
73  const CompilerType FuncPtr_type =
74  clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
75 
76  m_block_struct_type = clang_ast_context->CreateStructForIdentifier(
77  ConstString(), {{isa_name, isa_type},
78  {flags_name, flags_type},
79  {reserved_name, reserved_type},
80  {FuncPtr_name, FuncPtr_type}});
81  }
82 
83  ~BlockPointerSyntheticFrontEnd() override = default;
84 
85  size_t CalculateNumChildren() override {
86  const bool omit_empty_base_classes = false;
87  return m_block_struct_type.GetNumChildren(omit_empty_base_classes, nullptr);
88  }
89 
90  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
91  if (!m_block_struct_type.IsValid()) {
92  return lldb::ValueObjectSP();
93  }
94 
95  if (idx >= CalculateNumChildren()) {
96  return lldb::ValueObjectSP();
97  }
98 
99  const bool thread_and_frame_only_if_stopped = true;
100  ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(
101  thread_and_frame_only_if_stopped);
102  const bool transparent_pointers = false;
103  const bool omit_empty_base_classes = false;
104  const bool ignore_array_bounds = false;
105  ValueObject *value_object = nullptr;
106 
107  std::string child_name;
108  uint32_t child_byte_size = 0;
109  int32_t child_byte_offset = 0;
110  uint32_t child_bitfield_bit_size = 0;
111  uint32_t child_bitfield_bit_offset = 0;
112  bool child_is_base_class = false;
113  bool child_is_deref_of_parent = false;
114  uint64_t language_flags = 0;
115 
116  const CompilerType child_type =
117  m_block_struct_type.GetChildCompilerTypeAtIndex(
118  &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
119  ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
120  child_bitfield_bit_size, child_bitfield_bit_offset,
121  child_is_base_class, child_is_deref_of_parent, value_object,
122  language_flags);
123 
124  ValueObjectSP struct_pointer_sp =
125  m_backend.Cast(m_block_struct_type.GetPointerType());
126 
127  if (!struct_pointer_sp) {
128  return lldb::ValueObjectSP();
129  }
130 
131  Status err;
132  ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
133 
134  if (!struct_sp || !err.Success()) {
135  return lldb::ValueObjectSP();
136  }
137 
138  ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(
139  child_byte_offset, child_type, true,
140  ConstString(child_name.c_str(), child_name.size())));
141 
142  return child_sp;
143  }
144 
145  // return true if this object is now safe to use forever without ever
146  // updating again; the typical (and tested) answer here is 'false'
147  bool Update() override { return false; }
148 
149  // maybe return false if the block pointer is, say, null
150  bool MightHaveChildren() override { return true; }
151 
152  size_t GetIndexOfChildWithName(ConstString name) override {
153  if (!m_block_struct_type.IsValid())
154  return UINT32_MAX;
155 
156  const bool omit_empty_base_classes = false;
157  return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(),
158  omit_empty_base_classes);
159  }
160 
161 private:
162  CompilerType m_block_struct_type;
163 };
164 
165 } // namespace formatters
166 } // namespace lldb_private
167 
169  ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
170  lldb_private::SyntheticChildrenFrontEnd *synthetic_children =
171  BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
172  if (!synthetic_children) {
173  return false;
174  }
175 
176  synthetic_children->Update();
177 
178  static const ConstString s_FuncPtr_name("__FuncPtr");
179 
180  lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(
181  synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
182 
183  if (!child_sp) {
184  return false;
185  }
186 
187  lldb::ValueObjectSP qualified_child_representation_sp =
188  child_sp->GetQualifiedRepresentationIfAvailable(
190 
191  const char *child_value =
192  qualified_child_representation_sp->GetValueAsCString();
193 
194  s.Printf("%s", child_value);
195 
196  return true;
197 }
198 
201  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
202  if (!valobj_sp)
203  return nullptr;
204  return new BlockPointerSyntheticFrontEnd(valobj_sp);
205 }
bool BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
size_t GetIndexOfChildWithName(ConstString name) override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
CompilerType CreateStructForIdentifier(ConstString type_name, const std::initializer_list< std::pair< const char *, CompilerType >> &type_fields, bool packed=false)
#define UINT32_MAX
Definition: lldb-defines.h:31
SyntheticChildrenFrontEnd * BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx)=0
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool Success() const
Test for success condition.
Definition: Status.cpp:287
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:168
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
BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
virtual size_t GetIndexOfChildWithName(ConstString name)=0
A uniqued constant string class.
Definition: ConstString.h:38
Definition: SBAddress.h:15
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:565
bool IsBlockPointerType(CompilerType *function_pointer_type_ptr) const
CompilerType GetBasicType(lldb::BasicType type)
An error handling class.
Definition: Status.h:44