]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r308421, and update
[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/DataFormatters/FormattersHelpers.h"
21 #include "lldb/DataFormatters/LanguageCategory.h"
22 #include "lldb/Target/ExecutionContext.h"
23 #include "lldb/Target/Language.h"
24 #include "lldb/Utility/Log.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         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
664                   m_format_cache.GetCacheHits(),
665                   m_format_cache.GetCacheMisses());
666       }
667       return retval;
668     }
669     if (log)
670       log->Printf(
671           "[FormatManager::GetFormat] Cache search failed. Going normal route");
672   }
673
674   retval = m_categories_map.GetFormat(match_data);
675   if (!retval) {
676     if (log)
677       log->Printf("[FormatManager::GetFormat] Search failed. Giving language a "
678                   "chance.");
679     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
680       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
681         if (lang_category->Get(match_data, retval))
682           break;
683       }
684     }
685     if (retval) {
686       if (log)
687         log->Printf(
688             "[FormatManager::GetFormat] Language search success. Returning.");
689       return retval;
690     }
691   }
692   if (!retval) {
693     if (log)
694       log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded "
695                   "a chance.");
696     retval = GetHardcodedFormat(match_data);
697   }
698
699   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
700     if (log)
701       log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
702                   static_cast<void *>(retval.get()),
703                   match_data.GetTypeForCache().AsCString("<invalid>"));
704     m_format_cache.SetFormat(match_data.GetTypeForCache(), retval);
705   }
706   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
707             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
708   return retval;
709 }
710
711 lldb::TypeSummaryImplSP
712 FormatManager::GetHardcodedSummaryFormat(FormattersMatchData &match_data) {
713   TypeSummaryImplSP retval_sp;
714
715   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
716     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
717       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
718         break;
719     }
720   }
721
722   return retval_sp;
723 }
724
725 lldb::TypeSummaryImplSP
726 FormatManager::GetSummaryFormat(ValueObject &valobj,
727                                 lldb::DynamicValueType use_dynamic) {
728   FormattersMatchData match_data(valobj, use_dynamic);
729
730   TypeSummaryImplSP retval;
731   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
732   if (match_data.GetTypeForCache()) {
733     if (log)
734       log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache "
735                   "for type %s",
736                   match_data.GetTypeForCache().AsCString("<invalid>"));
737     if (m_format_cache.GetSummary(match_data.GetTypeForCache(), retval)) {
738       if (log) {
739         log->Printf("[FormatManager::GetSummaryFormat] Cache search success. "
740                     "Returning.");
741         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
742                   m_format_cache.GetCacheHits(),
743                   m_format_cache.GetCacheMisses());
744       }
745       return retval;
746     }
747     if (log)
748       log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. "
749                   "Going normal route");
750   }
751
752   retval = m_categories_map.GetSummaryFormat(match_data);
753   if (!retval) {
754     if (log)
755       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
756                   "language a chance.");
757     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
758       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
759         if (lang_category->Get(match_data, retval))
760           break;
761       }
762     }
763     if (retval) {
764       if (log)
765         log->Printf("[FormatManager::GetSummaryFormat] Language search "
766                     "success. Returning.");
767       return retval;
768     }
769   }
770   if (!retval) {
771     if (log)
772       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
773                   "hardcoded a chance.");
774     retval = GetHardcodedSummaryFormat(match_data);
775   }
776
777   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
778     if (log)
779       log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
780                   static_cast<void *>(retval.get()),
781                   match_data.GetTypeForCache().AsCString("<invalid>"));
782     m_format_cache.SetSummary(match_data.GetTypeForCache(), retval);
783   }
784   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
785             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
786   return retval;
787 }
788
789 #ifndef LLDB_DISABLE_PYTHON
790 lldb::SyntheticChildrenSP
791 FormatManager::GetHardcodedSyntheticChildren(FormattersMatchData &match_data) {
792   SyntheticChildrenSP retval_sp;
793
794   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
795     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
796       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
797         break;
798     }
799   }
800
801   return retval_sp;
802 }
803
804 lldb::SyntheticChildrenSP
805 FormatManager::GetSyntheticChildren(ValueObject &valobj,
806                                     lldb::DynamicValueType use_dynamic) {
807   FormattersMatchData match_data(valobj, use_dynamic);
808
809   SyntheticChildrenSP retval;
810   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
811   if (match_data.GetTypeForCache()) {
812     if (log)
813       log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into "
814                   "cache for type %s",
815                   match_data.GetTypeForCache().AsCString("<invalid>"));
816     if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(), retval)) {
817       if (log) {
818         log->Printf("[FormatManager::GetSyntheticChildren] Cache search "
819                     "success. Returning.");
820         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
821                   m_format_cache.GetCacheHits(),
822                   m_format_cache.GetCacheMisses());
823       }
824       return retval;
825     }
826     if (log)
827       log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. "
828                   "Going normal route");
829   }
830
831   retval = m_categories_map.GetSyntheticChildren(match_data);
832   if (!retval) {
833     if (log)
834       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
835                   "language a chance.");
836     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
837       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
838         if (lang_category->Get(match_data, retval))
839           break;
840       }
841     }
842     if (retval) {
843       if (log)
844         log->Printf("[FormatManager::GetSyntheticChildren] Language search "
845                     "success. Returning.");
846       return retval;
847     }
848   }
849   if (!retval) {
850     if (log)
851       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
852                   "hardcoded a chance.");
853     retval = GetHardcodedSyntheticChildren(match_data);
854   }
855
856   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
857     if (log)
858       log->Printf(
859           "[FormatManager::GetSyntheticChildren] Caching %p for type %s",
860           static_cast<void *>(retval.get()),
861           match_data.GetTypeForCache().AsCString("<invalid>"));
862     m_format_cache.SetSynthetic(match_data.GetTypeForCache(), retval);
863   }
864   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
865             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
866   return retval;
867 }
868 #endif
869
870 lldb::TypeValidatorImplSP
871 FormatManager::GetValidator(ValueObject &valobj,
872                             lldb::DynamicValueType use_dynamic) {
873   FormattersMatchData match_data(valobj, use_dynamic);
874
875   TypeValidatorImplSP retval;
876   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
877   if (match_data.GetTypeForCache()) {
878     if (log)
879       log->Printf(
880           "\n\n[FormatManager::GetValidator] Looking into cache for type %s",
881           match_data.GetTypeForCache().AsCString("<invalid>"));
882     if (m_format_cache.GetValidator(match_data.GetTypeForCache(), retval)) {
883       if (log) {
884         log->Printf(
885             "[FormatManager::GetValidator] Cache search success. Returning.");
886         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
887                   m_format_cache.GetCacheHits(),
888                   m_format_cache.GetCacheMisses());
889       }
890       return retval;
891     }
892     if (log)
893       log->Printf("[FormatManager::GetValidator] Cache search failed. Going "
894                   "normal route");
895   }
896
897   retval = m_categories_map.GetValidator(match_data);
898   if (!retval) {
899     if (log)
900       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
901                   "language a chance.");
902     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
903       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
904         if (lang_category->Get(match_data, retval))
905           break;
906       }
907     }
908     if (retval) {
909       if (log)
910         log->Printf("[FormatManager::GetValidator] Language search success. "
911                     "Returning.");
912       return retval;
913     }
914   }
915   if (!retval) {
916     if (log)
917       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
918                   "hardcoded a chance.");
919     retval = GetHardcodedValidator(match_data);
920   }
921
922   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
923     if (log)
924       log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
925                   static_cast<void *>(retval.get()),
926                   match_data.GetTypeForCache().AsCString("<invalid>"));
927     m_format_cache.SetValidator(match_data.GetTypeForCache(), retval);
928   }
929   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
930             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
931   return retval;
932 }
933
934 lldb::TypeValidatorImplSP
935 FormatManager::GetHardcodedValidator(FormattersMatchData &match_data) {
936   TypeValidatorImplSP retval_sp;
937
938   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
939     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
940       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
941         break;
942     }
943   }
944
945   return retval_sp;
946 }
947
948 FormatManager::FormatManager()
949     : m_last_revision(0), m_format_cache(), m_language_categories_mutex(),
950       m_language_categories_map(), m_named_summaries_map(this),
951       m_categories_map(this), m_default_category_name(ConstString("default")),
952       m_system_category_name(ConstString("system")),
953       m_vectortypes_category_name(ConstString("VectorTypes")) {
954   LoadSystemFormatters();
955   LoadVectorFormatters();
956
957   EnableCategory(m_vectortypes_category_name, TypeCategoryMap::Last,
958                  lldb::eLanguageTypeObjC_plus_plus);
959   EnableCategory(m_system_category_name, TypeCategoryMap::Last,
960                  lldb::eLanguageTypeObjC_plus_plus);
961 }
962
963 void FormatManager::LoadSystemFormatters() {
964   TypeSummaryImpl::Flags string_flags;
965   string_flags.SetCascades(true)
966       .SetSkipPointers(true)
967       .SetSkipReferences(false)
968       .SetDontShowChildren(true)
969       .SetDontShowValue(false)
970       .SetShowMembersOneLiner(false)
971       .SetHideItemNames(false);
972
973   TypeSummaryImpl::Flags string_array_flags;
974   string_array_flags.SetCascades(true)
975       .SetSkipPointers(true)
976       .SetSkipReferences(false)
977       .SetDontShowChildren(true)
978       .SetDontShowValue(true)
979       .SetShowMembersOneLiner(false)
980       .SetHideItemNames(false);
981
982   lldb::TypeSummaryImplSP string_format(
983       new StringSummaryFormat(string_flags, "${var%s}"));
984
985   lldb::TypeSummaryImplSP string_array_format(
986       new StringSummaryFormat(string_array_flags, "${var%s}"));
987
988   lldb::RegularExpressionSP any_size_char_arr(
989       new RegularExpression(llvm::StringRef("char \\[[0-9]+\\]")));
990   lldb::RegularExpressionSP any_size_wchar_arr(
991       new RegularExpression(llvm::StringRef("wchar_t \\[[0-9]+\\]")));
992
993   TypeCategoryImpl::SharedPointer sys_category_sp =
994       GetCategory(m_system_category_name);
995
996   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"),
997                                                     string_format);
998   sys_category_sp->GetTypeSummariesContainer()->Add(
999       ConstString("unsigned char *"), string_format);
1000   sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr,
1001                                                          string_array_format);
1002
1003   lldb::TypeSummaryImplSP ostype_summary(
1004       new StringSummaryFormat(TypeSummaryImpl::Flags()
1005                                   .SetCascades(false)
1006                                   .SetSkipPointers(true)
1007                                   .SetSkipReferences(true)
1008                                   .SetDontShowChildren(true)
1009                                   .SetDontShowValue(false)
1010                                   .SetShowMembersOneLiner(false)
1011                                   .SetHideItemNames(false),
1012                               "${var%O}"));
1013
1014   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"),
1015                                                     ostype_summary);
1016
1017 #ifndef LLDB_DISABLE_PYTHON
1018   TypeFormatImpl::Flags fourchar_flags;
1019   fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(
1020       true);
1021
1022   AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"),
1023             fourchar_flags);
1024 #endif
1025 }
1026
1027 void FormatManager::LoadVectorFormatters() {
1028   TypeCategoryImpl::SharedPointer vectors_category_sp =
1029       GetCategory(m_vectortypes_category_name);
1030
1031   TypeSummaryImpl::Flags vector_flags;
1032   vector_flags.SetCascades(true)
1033       .SetSkipPointers(true)
1034       .SetSkipReferences(false)
1035       .SetDontShowChildren(true)
1036       .SetDontShowValue(false)
1037       .SetShowMembersOneLiner(true)
1038       .SetHideItemNames(true);
1039
1040   AddStringSummary(vectors_category_sp, "${var.uint128}",
1041                    ConstString("builtin_type_vec128"), vector_flags);
1042
1043   AddStringSummary(vectors_category_sp, "", ConstString("float [4]"),
1044                    vector_flags);
1045   AddStringSummary(vectors_category_sp, "", ConstString("int32_t [4]"),
1046                    vector_flags);
1047   AddStringSummary(vectors_category_sp, "", ConstString("int16_t [8]"),
1048                    vector_flags);
1049   AddStringSummary(vectors_category_sp, "", ConstString("vDouble"),
1050                    vector_flags);
1051   AddStringSummary(vectors_category_sp, "", ConstString("vFloat"),
1052                    vector_flags);
1053   AddStringSummary(vectors_category_sp, "", ConstString("vSInt8"),
1054                    vector_flags);
1055   AddStringSummary(vectors_category_sp, "", ConstString("vSInt16"),
1056                    vector_flags);
1057   AddStringSummary(vectors_category_sp, "", ConstString("vSInt32"),
1058                    vector_flags);
1059   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1060                    vector_flags);
1061   AddStringSummary(vectors_category_sp, "", ConstString("vUInt8"),
1062                    vector_flags);
1063   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1064                    vector_flags);
1065   AddStringSummary(vectors_category_sp, "", ConstString("vUInt32"),
1066                    vector_flags);
1067   AddStringSummary(vectors_category_sp, "", ConstString("vBool32"),
1068                    vector_flags);
1069 }