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/LLDBLog.h"
21 #include "lldb/Utility/Log.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 using namespace lldb_private::formatters;
26 
27 namespace lldb_private {
28 namespace formatters {
29 
31 public:
32  BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
33  : SyntheticChildrenFrontEnd(*valobj_sp), m_block_struct_type() {
34  CompilerType block_pointer_type(m_backend.GetCompilerType());
35  CompilerType function_pointer_type;
36  block_pointer_type.IsBlockPointerType(&function_pointer_type);
37 
38  TargetSP target_sp(m_backend.GetTargetSP());
39 
40  if (!target_sp) {
41  return;
42  }
43 
44  auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(
46  if (auto err = type_system_or_err.takeError()) {
47  LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), std::move(err),
48  "Failed to get scratch TypeSystemClang");
49  return;
50  }
51 
52  auto ts = block_pointer_type.GetTypeSystem();
53  auto clang_ast_context = ts.dyn_cast_or_null<TypeSystemClang>();
54  if (!clang_ast_context)
55  return;
56 
57  std::shared_ptr<ClangASTImporter> clang_ast_importer;
58  auto *state = target_sp->GetPersistentExpressionStateForLanguage(
60  if (state) {
61  auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
62  clang_ast_importer = persistent_vars->GetClangASTImporter();
63  }
64 
65  if (!clang_ast_importer) {
66  return;
67  }
68 
69  const char *const isa_name("__isa");
70  const CompilerType isa_type =
71  clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
72  const char *const flags_name("__flags");
73  const CompilerType flags_type =
74  clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
75  const char *const reserved_name("__reserved");
76  const CompilerType reserved_type =
77  clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
78  const char *const FuncPtr_name("__FuncPtr");
79 
80  m_block_struct_type = clang_ast_context->CreateStructForIdentifier(
81  ConstString(), {{isa_name, isa_type},
82  {flags_name, flags_type},
83  {reserved_name, reserved_type},
84  {FuncPtr_name, function_pointer_type}});
85  }
86 
87  ~BlockPointerSyntheticFrontEnd() override = default;
88 
89  size_t CalculateNumChildren() override {
90  const bool omit_empty_base_classes = false;
91  return m_block_struct_type.GetNumChildren(omit_empty_base_classes, nullptr);
92  }
93 
94  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
95  if (!m_block_struct_type.IsValid()) {
96  return lldb::ValueObjectSP();
97  }
98 
99  if (idx >= CalculateNumChildren()) {
100  return lldb::ValueObjectSP();
101  }
102 
103  const bool thread_and_frame_only_if_stopped = true;
104  ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(
105  thread_and_frame_only_if_stopped);
106  const bool transparent_pointers = false;
107  const bool omit_empty_base_classes = false;
108  const bool ignore_array_bounds = false;
109  ValueObject *value_object = nullptr;
110 
111  std::string child_name;
112  uint32_t child_byte_size = 0;
113  int32_t child_byte_offset = 0;
114  uint32_t child_bitfield_bit_size = 0;
115  uint32_t child_bitfield_bit_offset = 0;
116  bool child_is_base_class = false;
117  bool child_is_deref_of_parent = false;
118  uint64_t language_flags = 0;
119 
120  const CompilerType child_type =
121  m_block_struct_type.GetChildCompilerTypeAtIndex(
122  &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
123  ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
124  child_bitfield_bit_size, child_bitfield_bit_offset,
125  child_is_base_class, child_is_deref_of_parent, value_object,
126  language_flags);
127 
128  ValueObjectSP struct_pointer_sp =
129  m_backend.Cast(m_block_struct_type.GetPointerType());
130 
131  if (!struct_pointer_sp) {
132  return lldb::ValueObjectSP();
133  }
134 
135  Status err;
136  ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
137 
138  if (!struct_sp || !err.Success()) {
139  return lldb::ValueObjectSP();
140  }
141 
142  ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(
143  child_byte_offset, child_type, true,
144  ConstString(child_name.c_str(), child_name.size())));
145 
146  return child_sp;
147  }
148 
149  // return true if this object is now safe to use forever without ever
150  // updating again; the typical (and tested) answer here is 'false'
151  bool Update() override { return false; }
152 
153  // maybe return false if the block pointer is, say, null
154  bool MightHaveChildren() override { return true; }
155 
156  size_t GetIndexOfChildWithName(ConstString name) override {
157  if (!m_block_struct_type.IsValid())
158  return UINT32_MAX;
159 
160  const bool omit_empty_base_classes = false;
161  return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(),
162  omit_empty_base_classes);
163  }
164 
165 private:
167 };
168 
169 } // namespace formatters
170 } // namespace lldb_private
171 
173  ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
174  lldb_private::SyntheticChildrenFrontEnd *synthetic_children =
175  BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
176  if (!synthetic_children) {
177  return false;
178  }
179 
180  synthetic_children->Update();
181 
182  static const ConstString s_FuncPtr_name("__FuncPtr");
183 
184  lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(
185  synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
186 
187  if (!child_sp) {
188  return false;
189  }
190 
191  lldb::ValueObjectSP qualified_child_representation_sp =
192  child_sp->GetQualifiedRepresentationIfAvailable(
194 
195  const char *child_value =
196  qualified_child_representation_sp->GetValueAsCString();
197 
198  s.Printf("%s", child_value);
199 
200  return true;
201 }
202 
205  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
206  if (!valobj_sp)
207  return nullptr;
208  return new BlockPointerSyntheticFrontEnd(valobj_sp);
209 }
lldb_private::formatters::BlockPointerSyntheticFrontEnd::MightHaveChildren
bool MightHaveChildren() override
Definition: BlockPointer.cpp:154
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::formatters::BlockPointerSyntheticFrontEnd::GetIndexOfChildWithName
size_t GetIndexOfChildWithName(ConstString name) override
Definition: BlockPointer.cpp:156
CalculateNumChildren
static size_t CalculateNumChildren(CompilerType container_type, CompilerType element_type, lldb_private::ExecutionContextScope *exe_scope=nullptr)
Definition: VectorType.cpp:171
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:192
lldb_private::formatters::BlockPointerSyntheticFrontEnd::m_block_struct_type
CompilerType m_block_struct_type
Definition: BlockPointer.cpp:166
lldb_private::Stream
Definition: Stream.h:28
Target.h
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:287
lldb::eDynamicDontRunTarget
@ eDynamicDontRunTarget
Definition: lldb-enumerations.h:498
lldb_private::CompilerType::GetTypeSystem
TypeSystemSPWrapper GetTypeSystem() const
Accessors.
Definition: CompilerType.cpp:980
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:32
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:675
ClangPersistentVariables.h
lldb::eBasicTypeInt
@ eBasicTypeInt
Definition: lldb-enumerations.h:762
lldb_private::ConstString
Definition: ConstString.h:39
lldb::eLanguageTypeC_plus_plus
@ eLanguageTypeC_plus_plus
ISO C++:1998.
Definition: lldb-enumerations.h:442
lldb_private::formatters::BlockPointerSummaryProvider
bool BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &)
Definition: BlockPointer.cpp:172
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
TypeSystem.h
lldb_private::formatters::BlockPointerSyntheticFrontEnd::Update
bool Update() override
Definition: BlockPointer.cpp:151
lldb::eBasicTypeObjCClass
@ eBasicTypeObjCClass
Definition: lldb-enumerations.h:779
CompilerType.h
lldb_private::formatters::BlockPointerSyntheticFrontEnd
Definition: BlockPointer.cpp:30
ValueObject.h
lldb_private::CompilerType::IsBlockPointerType
bool IsBlockPointerType(CompilerType *function_pointer_type_ptr=nullptr) const
Definition: CompilerType.cpp:156
lldb_private::Status
Definition: Status.h:44
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
uint32_t
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
lldb_private::formatters::BlockPointerSyntheticFrontEnd::GetChildAtIndex
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: BlockPointer.cpp:94
lldb_private::TypeSummaryOptions
Definition: TypeSummary.h:26
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:35
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:89
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
BlockPointer.h
lldb_private::SyntheticChildrenFrontEnd::GetIndexOfChildWithName
virtual size_t GetIndexOfChildWithName(ConstString name)=0
lldb_private::formatters::BlockPointerSyntheticFrontEndCreator
SyntheticChildrenFrontEnd * BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: BlockPointer.cpp:204
lldb_private::TypeSystemClang
A TypeSystem implementation based on Clang.
Definition: TypeSystemClang.h:105
lldb_private::CompilerType::TypeSystemSPWrapper::dyn_cast_or_null
std::shared_ptr< TypeSystemType > dyn_cast_or_null()
Return a shared_ptr<TypeSystemType> if dyn_cast succeeds.
Definition: CompilerType.h:67
lldb_private::SyntheticChildrenFrontEnd::Update
virtual bool Update()=0
ClangASTImporter.h
lldb_private::CXXSyntheticChildren
Definition: TypeSynthetic.h:358
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
FormattersHelpers.h
lldb
Definition: SBAddress.h:15
LLDB_LOG_ERROR
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:360
LLDBLog.h