LLDB  mainline
TypeCategory.cpp
Go to the documentation of this file.
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 
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  : m_format_cont("format", "regex-format", clist),
19  m_summary_cont("summary", "regex-summary", clist),
20  m_filter_cont("filter", "regex-filter", clist),
21  m_synth_cont("synth", "regex-synth", clist), m_enabled(false),
22  m_change_listener(clist), m_mutex(), m_name(name), m_languages() {}
23 
24 static bool IsApplicable(lldb::LanguageType category_lang,
25  lldb::LanguageType valobj_lang) {
26  switch (category_lang) {
27  // Unless we know better, allow only exact equality.
28  default:
29  return category_lang == valobj_lang;
30 
31  // the C family, we consider it as one
32  case eLanguageTypeC89:
33  case eLanguageTypeC:
34  case eLanguageTypeC99:
35  return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
36  valobj_lang == eLanguageTypeC99;
37 
38  // ObjC knows about C and itself
39  case eLanguageTypeObjC:
40  return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
41  valobj_lang == eLanguageTypeC99 || valobj_lang == eLanguageTypeObjC;
42 
43  // C++ knows about C and C++
45  return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
46  valobj_lang == eLanguageTypeC99 ||
47  valobj_lang == eLanguageTypeC_plus_plus;
48 
49  // ObjC++ knows about C,C++,ObjC and ObjC++
51  return valobj_lang == eLanguageTypeC89 || valobj_lang == eLanguageTypeC ||
52  valobj_lang == eLanguageTypeC99 ||
53  valobj_lang == eLanguageTypeC_plus_plus ||
54  valobj_lang == eLanguageTypeObjC;
55 
56  // Categories with unspecified language match everything.
58  return true;
59  }
60 }
61 
63  for (size_t idx = 0; idx < GetNumLanguages(); idx++) {
64  const lldb::LanguageType category_lang = GetLanguageAtIndex(idx);
65  if (::IsApplicable(category_lang, lang))
66  return true;
67  }
68  return false;
69 }
70 
72  if (m_languages.empty())
73  return 1;
74  return m_languages.size();
75 }
76 
78  if (m_languages.empty())
80  return m_languages[idx];
81 }
82 
84  m_languages.push_back(lang);
85 }
86 
88  const FormattersMatchVector &candidates,
89  lldb::TypeFormatImplSP &entry) {
90  if (!IsEnabled() || !IsApplicable(lang))
91  return false;
92  if (GetTypeFormatsContainer()->Get(candidates, entry))
93  return true;
94  bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry);
95  return regex;
96 }
97 
99  const FormattersMatchVector &candidates,
100  lldb::TypeSummaryImplSP &entry) {
101  if (!IsEnabled() || !IsApplicable(lang))
102  return false;
103  if (GetTypeSummariesContainer()->Get(candidates, entry))
104  return true;
105  bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry);
106  return regex;
107 }
108 
110  const FormattersMatchVector &candidates,
111  lldb::SyntheticChildrenSP &entry) {
112  if (!IsEnabled() || !IsApplicable(lang))
113  return false;
115  // first find both Filter and Synth, and then check which is most recent
116 
117  if (!GetTypeFiltersContainer()->Get(candidates, filter_sp))
118  GetRegexTypeFiltersContainer()->Get(candidates, filter_sp);
119 
120  bool pick_synth = false;
122  if (!GetTypeSyntheticsContainer()->Get(candidates, synth))
123  GetRegexTypeSyntheticsContainer()->Get(candidates, synth);
124  if (!filter_sp.get() && !synth.get())
125  return false;
126  else if (!filter_sp.get() && synth.get())
127  pick_synth = true;
128 
129  else if (filter_sp.get() && !synth.get())
130  pick_synth = false;
131 
132  else /*if (filter_sp.get() && synth.get())*/
133  {
134  pick_synth = filter_sp->GetRevision() <= synth->GetRevision();
135  }
136  if (pick_synth) {
137  entry = synth;
138  return true;
139  } else {
140  entry = filter_sp;
141  return true;
142  }
143  return false;
144 }
145 
147  if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
148  GetTypeFormatsContainer()->Clear();
149  if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
150  GetRegexTypeFormatsContainer()->Clear();
151 
152  if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
153  GetTypeSummariesContainer()->Clear();
154  if ((items & eFormatCategoryItemRegexSummary) ==
155  eFormatCategoryItemRegexSummary)
157 
158  if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
159  GetTypeFiltersContainer()->Clear();
160  if ((items & eFormatCategoryItemRegexFilter) ==
161  eFormatCategoryItemRegexFilter)
162  GetRegexTypeFiltersContainer()->Clear();
163 
164  if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
165  GetTypeSyntheticsContainer()->Clear();
166  if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
168 }
169 
171  bool success = false;
172 
173  if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
174  success = GetTypeFormatsContainer()->Delete(name) || success;
175  if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
176  success = GetRegexTypeFormatsContainer()->Delete(name) || success;
177 
178  if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
179  success = GetTypeSummariesContainer()->Delete(name) || success;
180  if ((items & eFormatCategoryItemRegexSummary) ==
181  eFormatCategoryItemRegexSummary)
182  success = GetRegexTypeSummariesContainer()->Delete(name) || success;
183 
184  if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
185  success = GetTypeFiltersContainer()->Delete(name) || success;
186  if ((items & eFormatCategoryItemRegexFilter) ==
187  eFormatCategoryItemRegexFilter)
188  success = GetRegexTypeFiltersContainer()->Delete(name) || success;
189 
190  if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
191  success = GetTypeSyntheticsContainer()->Delete(name) || success;
192  if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
193  success = GetRegexTypeSyntheticsContainer()->Delete(name) || success;
194 
195  return success;
196 }
197 
199  uint32_t count = 0;
200 
201  if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue)
202  count += GetTypeFormatsContainer()->GetCount();
203  if ((items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue)
204  count += GetRegexTypeFormatsContainer()->GetCount();
205 
206  if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary)
207  count += GetTypeSummariesContainer()->GetCount();
208  if ((items & eFormatCategoryItemRegexSummary) ==
209  eFormatCategoryItemRegexSummary)
210  count += GetRegexTypeSummariesContainer()->GetCount();
211 
212  if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter)
213  count += GetTypeFiltersContainer()->GetCount();
214  if ((items & eFormatCategoryItemRegexFilter) ==
215  eFormatCategoryItemRegexFilter)
216  count += GetRegexTypeFiltersContainer()->GetCount();
217 
218  if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth)
219  count += GetTypeSyntheticsContainer()->GetCount();
220  if ((items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth)
221  count += GetRegexTypeSyntheticsContainer()->GetCount();
222 
223  return count;
224 }
225 
227  FormatCategoryItems items, bool only_enabled,
228  const char **matching_category,
229  FormatCategoryItems *matching_type) {
230  if (!IsEnabled() && only_enabled)
231  return false;
232 
233  lldb::TypeFormatImplSP format_sp;
234  lldb::TypeSummaryImplSP summary_sp;
237 
238  if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue) {
239  if (GetTypeFormatsContainer()->Get(type_name, format_sp)) {
240  if (matching_category)
241  *matching_category = m_name.GetCString();
242  if (matching_type)
243  *matching_type = eFormatCategoryItemValue;
244  return true;
245  }
246  }
247  if ((items & eFormatCategoryItemRegexValue) ==
248  eFormatCategoryItemRegexValue) {
249  if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp)) {
250  if (matching_category)
251  *matching_category = m_name.GetCString();
252  if (matching_type)
253  *matching_type = eFormatCategoryItemRegexValue;
254  return true;
255  }
256  }
257 
258  if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary) {
259  if (GetTypeSummariesContainer()->Get(type_name, summary_sp)) {
260  if (matching_category)
261  *matching_category = m_name.GetCString();
262  if (matching_type)
263  *matching_type = eFormatCategoryItemSummary;
264  return true;
265  }
266  }
267  if ((items & eFormatCategoryItemRegexSummary) ==
268  eFormatCategoryItemRegexSummary) {
269  if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp)) {
270  if (matching_category)
271  *matching_category = m_name.GetCString();
272  if (matching_type)
273  *matching_type = eFormatCategoryItemRegexSummary;
274  return true;
275  }
276  }
277 
278  if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter) {
279  if (GetTypeFiltersContainer()->Get(type_name, filter_sp)) {
280  if (matching_category)
281  *matching_category = m_name.GetCString();
282  if (matching_type)
283  *matching_type = eFormatCategoryItemFilter;
284  return true;
285  }
286  }
287  if ((items & eFormatCategoryItemRegexFilter) ==
288  eFormatCategoryItemRegexFilter) {
289  if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp)) {
290  if (matching_category)
291  *matching_category = m_name.GetCString();
292  if (matching_type)
293  *matching_type = eFormatCategoryItemRegexFilter;
294  return true;
295  }
296  }
297 
298  if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth) {
299  if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
300  if (matching_category)
301  *matching_category = m_name.GetCString();
302  if (matching_type)
303  *matching_type = eFormatCategoryItemSynth;
304  return true;
305  }
306  }
307  if ((items & eFormatCategoryItemRegexSynth) ==
308  eFormatCategoryItemRegexSynth) {
309  if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
310  if (matching_category)
311  *matching_category = m_name.GetCString();
312  if (matching_type)
313  *matching_type = eFormatCategoryItemRegexSynth;
314  return true;
315  }
316  }
317 
318  return false;
319 }
320 
322 TypeCategoryImpl::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
324 
325  if (type_sp) {
326  if (type_sp->IsRegex())
327  GetRegexTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
328  retval);
329  else
330  GetTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
331  retval);
332  }
333 
334  return retval;
335 }
336 
338 TypeCategoryImpl::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
340 
341  if (type_sp) {
342  if (type_sp->IsRegex())
343  GetRegexTypeSummariesContainer()->GetExact(
344  ConstString(type_sp->GetName()), retval);
345  else
346  GetTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),
347  retval);
348  }
349 
350  return retval;
351 }
352 
354 TypeCategoryImpl::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
356 
357  if (type_sp) {
358  if (type_sp->IsRegex())
359  GetRegexTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
360  retval);
361  else
362  GetTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
363  retval);
364  }
365 
366  return retval;
367 }
368 
370 TypeCategoryImpl::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
372 
373  if (type_sp) {
374  if (type_sp->IsRegex())
376  ConstString(type_sp->GetName()), retval);
377  else
378  GetTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),
379  retval);
380  }
381 
382  return retval;
383 }
384 
385 lldb::TypeNameSpecifierImplSP
387  if (index < GetTypeSummariesContainer()->GetCount())
388  return GetTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(index);
389  else
390  return GetRegexTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(
391  index - GetTypeSummariesContainer()->GetCount());
392 }
393 
396  if (index < GetTypeFormatsContainer()->GetCount())
397  return GetTypeFormatsContainer()->GetAtIndex(index);
398  else
399  return GetRegexTypeFormatsContainer()->GetAtIndex(
400  index - GetTypeFormatsContainer()->GetCount());
401 }
402 
405  if (index < GetTypeSummariesContainer()->GetCount())
406  return GetTypeSummariesContainer()->GetAtIndex(index);
407  else
408  return GetRegexTypeSummariesContainer()->GetAtIndex(
409  index - GetTypeSummariesContainer()->GetCount());
410 }
411 
414  if (index < GetTypeFiltersContainer()->GetCount())
415  return GetTypeFiltersContainer()->GetAtIndex(index);
416  else
417  return GetRegexTypeFiltersContainer()->GetAtIndex(
418  index - GetTypeFiltersContainer()->GetCount());
419 }
420 
421 lldb::TypeNameSpecifierImplSP
423  if (index < GetTypeFormatsContainer()->GetCount())
424  return GetTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(index);
425  else
426  return GetRegexTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(
427  index - GetTypeFormatsContainer()->GetCount());
428 }
429 
430 lldb::TypeNameSpecifierImplSP
432  if (index < GetTypeFiltersContainer()->GetCount())
433  return GetTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(index);
434  else
435  return GetRegexTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(
436  index - GetTypeFiltersContainer()->GetCount());
437 }
438 
441  if (index < GetTypeSyntheticsContainer()->GetCount())
442  return GetTypeSyntheticsContainer()->GetAtIndex(index);
443  else
444  return GetRegexTypeSyntheticsContainer()->GetAtIndex(
445  index - GetTypeSyntheticsContainer()->GetCount());
446 }
447 
448 lldb::TypeNameSpecifierImplSP
450  if (index < GetTypeSyntheticsContainer()->GetCount())
451  return GetTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(index);
452  else
453  return GetRegexTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(
454  index - GetTypeSyntheticsContainer()->GetCount());
455 }
456 
457 void TypeCategoryImpl::Enable(bool value, uint32_t position) {
458  std::lock_guard<std::recursive_mutex> guard(m_mutex);
459  if ((m_enabled = value))
460  m_enabled_position = position;
461  if (m_change_listener)
463 }
464 
466  StreamString stream;
467  stream.Printf("%s (%s", GetName(), (IsEnabled() ? "enabled" : "disabled"));
468  StreamString lang_stream;
469  lang_stream.Printf(", applicable for language(s): ");
470  bool print_lang = false;
471  for (size_t idx = 0; idx < GetNumLanguages(); idx++) {
472  const lldb::LanguageType lang = GetLanguageAtIndex(idx);
473  if (lang != lldb::eLanguageTypeUnknown)
474  print_lang = true;
475  lang_stream.Printf("%s%s", Language::GetNameForLanguageType(lang),
476  idx + 1 < GetNumLanguages() ? ", " : "");
477  }
478  if (print_lang)
479  stream.PutCString(lang_stream.GetString());
480  stream.PutChar(')');
481  return std::string(stream.GetString());
482 }
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
FilterContainer::MapValueType GetFilterAtIndex(size_t index)
A class that represents a running process on the host machine.
SynthContainerSP GetTypeSyntheticsContainer()
Definition: TypeCategory.h:263
ExactMatchContainer::MapValueType MapValueType
Definition: TypeCategory.h:35
FormatContainer::MapValueType GetFormatAtIndex(size_t index)
SynthContainer::MapValueType GetSyntheticAtIndex(size_t index)
SummaryContainer::MapValueType GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp)
void Clear(FormatCategoryItems items=ALL_ITEM_TYPES)
bool Get(lldb::LanguageType lang, const FormattersMatchVector &candidates, lldb::TypeFormatImplSP &entry)
FormatContainerSP GetTypeFormatsContainer()
Definition: TypeCategory.h:206
bool IsApplicable(lldb::LanguageType lang)
std::shared_ptr< TypeFilterImpl > SharedPointer
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForSummaryAtIndex(size_t index)
std::vector< FormattersMatchCandidate > FormattersMatchVector
Definition: FormatClasses.h:81
lldb::LanguageType GetLanguageAtIndex(size_t idx)
std::shared_ptr< SyntheticChildren > SharedPointer
RegexFilterContainerSP GetRegexTypeFiltersContainer()
Definition: TypeCategory.h:230
FilterContainerSP GetTypeFiltersContainer()
Definition: TypeCategory.h:226
LanguageType
Programming language type.
FilterContainer::MapValueType GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp)
SummaryContainerSP GetTypeSummariesContainer()
Definition: TypeCategory.h:216
FormatContainer::MapValueType GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp)
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
uint32_t GetCount(FormatCategoryItems items=ALL_ITEM_TYPES)
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForFilterAtIndex(size_t index)
SynthContainer::MapValueType GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp)
std::recursive_mutex m_mutex
Definition: TypeCategory.h:330
void AddLanguage(lldb::LanguageType lang)
bool AnyMatches(ConstString type_name, FormatCategoryItems items=ALL_ITEM_TYPES, bool only_enabled=true, const char **matching_category=nullptr, FormatCategoryItems *matching_type=nullptr)
RegexFormatContainerSP GetRegexTypeFormatsContainer()
Definition: TypeCategory.h:210
RegexSummaryContainerSP GetRegexTypeSummariesContainer()
Definition: TypeCategory.h:220
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForSyntheticAtIndex(size_t index)
void Enable(bool value, uint32_t position)
size_t PutChar(char ch)
Definition: Stream.cpp:104
A uniqued constant string class.
Definition: ConstString.h:40
Unknown or invalid language value.
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:246
Non-standardized C, such as K&R.
Definition: SBAddress.h:15
SummaryContainer::MapValueType GetSummaryAtIndex(size_t index)
std::vector< lldb::LanguageType > m_languages
Definition: TypeCategory.h:334
IFormatChangeListener * m_change_listener
Definition: TypeCategory.h:328
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:206
RegexSynthContainerSP GetRegexTypeSyntheticsContainer()
Definition: TypeCategory.h:267
bool Delete(ConstString name, FormatCategoryItems items=ALL_ITEM_TYPES)
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForFormatAtIndex(size_t index)