]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp
Merge clang 7.0.1 and several follow-up changes
[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 eLazyBoolCalculate == no
498   // 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 to show them, but avoid nesting children in children
536     if (child_sp->GetSyntheticChildren().get() != nullptr) {
537       ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
538       // wait.. wat? just get out of here..
539       if (!synth_sp)
540         return false;
541       // but if we only have them to provide a value, keep going
542       if (synth_sp->MightHaveChildren() == false &&
543           synth_sp->DoesProvideSyntheticValue())
544         is_synth_val = true;
545       else
546         return false;
547     }
548
549     total_children_name_len += child_sp->GetName().GetLength();
550
551     // 50 itself is a "randomly" chosen number - the idea is that
552     // overly long structs should not get this treatment
553     // FIXME: maybe make this a user-tweakable setting?
554     if (total_children_name_len > 50)
555       return false;
556
557     // if a summary is there..
558     if (child_sp->GetSummaryFormat()) {
559       // and it wants children, then bail out
560       if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
561         return false;
562     }
563
564     // if this child has children..
565     if (child_sp->GetNumChildren()) {
566       // ...and no summary...
567       // (if it had a summary and the summary wanted children, we would have
568       // bailed out anyway
569       //  so this only makes us bail out if this has no summary and we would
570       //  then print children)
571       if (!child_sp->GetSummaryFormat() && !is_synth_val) // but again only do
572                                                           // that if not a
573                                                           // synthetic valued
574                                                           // child
575         return false;                                     // then bail out
576     }
577   }
578   return true;
579 }
580
581 ConstString FormatManager::GetValidTypeName(const ConstString &type) {
582   return ::GetValidTypeName_Impl(type);
583 }
584
585 ConstString FormatManager::GetTypeForCache(ValueObject &valobj,
586                                            lldb::DynamicValueType use_dynamic) {
587   ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(
588       use_dynamic, valobj.IsSynthetic());
589   if (valobj_sp && valobj_sp->GetCompilerType().IsValid()) {
590     if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
591       return valobj_sp->GetQualifiedTypeName();
592   }
593   return ConstString();
594 }
595
596 std::vector<lldb::LanguageType>
597 FormatManager::GetCandidateLanguages(ValueObject &valobj) {
598   lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
599   return GetCandidateLanguages(lang_type);
600 }
601
602 std::vector<lldb::LanguageType>
603 FormatManager::GetCandidateLanguages(lldb::LanguageType lang_type) {
604   switch (lang_type) {
605   case lldb::eLanguageTypeC:
606   case lldb::eLanguageTypeC89:
607   case lldb::eLanguageTypeC99:
608   case lldb::eLanguageTypeC11:
609   case lldb::eLanguageTypeC_plus_plus:
610   case lldb::eLanguageTypeC_plus_plus_03:
611   case lldb::eLanguageTypeC_plus_plus_11:
612   case lldb::eLanguageTypeC_plus_plus_14:
613     return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
614   default:
615     return {lang_type};
616   }
617 }
618
619 LanguageCategory *
620 FormatManager::GetCategoryForLanguage(lldb::LanguageType lang_type) {
621   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
622   auto iter = m_language_categories_map.find(lang_type),
623        end = m_language_categories_map.end();
624   if (iter != end)
625     return iter->second.get();
626   LanguageCategory *lang_category = new LanguageCategory(lang_type);
627   m_language_categories_map[lang_type] =
628       LanguageCategory::UniquePointer(lang_category);
629   return lang_category;
630 }
631
632 lldb::TypeFormatImplSP
633 FormatManager::GetHardcodedFormat(FormattersMatchData &match_data) {
634   TypeFormatImplSP retval_sp;
635
636   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
637     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
638       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
639         break;
640     }
641   }
642
643   return retval_sp;
644 }
645
646 lldb::TypeFormatImplSP
647 FormatManager::GetFormat(ValueObject &valobj,
648                          lldb::DynamicValueType use_dynamic) {
649   FormattersMatchData match_data(valobj, use_dynamic);
650
651   TypeFormatImplSP retval;
652   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
653   if (match_data.GetTypeForCache()) {
654     if (log)
655       log->Printf(
656           "\n\n[FormatManager::GetFormat] Looking into cache for type %s",
657           match_data.GetTypeForCache().AsCString("<invalid>"));
658     if (m_format_cache.GetFormat(match_data.GetTypeForCache(), retval)) {
659       if (log) {
660         log->Printf(
661             "[FormatManager::GetFormat] Cache search success. Returning.");
662         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
663                   m_format_cache.GetCacheHits(),
664                   m_format_cache.GetCacheMisses());
665       }
666       return retval;
667     }
668     if (log)
669       log->Printf(
670           "[FormatManager::GetFormat] Cache search failed. Going normal route");
671   }
672
673   retval = m_categories_map.GetFormat(match_data);
674   if (!retval) {
675     if (log)
676       log->Printf("[FormatManager::GetFormat] Search failed. Giving language a "
677                   "chance.");
678     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
679       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
680         if (lang_category->Get(match_data, retval))
681           break;
682       }
683     }
684     if (retval) {
685       if (log)
686         log->Printf(
687             "[FormatManager::GetFormat] Language search success. Returning.");
688       return retval;
689     }
690   }
691   if (!retval) {
692     if (log)
693       log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded "
694                   "a chance.");
695     retval = GetHardcodedFormat(match_data);
696   }
697
698   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
699     if (log)
700       log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
701                   static_cast<void *>(retval.get()),
702                   match_data.GetTypeForCache().AsCString("<invalid>"));
703     m_format_cache.SetFormat(match_data.GetTypeForCache(), retval);
704   }
705   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
706             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
707   return retval;
708 }
709
710 lldb::TypeSummaryImplSP
711 FormatManager::GetHardcodedSummaryFormat(FormattersMatchData &match_data) {
712   TypeSummaryImplSP retval_sp;
713
714   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
715     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
716       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
717         break;
718     }
719   }
720
721   return retval_sp;
722 }
723
724 lldb::TypeSummaryImplSP
725 FormatManager::GetSummaryFormat(ValueObject &valobj,
726                                 lldb::DynamicValueType use_dynamic) {
727   FormattersMatchData match_data(valobj, use_dynamic);
728
729   TypeSummaryImplSP retval;
730   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
731   if (match_data.GetTypeForCache()) {
732     if (log)
733       log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache "
734                   "for type %s",
735                   match_data.GetTypeForCache().AsCString("<invalid>"));
736     if (m_format_cache.GetSummary(match_data.GetTypeForCache(), retval)) {
737       if (log) {
738         log->Printf("[FormatManager::GetSummaryFormat] Cache search success. "
739                     "Returning.");
740         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
741                   m_format_cache.GetCacheHits(),
742                   m_format_cache.GetCacheMisses());
743       }
744       return retval;
745     }
746     if (log)
747       log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. "
748                   "Going normal route");
749   }
750
751   retval = m_categories_map.GetSummaryFormat(match_data);
752   if (!retval) {
753     if (log)
754       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
755                   "language a chance.");
756     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
757       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
758         if (lang_category->Get(match_data, retval))
759           break;
760       }
761     }
762     if (retval) {
763       if (log)
764         log->Printf("[FormatManager::GetSummaryFormat] Language search "
765                     "success. Returning.");
766       return retval;
767     }
768   }
769   if (!retval) {
770     if (log)
771       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
772                   "hardcoded a chance.");
773     retval = GetHardcodedSummaryFormat(match_data);
774   }
775
776   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
777     if (log)
778       log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
779                   static_cast<void *>(retval.get()),
780                   match_data.GetTypeForCache().AsCString("<invalid>"));
781     m_format_cache.SetSummary(match_data.GetTypeForCache(), retval);
782   }
783   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
784             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
785   return retval;
786 }
787
788 #ifndef LLDB_DISABLE_PYTHON
789 lldb::SyntheticChildrenSP
790 FormatManager::GetHardcodedSyntheticChildren(FormattersMatchData &match_data) {
791   SyntheticChildrenSP retval_sp;
792
793   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
794     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
795       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
796         break;
797     }
798   }
799
800   return retval_sp;
801 }
802
803 lldb::SyntheticChildrenSP
804 FormatManager::GetSyntheticChildren(ValueObject &valobj,
805                                     lldb::DynamicValueType use_dynamic) {
806   FormattersMatchData match_data(valobj, use_dynamic);
807
808   SyntheticChildrenSP retval;
809   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
810   if (match_data.GetTypeForCache()) {
811     if (log)
812       log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into "
813                   "cache for type %s",
814                   match_data.GetTypeForCache().AsCString("<invalid>"));
815     if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(), retval)) {
816       if (log) {
817         log->Printf("[FormatManager::GetSyntheticChildren] Cache search "
818                     "success. Returning.");
819         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
820                   m_format_cache.GetCacheHits(),
821                   m_format_cache.GetCacheMisses());
822       }
823       return retval;
824     }
825     if (log)
826       log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. "
827                   "Going normal route");
828   }
829
830   retval = m_categories_map.GetSyntheticChildren(match_data);
831   if (!retval) {
832     if (log)
833       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
834                   "language a chance.");
835     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
836       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
837         if (lang_category->Get(match_data, retval))
838           break;
839       }
840     }
841     if (retval) {
842       if (log)
843         log->Printf("[FormatManager::GetSyntheticChildren] Language search "
844                     "success. Returning.");
845       return retval;
846     }
847   }
848   if (!retval) {
849     if (log)
850       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
851                   "hardcoded a chance.");
852     retval = GetHardcodedSyntheticChildren(match_data);
853   }
854
855   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
856     if (log)
857       log->Printf(
858           "[FormatManager::GetSyntheticChildren] Caching %p for type %s",
859           static_cast<void *>(retval.get()),
860           match_data.GetTypeForCache().AsCString("<invalid>"));
861     m_format_cache.SetSynthetic(match_data.GetTypeForCache(), retval);
862   }
863   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
864             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
865   return retval;
866 }
867 #endif
868
869 lldb::TypeValidatorImplSP
870 FormatManager::GetValidator(ValueObject &valobj,
871                             lldb::DynamicValueType use_dynamic) {
872   FormattersMatchData match_data(valobj, use_dynamic);
873
874   TypeValidatorImplSP retval;
875   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
876   if (match_data.GetTypeForCache()) {
877     if (log)
878       log->Printf(
879           "\n\n[FormatManager::GetValidator] Looking into cache for type %s",
880           match_data.GetTypeForCache().AsCString("<invalid>"));
881     if (m_format_cache.GetValidator(match_data.GetTypeForCache(), retval)) {
882       if (log) {
883         log->Printf(
884             "[FormatManager::GetValidator] Cache search success. Returning.");
885         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
886                   m_format_cache.GetCacheHits(),
887                   m_format_cache.GetCacheMisses());
888       }
889       return retval;
890     }
891     if (log)
892       log->Printf("[FormatManager::GetValidator] Cache search failed. Going "
893                   "normal route");
894   }
895
896   retval = m_categories_map.GetValidator(match_data);
897   if (!retval) {
898     if (log)
899       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
900                   "language a chance.");
901     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
902       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
903         if (lang_category->Get(match_data, retval))
904           break;
905       }
906     }
907     if (retval) {
908       if (log)
909         log->Printf("[FormatManager::GetValidator] Language search success. "
910                     "Returning.");
911       return retval;
912     }
913   }
914   if (!retval) {
915     if (log)
916       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
917                   "hardcoded a chance.");
918     retval = GetHardcodedValidator(match_data);
919   }
920
921   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
922     if (log)
923       log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
924                   static_cast<void *>(retval.get()),
925                   match_data.GetTypeForCache().AsCString("<invalid>"));
926     m_format_cache.SetValidator(match_data.GetTypeForCache(), retval);
927   }
928   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
929             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
930   return retval;
931 }
932
933 lldb::TypeValidatorImplSP
934 FormatManager::GetHardcodedValidator(FormattersMatchData &match_data) {
935   TypeValidatorImplSP retval_sp;
936
937   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
938     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
939       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
940         break;
941     }
942   }
943
944   return retval_sp;
945 }
946
947 FormatManager::FormatManager()
948     : m_last_revision(0), m_format_cache(), m_language_categories_mutex(),
949       m_language_categories_map(), m_named_summaries_map(this),
950       m_categories_map(this), m_default_category_name(ConstString("default")),
951       m_system_category_name(ConstString("system")),
952       m_vectortypes_category_name(ConstString("VectorTypes")) {
953   LoadSystemFormatters();
954   LoadVectorFormatters();
955
956   EnableCategory(m_vectortypes_category_name, TypeCategoryMap::Last,
957                  lldb::eLanguageTypeObjC_plus_plus);
958   EnableCategory(m_system_category_name, TypeCategoryMap::Last,
959                  lldb::eLanguageTypeObjC_plus_plus);
960 }
961
962 void FormatManager::LoadSystemFormatters() {
963   TypeSummaryImpl::Flags string_flags;
964   string_flags.SetCascades(true)
965       .SetSkipPointers(true)
966       .SetSkipReferences(false)
967       .SetDontShowChildren(true)
968       .SetDontShowValue(false)
969       .SetShowMembersOneLiner(false)
970       .SetHideItemNames(false);
971
972   TypeSummaryImpl::Flags string_array_flags;
973   string_array_flags.SetCascades(true)
974       .SetSkipPointers(true)
975       .SetSkipReferences(false)
976       .SetDontShowChildren(true)
977       .SetDontShowValue(true)
978       .SetShowMembersOneLiner(false)
979       .SetHideItemNames(false);
980
981   lldb::TypeSummaryImplSP string_format(
982       new StringSummaryFormat(string_flags, "${var%s}"));
983
984   lldb::TypeSummaryImplSP string_array_format(
985       new StringSummaryFormat(string_array_flags, "${var%s}"));
986
987   lldb::RegularExpressionSP any_size_char_arr(
988       new RegularExpression(llvm::StringRef("char \\[[0-9]+\\]")));
989   lldb::RegularExpressionSP any_size_wchar_arr(
990       new RegularExpression(llvm::StringRef("wchar_t \\[[0-9]+\\]")));
991
992   TypeCategoryImpl::SharedPointer sys_category_sp =
993       GetCategory(m_system_category_name);
994
995   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"),
996                                                     string_format);
997   sys_category_sp->GetTypeSummariesContainer()->Add(
998       ConstString("unsigned char *"), string_format);
999   sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr,
1000                                                          string_array_format);
1001
1002   lldb::TypeSummaryImplSP ostype_summary(
1003       new StringSummaryFormat(TypeSummaryImpl::Flags()
1004                                   .SetCascades(false)
1005                                   .SetSkipPointers(true)
1006                                   .SetSkipReferences(true)
1007                                   .SetDontShowChildren(true)
1008                                   .SetDontShowValue(false)
1009                                   .SetShowMembersOneLiner(false)
1010                                   .SetHideItemNames(false),
1011                               "${var%O}"));
1012
1013   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"),
1014                                                     ostype_summary);
1015
1016 #ifndef LLDB_DISABLE_PYTHON
1017   TypeFormatImpl::Flags fourchar_flags;
1018   fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(
1019       true);
1020
1021   AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"),
1022             fourchar_flags);
1023 #endif
1024 }
1025
1026 void FormatManager::LoadVectorFormatters() {
1027   TypeCategoryImpl::SharedPointer vectors_category_sp =
1028       GetCategory(m_vectortypes_category_name);
1029
1030   TypeSummaryImpl::Flags vector_flags;
1031   vector_flags.SetCascades(true)
1032       .SetSkipPointers(true)
1033       .SetSkipReferences(false)
1034       .SetDontShowChildren(true)
1035       .SetDontShowValue(false)
1036       .SetShowMembersOneLiner(true)
1037       .SetHideItemNames(true);
1038
1039   AddStringSummary(vectors_category_sp, "${var.uint128}",
1040                    ConstString("builtin_type_vec128"), vector_flags);
1041
1042   AddStringSummary(vectors_category_sp, "", ConstString("float [4]"),
1043                    vector_flags);
1044   AddStringSummary(vectors_category_sp, "", ConstString("int32_t [4]"),
1045                    vector_flags);
1046   AddStringSummary(vectors_category_sp, "", ConstString("int16_t [8]"),
1047                    vector_flags);
1048   AddStringSummary(vectors_category_sp, "", ConstString("vDouble"),
1049                    vector_flags);
1050   AddStringSummary(vectors_category_sp, "", ConstString("vFloat"),
1051                    vector_flags);
1052   AddStringSummary(vectors_category_sp, "", ConstString("vSInt8"),
1053                    vector_flags);
1054   AddStringSummary(vectors_category_sp, "", ConstString("vSInt16"),
1055                    vector_flags);
1056   AddStringSummary(vectors_category_sp, "", ConstString("vSInt32"),
1057                    vector_flags);
1058   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1059                    vector_flags);
1060   AddStringSummary(vectors_category_sp, "", ConstString("vUInt8"),
1061                    vector_flags);
1062   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1063                    vector_flags);
1064   AddStringSummary(vectors_category_sp, "", ConstString("vUInt32"),
1065                    vector_flags);
1066   AddStringSummary(vectors_category_sp, "", ConstString("vBool32"),
1067                    vector_flags);
1068 }