]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp
MFV r319740: 8168 NULL pointer dereference in zfs_create()
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / DataFormatters / FormatManager.cpp
1 //===-- FormatManager.cpp ----------------------------------------*- C++-*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/DataFormatters/FormatManager.h"
11
12 #include "llvm/ADT/STLExtras.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Log.h"
21 #include "lldb/DataFormatters/FormattersHelpers.h"
22 #include "lldb/DataFormatters/LanguageCategory.h"
23 #include "lldb/Target/ExecutionContext.h"
24 #include "lldb/Target/Language.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28 using namespace lldb_private::formatters;
29
30 struct FormatInfo {
31   Format format;
32   const char format_char;  // One or more format characters that can be used for
33                            // this format.
34   const char *format_name; // Long format name that can be used to specify the
35                            // current format
36 };
37
38 static FormatInfo g_format_infos[] = {
39     {eFormatDefault, '\0', "default"},
40     {eFormatBoolean, 'B', "boolean"},
41     {eFormatBinary, 'b', "binary"},
42     {eFormatBytes, 'y', "bytes"},
43     {eFormatBytesWithASCII, 'Y', "bytes with ASCII"},
44     {eFormatChar, 'c', "character"},
45     {eFormatCharPrintable, 'C', "printable character"},
46     {eFormatComplexFloat, 'F', "complex float"},
47     {eFormatCString, 's', "c-string"},
48     {eFormatDecimal, 'd', "decimal"},
49     {eFormatEnum, 'E', "enumeration"},
50     {eFormatHex, 'x', "hex"},
51     {eFormatHexUppercase, 'X', "uppercase hex"},
52     {eFormatFloat, 'f', "float"},
53     {eFormatOctal, 'o', "octal"},
54     {eFormatOSType, 'O', "OSType"},
55     {eFormatUnicode16, 'U', "unicode16"},
56     {eFormatUnicode32, '\0', "unicode32"},
57     {eFormatUnsigned, 'u', "unsigned decimal"},
58     {eFormatPointer, 'p', "pointer"},
59     {eFormatVectorOfChar, '\0', "char[]"},
60     {eFormatVectorOfSInt8, '\0', "int8_t[]"},
61     {eFormatVectorOfUInt8, '\0', "uint8_t[]"},
62     {eFormatVectorOfSInt16, '\0', "int16_t[]"},
63     {eFormatVectorOfUInt16, '\0', "uint16_t[]"},
64     {eFormatVectorOfSInt32, '\0', "int32_t[]"},
65     {eFormatVectorOfUInt32, '\0', "uint32_t[]"},
66     {eFormatVectorOfSInt64, '\0', "int64_t[]"},
67     {eFormatVectorOfUInt64, '\0', "uint64_t[]"},
68     {eFormatVectorOfFloat16, '\0', "float16[]"},
69     {eFormatVectorOfFloat32, '\0', "float32[]"},
70     {eFormatVectorOfFloat64, '\0', "float64[]"},
71     {eFormatVectorOfUInt128, '\0', "uint128_t[]"},
72     {eFormatComplexInteger, 'I', "complex integer"},
73     {eFormatCharArray, 'a', "character array"},
74     {eFormatAddressInfo, 'A', "address"},
75     {eFormatHexFloat, '\0', "hex float"},
76     {eFormatInstruction, 'i', "instruction"},
77     {eFormatVoid, 'v', "void"}};
78
79 static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
80
81 static bool GetFormatFromFormatChar(char format_char, Format &format) {
82   for (uint32_t i = 0; i < g_num_format_infos; ++i) {
83     if (g_format_infos[i].format_char == format_char) {
84       format = g_format_infos[i].format;
85       return true;
86     }
87   }
88   format = eFormatInvalid;
89   return false;
90 }
91
92 static bool GetFormatFromFormatName(const char *format_name,
93                                     bool partial_match_ok, Format &format) {
94   uint32_t i;
95   for (i = 0; i < g_num_format_infos; ++i) {
96     if (strcasecmp(g_format_infos[i].format_name, format_name) == 0) {
97       format = g_format_infos[i].format;
98       return true;
99     }
100   }
101
102   if (partial_match_ok) {
103     for (i = 0; i < g_num_format_infos; ++i) {
104       if (strcasestr(g_format_infos[i].format_name, format_name) ==
105           g_format_infos[i].format_name) {
106         format = g_format_infos[i].format;
107         return true;
108       }
109     }
110   }
111   format = eFormatInvalid;
112   return false;
113 }
114
115 void FormatManager::Changed() {
116   ++m_last_revision;
117   m_format_cache.Clear();
118   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
119   for (auto &iter : m_language_categories_map) {
120     if (iter.second)
121       iter.second->GetFormatCache().Clear();
122   }
123 }
124
125 bool FormatManager::GetFormatFromCString(const char *format_cstr,
126                                          bool partial_match_ok,
127                                          lldb::Format &format) {
128   bool success = false;
129   if (format_cstr && format_cstr[0]) {
130     if (format_cstr[1] == '\0') {
131       success = GetFormatFromFormatChar(format_cstr[0], format);
132       if (success)
133         return true;
134     }
135
136     success = GetFormatFromFormatName(format_cstr, partial_match_ok, format);
137   }
138   if (!success)
139     format = eFormatInvalid;
140   return success;
141 }
142
143 char FormatManager::GetFormatAsFormatChar(lldb::Format format) {
144   for (uint32_t i = 0; i < g_num_format_infos; ++i) {
145     if (g_format_infos[i].format == format)
146       return g_format_infos[i].format_char;
147   }
148   return '\0';
149 }
150
151 const char *FormatManager::GetFormatAsCString(Format format) {
152   if (format >= eFormatDefault && format < kNumFormats)
153     return g_format_infos[format].format_name;
154   return NULL;
155 }
156
157 void FormatManager::EnableAllCategories() {
158   m_categories_map.EnableAllCategories();
159   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
160   for (auto &iter : m_language_categories_map) {
161     if (iter.second)
162       iter.second->Enable();
163   }
164 }
165
166 void FormatManager::DisableAllCategories() {
167   m_categories_map.DisableAllCategories();
168   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
169   for (auto &iter : m_language_categories_map) {
170     if (iter.second)
171       iter.second->Disable();
172   }
173 }
174
175 void FormatManager::GetPossibleMatches(
176     ValueObject &valobj, CompilerType compiler_type, uint32_t reason,
177     lldb::DynamicValueType use_dynamic, FormattersMatchVector &entries,
178     bool did_strip_ptr, bool did_strip_ref, bool did_strip_typedef,
179     bool root_level) {
180   compiler_type = compiler_type.GetTypeForFormatters();
181   ConstString type_name(compiler_type.GetConstTypeName());
182   if (valobj.GetBitfieldBitSize() > 0) {
183     StreamString sstring;
184     sstring.Printf("%s:%d", type_name.AsCString(), valobj.GetBitfieldBitSize());
185     ConstString bitfieldname(sstring.GetString());
186     entries.push_back(
187         {bitfieldname, 0, did_strip_ptr, did_strip_ref, did_strip_typedef});
188     reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
189   }
190
191   if (!compiler_type.IsMeaninglessWithoutDynamicResolution()) {
192     entries.push_back(
193         {type_name, reason, did_strip_ptr, did_strip_ref, did_strip_typedef});
194
195     ConstString display_type_name(compiler_type.GetDisplayTypeName());
196     if (display_type_name != type_name)
197       entries.push_back({display_type_name, reason, did_strip_ptr,
198                          did_strip_ref, did_strip_typedef});
199   }
200
201   for (bool is_rvalue_ref = true, j = true;
202        j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false) {
203     CompilerType non_ref_type = compiler_type.GetNonReferenceType();
204     GetPossibleMatches(
205         valobj, non_ref_type,
206         reason |
207             lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
208         use_dynamic, entries, did_strip_ptr, true, did_strip_typedef);
209     if (non_ref_type.IsTypedefType()) {
210       CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
211       deffed_referenced_type =
212           is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType()
213                         : deffed_referenced_type.GetLValueReferenceType();
214       GetPossibleMatches(
215           valobj, deffed_referenced_type,
216           reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
217           use_dynamic, entries, did_strip_ptr, did_strip_ref,
218           true); // this is not exactly the usual meaning of stripping typedefs
219     }
220   }
221
222   if (compiler_type.IsPointerType()) {
223     CompilerType non_ptr_type = compiler_type.GetPointeeType();
224     GetPossibleMatches(
225         valobj, non_ptr_type,
226         reason |
227             lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
228         use_dynamic, entries, true, did_strip_ref, did_strip_typedef);
229     if (non_ptr_type.IsTypedefType()) {
230       CompilerType deffed_pointed_type =
231           non_ptr_type.GetTypedefedType().GetPointerType();
232       GetPossibleMatches(
233           valobj, deffed_pointed_type,
234           reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
235           use_dynamic, entries, did_strip_ptr, did_strip_ref,
236           true); // this is not exactly the usual meaning of stripping typedefs
237     }
238   }
239
240   for (lldb::LanguageType language_type : GetCandidateLanguages(valobj)) {
241     if (Language *language = Language::FindPlugin(language_type)) {
242       for (ConstString candidate :
243            language->GetPossibleFormattersMatches(valobj, use_dynamic)) {
244         entries.push_back(
245             {candidate,
246              reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
247              did_strip_ptr, did_strip_ref, did_strip_typedef});
248       }
249     }
250   }
251
252   // try to strip typedef chains
253   if (compiler_type.IsTypedefType()) {
254     CompilerType deffed_type = compiler_type.GetTypedefedType();
255     GetPossibleMatches(
256         valobj, deffed_type,
257         reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
258         use_dynamic, entries, did_strip_ptr, did_strip_ref, true);
259   }
260
261   if (root_level) {
262     do {
263       if (!compiler_type.IsValid())
264         break;
265
266       CompilerType unqual_compiler_ast_type =
267           compiler_type.GetFullyUnqualifiedType();
268       if (!unqual_compiler_ast_type.IsValid())
269         break;
270       if (unqual_compiler_ast_type.GetOpaqueQualType() !=
271           compiler_type.GetOpaqueQualType())
272         GetPossibleMatches(valobj, unqual_compiler_ast_type, reason,
273                            use_dynamic, entries, did_strip_ptr, did_strip_ref,
274                            did_strip_typedef);
275     } while (false);
276
277     // if all else fails, go to static type
278     if (valobj.IsDynamic()) {
279       lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
280       if (static_value_sp)
281         GetPossibleMatches(
282             *static_value_sp.get(), static_value_sp->GetCompilerType(),
283             reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
284             use_dynamic, entries, did_strip_ptr, did_strip_ref,
285             did_strip_typedef, true);
286     }
287   }
288 }
289
290 lldb::TypeFormatImplSP
291 FormatManager::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
292   if (!type_sp)
293     return lldb::TypeFormatImplSP();
294   lldb::TypeFormatImplSP format_chosen_sp;
295   uint32_t num_categories = m_categories_map.GetCount();
296   lldb::TypeCategoryImplSP category_sp;
297   uint32_t prio_category = UINT32_MAX;
298   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
299     category_sp = GetCategoryAtIndex(category_id);
300     if (category_sp->IsEnabled() == false)
301       continue;
302     lldb::TypeFormatImplSP format_current_sp =
303         category_sp->GetFormatForType(type_sp);
304     if (format_current_sp &&
305         (format_chosen_sp.get() == NULL ||
306          (prio_category > category_sp->GetEnabledPosition()))) {
307       prio_category = category_sp->GetEnabledPosition();
308       format_chosen_sp = format_current_sp;
309     }
310   }
311   return format_chosen_sp;
312 }
313
314 lldb::TypeSummaryImplSP
315 FormatManager::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
316   if (!type_sp)
317     return lldb::TypeSummaryImplSP();
318   lldb::TypeSummaryImplSP summary_chosen_sp;
319   uint32_t num_categories = m_categories_map.GetCount();
320   lldb::TypeCategoryImplSP category_sp;
321   uint32_t prio_category = UINT32_MAX;
322   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
323     category_sp = GetCategoryAtIndex(category_id);
324     if (category_sp->IsEnabled() == false)
325       continue;
326     lldb::TypeSummaryImplSP summary_current_sp =
327         category_sp->GetSummaryForType(type_sp);
328     if (summary_current_sp &&
329         (summary_chosen_sp.get() == NULL ||
330          (prio_category > category_sp->GetEnabledPosition()))) {
331       prio_category = category_sp->GetEnabledPosition();
332       summary_chosen_sp = summary_current_sp;
333     }
334   }
335   return summary_chosen_sp;
336 }
337
338 lldb::TypeFilterImplSP
339 FormatManager::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
340   if (!type_sp)
341     return lldb::TypeFilterImplSP();
342   lldb::TypeFilterImplSP filter_chosen_sp;
343   uint32_t num_categories = m_categories_map.GetCount();
344   lldb::TypeCategoryImplSP category_sp;
345   uint32_t prio_category = UINT32_MAX;
346   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
347     category_sp = GetCategoryAtIndex(category_id);
348     if (category_sp->IsEnabled() == false)
349       continue;
350     lldb::TypeFilterImplSP filter_current_sp(
351         (TypeFilterImpl *)category_sp->GetFilterForType(type_sp).get());
352     if (filter_current_sp &&
353         (filter_chosen_sp.get() == NULL ||
354          (prio_category > category_sp->GetEnabledPosition()))) {
355       prio_category = category_sp->GetEnabledPosition();
356       filter_chosen_sp = filter_current_sp;
357     }
358   }
359   return filter_chosen_sp;
360 }
361
362 #ifndef LLDB_DISABLE_PYTHON
363 lldb::ScriptedSyntheticChildrenSP
364 FormatManager::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
365   if (!type_sp)
366     return lldb::ScriptedSyntheticChildrenSP();
367   lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
368   uint32_t num_categories = m_categories_map.GetCount();
369   lldb::TypeCategoryImplSP category_sp;
370   uint32_t prio_category = UINT32_MAX;
371   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
372     category_sp = GetCategoryAtIndex(category_id);
373     if (category_sp->IsEnabled() == false)
374       continue;
375     lldb::ScriptedSyntheticChildrenSP synth_current_sp(
376         (ScriptedSyntheticChildren *)category_sp->GetSyntheticForType(type_sp)
377             .get());
378     if (synth_current_sp &&
379         (synth_chosen_sp.get() == NULL ||
380          (prio_category > category_sp->GetEnabledPosition()))) {
381       prio_category = category_sp->GetEnabledPosition();
382       synth_chosen_sp = synth_current_sp;
383     }
384   }
385   return synth_chosen_sp;
386 }
387 #endif
388
389 #ifndef LLDB_DISABLE_PYTHON
390 lldb::SyntheticChildrenSP FormatManager::GetSyntheticChildrenForType(
391     lldb::TypeNameSpecifierImplSP type_sp) {
392   if (!type_sp)
393     return lldb::SyntheticChildrenSP();
394   lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
395   lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
396   if (filter_sp->GetRevision() > synth_sp->GetRevision())
397     return lldb::SyntheticChildrenSP(filter_sp.get());
398   else
399     return lldb::SyntheticChildrenSP(synth_sp.get());
400 }
401 #endif
402
403 lldb::TypeValidatorImplSP
404 FormatManager::GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp) {
405   if (!type_sp)
406     return lldb::TypeValidatorImplSP();
407   lldb::TypeValidatorImplSP validator_chosen_sp;
408   uint32_t num_categories = m_categories_map.GetCount();
409   lldb::TypeCategoryImplSP category_sp;
410   uint32_t prio_category = UINT32_MAX;
411   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
412     category_sp = GetCategoryAtIndex(category_id);
413     if (category_sp->IsEnabled() == false)
414       continue;
415     lldb::TypeValidatorImplSP validator_current_sp(
416         category_sp->GetValidatorForType(type_sp).get());
417     if (validator_current_sp &&
418         (validator_chosen_sp.get() == NULL ||
419          (prio_category > category_sp->GetEnabledPosition()))) {
420       prio_category = category_sp->GetEnabledPosition();
421       validator_chosen_sp = validator_current_sp;
422     }
423   }
424   return validator_chosen_sp;
425 }
426
427 void FormatManager::ForEachCategory(TypeCategoryMap::ForEachCallback callback) {
428   m_categories_map.ForEach(callback);
429   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
430   for (const auto &entry : m_language_categories_map) {
431     if (auto category_sp = entry.second->GetCategory()) {
432       if (!callback(category_sp))
433         break;
434     }
435   }
436 }
437
438 lldb::TypeCategoryImplSP
439 FormatManager::GetCategory(const ConstString &category_name, bool can_create) {
440   if (!category_name)
441     return GetCategory(m_default_category_name);
442   lldb::TypeCategoryImplSP category;
443   if (m_categories_map.Get(category_name, category))
444     return category;
445
446   if (!can_create)
447     return lldb::TypeCategoryImplSP();
448
449   m_categories_map.Add(
450       category_name,
451       lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
452   return GetCategory(category_name);
453 }
454
455 lldb::Format FormatManager::GetSingleItemFormat(lldb::Format vector_format) {
456   switch (vector_format) {
457   case eFormatVectorOfChar:
458     return eFormatCharArray;
459
460   case eFormatVectorOfSInt8:
461   case eFormatVectorOfSInt16:
462   case eFormatVectorOfSInt32:
463   case eFormatVectorOfSInt64:
464     return eFormatDecimal;
465
466   case eFormatVectorOfUInt8:
467   case eFormatVectorOfUInt16:
468   case eFormatVectorOfUInt32:
469   case eFormatVectorOfUInt64:
470   case eFormatVectorOfUInt128:
471     return eFormatHex;
472
473   case eFormatVectorOfFloat16:
474   case eFormatVectorOfFloat32:
475   case eFormatVectorOfFloat64:
476     return eFormatFloat;
477
478   default:
479     return lldb::eFormatInvalid;
480   }
481 }
482
483 bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) {
484   // if settings say no oneline whatsoever
485   if (valobj.GetTargetSP().get() &&
486       valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
487     return false; // then don't oneline
488
489   // if this object has a summary, then ask the summary
490   if (valobj.GetSummaryFormat().get() != nullptr)
491     return valobj.GetSummaryFormat()->IsOneLiner();
492
493   // no children, no party
494   if (valobj.GetNumChildren() == 0)
495     return false;
496
497   // ask the type if it has any opinion about this
498   // eLazyBoolCalculate == no opinion; other values should be self explanatory
499   CompilerType compiler_type(valobj.GetCompilerType());
500   if (compiler_type.IsValid()) {
501     switch (compiler_type.ShouldPrintAsOneLiner(&valobj)) {
502     case eLazyBoolNo:
503       return false;
504     case eLazyBoolYes:
505       return true;
506     case eLazyBoolCalculate:
507       break;
508     }
509   }
510
511   size_t total_children_name_len = 0;
512
513   for (size_t idx = 0; idx < valobj.GetNumChildren(); idx++) {
514     bool is_synth_val = false;
515     ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
516     // something is wrong here - bail out
517     if (!child_sp)
518       return false;
519
520     // also ask the child's type if it has any opinion
521     CompilerType child_compiler_type(child_sp->GetCompilerType());
522     if (child_compiler_type.IsValid()) {
523       switch (child_compiler_type.ShouldPrintAsOneLiner(child_sp.get())) {
524       case eLazyBoolYes:
525       // an opinion of yes is only binding for the child, so keep going
526       case eLazyBoolCalculate:
527         break;
528       case eLazyBoolNo:
529         // but if the child says no, then it's a veto on the whole thing
530         return false;
531       }
532     }
533
534     // if we decided to define synthetic children for a type, we probably care
535     // enough
536     // to show them, but avoid nesting children in children
537     if (child_sp->GetSyntheticChildren().get() != nullptr) {
538       ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
539       // wait.. wat? just get out of here..
540       if (!synth_sp)
541         return false;
542       // but if we only have them to provide a value, keep going
543       if (synth_sp->MightHaveChildren() == false &&
544           synth_sp->DoesProvideSyntheticValue())
545         is_synth_val = true;
546       else
547         return false;
548     }
549
550     total_children_name_len += child_sp->GetName().GetLength();
551
552     // 50 itself is a "randomly" chosen number - the idea is that
553     // overly long structs should not get this treatment
554     // FIXME: maybe make this a user-tweakable setting?
555     if (total_children_name_len > 50)
556       return false;
557
558     // if a summary is there..
559     if (child_sp->GetSummaryFormat()) {
560       // and it wants children, then bail out
561       if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
562         return false;
563     }
564
565     // if this child has children..
566     if (child_sp->GetNumChildren()) {
567       // ...and no summary...
568       // (if it had a summary and the summary wanted children, we would have
569       // bailed out anyway
570       //  so this only makes us bail out if this has no summary and we would
571       //  then print children)
572       if (!child_sp->GetSummaryFormat() && !is_synth_val) // but again only do
573                                                           // that if not a
574                                                           // synthetic valued
575                                                           // child
576         return false;                                     // then bail out
577     }
578   }
579   return true;
580 }
581
582 ConstString FormatManager::GetValidTypeName(const ConstString &type) {
583   return ::GetValidTypeName_Impl(type);
584 }
585
586 ConstString FormatManager::GetTypeForCache(ValueObject &valobj,
587                                            lldb::DynamicValueType use_dynamic) {
588   ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(
589       use_dynamic, valobj.IsSynthetic());
590   if (valobj_sp && valobj_sp->GetCompilerType().IsValid()) {
591     if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
592       return valobj_sp->GetQualifiedTypeName();
593   }
594   return ConstString();
595 }
596
597 std::vector<lldb::LanguageType>
598 FormatManager::GetCandidateLanguages(ValueObject &valobj) {
599   lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
600   return GetCandidateLanguages(lang_type);
601 }
602
603 std::vector<lldb::LanguageType>
604 FormatManager::GetCandidateLanguages(lldb::LanguageType lang_type) {
605   switch (lang_type) {
606   case lldb::eLanguageTypeC:
607   case lldb::eLanguageTypeC89:
608   case lldb::eLanguageTypeC99:
609   case lldb::eLanguageTypeC11:
610   case lldb::eLanguageTypeC_plus_plus:
611   case lldb::eLanguageTypeC_plus_plus_03:
612   case lldb::eLanguageTypeC_plus_plus_11:
613   case lldb::eLanguageTypeC_plus_plus_14:
614     return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
615   default:
616     return {lang_type};
617   }
618 }
619
620 LanguageCategory *
621 FormatManager::GetCategoryForLanguage(lldb::LanguageType lang_type) {
622   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
623   auto iter = m_language_categories_map.find(lang_type),
624        end = m_language_categories_map.end();
625   if (iter != end)
626     return iter->second.get();
627   LanguageCategory *lang_category = new LanguageCategory(lang_type);
628   m_language_categories_map[lang_type] =
629       LanguageCategory::UniquePointer(lang_category);
630   return lang_category;
631 }
632
633 lldb::TypeFormatImplSP
634 FormatManager::GetHardcodedFormat(FormattersMatchData &match_data) {
635   TypeFormatImplSP retval_sp;
636
637   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
638     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
639       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
640         break;
641     }
642   }
643
644   return retval_sp;
645 }
646
647 lldb::TypeFormatImplSP
648 FormatManager::GetFormat(ValueObject &valobj,
649                          lldb::DynamicValueType use_dynamic) {
650   FormattersMatchData match_data(valobj, use_dynamic);
651
652   TypeFormatImplSP retval;
653   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
654   if (match_data.GetTypeForCache()) {
655     if (log)
656       log->Printf(
657           "\n\n[FormatManager::GetFormat] Looking into cache for type %s",
658           match_data.GetTypeForCache().AsCString("<invalid>"));
659     if (m_format_cache.GetFormat(match_data.GetTypeForCache(), retval)) {
660       if (log) {
661         log->Printf(
662             "[FormatManager::GetFormat] Cache search success. Returning.");
663         if (log->GetDebug())
664           log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64
665                       " - Cache Misses: %" PRIu64,
666                       m_format_cache.GetCacheHits(),
667                       m_format_cache.GetCacheMisses());
668       }
669       return retval;
670     }
671     if (log)
672       log->Printf(
673           "[FormatManager::GetFormat] Cache search failed. Going normal route");
674   }
675
676   retval = m_categories_map.GetFormat(match_data);
677   if (!retval) {
678     if (log)
679       log->Printf("[FormatManager::GetFormat] Search failed. Giving language a "
680                   "chance.");
681     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
682       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
683         if (lang_category->Get(match_data, retval))
684           break;
685       }
686     }
687     if (retval) {
688       if (log)
689         log->Printf(
690             "[FormatManager::GetFormat] Language search success. Returning.");
691       return retval;
692     }
693   }
694   if (!retval) {
695     if (log)
696       log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded "
697                   "a chance.");
698     retval = GetHardcodedFormat(match_data);
699   }
700
701   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
702     if (log)
703       log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
704                   static_cast<void *>(retval.get()),
705                   match_data.GetTypeForCache().AsCString("<invalid>"));
706     m_format_cache.SetFormat(match_data.GetTypeForCache(), retval);
707   }
708   if (log && log->GetDebug())
709     log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64
710                 " - Cache Misses: %" PRIu64,
711                 m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
712   return retval;
713 }
714
715 lldb::TypeSummaryImplSP
716 FormatManager::GetHardcodedSummaryFormat(FormattersMatchData &match_data) {
717   TypeSummaryImplSP retval_sp;
718
719   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
720     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
721       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
722         break;
723     }
724   }
725
726   return retval_sp;
727 }
728
729 lldb::TypeSummaryImplSP
730 FormatManager::GetSummaryFormat(ValueObject &valobj,
731                                 lldb::DynamicValueType use_dynamic) {
732   FormattersMatchData match_data(valobj, use_dynamic);
733
734   TypeSummaryImplSP retval;
735   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
736   if (match_data.GetTypeForCache()) {
737     if (log)
738       log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache "
739                   "for type %s",
740                   match_data.GetTypeForCache().AsCString("<invalid>"));
741     if (m_format_cache.GetSummary(match_data.GetTypeForCache(), retval)) {
742       if (log) {
743         log->Printf("[FormatManager::GetSummaryFormat] Cache search success. "
744                     "Returning.");
745         if (log->GetDebug())
746           log->Printf("[FormatManager::GetSummaryFormat] Cache hits: %" PRIu64
747                       " - Cache Misses: %" PRIu64,
748                       m_format_cache.GetCacheHits(),
749                       m_format_cache.GetCacheMisses());
750       }
751       return retval;
752     }
753     if (log)
754       log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. "
755                   "Going normal route");
756   }
757
758   retval = m_categories_map.GetSummaryFormat(match_data);
759   if (!retval) {
760     if (log)
761       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
762                   "language a chance.");
763     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
764       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
765         if (lang_category->Get(match_data, retval))
766           break;
767       }
768     }
769     if (retval) {
770       if (log)
771         log->Printf("[FormatManager::GetSummaryFormat] Language search "
772                     "success. Returning.");
773       return retval;
774     }
775   }
776   if (!retval) {
777     if (log)
778       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
779                   "hardcoded a chance.");
780     retval = GetHardcodedSummaryFormat(match_data);
781   }
782
783   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
784     if (log)
785       log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
786                   static_cast<void *>(retval.get()),
787                   match_data.GetTypeForCache().AsCString("<invalid>"));
788     m_format_cache.SetSummary(match_data.GetTypeForCache(), retval);
789   }
790   if (log && log->GetDebug())
791     log->Printf("[FormatManager::GetSummaryFormat] Cache hits: %" PRIu64
792                 " - Cache Misses: %" PRIu64,
793                 m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
794   return retval;
795 }
796
797 #ifndef LLDB_DISABLE_PYTHON
798 lldb::SyntheticChildrenSP
799 FormatManager::GetHardcodedSyntheticChildren(FormattersMatchData &match_data) {
800   SyntheticChildrenSP retval_sp;
801
802   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
803     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
804       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
805         break;
806     }
807   }
808
809   return retval_sp;
810 }
811
812 lldb::SyntheticChildrenSP
813 FormatManager::GetSyntheticChildren(ValueObject &valobj,
814                                     lldb::DynamicValueType use_dynamic) {
815   FormattersMatchData match_data(valobj, use_dynamic);
816
817   SyntheticChildrenSP retval;
818   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
819   if (match_data.GetTypeForCache()) {
820     if (log)
821       log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into "
822                   "cache for type %s",
823                   match_data.GetTypeForCache().AsCString("<invalid>"));
824     if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(), retval)) {
825       if (log) {
826         log->Printf("[FormatManager::GetSyntheticChildren] Cache search "
827                     "success. Returning.");
828         if (log->GetDebug())
829           log->Printf(
830               "[FormatManager::GetSyntheticChildren] Cache hits: %" PRIu64
831               " - Cache Misses: %" PRIu64,
832               m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
833       }
834       return retval;
835     }
836     if (log)
837       log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. "
838                   "Going normal route");
839   }
840
841   retval = m_categories_map.GetSyntheticChildren(match_data);
842   if (!retval) {
843     if (log)
844       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
845                   "language a chance.");
846     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
847       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
848         if (lang_category->Get(match_data, retval))
849           break;
850       }
851     }
852     if (retval) {
853       if (log)
854         log->Printf("[FormatManager::GetSyntheticChildren] Language search "
855                     "success. Returning.");
856       return retval;
857     }
858   }
859   if (!retval) {
860     if (log)
861       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
862                   "hardcoded a chance.");
863     retval = GetHardcodedSyntheticChildren(match_data);
864   }
865
866   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
867     if (log)
868       log->Printf(
869           "[FormatManager::GetSyntheticChildren] Caching %p for type %s",
870           static_cast<void *>(retval.get()),
871           match_data.GetTypeForCache().AsCString("<invalid>"));
872     m_format_cache.SetSynthetic(match_data.GetTypeForCache(), retval);
873   }
874   if (log && log->GetDebug())
875     log->Printf("[FormatManager::GetSyntheticChildren] Cache hits: %" PRIu64
876                 " - Cache Misses: %" PRIu64,
877                 m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
878   return retval;
879 }
880 #endif
881
882 lldb::TypeValidatorImplSP
883 FormatManager::GetValidator(ValueObject &valobj,
884                             lldb::DynamicValueType use_dynamic) {
885   FormattersMatchData match_data(valobj, use_dynamic);
886
887   TypeValidatorImplSP retval;
888   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
889   if (match_data.GetTypeForCache()) {
890     if (log)
891       log->Printf(
892           "\n\n[FormatManager::GetValidator] Looking into cache for type %s",
893           match_data.GetTypeForCache().AsCString("<invalid>"));
894     if (m_format_cache.GetValidator(match_data.GetTypeForCache(), retval)) {
895       if (log) {
896         log->Printf(
897             "[FormatManager::GetValidator] Cache search success. Returning.");
898         if (log->GetDebug())
899           log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64
900                       " - Cache Misses: %" PRIu64,
901                       m_format_cache.GetCacheHits(),
902                       m_format_cache.GetCacheMisses());
903       }
904       return retval;
905     }
906     if (log)
907       log->Printf("[FormatManager::GetValidator] Cache search failed. Going "
908                   "normal route");
909   }
910
911   retval = m_categories_map.GetValidator(match_data);
912   if (!retval) {
913     if (log)
914       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
915                   "language a chance.");
916     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
917       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
918         if (lang_category->Get(match_data, retval))
919           break;
920       }
921     }
922     if (retval) {
923       if (log)
924         log->Printf("[FormatManager::GetValidator] Language search success. "
925                     "Returning.");
926       return retval;
927     }
928   }
929   if (!retval) {
930     if (log)
931       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
932                   "hardcoded a chance.");
933     retval = GetHardcodedValidator(match_data);
934   }
935
936   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
937     if (log)
938       log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
939                   static_cast<void *>(retval.get()),
940                   match_data.GetTypeForCache().AsCString("<invalid>"));
941     m_format_cache.SetValidator(match_data.GetTypeForCache(), retval);
942   }
943   if (log && log->GetDebug())
944     log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64
945                 " - Cache Misses: %" PRIu64,
946                 m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
947   return retval;
948 }
949
950 lldb::TypeValidatorImplSP
951 FormatManager::GetHardcodedValidator(FormattersMatchData &match_data) {
952   TypeValidatorImplSP retval_sp;
953
954   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
955     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
956       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
957         break;
958     }
959   }
960
961   return retval_sp;
962 }
963
964 FormatManager::FormatManager()
965     : m_last_revision(0), m_format_cache(), m_language_categories_mutex(),
966       m_language_categories_map(), m_named_summaries_map(this),
967       m_categories_map(this), m_default_category_name(ConstString("default")),
968       m_system_category_name(ConstString("system")),
969       m_vectortypes_category_name(ConstString("VectorTypes")) {
970   LoadSystemFormatters();
971   LoadVectorFormatters();
972
973   EnableCategory(m_vectortypes_category_name, TypeCategoryMap::Last,
974                  lldb::eLanguageTypeObjC_plus_plus);
975   EnableCategory(m_system_category_name, TypeCategoryMap::Last,
976                  lldb::eLanguageTypeObjC_plus_plus);
977 }
978
979 void FormatManager::LoadSystemFormatters() {
980   TypeSummaryImpl::Flags string_flags;
981   string_flags.SetCascades(true)
982       .SetSkipPointers(true)
983       .SetSkipReferences(false)
984       .SetDontShowChildren(true)
985       .SetDontShowValue(false)
986       .SetShowMembersOneLiner(false)
987       .SetHideItemNames(false);
988
989   TypeSummaryImpl::Flags string_array_flags;
990   string_array_flags.SetCascades(true)
991       .SetSkipPointers(true)
992       .SetSkipReferences(false)
993       .SetDontShowChildren(true)
994       .SetDontShowValue(true)
995       .SetShowMembersOneLiner(false)
996       .SetHideItemNames(false);
997
998   lldb::TypeSummaryImplSP string_format(
999       new StringSummaryFormat(string_flags, "${var%s}"));
1000
1001   lldb::TypeSummaryImplSP string_array_format(
1002       new StringSummaryFormat(string_array_flags, "${var%s}"));
1003
1004   lldb::RegularExpressionSP any_size_char_arr(
1005       new RegularExpression(llvm::StringRef("char \\[[0-9]+\\]")));
1006   lldb::RegularExpressionSP any_size_wchar_arr(
1007       new RegularExpression(llvm::StringRef("wchar_t \\[[0-9]+\\]")));
1008
1009   TypeCategoryImpl::SharedPointer sys_category_sp =
1010       GetCategory(m_system_category_name);
1011
1012   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"),
1013                                                     string_format);
1014   sys_category_sp->GetTypeSummariesContainer()->Add(
1015       ConstString("unsigned char *"), string_format);
1016   sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr,
1017                                                          string_array_format);
1018
1019   lldb::TypeSummaryImplSP ostype_summary(
1020       new StringSummaryFormat(TypeSummaryImpl::Flags()
1021                                   .SetCascades(false)
1022                                   .SetSkipPointers(true)
1023                                   .SetSkipReferences(true)
1024                                   .SetDontShowChildren(true)
1025                                   .SetDontShowValue(false)
1026                                   .SetShowMembersOneLiner(false)
1027                                   .SetHideItemNames(false),
1028                               "${var%O}"));
1029
1030   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"),
1031                                                     ostype_summary);
1032
1033 #ifndef LLDB_DISABLE_PYTHON
1034   TypeFormatImpl::Flags fourchar_flags;
1035   fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(
1036       true);
1037
1038   AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"),
1039             fourchar_flags);
1040 #endif
1041 }
1042
1043 void FormatManager::LoadVectorFormatters() {
1044   TypeCategoryImpl::SharedPointer vectors_category_sp =
1045       GetCategory(m_vectortypes_category_name);
1046
1047   TypeSummaryImpl::Flags vector_flags;
1048   vector_flags.SetCascades(true)
1049       .SetSkipPointers(true)
1050       .SetSkipReferences(false)
1051       .SetDontShowChildren(true)
1052       .SetDontShowValue(false)
1053       .SetShowMembersOneLiner(true)
1054       .SetHideItemNames(true);
1055
1056   AddStringSummary(vectors_category_sp, "${var.uint128}",
1057                    ConstString("builtin_type_vec128"), vector_flags);
1058
1059   AddStringSummary(vectors_category_sp, "", ConstString("float [4]"),
1060                    vector_flags);
1061   AddStringSummary(vectors_category_sp, "", ConstString("int32_t [4]"),
1062                    vector_flags);
1063   AddStringSummary(vectors_category_sp, "", ConstString("int16_t [8]"),
1064                    vector_flags);
1065   AddStringSummary(vectors_category_sp, "", ConstString("vDouble"),
1066                    vector_flags);
1067   AddStringSummary(vectors_category_sp, "", ConstString("vFloat"),
1068                    vector_flags);
1069   AddStringSummary(vectors_category_sp, "", ConstString("vSInt8"),
1070                    vector_flags);
1071   AddStringSummary(vectors_category_sp, "", ConstString("vSInt16"),
1072                    vector_flags);
1073   AddStringSummary(vectors_category_sp, "", ConstString("vSInt32"),
1074                    vector_flags);
1075   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1076                    vector_flags);
1077   AddStringSummary(vectors_category_sp, "", ConstString("vUInt8"),
1078                    vector_flags);
1079   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1080                    vector_flags);
1081   AddStringSummary(vectors_category_sp, "", ConstString("vUInt32"),
1082                    vector_flags);
1083   AddStringSummary(vectors_category_sp, "", ConstString("vBool32"),
1084                    vector_flags);
1085 }