/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- TypeSummary.h -------------------------------------------*- 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 | | #ifndef LLDB_DATAFORMATTERS_TYPESUMMARY_H |
10 | | #define LLDB_DATAFORMATTERS_TYPESUMMARY_H |
11 | | |
12 | | #include <cstdint> |
13 | | |
14 | | #include <functional> |
15 | | #include <memory> |
16 | | #include <string> |
17 | | |
18 | | #include "lldb/lldb-enumerations.h" |
19 | | #include "lldb/lldb-public.h" |
20 | | |
21 | | #include "lldb/Core/FormatEntity.h" |
22 | | #include "lldb/Utility/Status.h" |
23 | | #include "lldb/Utility/StructuredData.h" |
24 | | |
25 | | namespace lldb_private { |
26 | | class TypeSummaryOptions { |
27 | | public: |
28 | | TypeSummaryOptions(); |
29 | | |
30 | | ~TypeSummaryOptions() = default; |
31 | | |
32 | | lldb::LanguageType GetLanguage() const; |
33 | | |
34 | | lldb::TypeSummaryCapping GetCapping() const; |
35 | | |
36 | | TypeSummaryOptions &SetLanguage(lldb::LanguageType); |
37 | | |
38 | | TypeSummaryOptions &SetCapping(lldb::TypeSummaryCapping); |
39 | | |
40 | | private: |
41 | | lldb::LanguageType m_lang = lldb::eLanguageTypeUnknown; |
42 | | lldb::TypeSummaryCapping m_capping = lldb::eTypeSummaryCapped; |
43 | | }; |
44 | | |
45 | | class TypeSummaryImpl { |
46 | | public: |
47 | | enum class Kind { eSummaryString, eScript, eCallback, eInternal }; |
48 | | |
49 | 146k | virtual ~TypeSummaryImpl() = default; |
50 | | |
51 | 29 | Kind GetKind() const { return m_kind; } |
52 | | |
53 | | class Flags { |
54 | | public: |
55 | 16.5k | Flags() = default; |
56 | | |
57 | 277k | Flags(const Flags &other) : m_flags(other.m_flags) {} |
58 | | |
59 | 13 | Flags(uint32_t value) : m_flags(value) {} |
60 | | |
61 | 0 | Flags &operator=(const Flags &rhs) { |
62 | 0 | if (&rhs != this) |
63 | 0 | m_flags = rhs.m_flags; |
64 | 0 |
|
65 | 0 | return *this; |
66 | 0 | } |
67 | | |
68 | 0 | Flags &operator=(const uint32_t &rhs) { |
69 | 0 | m_flags = rhs; |
70 | 0 | return *this; |
71 | 0 | } |
72 | | |
73 | 333 | Flags &Clear() { |
74 | 333 | m_flags = 0; |
75 | 333 | return *this; |
76 | 333 | } |
77 | | |
78 | 5.31k | bool GetCascades() const { |
79 | 5.31k | return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade; |
80 | 5.31k | } |
81 | | |
82 | 10.8k | Flags &SetCascades(bool value = true) { |
83 | 10.8k | if (value) |
84 | 9.38k | m_flags |= lldb::eTypeOptionCascade; |
85 | 1.43k | else |
86 | 1.43k | m_flags &= ~lldb::eTypeOptionCascade; |
87 | 10.8k | return *this; |
88 | 10.8k | } |
89 | | |
90 | 5.31k | bool GetSkipPointers() const { |
91 | 5.31k | return (m_flags & lldb::eTypeOptionSkipPointers) == |
92 | 5.31k | lldb::eTypeOptionSkipPointers; |
93 | 5.31k | } |
94 | | |
95 | 13.5k | Flags &SetSkipPointers(bool value = true) { |
96 | 13.5k | if (value) |
97 | 8.40k | m_flags |= lldb::eTypeOptionSkipPointers; |
98 | 5.17k | else |
99 | 5.17k | m_flags &= ~lldb::eTypeOptionSkipPointers; |
100 | 13.5k | return *this; |
101 | 13.5k | } |
102 | | |
103 | 5.04k | bool GetSkipReferences() const { |
104 | 5.04k | return (m_flags & lldb::eTypeOptionSkipReferences) == |
105 | 5.04k | lldb::eTypeOptionSkipReferences; |
106 | 5.04k | } |
107 | | |
108 | 10.8k | Flags &SetSkipReferences(bool value = true) { |
109 | 10.8k | if (value) |
110 | 1.43k | m_flags |= lldb::eTypeOptionSkipReferences; |
111 | 9.38k | else |
112 | 9.38k | m_flags &= ~lldb::eTypeOptionSkipReferences; |
113 | 10.8k | return *this; |
114 | 10.8k | } |
115 | | |
116 | 11.5k | bool GetDontShowChildren() const { |
117 | 11.5k | return (m_flags & lldb::eTypeOptionHideChildren) == |
118 | 11.5k | lldb::eTypeOptionHideChildren; |
119 | 11.5k | } |
120 | | |
121 | 12.9k | Flags &SetDontShowChildren(bool value = true) { |
122 | 12.9k | if (value) |
123 | 10.1k | m_flags |= lldb::eTypeOptionHideChildren; |
124 | 2.79k | else |
125 | 2.79k | m_flags &= ~lldb::eTypeOptionHideChildren; |
126 | 12.9k | return *this; |
127 | 12.9k | } |
128 | | |
129 | 157 | bool GetHideEmptyAggregates() const { |
130 | 157 | return (m_flags & lldb::eTypeOptionHideEmptyAggregates) == |
131 | 157 | lldb::eTypeOptionHideEmptyAggregates; |
132 | 157 | } |
133 | | |
134 | 2 | Flags &SetHideEmptyAggregates(bool value = true) { |
135 | 2 | if (value) |
136 | 2 | m_flags |= lldb::eTypeOptionHideEmptyAggregates; |
137 | 0 | else |
138 | 0 | m_flags &= ~lldb::eTypeOptionHideEmptyAggregates; |
139 | 2 | return *this; |
140 | 2 | } |
141 | | |
142 | 6.66k | bool GetDontShowValue() const { |
143 | 6.66k | return (m_flags & lldb::eTypeOptionHideValue) == |
144 | 6.66k | lldb::eTypeOptionHideValue; |
145 | 6.66k | } |
146 | | |
147 | 10.1k | Flags &SetDontShowValue(bool value = true) { |
148 | 10.1k | if (value) |
149 | 4.87k | m_flags |= lldb::eTypeOptionHideValue; |
150 | 5.32k | else |
151 | 5.32k | m_flags &= ~lldb::eTypeOptionHideValue; |
152 | 10.1k | return *this; |
153 | 10.1k | } |
154 | | |
155 | 12.3k | bool GetShowMembersOneLiner() const { |
156 | 12.3k | return (m_flags & lldb::eTypeOptionShowOneLiner) == |
157 | 12.3k | lldb::eTypeOptionShowOneLiner; |
158 | 12.3k | } |
159 | | |
160 | 14.3k | Flags &SetShowMembersOneLiner(bool value = true) { |
161 | 14.3k | if (value) |
162 | 6.28k | m_flags |= lldb::eTypeOptionShowOneLiner; |
163 | 8.05k | else |
164 | 8.05k | m_flags &= ~lldb::eTypeOptionShowOneLiner; |
165 | 14.3k | return *this; |
166 | 14.3k | } |
167 | | |
168 | 3.71k | bool GetHideItemNames() const { |
169 | 3.71k | return (m_flags & lldb::eTypeOptionHideNames) == |
170 | 3.71k | lldb::eTypeOptionHideNames; |
171 | 3.71k | } |
172 | | |
173 | 10.1k | Flags &SetHideItemNames(bool value = true) { |
174 | 10.1k | if (value) |
175 | 2.74k | m_flags |= lldb::eTypeOptionHideNames; |
176 | 7.37k | else |
177 | 7.37k | m_flags &= ~lldb::eTypeOptionHideNames; |
178 | 10.1k | return *this; |
179 | 10.1k | } |
180 | | |
181 | 1.45k | bool GetNonCacheable() const { |
182 | 1.45k | return (m_flags & lldb::eTypeOptionNonCacheable) == |
183 | 1.45k | lldb::eTypeOptionNonCacheable; |
184 | 1.45k | } |
185 | | |
186 | 0 | Flags &SetNonCacheable(bool value = true) { |
187 | 0 | if (value) |
188 | 0 | m_flags |= lldb::eTypeOptionNonCacheable; |
189 | 0 | else |
190 | 0 | m_flags &= ~lldb::eTypeOptionNonCacheable; |
191 | 0 | return *this; |
192 | 0 | } |
193 | | |
194 | 0 | uint32_t GetValue() { return m_flags; } |
195 | | |
196 | 0 | void SetValue(uint32_t value) { m_flags = value; } |
197 | | |
198 | | private: |
199 | | uint32_t m_flags = lldb::eTypeOptionCascade; |
200 | | }; |
201 | | |
202 | 5.31k | bool Cascades() const { return m_flags.GetCascades(); } |
203 | | |
204 | 5.31k | bool SkipsPointers() const { return m_flags.GetSkipPointers(); } |
205 | | |
206 | 5.04k | bool SkipsReferences() const { return m_flags.GetSkipReferences(); } |
207 | | |
208 | 1.45k | bool NonCacheable() const { return m_flags.GetNonCacheable(); } |
209 | | |
210 | 11.5k | virtual bool DoesPrintChildren(ValueObject *valobj) const { |
211 | 11.5k | return !m_flags.GetDontShowChildren(); |
212 | 11.5k | } |
213 | | |
214 | 157 | virtual bool DoesPrintEmptyAggregates() const { |
215 | 157 | return !m_flags.GetHideEmptyAggregates(); |
216 | 157 | } |
217 | | |
218 | 6.66k | virtual bool DoesPrintValue(ValueObject *valobj) const { |
219 | 6.66k | return !m_flags.GetDontShowValue(); |
220 | 6.66k | } |
221 | | |
222 | 11.6k | bool IsOneLiner() const { return m_flags.GetShowMembersOneLiner(); } |
223 | | |
224 | 3.71k | virtual bool HideNames(ValueObject *valobj) const { |
225 | 3.71k | return m_flags.GetHideItemNames(); |
226 | 3.71k | } |
227 | | |
228 | 0 | void SetCascades(bool value) { m_flags.SetCascades(value); } |
229 | | |
230 | 0 | void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); } |
231 | | |
232 | 0 | void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); } |
233 | | |
234 | 0 | virtual void SetDoesPrintChildren(bool value) { |
235 | 0 | m_flags.SetDontShowChildren(!value); |
236 | 0 | } |
237 | | |
238 | 0 | virtual void SetDoesPrintValue(bool value) { |
239 | 0 | m_flags.SetDontShowValue(!value); |
240 | 0 | } |
241 | | |
242 | 0 | void SetIsOneLiner(bool value) { m_flags.SetShowMembersOneLiner(value); } |
243 | | |
244 | 0 | virtual void SetHideNames(bool value) { m_flags.SetHideItemNames(value); } |
245 | | |
246 | 0 | virtual void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); } |
247 | | |
248 | 0 | uint32_t GetOptions() { return m_flags.GetValue(); } |
249 | | |
250 | 0 | void SetOptions(uint32_t value) { m_flags.SetValue(value); } |
251 | | |
252 | | // we are using a ValueObject* instead of a ValueObjectSP because we do not |
253 | | // need to hold on to this for extended periods of time and we trust the |
254 | | // ValueObject to stay around for as long as it is required for us to |
255 | | // generate its summary |
256 | | virtual bool FormatObject(ValueObject *valobj, std::string &dest, |
257 | | const TypeSummaryOptions &options) = 0; |
258 | | |
259 | | virtual std::string GetDescription() = 0; |
260 | | |
261 | 151k | uint32_t &GetRevision() { return m_my_revision; } |
262 | | |
263 | | typedef std::shared_ptr<TypeSummaryImpl> SharedPointer; |
264 | | |
265 | | protected: |
266 | | uint32_t m_my_revision = 0; |
267 | | Flags m_flags; |
268 | | |
269 | | TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags); |
270 | | |
271 | | private: |
272 | | Kind m_kind; |
273 | | TypeSummaryImpl(const TypeSummaryImpl &) = delete; |
274 | | const TypeSummaryImpl &operator=(const TypeSummaryImpl &) = delete; |
275 | | }; |
276 | | |
277 | | // simple string-based summaries, using ${var to show data |
278 | | struct StringSummaryFormat : public TypeSummaryImpl { |
279 | | std::string m_format_str; |
280 | | FormatEntity::Entry m_format; |
281 | | Status m_error; |
282 | | |
283 | | StringSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *f); |
284 | | |
285 | 33.6k | ~StringSummaryFormat() override = default; |
286 | | |
287 | 1 | const char *GetSummaryString() const { return m_format_str.c_str(); } |
288 | | |
289 | | void SetSummaryString(const char *f); |
290 | | |
291 | | bool FormatObject(ValueObject *valobj, std::string &dest, |
292 | | const TypeSummaryOptions &options) override; |
293 | | |
294 | | std::string GetDescription() override; |
295 | | |
296 | 3 | static bool classof(const TypeSummaryImpl *S) { |
297 | 3 | return S->GetKind() == Kind::eSummaryString; |
298 | 3 | } |
299 | | |
300 | | private: |
301 | | StringSummaryFormat(const StringSummaryFormat &) = delete; |
302 | | const StringSummaryFormat &operator=(const StringSummaryFormat &) = delete; |
303 | | }; |
304 | | |
305 | | // summaries implemented via a C++ function |
306 | | struct CXXFunctionSummaryFormat : public TypeSummaryImpl { |
307 | | // we should convert these to SBValue and SBStream if we ever cross the |
308 | | // boundary towards the external world |
309 | | typedef std::function<bool(ValueObject &, Stream &, |
310 | | const TypeSummaryOptions &)> |
311 | | Callback; |
312 | | |
313 | | Callback m_impl; |
314 | | std::string m_description; |
315 | | |
316 | | CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags &flags, Callback impl, |
317 | | const char *description); |
318 | | |
319 | 111k | ~CXXFunctionSummaryFormat() override = default; |
320 | | |
321 | 0 | Callback GetBackendFunction() const { return m_impl; } |
322 | | |
323 | 0 | const char *GetTextualInfo() const { return m_description.c_str(); } |
324 | | |
325 | 0 | void SetBackendFunction(Callback cb_func) { m_impl = std::move(cb_func); } |
326 | | |
327 | 0 | void SetTextualInfo(const char *descr) { |
328 | 0 | if (descr) |
329 | 0 | m_description.assign(descr); |
330 | 0 | else |
331 | 0 | m_description.clear(); |
332 | 0 | } |
333 | | |
334 | | bool FormatObject(ValueObject *valobj, std::string &dest, |
335 | | const TypeSummaryOptions &options) override; |
336 | | |
337 | | std::string GetDescription() override; |
338 | | |
339 | 0 | static bool classof(const TypeSummaryImpl *S) { |
340 | 0 | return S->GetKind() == Kind::eCallback; |
341 | 0 | } |
342 | | |
343 | | typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer; |
344 | | |
345 | | private: |
346 | | CXXFunctionSummaryFormat(const CXXFunctionSummaryFormat &) = delete; |
347 | | const CXXFunctionSummaryFormat & |
348 | | operator=(const CXXFunctionSummaryFormat &) = delete; |
349 | | }; |
350 | | |
351 | | // Python-based summaries, running script code to show data |
352 | | struct ScriptSummaryFormat : public TypeSummaryImpl { |
353 | | std::string m_function_name; |
354 | | std::string m_python_script; |
355 | | StructuredData::ObjectSP m_script_function_sp; |
356 | | |
357 | | ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags, |
358 | | const char *function_name, |
359 | | const char *python_script = nullptr); |
360 | | |
361 | 708 | ~ScriptSummaryFormat() override = default; |
362 | | |
363 | 4 | const char *GetFunctionName() const { return m_function_name.c_str(); } |
364 | | |
365 | 13 | const char *GetPythonScript() const { return m_python_script.c_str(); } |
366 | | |
367 | 4 | void SetFunctionName(const char *function_name) { |
368 | 4 | if (function_name) |
369 | 4 | m_function_name.assign(function_name); |
370 | 0 | else |
371 | 0 | m_function_name.clear(); |
372 | 4 | m_python_script.clear(); |
373 | 4 | } |
374 | | |
375 | 0 | void SetPythonScript(const char *script) { |
376 | 0 | if (script) |
377 | 0 | m_python_script.assign(script); |
378 | 0 | else |
379 | 0 | m_python_script.clear(); |
380 | 0 | } |
381 | | |
382 | | bool FormatObject(ValueObject *valobj, std::string &dest, |
383 | | const TypeSummaryOptions &options) override; |
384 | | |
385 | | std::string GetDescription() override; |
386 | | |
387 | 26 | static bool classof(const TypeSummaryImpl *S) { |
388 | 26 | return S->GetKind() == Kind::eScript; |
389 | 26 | } |
390 | | |
391 | | typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer; |
392 | | |
393 | | private: |
394 | | ScriptSummaryFormat(const ScriptSummaryFormat &) = delete; |
395 | | const ScriptSummaryFormat &operator=(const ScriptSummaryFormat &) = delete; |
396 | | }; |
397 | | } // namespace lldb_private |
398 | | |
399 | | #endif // LLDB_DATAFORMATTERS_TYPESUMMARY_H |