Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/DataFormatters/TypeCategory.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- TypeCategory.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
#include "lldb/DataFormatters/TypeCategory.h"
10
#include "lldb/Target/Language.h"
11
12
13
using namespace lldb;
14
using namespace lldb_private;
15
16
TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener *clist,
17
                                   ConstString name)
18
3.62k
    : m_format_cont(clist), m_summary_cont(clist), m_filter_cont(clist),
19
3.62k
      m_synth_cont(clist), m_enabled(false), m_change_listener(clist),
20
3.62k
      m_mutex(), m_name(name), m_languages() {}
21
22
static bool IsApplicable(lldb::LanguageType category_lang,
23
90.0k
                         lldb::LanguageType valobj_lang) {
24
90.0k
  switch (category_lang) {
25
  // Unless we know better, allow only exact equality.
26
0
  default:
27
0
    return category_lang == valobj_lang;
28
29
  // the C family, we consider it as one
30
0
  case eLanguageTypeC89:
31
0
  case eLanguageTypeC:
32
0
  case eLanguageTypeC99:
33
0
    return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
34
0
           valobj_lang == eLanguageTypeC99;
35
36
  // ObjC knows about C and itself
37
0
  case eLanguageTypeObjC:
38
0
    return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
39
0
           valobj_lang == eLanguageTypeC99 || valobj_lang == eLanguageTypeObjC;
40
41
  // C++ knows about C and C++
42
0
  case eLanguageTypeC_plus_plus:
43
0
    return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
44
0
           valobj_lang == eLanguageTypeC99 ||
45
0
           valobj_lang == eLanguageTypeC_plus_plus;
46
47
  // ObjC++ knows about C,C++,ObjC and ObjC++
48
36.6k
  case eLanguageTypeObjC_plus_plus:
49
36.6k
    return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
50
36.6k
           
valobj_lang == eLanguageTypeC9917.5k
||
51
36.6k
           
valobj_lang == eLanguageTypeC_plus_plus17.5k
||
52
36.6k
           
valobj_lang == eLanguageTypeObjC3.02k
;
53
54
  // Categories with unspecified language match everything.
55
53.4k
  case eLanguageTypeUnknown:
56
53.4k
    return true;
57
90.0k
  }
58
90.0k
}
59
60
90.0k
bool TypeCategoryImpl::IsApplicable(lldb::LanguageType lang) {
61
90.0k
  for (size_t idx = 0; idx < GetNumLanguages(); 
idx++0
) {
62
90.0k
    const lldb::LanguageType category_lang = GetLanguageAtIndex(idx);
63
90.0k
    if (::IsApplicable(category_lang, lang))
64
90.0k
      return true;
65
90.0k
  }
66
0
  return false;
67
90.0k
}
68
69
90.4k
size_t TypeCategoryImpl::GetNumLanguages() {
70
90.4k
  if (m_languages.empty())
71
53.0k
    return 1;
72
37.4k
  return m_languages.size();
73
90.4k
}
74
75
90.1k
lldb::LanguageType TypeCategoryImpl::GetLanguageAtIndex(size_t idx) {
76
90.1k
  if (m_languages.empty())
77
52.8k
    return lldb::eLanguageTypeUnknown;
78
37.3k
  return m_languages[idx];
79
90.1k
}
80
81
1.50k
void TypeCategoryImpl::AddLanguage(lldb::LanguageType lang) {
82
1.50k
  m_languages.push_back(lang);
83
1.50k
}
84
85
bool TypeCategoryImpl::Get(lldb::LanguageType lang,
86
                           const FormattersMatchVector &candidates,
87
32.4k
                           lldb::TypeFormatImplSP &entry) {
88
32.4k
  if (!IsEnabled() || !IsApplicable(lang))
89
0
    return false;
90
32.4k
  return m_format_cont.Get(candidates, entry);
91
32.4k
}
92
93
bool TypeCategoryImpl::Get(lldb::LanguageType lang,
94
                           const FormattersMatchVector &candidates,
95
27.7k
                           lldb::TypeSummaryImplSP &entry) {
96
27.7k
  if (!IsEnabled() || !IsApplicable(lang))
97
0
    return false;
98
27.7k
  return m_summary_cont.Get(candidates, entry);
99
27.7k
}
100
101
bool TypeCategoryImpl::Get(lldb::LanguageType lang,
102
                           const FormattersMatchVector &candidates,
103
29.8k
                           lldb::SyntheticChildrenSP &entry) {
104
29.8k
  if (!IsEnabled() || !IsApplicable(lang))
105
0
    return false;
106
107
  // first find both Filter and Synth, and then check which is most recent
108
29.8k
  bool pick_synth = false;
109
110
29.8k
  TypeFilterImpl::SharedPointer filter_sp;
111
29.8k
  m_filter_cont.Get(candidates, filter_sp);
112
113
29.8k
  ScriptedSyntheticChildren::SharedPointer synth_sp;
114
29.8k
  m_synth_cont.Get(candidates, synth_sp);
115
116
29.8k
  if (!filter_sp.get() && 
!synth_sp.get()29.8k
)
117
29.3k
    return false;
118
534
  else if (!filter_sp.get() && 
synth_sp.get()476
)
119
476
    pick_synth = true;
120
58
  else if (filter_sp.get() && !synth_sp.get())
121
58
    pick_synth = false;
122
0
  else /*if (filter_sp.get() && synth_sp.get())*/
123
0
  {
124
0
    pick_synth = filter_sp->GetRevision() <= synth_sp->GetRevision();
125
0
  }
126
127
534
  if (pick_synth) {
128
476
    entry = synth_sp;
129
476
    return true;
130
476
  } else {
131
58
    entry = filter_sp;
132
58
    return true;
133
58
  }
134
0
  return false;
135
534
}
136
137
446
void TypeCategoryImpl::Clear(FormatCategoryItems items) {
138
446
  if (items & eFormatCategoryItemFormat)
139
130
    m_format_cont.Clear();
140
141
446
  if (items & eFormatCategoryItemSummary)
142
162
    m_summary_cont.Clear();
143
144
446
  if (items & eFormatCategoryItemFilter)
145
43
    m_filter_cont.Clear();
146
147
446
  if (items & eFormatCategoryItemSynth)
148
111
    m_synth_cont.Clear();
149
446
}
150
151
82
bool TypeCategoryImpl::Delete(ConstString name, FormatCategoryItems items) {
152
82
  bool success = false;
153
154
82
  if (items & eFormatCategoryItemFormat)
155
12
    success = m_format_cont.Delete(name) || 
success6
;
156
157
82
  if (items & eFormatCategoryItemSummary)
158
54
    success = m_summary_cont.Delete(name) || 
success8
;
159
160
82
  if (items & eFormatCategoryItemFilter)
161
4
    success = m_filter_cont.Delete(name) || 
success0
;
162
163
82
  if (items & eFormatCategoryItemSynth)
164
12
    success = m_synth_cont.Delete(name) || 
success0
;
165
166
82
  return success;
167
82
}
168
169
30
uint32_t TypeCategoryImpl::GetCount(FormatCategoryItems items) {
170
30
  uint32_t count = 0;
171
172
30
  if (items & eFormatCategoryItemFormat)
173
30
    count += m_format_cont.GetCount();
174
175
30
  if (items & eFormatCategoryItemSummary)
176
30
    count += m_summary_cont.GetCount();
177
178
30
  if (items & eFormatCategoryItemFilter)
179
30
    count += m_filter_cont.GetCount();
180
181
30
  if (items & eFormatCategoryItemSynth)
182
30
    count += m_synth_cont.GetCount();
183
184
30
  return count;
185
30
}
186
187
bool TypeCategoryImpl::AnyMatches(
188
    const FormattersMatchCandidate &candidate_type, FormatCategoryItems items,
189
    bool only_enabled, const char **matching_category,
190
53
    FormatCategoryItems *matching_type) {
191
53
  if (!IsEnabled() && 
only_enabled2
)
192
0
    return false;
193
194
53
  if (items & eFormatCategoryItemFormat) {
195
0
    if (m_format_cont.AnyMatches(candidate_type)) {
196
0
      if (matching_category)
197
0
        *matching_category = m_name.GetCString();
198
0
      if (matching_type)
199
0
        *matching_type = eFormatCategoryItemFormat;
200
0
      return true;
201
0
    }
202
0
  }
203
204
53
  if (items & eFormatCategoryItemSummary) {
205
0
    if (m_summary_cont.AnyMatches(candidate_type)) {
206
0
      if (matching_category)
207
0
        *matching_category = m_name.GetCString();
208
0
      if (matching_type)
209
0
        *matching_type = eFormatCategoryItemSummary;
210
0
      return true;
211
0
    }
212
0
  }
213
214
53
  if (items & eFormatCategoryItemFilter) {
215
28
    if (m_filter_cont.AnyMatches(candidate_type)) {
216
2
      if (matching_category)
217
0
        *matching_category = m_name.GetCString();
218
2
      if (matching_type)
219
0
        *matching_type = eFormatCategoryItemFilter;
220
2
      return true;
221
2
    }
222
28
  }
223
224
51
  if (items & eFormatCategoryItemSynth) {
225
25
    if (m_synth_cont.AnyMatches(candidate_type)) {
226
2
      if (matching_category)
227
0
        *matching_category = m_name.GetCString();
228
2
      if (matching_type)
229
0
        *matching_type = eFormatCategoryItemSynth;
230
2
      return true;
231
2
    }
232
25
  }
233
234
49
  return false;
235
51
}
236
237
void TypeCategoryImpl::AutoComplete(CompletionRequest &request,
238
40
                                    FormatCategoryItems items) {
239
40
  if (items & eFormatCategoryItemFormat)
240
10
    m_format_cont.AutoComplete(request);
241
40
  if (items & eFormatCategoryItemSummary)
242
10
    m_summary_cont.AutoComplete(request);
243
40
  if (items & eFormatCategoryItemFilter)
244
10
    m_filter_cont.AutoComplete(request);
245
40
  if (items & eFormatCategoryItemSynth)
246
10
    m_synth_cont.AutoComplete(request);
247
40
}
248
249
TypeCategoryImpl::FormatContainer::MapValueType
250
0
TypeCategoryImpl::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
251
0
  return m_format_cont.GetForTypeNameSpecifier(type_sp);
252
0
}
253
254
TypeCategoryImpl::SummaryContainer::MapValueType
255
150
TypeCategoryImpl::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
256
150
  return m_summary_cont.GetForTypeNameSpecifier(type_sp);
257
150
}
258
259
TypeCategoryImpl::FilterContainer::MapValueType
260
6
TypeCategoryImpl::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
261
6
  return m_filter_cont.GetForTypeNameSpecifier(type_sp);
262
6
}
263
264
TypeCategoryImpl::SynthContainer::MapValueType
265
0
TypeCategoryImpl::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
266
0
  return m_synth_cont.GetForTypeNameSpecifier(type_sp);
267
0
}
268
269
TypeCategoryImpl::FormatContainer::MapValueType
270
0
TypeCategoryImpl::GetFormatAtIndex(size_t index) {
271
0
  return m_format_cont.GetAtIndex(index);
272
0
}
273
274
TypeCategoryImpl::SummaryContainer::MapValueType
275
0
TypeCategoryImpl::GetSummaryAtIndex(size_t index) {
276
0
  return m_summary_cont.GetAtIndex(index);
277
0
}
278
279
TypeCategoryImpl::FilterContainer::MapValueType
280
0
TypeCategoryImpl::GetFilterAtIndex(size_t index) {
281
0
  return m_filter_cont.GetAtIndex(index);
282
0
}
283
284
TypeCategoryImpl::SynthContainer::MapValueType
285
0
TypeCategoryImpl::GetSyntheticAtIndex(size_t index) {
286
0
  return m_synth_cont.GetAtIndex(index);
287
0
}
288
289
lldb::TypeNameSpecifierImplSP
290
0
TypeCategoryImpl::GetTypeNameSpecifierForFormatAtIndex(size_t index) {
291
0
  return m_format_cont.GetTypeNameSpecifierAtIndex(index);
292
0
}
293
294
lldb::TypeNameSpecifierImplSP
295
0
TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex(size_t index) {
296
0
  return m_summary_cont.GetTypeNameSpecifierAtIndex(index);
297
0
}
298
299
lldb::TypeNameSpecifierImplSP
300
0
TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex(size_t index) {
301
0
  return m_filter_cont.GetTypeNameSpecifierAtIndex(index);
302
0
}
303
304
lldb::TypeNameSpecifierImplSP
305
0
TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex(size_t index) {
306
0
  return m_synth_cont.GetTypeNameSpecifierAtIndex(index);
307
0
}
308
309
3.71k
void TypeCategoryImpl::Enable(bool value, uint32_t position) {
310
3.71k
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
311
3.71k
  if ((m_enabled = value))
312
3.65k
    m_enabled_position = position;
313
3.71k
  if (m_change_listener)
314
3.71k
    m_change_listener->Changed();
315
3.71k
}
316
317
123
std::string TypeCategoryImpl::GetDescription() {
318
123
  StreamString stream;
319
123
  stream.Printf("%s (%s", GetName(), (IsEnabled() ? 
"enabled"88
:
"disabled"35
));
320
123
  StreamString lang_stream;
321
123
  lang_stream.Printf(", applicable for language(s): ");
322
123
  bool print_lang = false;
323
246
  for (size_t idx = 0; idx < GetNumLanguages(); 
idx++123
) {
324
123
    const lldb::LanguageType lang = GetLanguageAtIndex(idx);
325
123
    if (lang != lldb::eLanguageTypeUnknown)
326
40
      print_lang = true;
327
123
    lang_stream.Printf("%s%s", Language::GetNameForLanguageType(lang),
328
123
                       idx + 1 < GetNumLanguages() ? 
", "0
: "");
329
123
  }
330
123
  if (print_lang)
331
40
    stream.PutCString(lang_stream.GetString());
332
123
  stream.PutChar(')');
333
123
  return std::string(stream.GetString());
334
123
}