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();