Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/DataFormatters/FormatClasses.h
Line
Count
Source (jump to first uncovered line)
1
//===-- FormatClasses.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_FORMATCLASSES_H
10
#define LLDB_DATAFORMATTERS_FORMATCLASSES_H
11
12
#include <functional>
13
#include <memory>
14
#include <string>
15
#include <vector>
16
17
#include "lldb/DataFormatters/TypeFormat.h"
18
#include "lldb/DataFormatters/TypeSummary.h"
19
#include "lldb/DataFormatters/TypeSynthetic.h"
20
#include "lldb/Interpreter/ScriptInterpreter.h"
21
#include "lldb/Symbol/CompilerType.h"
22
#include "lldb/Symbol/Type.h"
23
#include "lldb/lldb-enumerations.h"
24
#include "lldb/lldb-public.h"
25
26
namespace lldb_private {
27
28
class HardcodedFormatters {
29
public:
30
  template <typename FormatterType>
31
  using HardcodedFormatterFinder =
32
      std::function<typename FormatterType::SharedPointer(
33
          lldb_private::ValueObject &, lldb::DynamicValueType,
34
          FormatManager &)>;
35
36
  template <typename FormatterType>
37
  using HardcodedFormatterFinders =
38
      std::vector<HardcodedFormatterFinder<FormatterType>>;
39
40
  typedef HardcodedFormatterFinders<TypeFormatImpl> HardcodedFormatFinder;
41
  typedef HardcodedFormatterFinders<TypeSummaryImpl> HardcodedSummaryFinder;
42
  typedef HardcodedFormatterFinders<SyntheticChildren> HardcodedSyntheticFinder;
43
};
44
45
class FormattersMatchCandidate {
46
public:
47
  // Contains flags to indicate how this candidate was generated (e.g. if
48
  // typedefs were stripped, or pointers were skipped). These are later compared
49
  // to flags in formatters to confirm a string match.
50
  struct Flags {
51
    bool stripped_pointer = false;
52
    bool stripped_reference = false;
53
    bool stripped_typedef = false;
54
55
    // Returns a copy of this with the "stripped pointer" flag set.
56
8.81k
    Flags WithStrippedPointer() {
57
8.81k
      Flags result(*this);
58
8.81k
      result.stripped_pointer = true;
59
8.81k
      return result;
60
8.81k
    }
61
62
    // Returns a copy of this with the "stripped reference" flag set.
63
584
    Flags WithStrippedReference() {
64
584
      Flags result(*this);
65
584
      result.stripped_reference = true;
66
584
      return result;
67
584
    }
68
69
    // Returns a copy of this with the "stripped typedef" flag set.
70
4.12k
    Flags WithStrippedTypedef() {
71
4.12k
      Flags result(*this);
72
4.12k
      result.stripped_typedef = true;
73
4.12k
      return result;
74
4.12k
    }
75
  };
76
77
  FormattersMatchCandidate(ConstString name,
78
                           ScriptInterpreter *script_interpreter, TypeImpl type,
79
                           Flags flags)
80
37.1k
      : m_type_name(name), m_script_interpreter(script_interpreter),
81
37.1k
        m_type(type), m_flags(flags) {}
82
83
3.62M
  ~FormattersMatchCandidate() = default;
84
85
2.67M
  ConstString GetTypeName() const { return m_type_name; }
86
87
44
  TypeImpl GetType() const { return m_type; }
88
89
88
  ScriptInterpreter *GetScriptInterpreter() const {
90
88
    return m_script_interpreter;
91
88
  }
92
93
556
  bool DidStripPointer() const { return m_flags.stripped_pointer; }
94
95
51
  bool DidStripReference() const { return m_flags.stripped_reference; }
96
97
97
  bool DidStripTypedef() const { return m_flags.stripped_typedef; }
98
99
  template <class Formatter>
100
2.32k
  bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const {
101
2.32k
    if (!formatter_sp)
102
0
      return false;
103
2.32k
    if (formatter_sp->Cascades() == false && 
DidStripTypedef()97
)
104
6
      return false;
105
2.32k
    if (formatter_sp->SkipsPointers() && 
DidStripPointer()556
)
106
272
      return false;
107
2.04k
    if (formatter_sp->SkipsReferences() && 
DidStripReference()51
)
108
0
      return false;
109
2.04k
    return true;
110
2.04k
  }
bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::TypeFormatImpl>(std::__1::shared_ptr<lldb_private::TypeFormatImpl> const&) const
Line
Count
Source
100
57
  bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const {
101
57
    if (!formatter_sp)
102
0
      return false;
103
57
    if (formatter_sp->Cascades() == false && 
DidStripTypedef()15
)
104
6
      return false;
105
51
    if (formatter_sp->SkipsPointers() && 
DidStripPointer()2
)
106
0
      return false;
107
51
    if (formatter_sp->SkipsReferences() && 
DidStripReference()2
)
108
0
      return false;
109
51
    return true;
110
51
  }
bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::TypeSummaryImpl>(std::__1::shared_ptr<lldb_private::TypeSummaryImpl> const&) const
Line
Count
Source
100
1.72k
  bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const {
101
1.72k
    if (!formatter_sp)
102
0
      return false;
103
1.72k
    if (formatter_sp->Cascades() == false && 
DidStripTypedef()64
)
104
0
      return false;
105
1.72k
    if (formatter_sp->SkipsPointers() && 
DidStripPointer()550
)
106
270
      return false;
107
1.45k
    if (formatter_sp->SkipsReferences() && 
DidStripReference()49
)
108
0
      return false;
109
1.45k
    return true;
110
1.45k
  }
bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::TypeFilterImpl>(std::__1::shared_ptr<lldb_private::TypeFilterImpl> const&) const
Line
Count
Source
100
62
  bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const {
101
62
    if (!formatter_sp)
102
0
      return false;
103
62
    if (formatter_sp->Cascades() == false && 
DidStripTypedef()12
)
104
0
      return false;
105
62
    if (formatter_sp->SkipsPointers() && 
DidStripPointer()4
)
106
2
      return false;
107
60
    if (formatter_sp->SkipsReferences() && 
DidStripReference()0
)
108
0
      return false;
109
60
    return true;
110
60
  }
bool lldb_private::FormattersMatchCandidate::IsMatch<lldb_private::SyntheticChildren>(std::__1::shared_ptr<lldb_private::SyntheticChildren> const&) const
Line
Count
Source
100
482
  bool IsMatch(const std::shared_ptr<Formatter> &formatter_sp) const {
101
482
    if (!formatter_sp)
102
0
      return false;
103
482
    if (formatter_sp->Cascades() == false && 
DidStripTypedef()6
)
104
0
      return false;
105
482
    if (formatter_sp->SkipsPointers() && 
DidStripPointer()0
)
106
0
      return false;
107
482
    if (formatter_sp->SkipsReferences() && 
DidStripReference()0
)
108
0
      return false;
109
482
    return true;
110
482
  }
111
112
private:
113
  ConstString m_type_name;
114
  // If a formatter provides a matching callback function, we need the script
115
  // interpreter and the type object (as an argument to the callback).
116
  ScriptInterpreter *m_script_interpreter;
117
  TypeImpl m_type;
118
  Flags m_flags;
119
};
120
121
typedef std::vector<FormattersMatchCandidate> FormattersMatchVector;
122
typedef std::vector<lldb::LanguageType> CandidateLanguagesVector;
123
124
class FormattersMatchData {
125
public:
126
  FormattersMatchData(ValueObject &, lldb::DynamicValueType);
127
128
  FormattersMatchVector GetMatchesVector();
129
130
  ConstString GetTypeForCache();
131
132
  CandidateLanguagesVector GetCandidateLanguages();
133
134
  ValueObject &GetValueObject();
135
136
  lldb::DynamicValueType GetDynamicValueType();
137
138
private:
139
  ValueObject &m_valobj;
140
  lldb::DynamicValueType m_dynamic_value_type;
141
  std::pair<FormattersMatchVector, bool> m_formatters_match_vector;
142
  ConstString m_type_for_cache;
143
  CandidateLanguagesVector m_candidate_languages;
144
};
145
146
class TypeNameSpecifierImpl {
147
public:
148
  TypeNameSpecifierImpl() = default;
149
150
  TypeNameSpecifierImpl(llvm::StringRef name,
151
                        lldb::FormatterMatchType match_type)
152
206k
      : m_match_type(match_type) {
153
206k
    m_type.m_type_name = std::string(name);
154
206k
  }
155
156
  // if constructing with a given type, we consider that a case of exact match.
157
  TypeNameSpecifierImpl(lldb::TypeSP type)
158
0
      : m_match_type(lldb::eFormatterMatchExact) {
159
0
    if (type) {
160
0
      m_type.m_type_name = std::string(type->GetName().GetStringRef());
161
0
      m_type.m_compiler_type = type->GetForwardCompilerType();
162
0
    }
163
0
  }
164
165
  TypeNameSpecifierImpl(CompilerType type)
166
0
      : m_match_type(lldb::eFormatterMatchExact) {
167
0
    if (type.IsValid()) {
168
0
      m_type.m_type_name.assign(type.GetTypeName().GetCString());
169
0
      m_type.m_compiler_type = type;
170
0
    }
171
0
  }
172
173
274k
  const char *GetName() {
174
274k
    if (m_type.m_type_name.size())
175
274k
      return m_type.m_type_name.c_str();
176
0
    return nullptr;
177
274k
  }
178
179
0
  CompilerType GetCompilerType() {
180
0
    if (m_type.m_compiler_type.IsValid())
181
0
      return m_type.m_compiler_type;
182
0
    return CompilerType();
183
0
  }
184
185
413k
  lldb::FormatterMatchType GetMatchType() { return m_match_type; }
186
187
0
  bool IsRegex() { return m_match_type == lldb::eFormatterMatchRegex; }
188
189
private:
190
  lldb::FormatterMatchType m_match_type = lldb::eFormatterMatchExact;
191
  // TODO: Replace this with TypeAndOrName.
192
  struct TypeOrName {
193
    std::string m_type_name;
194
    CompilerType m_compiler_type;
195
  };
196
  TypeOrName m_type;
197
198
  TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete;
199
  const TypeNameSpecifierImpl &
200
  operator=(const TypeNameSpecifierImpl &) = delete;
201
};
202
203
} // namespace lldb_private
204
205
#endif // LLDB_DATAFORMATTERS_FORMATCLASSES_H