/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/DataFormatters/TypeSynthetic.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- TypeSynthetic.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 | | |
10 | | |
11 | | |
12 | | #include "lldb/lldb-enumerations.h" |
13 | | #include "lldb/lldb-public.h" |
14 | | |
15 | | #include "lldb/Core/Debugger.h" |
16 | | #include "lldb/DataFormatters/TypeSynthetic.h" |
17 | | #include "lldb/Interpreter/CommandInterpreter.h" |
18 | | #include "lldb/Interpreter/ScriptInterpreter.h" |
19 | | #include "lldb/Symbol/CompilerType.h" |
20 | | #include "lldb/Target/Target.h" |
21 | | #include "lldb/Utility/StreamString.h" |
22 | | |
23 | | using namespace lldb; |
24 | | using namespace lldb_private; |
25 | | |
26 | 60 | void TypeFilterImpl::AddExpressionPath(const std::string &path) { |
27 | 60 | bool need_add_dot = true; |
28 | 60 | if (path[0] == '.' || (path[0] == '-' && path[1] == '>'0 ) || path[0] == '[') |
29 | 0 | need_add_dot = false; |
30 | | // add a '.' symbol to help forgetful users |
31 | 60 | if (!need_add_dot) |
32 | 0 | m_expression_paths.push_back(path); |
33 | 60 | else |
34 | 60 | m_expression_paths.push_back(std::string(".") + path); |
35 | 60 | } |
36 | | |
37 | | bool TypeFilterImpl::SetExpressionPathAtIndex(size_t i, |
38 | 2 | const std::string &path) { |
39 | 2 | if (i >= GetCount()) |
40 | 0 | return false; |
41 | 2 | bool need_add_dot = true; |
42 | 2 | if (path[0] == '.' || (path[0] == '-' && path[1] == '>'0 ) || path[0] == '[') |
43 | 0 | need_add_dot = false; |
44 | | // add a '.' symbol to help forgetful users |
45 | 2 | if (!need_add_dot) |
46 | 0 | m_expression_paths[i] = path; |
47 | 2 | else |
48 | 2 | m_expression_paths[i] = std::string(".") + path; |
49 | 2 | return true; |
50 | 2 | } |
51 | | |
52 | | size_t |
53 | 15 | TypeFilterImpl::FrontEnd::GetIndexOfChildWithName(ConstString name) { |
54 | 15 | const char *name_cstr = name.GetCString(); |
55 | 15 | if (name_cstr) { |
56 | 25 | for (size_t i = 0; i < filter->GetCount(); i++10 ) { |
57 | 20 | const char *expr_cstr = filter->GetExpressionPathAtIndex(i); |
58 | 20 | if (expr_cstr) { |
59 | 20 | if (*expr_cstr == '.') |
60 | 20 | expr_cstr++; |
61 | 0 | else if (*expr_cstr == '-' && *(expr_cstr + 1) == '>') |
62 | 0 | expr_cstr += 2; |
63 | 20 | } |
64 | 20 | if (expr_cstr) { |
65 | 20 | if (!::strcmp(name_cstr, expr_cstr)) |
66 | 10 | return i; |
67 | 20 | } |
68 | 20 | } |
69 | 15 | } |
70 | 5 | return UINT32_MAX; |
71 | 15 | } |
72 | | |
73 | 2 | std::string TypeFilterImpl::GetDescription() { |
74 | 2 | StreamString sstr; |
75 | 2 | sstr.Printf("%s%s%s {\n", Cascades() ? "" : " (not cascading)"0 , |
76 | 2 | SkipsPointers() ? " (skip pointers)"0 : "", |
77 | 2 | SkipsReferences() ? " (skip references)"0 : ""); |
78 | | |
79 | 6 | for (size_t i = 0; i < GetCount(); i++4 ) { |
80 | 4 | sstr.Printf(" %s\n", GetExpressionPathAtIndex(i)); |
81 | 4 | } |
82 | | |
83 | 2 | sstr.Printf("}"); |
84 | 2 | return std::string(sstr.GetString()); |
85 | 2 | } |
86 | | |
87 | 56.3k | SyntheticChildren::SyntheticChildren(const Flags &flags) : m_flags(flags) {} |
88 | | |
89 | 56.2k | SyntheticChildren::~SyntheticChildren() = default; |
90 | | |
91 | | CXXSyntheticChildren::CXXSyntheticChildren( |
92 | | const SyntheticChildren::Flags &flags, const char *description, |
93 | | CreateFrontEndCallback callback) |
94 | 48.6k | : SyntheticChildren(flags), m_create_callback(std::move(callback)), |
95 | 48.6k | m_description(description ? description : ""0 ) {} |
96 | | |
97 | 48.6k | CXXSyntheticChildren::~CXXSyntheticChildren() = default; |
98 | | |
99 | 0 | bool SyntheticChildren::IsScripted() { return false; } |
100 | | |
101 | 0 | std::string SyntheticChildren::GetDescription() { return ""; } |
102 | | |
103 | | SyntheticChildrenFrontEnd::AutoPointer |
104 | 0 | SyntheticChildren::GetFrontEnd(ValueObject &backend) { |
105 | 0 | return nullptr; |
106 | 0 | } |
107 | | |
108 | 272 | std::string CXXSyntheticChildren::GetDescription() { |
109 | 272 | StreamString sstr; |
110 | 272 | sstr.Printf("%s%s%s %s", Cascades() ? "" : " (not cascading)"0 , |
111 | 272 | SkipsPointers() ? " (skip pointers)"0 : "", |
112 | 272 | SkipsReferences() ? " (skip references)"0 : "", |
113 | 272 | m_description.c_str()); |
114 | | |
115 | 272 | return std::string(sstr.GetString()); |
116 | 272 | } |
117 | | |
118 | | lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromExpression( |
119 | | llvm::StringRef name, llvm::StringRef expression, |
120 | 0 | const ExecutionContext &exe_ctx) { |
121 | 0 | ValueObjectSP valobj_sp( |
122 | 0 | ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx)); |
123 | 0 | if (valobj_sp) |
124 | 0 | valobj_sp->SetSyntheticChildrenGenerated(true); |
125 | 0 | return valobj_sp; |
126 | 0 | } |
127 | | |
128 | | lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromAddress( |
129 | | llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, |
130 | 690 | CompilerType type) { |
131 | 690 | ValueObjectSP valobj_sp( |
132 | 690 | ValueObject::CreateValueObjectFromAddress(name, address, exe_ctx, type)); |
133 | 690 | if (valobj_sp) |
134 | 690 | valobj_sp->SetSyntheticChildrenGenerated(true); |
135 | 690 | return valobj_sp; |
136 | 690 | } |
137 | | |
138 | | lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromData( |
139 | | llvm::StringRef name, const DataExtractor &data, |
140 | 8.72k | const ExecutionContext &exe_ctx, CompilerType type) { |
141 | 8.72k | ValueObjectSP valobj_sp( |
142 | 8.72k | ValueObject::CreateValueObjectFromData(name, data, exe_ctx, type)); |
143 | 8.72k | if (valobj_sp) |
144 | 8.72k | valobj_sp->SetSyntheticChildrenGenerated(true); |
145 | 8.72k | return valobj_sp; |
146 | 8.72k | } |
147 | | |
148 | | ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass, |
149 | | ValueObject &backend) |
150 | 103 | : SyntheticChildrenFrontEnd(backend), m_python_class(pclass), |
151 | 103 | m_wrapper_sp(), m_interpreter(nullptr) { |
152 | 103 | if (backend.GetID() == LLDB_INVALID_UID) |
153 | 0 | return; |
154 | | |
155 | 103 | TargetSP target_sp = backend.GetTargetSP(); |
156 | | |
157 | 103 | if (!target_sp) |
158 | 0 | return; |
159 | | |
160 | 103 | m_interpreter = target_sp->GetDebugger().GetScriptInterpreter(); |
161 | | |
162 | 103 | if (m_interpreter != nullptr) |
163 | 103 | m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider( |
164 | 103 | m_python_class.c_str(), backend.GetSP()); |
165 | 103 | } |
166 | | |
167 | 3 | ScriptedSyntheticChildren::FrontEnd::~FrontEnd() = default; |
168 | | |
169 | | lldb::ValueObjectSP |
170 | 996 | ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex(size_t idx) { |
171 | 996 | if (!m_wrapper_sp || !m_interpreter) |
172 | 0 | return lldb::ValueObjectSP(); |
173 | | |
174 | 996 | return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx); |
175 | 996 | } |
176 | | |
177 | 103 | bool ScriptedSyntheticChildren::FrontEnd::IsValid() { |
178 | 103 | return (m_wrapper_sp && m_wrapper_sp->IsValid() && m_interpreter100 ); |
179 | 103 | } |
180 | | |
181 | 0 | size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren() { |
182 | 0 | if (!m_wrapper_sp || m_interpreter == nullptr) |
183 | 0 | return 0; |
184 | 0 | return m_interpreter->CalculateNumChildren(m_wrapper_sp, UINT32_MAX); |
185 | 0 | } |
186 | | |
187 | 94 | size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren(uint32_t max) { |
188 | 94 | if (!m_wrapper_sp || m_interpreter == nullptr) |
189 | 0 | return 0; |
190 | 94 | return m_interpreter->CalculateNumChildren(m_wrapper_sp, max); |
191 | 94 | } |
192 | | |
193 | 115 | bool ScriptedSyntheticChildren::FrontEnd::Update() { |
194 | 115 | if (!m_wrapper_sp || m_interpreter == nullptr) |
195 | 0 | return false; |
196 | | |
197 | 115 | return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp); |
198 | 115 | } |
199 | | |
200 | 20 | bool ScriptedSyntheticChildren::FrontEnd::MightHaveChildren() { |
201 | 20 | if (!m_wrapper_sp || m_interpreter == nullptr) |
202 | 0 | return false; |
203 | | |
204 | 20 | return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp); |
205 | 20 | } |
206 | | |
207 | | size_t ScriptedSyntheticChildren::FrontEnd::GetIndexOfChildWithName( |
208 | 7 | ConstString name) { |
209 | 7 | if (!m_wrapper_sp || m_interpreter == nullptr) |
210 | 0 | return UINT32_MAX; |
211 | 7 | return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, |
212 | 7 | name.GetCString()); |
213 | 7 | } |
214 | | |
215 | 115 | lldb::ValueObjectSP ScriptedSyntheticChildren::FrontEnd::GetSyntheticValue() { |
216 | 115 | if (!m_wrapper_sp || m_interpreter == nullptr) |
217 | 0 | return nullptr; |
218 | | |
219 | 115 | return m_interpreter->GetSyntheticValue(m_wrapper_sp); |
220 | 115 | } |
221 | | |
222 | 135 | ConstString ScriptedSyntheticChildren::FrontEnd::GetSyntheticTypeName() { |
223 | 135 | if (!m_wrapper_sp || m_interpreter == nullptr) |
224 | 0 | return ConstString(); |
225 | | |
226 | 135 | return m_interpreter->GetSyntheticTypeName(m_wrapper_sp); |
227 | 135 | } |
228 | | |
229 | 50 | std::string ScriptedSyntheticChildren::GetDescription() { |
230 | 50 | StreamString sstr; |
231 | 50 | sstr.Printf("%s%s%s Python class %s", Cascades() ? "" : " (not cascading)"0 , |
232 | 50 | SkipsPointers() ? " (skip pointers)"0 : "", |
233 | 50 | SkipsReferences() ? " (skip references)"0 : "", |
234 | 50 | m_python_class.c_str()); |
235 | | |
236 | 50 | return std::string(sstr.GetString()); |
237 | 50 | } |