Coverage Report

Created: 2023-09-21 18:56

/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