1 //===-- TypeSynthetic.cpp ----------------------------------------*- C++
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
13 #include "lldb/lldb-enumerations.h"
14 #include "lldb/lldb-public.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/DataFormatters/TypeSynthetic.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/ScriptInterpreter.h"
20 #include "lldb/Symbol/CompilerType.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/StreamString.h"
25 using namespace lldb_private
;
27 void TypeFilterImpl::AddExpressionPath(const std::string
&path
) {
28 bool need_add_dot
= true;
29 if (path
[0] == '.' || (path
[0] == '-' && path
[1] == '>') || path
[0] == '[')
31 // add a '.' symbol to help forgetful users
33 m_expression_paths
.push_back(path
);
35 m_expression_paths
.push_back(std::string(".") + path
);
38 bool TypeFilterImpl::SetExpressionPathAtIndex(size_t i
,
39 const std::string
&path
) {
42 bool need_add_dot
= true;
43 if (path
[0] == '.' || (path
[0] == '-' && path
[1] == '>') || path
[0] == '[')
45 // add a '.' symbol to help forgetful users
47 m_expression_paths
[i
] = path
;
49 m_expression_paths
[i
] = std::string(".") + path
;
54 TypeFilterImpl::FrontEnd::GetIndexOfChildWithName(ConstString name
) {
55 const char *name_cstr
= name
.GetCString();
57 for (size_t i
= 0; i
< filter
->GetCount(); i
++) {
58 const char *expr_cstr
= filter
->GetExpressionPathAtIndex(i
);
60 if (*expr_cstr
== '.')
62 else if (*expr_cstr
== '-' && *(expr_cstr
+ 1) == '>')
66 if (!::strcmp(name_cstr
, expr_cstr
))
74 std::string
TypeFilterImpl::GetDescription() {
76 sstr
.Printf("%s%s%s {\n", Cascades() ? "" : " (not cascading)",
77 SkipsPointers() ? " (skip pointers)" : "",
78 SkipsReferences() ? " (skip references)" : "");
80 for (size_t i
= 0; i
< GetCount(); i
++) {
81 sstr
.Printf(" %s\n", GetExpressionPathAtIndex(i
));
85 return sstr
.GetString();
88 std::string
CXXSyntheticChildren::GetDescription() {
90 sstr
.Printf("%s%s%s %s", Cascades() ? "" : " (not cascading)",
91 SkipsPointers() ? " (skip pointers)" : "",
92 SkipsReferences() ? " (skip references)" : "",
93 m_description
.c_str());
95 return sstr
.GetString();
98 lldb::ValueObjectSP
SyntheticChildrenFrontEnd::CreateValueObjectFromExpression(
99 llvm::StringRef name
, llvm::StringRef expression
,
100 const ExecutionContext
&exe_ctx
) {
101 ValueObjectSP
valobj_sp(
102 ValueObject::CreateValueObjectFromExpression(name
, expression
, exe_ctx
));
104 valobj_sp
->SetSyntheticChildrenGenerated(true);
108 lldb::ValueObjectSP
SyntheticChildrenFrontEnd::CreateValueObjectFromAddress(
109 llvm::StringRef name
, uint64_t address
, const ExecutionContext
&exe_ctx
,
111 ValueObjectSP
valobj_sp(
112 ValueObject::CreateValueObjectFromAddress(name
, address
, exe_ctx
, type
));
114 valobj_sp
->SetSyntheticChildrenGenerated(true);
118 lldb::ValueObjectSP
SyntheticChildrenFrontEnd::CreateValueObjectFromData(
119 llvm::StringRef name
, const DataExtractor
&data
,
120 const ExecutionContext
&exe_ctx
, CompilerType type
) {
121 ValueObjectSP
valobj_sp(
122 ValueObject::CreateValueObjectFromData(name
, data
, exe_ctx
, type
));
124 valobj_sp
->SetSyntheticChildrenGenerated(true);
128 ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass
,
129 ValueObject
&backend
)
130 : SyntheticChildrenFrontEnd(backend
), m_python_class(pclass
),
131 m_wrapper_sp(), m_interpreter(nullptr) {
132 if (backend
== LLDB_INVALID_UID
)
135 TargetSP target_sp
= backend
.GetTargetSP();
140 m_interpreter
= target_sp
->GetDebugger().GetScriptInterpreter();
142 if (m_interpreter
!= nullptr)
143 m_wrapper_sp
= m_interpreter
->CreateSyntheticScriptedProvider(
144 m_python_class
.c_str(), backend
.GetSP());
147 ScriptedSyntheticChildren::FrontEnd::~FrontEnd() {}
150 ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex(size_t idx
) {
151 if (!m_wrapper_sp
|| !m_interpreter
)
152 return lldb::ValueObjectSP();
154 return m_interpreter
->GetChildAtIndex(m_wrapper_sp
, idx
);
157 bool ScriptedSyntheticChildren::FrontEnd::IsValid() {
158 return (m_wrapper_sp
&& m_wrapper_sp
->IsValid() && m_interpreter
);
161 size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren() {
162 if (!m_wrapper_sp
|| m_interpreter
== nullptr)
164 return m_interpreter
->CalculateNumChildren(m_wrapper_sp
, UINT32_MAX
);
167 size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren(uint32_t max
) {
168 if (!m_wrapper_sp
|| m_interpreter
== nullptr)
170 return m_interpreter
->CalculateNumChildren(m_wrapper_sp
, max
);
173 bool ScriptedSyntheticChildren::FrontEnd::Update() {
174 if (!m_wrapper_sp
|| m_interpreter
== nullptr)
177 return m_interpreter
->UpdateSynthProviderInstance(m_wrapper_sp
);
180 bool ScriptedSyntheticChildren::FrontEnd::MightHaveChildren() {
181 if (!m_wrapper_sp
|| m_interpreter
== nullptr)
184 return m_interpreter
->MightHaveChildrenSynthProviderInstance(m_wrapper_sp
);
187 size_t ScriptedSyntheticChildren::FrontEnd::GetIndexOfChildWithName(
189 if (!m_wrapper_sp
|| m_interpreter
== nullptr)
191 return m_interpreter
->GetIndexOfChildWithName(m_wrapper_sp
,
195 lldb::ValueObjectSP
ScriptedSyntheticChildren::FrontEnd::GetSyntheticValue() {
196 if (!m_wrapper_sp
|| m_interpreter
== nullptr)
199 return m_interpreter
->GetSyntheticValue(m_wrapper_sp
);
202 ConstString
ScriptedSyntheticChildren::FrontEnd::GetSyntheticTypeName() {
203 if (!m_wrapper_sp
|| m_interpreter
== nullptr)
204 return ConstString();
206 return m_interpreter
->GetSyntheticTypeName(m_wrapper_sp
);
209 std::string
ScriptedSyntheticChildren::GetDescription() {
211 sstr
.Printf("%s%s%s Python class %s", Cascades() ? "" : " (not cascading)",
212 SkipsPointers() ? " (skip pointers)" : "",
213 SkipsReferences() ? " (skip references)" : "",
214 m_python_class
.c_str());
216 return sstr
.GetString();