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