1435933ddSDimitry Andric //===-- FormatManager.cpp ----------------------------------------*- C++-*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/DataFormatters/FormatManager.h"
11ac7ddfbfSEd Maste 
129f2f44ceSEd Maste #include "llvm/ADT/STLExtras.h"
139f2f44ceSEd Maste 
14ac7ddfbfSEd Maste 
15ac7ddfbfSEd Maste #include "lldb/Core/Debugger.h"
169f2f44ceSEd Maste #include "lldb/DataFormatters/FormattersHelpers.h"
179f2f44ceSEd Maste #include "lldb/DataFormatters/LanguageCategory.h"
18ac7ddfbfSEd Maste #include "lldb/Target/ExecutionContext.h"
199f2f44ceSEd Maste #include "lldb/Target/Language.h"
20f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
21ac7ddfbfSEd Maste 
22ac7ddfbfSEd Maste using namespace lldb;
23ac7ddfbfSEd Maste using namespace lldb_private;
249f2f44ceSEd Maste using namespace lldb_private::formatters;
25ac7ddfbfSEd Maste 
26435933ddSDimitry Andric struct FormatInfo {
27ac7ddfbfSEd Maste   Format format;
28435933ddSDimitry Andric   const char format_char;  // One or more format characters that can be used for
29435933ddSDimitry Andric                            // this format.
30435933ddSDimitry Andric   const char *format_name; // Long format name that can be used to specify the
31435933ddSDimitry Andric                            // current format
32ac7ddfbfSEd Maste };
33ac7ddfbfSEd Maste 
34435933ddSDimitry Andric static FormatInfo g_format_infos[] = {
35ac7ddfbfSEd Maste     {eFormatDefault, '\0', "default"},
36ac7ddfbfSEd Maste     {eFormatBoolean, 'B', "boolean"},
37ac7ddfbfSEd Maste     {eFormatBinary, 'b', "binary"},
38ac7ddfbfSEd Maste     {eFormatBytes, 'y', "bytes"},
39ac7ddfbfSEd Maste     {eFormatBytesWithASCII, 'Y', "bytes with ASCII"},
40ac7ddfbfSEd Maste     {eFormatChar, 'c', "character"},
41ac7ddfbfSEd Maste     {eFormatCharPrintable, 'C', "printable character"},
42ac7ddfbfSEd Maste     {eFormatComplexFloat, 'F', "complex float"},
43ac7ddfbfSEd Maste     {eFormatCString, 's', "c-string"},
44ac7ddfbfSEd Maste     {eFormatDecimal, 'd', "decimal"},
45ac7ddfbfSEd Maste     {eFormatEnum, 'E', "enumeration"},
46ac7ddfbfSEd Maste     {eFormatHex, 'x', "hex"},
47ac7ddfbfSEd Maste     {eFormatHexUppercase, 'X', "uppercase hex"},
48ac7ddfbfSEd Maste     {eFormatFloat, 'f', "float"},
49ac7ddfbfSEd Maste     {eFormatOctal, 'o', "octal"},
50ac7ddfbfSEd Maste     {eFormatOSType, 'O', "OSType"},
51ac7ddfbfSEd Maste     {eFormatUnicode16, 'U', "unicode16"},
52ac7ddfbfSEd Maste     {eFormatUnicode32, '\0', "unicode32"},
53ac7ddfbfSEd Maste     {eFormatUnsigned, 'u', "unsigned decimal"},
54ac7ddfbfSEd Maste     {eFormatPointer, 'p', "pointer"},
55ac7ddfbfSEd Maste     {eFormatVectorOfChar, '\0', "char[]"},
56ac7ddfbfSEd Maste     {eFormatVectorOfSInt8, '\0', "int8_t[]"},
57ac7ddfbfSEd Maste     {eFormatVectorOfUInt8, '\0', "uint8_t[]"},
58ac7ddfbfSEd Maste     {eFormatVectorOfSInt16, '\0', "int16_t[]"},
59ac7ddfbfSEd Maste     {eFormatVectorOfUInt16, '\0', "uint16_t[]"},
60ac7ddfbfSEd Maste     {eFormatVectorOfSInt32, '\0', "int32_t[]"},
61ac7ddfbfSEd Maste     {eFormatVectorOfUInt32, '\0', "uint32_t[]"},
62ac7ddfbfSEd Maste     {eFormatVectorOfSInt64, '\0', "int64_t[]"},
63ac7ddfbfSEd Maste     {eFormatVectorOfUInt64, '\0', "uint64_t[]"},
649f2f44ceSEd Maste     {eFormatVectorOfFloat16, '\0', "float16[]"},
65ac7ddfbfSEd Maste     {eFormatVectorOfFloat32, '\0', "float32[]"},
66ac7ddfbfSEd Maste     {eFormatVectorOfFloat64, '\0', "float64[]"},
67ac7ddfbfSEd Maste     {eFormatVectorOfUInt128, '\0', "uint128_t[]"},
68ac7ddfbfSEd Maste     {eFormatComplexInteger, 'I', "complex integer"},
69ac7ddfbfSEd Maste     {eFormatCharArray, 'a', "character array"},
70ac7ddfbfSEd Maste     {eFormatAddressInfo, 'A', "address"},
71ac7ddfbfSEd Maste     {eFormatHexFloat, '\0', "hex float"},
72ac7ddfbfSEd Maste     {eFormatInstruction, 'i', "instruction"},
73435933ddSDimitry Andric     {eFormatVoid, 'v', "void"}};
74ac7ddfbfSEd Maste 
750127ef0fSEd Maste static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
76ac7ddfbfSEd Maste 
GetFormatFromFormatChar(char format_char,Format & format)77435933ddSDimitry Andric static bool GetFormatFromFormatChar(char format_char, Format &format) {
78435933ddSDimitry Andric   for (uint32_t i = 0; i < g_num_format_infos; ++i) {
79435933ddSDimitry Andric     if (g_format_infos[i].format_char == format_char) {
80ac7ddfbfSEd Maste       format = g_format_infos[i].format;
81ac7ddfbfSEd Maste       return true;
82ac7ddfbfSEd Maste     }
83ac7ddfbfSEd Maste   }
84ac7ddfbfSEd Maste   format = eFormatInvalid;
85ac7ddfbfSEd Maste   return false;
86ac7ddfbfSEd Maste }
87ac7ddfbfSEd Maste 
GetFormatFromFormatName(const char * format_name,bool partial_match_ok,Format & format)88435933ddSDimitry Andric static bool GetFormatFromFormatName(const char *format_name,
89435933ddSDimitry Andric                                     bool partial_match_ok, Format &format) {
90ac7ddfbfSEd Maste   uint32_t i;
91435933ddSDimitry Andric   for (i = 0; i < g_num_format_infos; ++i) {
92435933ddSDimitry Andric     if (strcasecmp(g_format_infos[i].format_name, format_name) == 0) {
93ac7ddfbfSEd Maste       format = g_format_infos[i].format;
94ac7ddfbfSEd Maste       return true;
95ac7ddfbfSEd Maste     }
96ac7ddfbfSEd Maste   }
97ac7ddfbfSEd Maste 
98435933ddSDimitry Andric   if (partial_match_ok) {
99435933ddSDimitry Andric     for (i = 0; i < g_num_format_infos; ++i) {
100435933ddSDimitry Andric       if (strcasestr(g_format_infos[i].format_name, format_name) ==
101435933ddSDimitry Andric           g_format_infos[i].format_name) {
102ac7ddfbfSEd Maste         format = g_format_infos[i].format;
103ac7ddfbfSEd Maste         return true;
104ac7ddfbfSEd Maste       }
105ac7ddfbfSEd Maste     }
106ac7ddfbfSEd Maste   }
107ac7ddfbfSEd Maste   format = eFormatInvalid;
108ac7ddfbfSEd Maste   return false;
109ac7ddfbfSEd Maste }
110ac7ddfbfSEd Maste 
Changed()111435933ddSDimitry Andric void FormatManager::Changed() {
1129f2f44ceSEd Maste   ++m_last_revision;
1139f2f44ceSEd Maste   m_format_cache.Clear();
1144bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
115435933ddSDimitry Andric   for (auto &iter : m_language_categories_map) {
1169f2f44ceSEd Maste     if (iter.second)
1179f2f44ceSEd Maste       iter.second->GetFormatCache().Clear();
1189f2f44ceSEd Maste   }
1199f2f44ceSEd Maste }
1209f2f44ceSEd Maste 
GetFormatFromCString(const char * format_cstr,bool partial_match_ok,lldb::Format & format)121435933ddSDimitry Andric bool FormatManager::GetFormatFromCString(const char *format_cstr,
122ac7ddfbfSEd Maste                                          bool partial_match_ok,
123435933ddSDimitry Andric                                          lldb::Format &format) {
124ac7ddfbfSEd Maste   bool success = false;
125435933ddSDimitry Andric   if (format_cstr && format_cstr[0]) {
126435933ddSDimitry Andric     if (format_cstr[1] == '\0') {
127ac7ddfbfSEd Maste       success = GetFormatFromFormatChar(format_cstr[0], format);
128ac7ddfbfSEd Maste       if (success)
129ac7ddfbfSEd Maste         return true;
130ac7ddfbfSEd Maste     }
131ac7ddfbfSEd Maste 
132ac7ddfbfSEd Maste     success = GetFormatFromFormatName(format_cstr, partial_match_ok, format);
133ac7ddfbfSEd Maste   }
134ac7ddfbfSEd Maste   if (!success)
135ac7ddfbfSEd Maste     format = eFormatInvalid;
136ac7ddfbfSEd Maste   return success;
137ac7ddfbfSEd Maste }
138ac7ddfbfSEd Maste 
GetFormatAsFormatChar(lldb::Format format)139435933ddSDimitry Andric char FormatManager::GetFormatAsFormatChar(lldb::Format format) {
140435933ddSDimitry Andric   for (uint32_t i = 0; i < g_num_format_infos; ++i) {
141ac7ddfbfSEd Maste     if (g_format_infos[i].format == format)
142ac7ddfbfSEd Maste       return g_format_infos[i].format_char;
143ac7ddfbfSEd Maste   }
144ac7ddfbfSEd Maste   return '\0';
145ac7ddfbfSEd Maste }
146ac7ddfbfSEd Maste 
GetFormatAsCString(Format format)147435933ddSDimitry Andric const char *FormatManager::GetFormatAsCString(Format format) {
148ac7ddfbfSEd Maste   if (format >= eFormatDefault && format < kNumFormats)
149ac7ddfbfSEd Maste     return g_format_infos[format].format_name;
150ac7ddfbfSEd Maste   return NULL;
151ac7ddfbfSEd Maste }
152ac7ddfbfSEd Maste 
EnableAllCategories()153435933ddSDimitry Andric void FormatManager::EnableAllCategories() {
1549f2f44ceSEd Maste   m_categories_map.EnableAllCategories();
1554bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
156435933ddSDimitry Andric   for (auto &iter : m_language_categories_map) {
1579f2f44ceSEd Maste     if (iter.second)
1589f2f44ceSEd Maste       iter.second->Enable();
1599f2f44ceSEd Maste   }
1609f2f44ceSEd Maste }
1619f2f44ceSEd Maste 
DisableAllCategories()162435933ddSDimitry Andric void FormatManager::DisableAllCategories() {
1639f2f44ceSEd Maste   m_categories_map.DisableAllCategories();
1644bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
165435933ddSDimitry Andric   for (auto &iter : m_language_categories_map) {
1669f2f44ceSEd Maste     if (iter.second)
1679f2f44ceSEd Maste       iter.second->Disable();
1689f2f44ceSEd Maste   }
1699f2f44ceSEd Maste }
1709f2f44ceSEd Maste 
GetPossibleMatches(ValueObject & valobj,CompilerType compiler_type,uint32_t reason,lldb::DynamicValueType use_dynamic,FormattersMatchVector & entries,bool did_strip_ptr,bool did_strip_ref,bool did_strip_typedef,bool root_level)171435933ddSDimitry Andric void FormatManager::GetPossibleMatches(
172435933ddSDimitry Andric     ValueObject &valobj, CompilerType compiler_type, uint32_t reason,
173435933ddSDimitry Andric     lldb::DynamicValueType use_dynamic, FormattersMatchVector &entries,
174435933ddSDimitry Andric     bool did_strip_ptr, bool did_strip_ref, bool did_strip_typedef,
175435933ddSDimitry Andric     bool root_level) {
1769f2f44ceSEd Maste   compiler_type = compiler_type.GetTypeForFormatters();
1779f2f44ceSEd Maste   ConstString type_name(compiler_type.GetConstTypeName());
178435933ddSDimitry Andric   if (valobj.GetBitfieldBitSize() > 0) {
179b952cd58SEd Maste     StreamString sstring;
180b952cd58SEd Maste     sstring.Printf("%s:%d", type_name.AsCString(), valobj.GetBitfieldBitSize());
181435933ddSDimitry Andric     ConstString bitfieldname(sstring.GetString());
182435933ddSDimitry Andric     entries.push_back(
183435933ddSDimitry Andric         {bitfieldname, 0, did_strip_ptr, did_strip_ref, did_strip_typedef});
184b952cd58SEd Maste     reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
185b952cd58SEd Maste   }
1869f2f44ceSEd Maste 
187435933ddSDimitry Andric   if (!compiler_type.IsMeaninglessWithoutDynamicResolution()) {
188435933ddSDimitry Andric     entries.push_back(
189435933ddSDimitry Andric         {type_name, reason, did_strip_ptr, did_strip_ref, did_strip_typedef});
190b952cd58SEd Maste 
1919f2f44ceSEd Maste     ConstString display_type_name(compiler_type.GetDisplayTypeName());
1920127ef0fSEd Maste     if (display_type_name != type_name)
193435933ddSDimitry Andric       entries.push_back({display_type_name, reason, did_strip_ptr,
194435933ddSDimitry Andric                          did_strip_ref, did_strip_typedef});
1959f2f44ceSEd Maste   }
1960127ef0fSEd Maste 
197435933ddSDimitry Andric   for (bool is_rvalue_ref = true, j = true;
198435933ddSDimitry Andric        j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false) {
1999f2f44ceSEd Maste     CompilerType non_ref_type = compiler_type.GetNonReferenceType();
200435933ddSDimitry Andric     GetPossibleMatches(
201435933ddSDimitry Andric         valobj, non_ref_type,
202435933ddSDimitry Andric         reason |
203435933ddSDimitry Andric             lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
204435933ddSDimitry Andric         use_dynamic, entries, did_strip_ptr, true, did_strip_typedef);
205435933ddSDimitry Andric     if (non_ref_type.IsTypedefType()) {
2069f2f44ceSEd Maste       CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
207435933ddSDimitry Andric       deffed_referenced_type =
208435933ddSDimitry Andric           is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType()
209435933ddSDimitry Andric                         : deffed_referenced_type.GetLValueReferenceType();
210435933ddSDimitry Andric       GetPossibleMatches(
211435933ddSDimitry Andric           valobj, deffed_referenced_type,
2120127ef0fSEd Maste           reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
213435933ddSDimitry Andric           use_dynamic, entries, did_strip_ptr, did_strip_ref,
2140127ef0fSEd Maste           true); // this is not exactly the usual meaning of stripping typedefs
215b952cd58SEd Maste     }
2160127ef0fSEd Maste   }
2170127ef0fSEd Maste 
218435933ddSDimitry Andric   if (compiler_type.IsPointerType()) {
2199f2f44ceSEd Maste     CompilerType non_ptr_type = compiler_type.GetPointeeType();
220435933ddSDimitry Andric     GetPossibleMatches(
221435933ddSDimitry Andric         valobj, non_ptr_type,
222435933ddSDimitry Andric         reason |
223435933ddSDimitry Andric             lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
224435933ddSDimitry Andric         use_dynamic, entries, true, did_strip_ref, did_strip_typedef);
225435933ddSDimitry Andric     if (non_ptr_type.IsTypedefType()) {
226435933ddSDimitry Andric       CompilerType deffed_pointed_type =
227435933ddSDimitry Andric           non_ptr_type.GetTypedefedType().GetPointerType();
228435933ddSDimitry Andric       GetPossibleMatches(
229435933ddSDimitry Andric           valobj, deffed_pointed_type,
2300127ef0fSEd Maste           reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
231435933ddSDimitry Andric           use_dynamic, entries, did_strip_ptr, did_strip_ref,
2320127ef0fSEd Maste           true); // this is not exactly the usual meaning of stripping typedefs
2330127ef0fSEd Maste     }
234b952cd58SEd Maste   }
235b952cd58SEd Maste 
236435933ddSDimitry Andric   for (lldb::LanguageType language_type : GetCandidateLanguages(valobj)) {
237435933ddSDimitry Andric     if (Language *language = Language::FindPlugin(language_type)) {
238435933ddSDimitry Andric       for (ConstString candidate :
239435933ddSDimitry Andric            language->GetPossibleFormattersMatches(valobj, use_dynamic)) {
240435933ddSDimitry Andric         entries.push_back(
241435933ddSDimitry Andric             {candidate,
2429f2f44ceSEd Maste              reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
243435933ddSDimitry Andric              did_strip_ptr, did_strip_ref, did_strip_typedef});
2449f2f44ceSEd Maste       }
2459f2f44ceSEd Maste     }
246b952cd58SEd Maste   }
247b952cd58SEd Maste 
248b952cd58SEd Maste   // try to strip typedef chains
249435933ddSDimitry Andric   if (compiler_type.IsTypedefType()) {
2509f2f44ceSEd Maste     CompilerType deffed_type = compiler_type.GetTypedefedType();
251435933ddSDimitry Andric     GetPossibleMatches(
252435933ddSDimitry Andric         valobj, deffed_type,
253b952cd58SEd Maste         reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
254435933ddSDimitry Andric         use_dynamic, entries, did_strip_ptr, did_strip_ref, true);
255b952cd58SEd Maste   }
256b952cd58SEd Maste 
257435933ddSDimitry Andric   if (root_level) {
258b952cd58SEd Maste     do {
2599f2f44ceSEd Maste       if (!compiler_type.IsValid())
260b952cd58SEd Maste         break;
261b952cd58SEd Maste 
262435933ddSDimitry Andric       CompilerType unqual_compiler_ast_type =
263435933ddSDimitry Andric           compiler_type.GetFullyUnqualifiedType();
2649f2f44ceSEd Maste       if (!unqual_compiler_ast_type.IsValid())
265b952cd58SEd Maste         break;
266435933ddSDimitry Andric       if (unqual_compiler_ast_type.GetOpaqueQualType() !=
267435933ddSDimitry Andric           compiler_type.GetOpaqueQualType())
268435933ddSDimitry Andric         GetPossibleMatches(valobj, unqual_compiler_ast_type, reason,
269435933ddSDimitry Andric                            use_dynamic, entries, did_strip_ptr, did_strip_ref,
270b952cd58SEd Maste                            did_strip_typedef);
271b952cd58SEd Maste     } while (false);
272b952cd58SEd Maste 
273b952cd58SEd Maste     // if all else fails, go to static type
274435933ddSDimitry Andric     if (valobj.IsDynamic()) {
275b952cd58SEd Maste       lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
276b952cd58SEd Maste       if (static_value_sp)
277435933ddSDimitry Andric         GetPossibleMatches(
278435933ddSDimitry Andric             *static_value_sp.get(), static_value_sp->GetCompilerType(),
279b952cd58SEd Maste             reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
280435933ddSDimitry Andric             use_dynamic, entries, did_strip_ptr, did_strip_ref,
281435933ddSDimitry Andric             did_strip_typedef, true);
282b952cd58SEd Maste     }
283b952cd58SEd Maste   }
284b952cd58SEd Maste }
285b952cd58SEd Maste 
28635617911SEd Maste lldb::TypeFormatImplSP
GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp)287435933ddSDimitry Andric FormatManager::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
28835617911SEd Maste   if (!type_sp)
28935617911SEd Maste     return lldb::TypeFormatImplSP();
29035617911SEd Maste   lldb::TypeFormatImplSP format_chosen_sp;
29135617911SEd Maste   uint32_t num_categories = m_categories_map.GetCount();
29235617911SEd Maste   lldb::TypeCategoryImplSP category_sp;
29335617911SEd Maste   uint32_t prio_category = UINT32_MAX;
294435933ddSDimitry Andric   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
29535617911SEd Maste     category_sp = GetCategoryAtIndex(category_id);
296*b5893f02SDimitry Andric     if (!category_sp->IsEnabled())
29735617911SEd Maste       continue;
298435933ddSDimitry Andric     lldb::TypeFormatImplSP format_current_sp =
299435933ddSDimitry Andric         category_sp->GetFormatForType(type_sp);
300435933ddSDimitry Andric     if (format_current_sp &&
301435933ddSDimitry Andric         (format_chosen_sp.get() == NULL ||
302435933ddSDimitry Andric          (prio_category > category_sp->GetEnabledPosition()))) {
30335617911SEd Maste       prio_category = category_sp->GetEnabledPosition();
30435617911SEd Maste       format_chosen_sp = format_current_sp;
30535617911SEd Maste     }
30635617911SEd Maste   }
30735617911SEd Maste   return format_chosen_sp;
30835617911SEd Maste }
30935617911SEd Maste 
310ac7ddfbfSEd Maste lldb::TypeSummaryImplSP
GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp)311435933ddSDimitry Andric FormatManager::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
312ac7ddfbfSEd Maste   if (!type_sp)
313ac7ddfbfSEd Maste     return lldb::TypeSummaryImplSP();
314ac7ddfbfSEd Maste   lldb::TypeSummaryImplSP summary_chosen_sp;
315ac7ddfbfSEd Maste   uint32_t num_categories = m_categories_map.GetCount();
316ac7ddfbfSEd Maste   lldb::TypeCategoryImplSP category_sp;
317ac7ddfbfSEd Maste   uint32_t prio_category = UINT32_MAX;
318435933ddSDimitry Andric   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
319ac7ddfbfSEd Maste     category_sp = GetCategoryAtIndex(category_id);
320*b5893f02SDimitry Andric     if (!category_sp->IsEnabled())
321ac7ddfbfSEd Maste       continue;
322435933ddSDimitry Andric     lldb::TypeSummaryImplSP summary_current_sp =
323435933ddSDimitry Andric         category_sp->GetSummaryForType(type_sp);
324435933ddSDimitry Andric     if (summary_current_sp &&
325435933ddSDimitry Andric         (summary_chosen_sp.get() == NULL ||
326435933ddSDimitry Andric          (prio_category > category_sp->GetEnabledPosition()))) {
327ac7ddfbfSEd Maste       prio_category = category_sp->GetEnabledPosition();
328ac7ddfbfSEd Maste       summary_chosen_sp = summary_current_sp;
329ac7ddfbfSEd Maste     }
330ac7ddfbfSEd Maste   }
331ac7ddfbfSEd Maste   return summary_chosen_sp;
332ac7ddfbfSEd Maste }
333ac7ddfbfSEd Maste 
334ac7ddfbfSEd Maste lldb::TypeFilterImplSP
GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp)335435933ddSDimitry Andric FormatManager::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
336ac7ddfbfSEd Maste   if (!type_sp)
337ac7ddfbfSEd Maste     return lldb::TypeFilterImplSP();
338ac7ddfbfSEd Maste   lldb::TypeFilterImplSP filter_chosen_sp;
339ac7ddfbfSEd Maste   uint32_t num_categories = m_categories_map.GetCount();
340ac7ddfbfSEd Maste   lldb::TypeCategoryImplSP category_sp;
341ac7ddfbfSEd Maste   uint32_t prio_category = UINT32_MAX;
342435933ddSDimitry Andric   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
343ac7ddfbfSEd Maste     category_sp = GetCategoryAtIndex(category_id);
344*b5893f02SDimitry Andric     if (!category_sp->IsEnabled())
345ac7ddfbfSEd Maste       continue;
346435933ddSDimitry Andric     lldb::TypeFilterImplSP filter_current_sp(
347435933ddSDimitry Andric         (TypeFilterImpl *)category_sp->GetFilterForType(type_sp).get());
348435933ddSDimitry Andric     if (filter_current_sp &&
349435933ddSDimitry Andric         (filter_chosen_sp.get() == NULL ||
350435933ddSDimitry Andric          (prio_category > category_sp->GetEnabledPosition()))) {
351ac7ddfbfSEd Maste       prio_category = category_sp->GetEnabledPosition();
352ac7ddfbfSEd Maste       filter_chosen_sp = filter_current_sp;
353ac7ddfbfSEd Maste     }
354ac7ddfbfSEd Maste   }
355ac7ddfbfSEd Maste   return filter_chosen_sp;
356ac7ddfbfSEd Maste }
357ac7ddfbfSEd Maste 
358ac7ddfbfSEd Maste #ifndef LLDB_DISABLE_PYTHON
359ac7ddfbfSEd Maste lldb::ScriptedSyntheticChildrenSP
GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp)360435933ddSDimitry Andric FormatManager::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
361ac7ddfbfSEd Maste   if (!type_sp)
362ac7ddfbfSEd Maste     return lldb::ScriptedSyntheticChildrenSP();
363ac7ddfbfSEd Maste   lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
364ac7ddfbfSEd Maste   uint32_t num_categories = m_categories_map.GetCount();
365ac7ddfbfSEd Maste   lldb::TypeCategoryImplSP category_sp;
366ac7ddfbfSEd Maste   uint32_t prio_category = UINT32_MAX;
367435933ddSDimitry Andric   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
368ac7ddfbfSEd Maste     category_sp = GetCategoryAtIndex(category_id);
369*b5893f02SDimitry Andric     if (!category_sp->IsEnabled())
370ac7ddfbfSEd Maste       continue;
371435933ddSDimitry Andric     lldb::ScriptedSyntheticChildrenSP synth_current_sp(
372435933ddSDimitry Andric         (ScriptedSyntheticChildren *)category_sp->GetSyntheticForType(type_sp)
373435933ddSDimitry Andric             .get());
374435933ddSDimitry Andric     if (synth_current_sp &&
375435933ddSDimitry Andric         (synth_chosen_sp.get() == NULL ||
376435933ddSDimitry Andric          (prio_category > category_sp->GetEnabledPosition()))) {
377ac7ddfbfSEd Maste       prio_category = category_sp->GetEnabledPosition();
378ac7ddfbfSEd Maste       synth_chosen_sp = synth_current_sp;
379ac7ddfbfSEd Maste     }
380ac7ddfbfSEd Maste   }
381ac7ddfbfSEd Maste   return synth_chosen_sp;
382ac7ddfbfSEd Maste }
383ac7ddfbfSEd Maste #endif
384ac7ddfbfSEd Maste 
385ac7ddfbfSEd Maste #ifndef LLDB_DISABLE_PYTHON
GetSyntheticChildrenForType(lldb::TypeNameSpecifierImplSP type_sp)386435933ddSDimitry Andric lldb::SyntheticChildrenSP FormatManager::GetSyntheticChildrenForType(
387435933ddSDimitry Andric     lldb::TypeNameSpecifierImplSP type_sp) {
388ac7ddfbfSEd Maste   if (!type_sp)
389ac7ddfbfSEd Maste     return lldb::SyntheticChildrenSP();
390ac7ddfbfSEd Maste   lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
391ac7ddfbfSEd Maste   lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
392ac7ddfbfSEd Maste   if (filter_sp->GetRevision() > synth_sp->GetRevision())
393ac7ddfbfSEd Maste     return lldb::SyntheticChildrenSP(filter_sp.get());
394ac7ddfbfSEd Maste   else
395ac7ddfbfSEd Maste     return lldb::SyntheticChildrenSP(synth_sp.get());
396ac7ddfbfSEd Maste }
397ac7ddfbfSEd Maste #endif
398ac7ddfbfSEd Maste 
3997aa51b79SEd Maste lldb::TypeValidatorImplSP
GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp)400435933ddSDimitry Andric FormatManager::GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp) {
4017aa51b79SEd Maste   if (!type_sp)
4027aa51b79SEd Maste     return lldb::TypeValidatorImplSP();
4037aa51b79SEd Maste   lldb::TypeValidatorImplSP validator_chosen_sp;
4047aa51b79SEd Maste   uint32_t num_categories = m_categories_map.GetCount();
4057aa51b79SEd Maste   lldb::TypeCategoryImplSP category_sp;
4067aa51b79SEd Maste   uint32_t prio_category = UINT32_MAX;
407435933ddSDimitry Andric   for (uint32_t category_id = 0; category_id < num_categories; category_id++) {
4087aa51b79SEd Maste     category_sp = GetCategoryAtIndex(category_id);
409*b5893f02SDimitry Andric     if (!category_sp->IsEnabled())
4107aa51b79SEd Maste       continue;
411435933ddSDimitry Andric     lldb::TypeValidatorImplSP validator_current_sp(
412435933ddSDimitry Andric         category_sp->GetValidatorForType(type_sp).get());
413435933ddSDimitry Andric     if (validator_current_sp &&
414435933ddSDimitry Andric         (validator_chosen_sp.get() == NULL ||
415435933ddSDimitry Andric          (prio_category > category_sp->GetEnabledPosition()))) {
4167aa51b79SEd Maste       prio_category = category_sp->GetEnabledPosition();
4177aa51b79SEd Maste       validator_chosen_sp = validator_current_sp;
4187aa51b79SEd Maste     }
4197aa51b79SEd Maste   }
4207aa51b79SEd Maste   return validator_chosen_sp;
4217aa51b79SEd Maste }
4227aa51b79SEd Maste 
ForEachCategory(TypeCategoryMap::ForEachCallback callback)423435933ddSDimitry Andric void FormatManager::ForEachCategory(TypeCategoryMap::ForEachCallback callback) {
4249f2f44ceSEd Maste   m_categories_map.ForEach(callback);
4254bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
426435933ddSDimitry Andric   for (const auto &entry : m_language_categories_map) {
427435933ddSDimitry Andric     if (auto category_sp = entry.second->GetCategory()) {
4289f2f44ceSEd Maste       if (!callback(category_sp))
4299f2f44ceSEd Maste         break;
4309f2f44ceSEd Maste     }
4319f2f44ceSEd Maste   }
4329f2f44ceSEd Maste }
4339f2f44ceSEd Maste 
434ac7ddfbfSEd Maste lldb::TypeCategoryImplSP
GetCategory(const ConstString & category_name,bool can_create)435435933ddSDimitry Andric FormatManager::GetCategory(const ConstString &category_name, bool can_create) {
436ac7ddfbfSEd Maste   if (!category_name)
437ac7ddfbfSEd Maste     return GetCategory(m_default_category_name);
438ac7ddfbfSEd Maste   lldb::TypeCategoryImplSP category;
439ac7ddfbfSEd Maste   if (m_categories_map.Get(category_name, category))
440ac7ddfbfSEd Maste     return category;
441ac7ddfbfSEd Maste 
442ac7ddfbfSEd Maste   if (!can_create)
443ac7ddfbfSEd Maste     return lldb::TypeCategoryImplSP();
444ac7ddfbfSEd Maste 
445435933ddSDimitry Andric   m_categories_map.Add(
446435933ddSDimitry Andric       category_name,
447435933ddSDimitry Andric       lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
448ac7ddfbfSEd Maste   return GetCategory(category_name);
449ac7ddfbfSEd Maste }
450ac7ddfbfSEd Maste 
GetSingleItemFormat(lldb::Format vector_format)451435933ddSDimitry Andric lldb::Format FormatManager::GetSingleItemFormat(lldb::Format vector_format) {
452435933ddSDimitry Andric   switch (vector_format) {
453ac7ddfbfSEd Maste   case eFormatVectorOfChar:
454ac7ddfbfSEd Maste     return eFormatCharArray;
455ac7ddfbfSEd Maste 
456ac7ddfbfSEd Maste   case eFormatVectorOfSInt8:
457ac7ddfbfSEd Maste   case eFormatVectorOfSInt16:
458ac7ddfbfSEd Maste   case eFormatVectorOfSInt32:
459ac7ddfbfSEd Maste   case eFormatVectorOfSInt64:
460ac7ddfbfSEd Maste     return eFormatDecimal;
461ac7ddfbfSEd Maste 
462ac7ddfbfSEd Maste   case eFormatVectorOfUInt8:
463ac7ddfbfSEd Maste   case eFormatVectorOfUInt16:
464ac7ddfbfSEd Maste   case eFormatVectorOfUInt32:
465ac7ddfbfSEd Maste   case eFormatVectorOfUInt64:
466ac7ddfbfSEd Maste   case eFormatVectorOfUInt128:
467ac7ddfbfSEd Maste     return eFormatHex;
468ac7ddfbfSEd Maste 
4699f2f44ceSEd Maste   case eFormatVectorOfFloat16:
470ac7ddfbfSEd Maste   case eFormatVectorOfFloat32:
471ac7ddfbfSEd Maste   case eFormatVectorOfFloat64:
472ac7ddfbfSEd Maste     return eFormatFloat;
473ac7ddfbfSEd Maste 
474ac7ddfbfSEd Maste   default:
475ac7ddfbfSEd Maste     return lldb::eFormatInvalid;
476ac7ddfbfSEd Maste   }
477ac7ddfbfSEd Maste }
478ac7ddfbfSEd Maste 
ShouldPrintAsOneLiner(ValueObject & valobj)479435933ddSDimitry Andric bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) {
48035617911SEd Maste   // if settings say no oneline whatsoever
481435933ddSDimitry Andric   if (valobj.GetTargetSP().get() &&
482*b5893f02SDimitry Andric       !valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries())
48335617911SEd Maste     return false; // then don't oneline
48435617911SEd Maste 
4857aa51b79SEd Maste   // if this object has a summary, then ask the summary
48635617911SEd Maste   if (valobj.GetSummaryFormat().get() != nullptr)
4877aa51b79SEd Maste     return valobj.GetSummaryFormat()->IsOneLiner();
48835617911SEd Maste 
48935617911SEd Maste   // no children, no party
49035617911SEd Maste   if (valobj.GetNumChildren() == 0)
49135617911SEd Maste     return false;
49235617911SEd Maste 
4934ba319b5SDimitry Andric   // ask the type if it has any opinion about this eLazyBoolCalculate == no
4944ba319b5SDimitry Andric   // opinion; other values should be self explanatory
4959f2f44ceSEd Maste   CompilerType compiler_type(valobj.GetCompilerType());
496435933ddSDimitry Andric   if (compiler_type.IsValid()) {
497435933ddSDimitry Andric     switch (compiler_type.ShouldPrintAsOneLiner(&valobj)) {
4989f2f44ceSEd Maste     case eLazyBoolNo:
4999f2f44ceSEd Maste       return false;
5009f2f44ceSEd Maste     case eLazyBoolYes:
5019f2f44ceSEd Maste       return true;
5029f2f44ceSEd Maste     case eLazyBoolCalculate:
5039f2f44ceSEd Maste       break;
5049f2f44ceSEd Maste     }
5059f2f44ceSEd Maste   }
5069f2f44ceSEd Maste 
50735617911SEd Maste   size_t total_children_name_len = 0;
50835617911SEd Maste 
509435933ddSDimitry Andric   for (size_t idx = 0; idx < valobj.GetNumChildren(); idx++) {
5107aa51b79SEd Maste     bool is_synth_val = false;
51135617911SEd Maste     ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
51235617911SEd Maste     // something is wrong here - bail out
51335617911SEd Maste     if (!child_sp)
51435617911SEd Maste       return false;
5159f2f44ceSEd Maste 
5169f2f44ceSEd Maste     // also ask the child's type if it has any opinion
5179f2f44ceSEd Maste     CompilerType child_compiler_type(child_sp->GetCompilerType());
518435933ddSDimitry Andric     if (child_compiler_type.IsValid()) {
519435933ddSDimitry Andric       switch (child_compiler_type.ShouldPrintAsOneLiner(child_sp.get())) {
5209f2f44ceSEd Maste       case eLazyBoolYes:
5219f2f44ceSEd Maste       // an opinion of yes is only binding for the child, so keep going
5229f2f44ceSEd Maste       case eLazyBoolCalculate:
5239f2f44ceSEd Maste         break;
5249f2f44ceSEd Maste       case eLazyBoolNo:
5259f2f44ceSEd Maste         // but if the child says no, then it's a veto on the whole thing
5269f2f44ceSEd Maste         return false;
5279f2f44ceSEd Maste       }
5289f2f44ceSEd Maste     }
5299f2f44ceSEd Maste 
530435933ddSDimitry Andric     // if we decided to define synthetic children for a type, we probably care
5314ba319b5SDimitry Andric     // enough to show them, but avoid nesting children in children
532435933ddSDimitry Andric     if (child_sp->GetSyntheticChildren().get() != nullptr) {
5337aa51b79SEd Maste       ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
5347aa51b79SEd Maste       // wait.. wat? just get out of here..
5357aa51b79SEd Maste       if (!synth_sp)
53635617911SEd Maste         return false;
5377aa51b79SEd Maste       // but if we only have them to provide a value, keep going
538*b5893f02SDimitry Andric       if (!synth_sp->MightHaveChildren() &&
539435933ddSDimitry Andric           synth_sp->DoesProvideSyntheticValue())
5407aa51b79SEd Maste         is_synth_val = true;
5417aa51b79SEd Maste       else
5427aa51b79SEd Maste         return false;
5437aa51b79SEd Maste     }
54435617911SEd Maste 
54535617911SEd Maste     total_children_name_len += child_sp->GetName().GetLength();
54635617911SEd Maste 
54735617911SEd Maste     // 50 itself is a "randomly" chosen number - the idea is that
54835617911SEd Maste     // overly long structs should not get this treatment
54935617911SEd Maste     // FIXME: maybe make this a user-tweakable setting?
55035617911SEd Maste     if (total_children_name_len > 50)
55135617911SEd Maste       return false;
55235617911SEd Maste 
55335617911SEd Maste     // if a summary is there..
554435933ddSDimitry Andric     if (child_sp->GetSummaryFormat()) {
55535617911SEd Maste       // and it wants children, then bail out
5560127ef0fSEd Maste       if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
55735617911SEd Maste         return false;
55835617911SEd Maste     }
55935617911SEd Maste 
56035617911SEd Maste     // if this child has children..
561435933ddSDimitry Andric     if (child_sp->GetNumChildren()) {
56235617911SEd Maste       // ...and no summary...
563435933ddSDimitry Andric       // (if it had a summary and the summary wanted children, we would have
564435933ddSDimitry Andric       // bailed out anyway
565435933ddSDimitry Andric       //  so this only makes us bail out if this has no summary and we would
566435933ddSDimitry Andric       //  then print children)
567435933ddSDimitry Andric       if (!child_sp->GetSummaryFormat() && !is_synth_val) // but again only do
568435933ddSDimitry Andric                                                           // that if not a
569435933ddSDimitry Andric                                                           // synthetic valued
570435933ddSDimitry Andric                                                           // child
57135617911SEd Maste         return false;                                     // then bail out
57235617911SEd Maste     }
57335617911SEd Maste   }
57435617911SEd Maste   return true;
57535617911SEd Maste }
57635617911SEd Maste 
GetValidTypeName(const ConstString & type)577435933ddSDimitry Andric ConstString FormatManager::GetValidTypeName(const ConstString &type) {
578ac7ddfbfSEd Maste   return ::GetValidTypeName_Impl(type);
579ac7ddfbfSEd Maste }
580ac7ddfbfSEd Maste 
GetTypeForCache(ValueObject & valobj,lldb::DynamicValueType use_dynamic)581435933ddSDimitry Andric ConstString FormatManager::GetTypeForCache(ValueObject &valobj,
582435933ddSDimitry Andric                                            lldb::DynamicValueType use_dynamic) {
583435933ddSDimitry Andric   ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(
584435933ddSDimitry Andric       use_dynamic, valobj.IsSynthetic());
585435933ddSDimitry Andric   if (valobj_sp && valobj_sp->GetCompilerType().IsValid()) {
5869f2f44ceSEd Maste     if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
5879f2f44ceSEd Maste       return valobj_sp->GetQualifiedTypeName();
588ac7ddfbfSEd Maste   }
589ac7ddfbfSEd Maste   return ConstString();
590ac7ddfbfSEd Maste }
591ac7ddfbfSEd Maste 
5929f2f44ceSEd Maste std::vector<lldb::LanguageType>
GetCandidateLanguages(ValueObject & valobj)593435933ddSDimitry Andric FormatManager::GetCandidateLanguages(ValueObject &valobj) {
5949f2f44ceSEd Maste   lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
5959f2f44ceSEd Maste   return GetCandidateLanguages(lang_type);
5960127ef0fSEd Maste }
5979f2f44ceSEd Maste 
5989f2f44ceSEd Maste std::vector<lldb::LanguageType>
GetCandidateLanguages(lldb::LanguageType lang_type)599435933ddSDimitry Andric FormatManager::GetCandidateLanguages(lldb::LanguageType lang_type) {
600435933ddSDimitry Andric   switch (lang_type) {
6019f2f44ceSEd Maste   case lldb::eLanguageTypeC:
6029f2f44ceSEd Maste   case lldb::eLanguageTypeC89:
6039f2f44ceSEd Maste   case lldb::eLanguageTypeC99:
6049f2f44ceSEd Maste   case lldb::eLanguageTypeC11:
6059f2f44ceSEd Maste   case lldb::eLanguageTypeC_plus_plus:
6069f2f44ceSEd Maste   case lldb::eLanguageTypeC_plus_plus_03:
6079f2f44ceSEd Maste   case lldb::eLanguageTypeC_plus_plus_11:
6089f2f44ceSEd Maste   case lldb::eLanguageTypeC_plus_plus_14:
6099f2f44ceSEd Maste     return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
6109f2f44ceSEd Maste   default:
6119f2f44ceSEd Maste     return {lang_type};
6129f2f44ceSEd Maste   }
6139f2f44ceSEd Maste }
6149f2f44ceSEd Maste 
6159f2f44ceSEd Maste LanguageCategory *
GetCategoryForLanguage(lldb::LanguageType lang_type)616435933ddSDimitry Andric FormatManager::GetCategoryForLanguage(lldb::LanguageType lang_type) {
6174bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_language_categories_mutex);
618435933ddSDimitry Andric   auto iter = m_language_categories_map.find(lang_type),
619435933ddSDimitry Andric        end = m_language_categories_map.end();
6209f2f44ceSEd Maste   if (iter != end)
6219f2f44ceSEd Maste     return iter->second.get();
6229f2f44ceSEd Maste   LanguageCategory *lang_category = new LanguageCategory(lang_type);
623435933ddSDimitry Andric   m_language_categories_map[lang_type] =
624435933ddSDimitry Andric       LanguageCategory::UniquePointer(lang_category);
6259f2f44ceSEd Maste   return lang_category;
6269f2f44ceSEd Maste }
6279f2f44ceSEd Maste 
6289f2f44ceSEd Maste lldb::TypeFormatImplSP
GetHardcodedFormat(FormattersMatchData & match_data)629435933ddSDimitry Andric FormatManager::GetHardcodedFormat(FormattersMatchData &match_data) {
6309f2f44ceSEd Maste   TypeFormatImplSP retval_sp;
6319f2f44ceSEd Maste 
632435933ddSDimitry Andric   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
633435933ddSDimitry Andric     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
6349f2f44ceSEd Maste       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
6359f2f44ceSEd Maste         break;
6369f2f44ceSEd Maste     }
6379f2f44ceSEd Maste   }
6389f2f44ceSEd Maste 
6399f2f44ceSEd Maste   return retval_sp;
64035617911SEd Maste }
64135617911SEd Maste 
64235617911SEd Maste lldb::TypeFormatImplSP
GetFormat(ValueObject & valobj,lldb::DynamicValueType use_dynamic)64335617911SEd Maste FormatManager::GetFormat(ValueObject &valobj,
644435933ddSDimitry Andric                          lldb::DynamicValueType use_dynamic) {
6459f2f44ceSEd Maste   FormattersMatchData match_data(valobj, use_dynamic);
6469f2f44ceSEd Maste 
64735617911SEd Maste   TypeFormatImplSP retval;
6489f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
649435933ddSDimitry Andric   if (match_data.GetTypeForCache()) {
65035617911SEd Maste     if (log)
651435933ddSDimitry Andric       log->Printf(
652435933ddSDimitry Andric           "\n\n[FormatManager::GetFormat] Looking into cache for type %s",
653435933ddSDimitry Andric           match_data.GetTypeForCache().AsCString("<invalid>"));
654435933ddSDimitry Andric     if (m_format_cache.GetFormat(match_data.GetTypeForCache(), retval)) {
655435933ddSDimitry Andric       if (log) {
656435933ddSDimitry Andric         log->Printf(
657435933ddSDimitry Andric             "[FormatManager::GetFormat] Cache search success. Returning.");
658f678e45dSDimitry Andric         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
659435933ddSDimitry Andric                   m_format_cache.GetCacheHits(),
660435933ddSDimitry Andric                   m_format_cache.GetCacheMisses());
66135617911SEd Maste       }
66235617911SEd Maste       return retval;
66335617911SEd Maste     }
66435617911SEd Maste     if (log)
665435933ddSDimitry Andric       log->Printf(
666435933ddSDimitry Andric           "[FormatManager::GetFormat] Cache search failed. Going normal route");
66735617911SEd Maste   }
6689f2f44ceSEd Maste 
6699f2f44ceSEd Maste   retval = m_categories_map.GetFormat(match_data);
670435933ddSDimitry Andric   if (!retval) {
6719f2f44ceSEd Maste     if (log)
672435933ddSDimitry Andric       log->Printf("[FormatManager::GetFormat] Search failed. Giving language a "
673435933ddSDimitry Andric                   "chance.");
674435933ddSDimitry Andric     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
675435933ddSDimitry Andric       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
6769f2f44ceSEd Maste         if (lang_category->Get(match_data, retval))
6779f2f44ceSEd Maste           break;
6789f2f44ceSEd Maste       }
6799f2f44ceSEd Maste     }
680435933ddSDimitry Andric     if (retval) {
6819f2f44ceSEd Maste       if (log)
682435933ddSDimitry Andric         log->Printf(
683435933ddSDimitry Andric             "[FormatManager::GetFormat] Language search success. Returning.");
6849f2f44ceSEd Maste       return retval;
6859f2f44ceSEd Maste     }
6869f2f44ceSEd Maste   }
687435933ddSDimitry Andric   if (!retval) {
68835617911SEd Maste     if (log)
689435933ddSDimitry Andric       log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded "
690435933ddSDimitry Andric                   "a chance.");
6919f2f44ceSEd Maste     retval = GetHardcodedFormat(match_data);
69235617911SEd Maste   }
6931c3bbb01SEd Maste 
694435933ddSDimitry Andric   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
69535617911SEd Maste     if (log)
6960127ef0fSEd Maste       log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
6970127ef0fSEd Maste                   static_cast<void *>(retval.get()),
6989f2f44ceSEd Maste                   match_data.GetTypeForCache().AsCString("<invalid>"));
6999f2f44ceSEd Maste     m_format_cache.SetFormat(match_data.GetTypeForCache(), retval);
70035617911SEd Maste   }
701f678e45dSDimitry Andric   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
702435933ddSDimitry Andric             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
70335617911SEd Maste   return retval;
70435617911SEd Maste }
70535617911SEd Maste 
7060127ef0fSEd Maste lldb::TypeSummaryImplSP
GetHardcodedSummaryFormat(FormattersMatchData & match_data)707435933ddSDimitry Andric FormatManager::GetHardcodedSummaryFormat(FormattersMatchData &match_data) {
7089f2f44ceSEd Maste   TypeSummaryImplSP retval_sp;
7099f2f44ceSEd Maste 
710435933ddSDimitry Andric   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
711435933ddSDimitry Andric     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
7129f2f44ceSEd Maste       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
7139f2f44ceSEd Maste         break;
7140127ef0fSEd Maste     }
7159f2f44ceSEd Maste   }
7169f2f44ceSEd Maste 
7179f2f44ceSEd Maste   return retval_sp;
71835617911SEd Maste }
71935617911SEd Maste 
720ac7ddfbfSEd Maste lldb::TypeSummaryImplSP
GetSummaryFormat(ValueObject & valobj,lldb::DynamicValueType use_dynamic)721ac7ddfbfSEd Maste FormatManager::GetSummaryFormat(ValueObject &valobj,
722435933ddSDimitry Andric                                 lldb::DynamicValueType use_dynamic) {
7239f2f44ceSEd Maste   FormattersMatchData match_data(valobj, use_dynamic);
7249f2f44ceSEd Maste 
725ac7ddfbfSEd Maste   TypeSummaryImplSP retval;
7269f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
727435933ddSDimitry Andric   if (match_data.GetTypeForCache()) {
728ac7ddfbfSEd Maste     if (log)
729435933ddSDimitry Andric       log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache "
730435933ddSDimitry Andric                   "for type %s",
731435933ddSDimitry Andric                   match_data.GetTypeForCache().AsCString("<invalid>"));
732435933ddSDimitry Andric     if (m_format_cache.GetSummary(match_data.GetTypeForCache(), retval)) {
733435933ddSDimitry Andric       if (log) {
734435933ddSDimitry Andric         log->Printf("[FormatManager::GetSummaryFormat] Cache search success. "
735435933ddSDimitry Andric                     "Returning.");
736f678e45dSDimitry Andric         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
737435933ddSDimitry Andric                   m_format_cache.GetCacheHits(),
738435933ddSDimitry Andric                   m_format_cache.GetCacheMisses());
739ac7ddfbfSEd Maste       }
740ac7ddfbfSEd Maste       return retval;
741ac7ddfbfSEd Maste     }
742ac7ddfbfSEd Maste     if (log)
743435933ddSDimitry Andric       log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. "
744435933ddSDimitry Andric                   "Going normal route");
745ac7ddfbfSEd Maste   }
7469f2f44ceSEd Maste 
7479f2f44ceSEd Maste   retval = m_categories_map.GetSummaryFormat(match_data);
748435933ddSDimitry Andric   if (!retval) {
7499f2f44ceSEd Maste     if (log)
750435933ddSDimitry Andric       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
751435933ddSDimitry Andric                   "language a chance.");
752435933ddSDimitry Andric     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
753435933ddSDimitry Andric       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
7549f2f44ceSEd Maste         if (lang_category->Get(match_data, retval))
7559f2f44ceSEd Maste           break;
7569f2f44ceSEd Maste       }
7579f2f44ceSEd Maste     }
758435933ddSDimitry Andric     if (retval) {
7599f2f44ceSEd Maste       if (log)
760435933ddSDimitry Andric         log->Printf("[FormatManager::GetSummaryFormat] Language search "
761435933ddSDimitry Andric                     "success. Returning.");
7629f2f44ceSEd Maste       return retval;
7639f2f44ceSEd Maste     }
7649f2f44ceSEd Maste   }
765435933ddSDimitry Andric   if (!retval) {
76635617911SEd Maste     if (log)
767435933ddSDimitry Andric       log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
768435933ddSDimitry Andric                   "hardcoded a chance.");
7699f2f44ceSEd Maste     retval = GetHardcodedSummaryFormat(match_data);
77035617911SEd Maste   }
7711c3bbb01SEd Maste 
772435933ddSDimitry Andric   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
773ac7ddfbfSEd Maste     if (log)
7740127ef0fSEd Maste       log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
7750127ef0fSEd Maste                   static_cast<void *>(retval.get()),
7769f2f44ceSEd Maste                   match_data.GetTypeForCache().AsCString("<invalid>"));
7779f2f44ceSEd Maste     m_format_cache.SetSummary(match_data.GetTypeForCache(), retval);
778ac7ddfbfSEd Maste   }
779f678e45dSDimitry Andric   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
780435933ddSDimitry Andric             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
781ac7ddfbfSEd Maste   return retval;
782ac7ddfbfSEd Maste }
783ac7ddfbfSEd Maste 
784ac7ddfbfSEd Maste #ifndef LLDB_DISABLE_PYTHON
7850127ef0fSEd Maste lldb::SyntheticChildrenSP
GetHardcodedSyntheticChildren(FormattersMatchData & match_data)786435933ddSDimitry Andric FormatManager::GetHardcodedSyntheticChildren(FormattersMatchData &match_data) {
7879f2f44ceSEd Maste   SyntheticChildrenSP retval_sp;
7889f2f44ceSEd Maste 
789435933ddSDimitry Andric   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
790435933ddSDimitry Andric     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
7919f2f44ceSEd Maste       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
7929f2f44ceSEd Maste         break;
7930127ef0fSEd Maste     }
7949f2f44ceSEd Maste   }
7959f2f44ceSEd Maste 
7969f2f44ceSEd Maste   return retval_sp;
79735617911SEd Maste }
79835617911SEd Maste 
799ac7ddfbfSEd Maste lldb::SyntheticChildrenSP
GetSyntheticChildren(ValueObject & valobj,lldb::DynamicValueType use_dynamic)800ac7ddfbfSEd Maste FormatManager::GetSyntheticChildren(ValueObject &valobj,
801435933ddSDimitry Andric                                     lldb::DynamicValueType use_dynamic) {
8029f2f44ceSEd Maste   FormattersMatchData match_data(valobj, use_dynamic);
8039f2f44ceSEd Maste 
804ac7ddfbfSEd Maste   SyntheticChildrenSP retval;
8059f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
806435933ddSDimitry Andric   if (match_data.GetTypeForCache()) {
807ac7ddfbfSEd Maste     if (log)
808435933ddSDimitry Andric       log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into "
809435933ddSDimitry Andric                   "cache for type %s",
810435933ddSDimitry Andric                   match_data.GetTypeForCache().AsCString("<invalid>"));
811435933ddSDimitry Andric     if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(), retval)) {
812435933ddSDimitry Andric       if (log) {
813435933ddSDimitry Andric         log->Printf("[FormatManager::GetSyntheticChildren] Cache search "
814435933ddSDimitry Andric                     "success. Returning.");
815f678e45dSDimitry Andric         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
816f678e45dSDimitry Andric                   m_format_cache.GetCacheHits(),
817f678e45dSDimitry Andric                   m_format_cache.GetCacheMisses());
818ac7ddfbfSEd Maste       }
819ac7ddfbfSEd Maste       return retval;
820ac7ddfbfSEd Maste     }
821ac7ddfbfSEd Maste     if (log)
822435933ddSDimitry Andric       log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. "
823435933ddSDimitry Andric                   "Going normal route");
824ac7ddfbfSEd Maste   }
8259f2f44ceSEd Maste 
8269f2f44ceSEd Maste   retval = m_categories_map.GetSyntheticChildren(match_data);
827435933ddSDimitry Andric   if (!retval) {
8289f2f44ceSEd Maste     if (log)
829435933ddSDimitry Andric       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
830435933ddSDimitry Andric                   "language a chance.");
831435933ddSDimitry Andric     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
832435933ddSDimitry Andric       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
8339f2f44ceSEd Maste         if (lang_category->Get(match_data, retval))
8349f2f44ceSEd Maste           break;
8359f2f44ceSEd Maste       }
8369f2f44ceSEd Maste     }
837435933ddSDimitry Andric     if (retval) {
8389f2f44ceSEd Maste       if (log)
839435933ddSDimitry Andric         log->Printf("[FormatManager::GetSyntheticChildren] Language search "
840435933ddSDimitry Andric                     "success. Returning.");
8419f2f44ceSEd Maste       return retval;
8429f2f44ceSEd Maste     }
8439f2f44ceSEd Maste   }
844435933ddSDimitry Andric   if (!retval) {
84535617911SEd Maste     if (log)
846435933ddSDimitry Andric       log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
847435933ddSDimitry Andric                   "hardcoded a chance.");
8489f2f44ceSEd Maste     retval = GetHardcodedSyntheticChildren(match_data);
84935617911SEd Maste   }
8501c3bbb01SEd Maste 
851435933ddSDimitry Andric   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
852ac7ddfbfSEd Maste     if (log)
853435933ddSDimitry Andric       log->Printf(
854435933ddSDimitry Andric           "[FormatManager::GetSyntheticChildren] Caching %p for type %s",
8550127ef0fSEd Maste           static_cast<void *>(retval.get()),
8569f2f44ceSEd Maste           match_data.GetTypeForCache().AsCString("<invalid>"));
8579f2f44ceSEd Maste     m_format_cache.SetSynthetic(match_data.GetTypeForCache(), retval);
858ac7ddfbfSEd Maste   }
859f678e45dSDimitry Andric   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
860435933ddSDimitry Andric             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
861ac7ddfbfSEd Maste   return retval;
862ac7ddfbfSEd Maste }
863ac7ddfbfSEd Maste #endif
864ac7ddfbfSEd Maste 
8657aa51b79SEd Maste lldb::TypeValidatorImplSP
GetValidator(ValueObject & valobj,lldb::DynamicValueType use_dynamic)8667aa51b79SEd Maste FormatManager::GetValidator(ValueObject &valobj,
867435933ddSDimitry Andric                             lldb::DynamicValueType use_dynamic) {
8689f2f44ceSEd Maste   FormattersMatchData match_data(valobj, use_dynamic);
8699f2f44ceSEd Maste 
8707aa51b79SEd Maste   TypeValidatorImplSP retval;
8719f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
872435933ddSDimitry Andric   if (match_data.GetTypeForCache()) {
8737aa51b79SEd Maste     if (log)
874435933ddSDimitry Andric       log->Printf(
875435933ddSDimitry Andric           "\n\n[FormatManager::GetValidator] Looking into cache for type %s",
876435933ddSDimitry Andric           match_data.GetTypeForCache().AsCString("<invalid>"));
877435933ddSDimitry Andric     if (m_format_cache.GetValidator(match_data.GetTypeForCache(), retval)) {
878435933ddSDimitry Andric       if (log) {
879435933ddSDimitry Andric         log->Printf(
880435933ddSDimitry Andric             "[FormatManager::GetValidator] Cache search success. Returning.");
881f678e45dSDimitry Andric         LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
882435933ddSDimitry Andric                   m_format_cache.GetCacheHits(),
883435933ddSDimitry Andric                   m_format_cache.GetCacheMisses());
8847aa51b79SEd Maste       }
8857aa51b79SEd Maste       return retval;
8867aa51b79SEd Maste     }
8877aa51b79SEd Maste     if (log)
888435933ddSDimitry Andric       log->Printf("[FormatManager::GetValidator] Cache search failed. Going "
889435933ddSDimitry Andric                   "normal route");
8907aa51b79SEd Maste   }
8919f2f44ceSEd Maste 
8929f2f44ceSEd Maste   retval = m_categories_map.GetValidator(match_data);
893435933ddSDimitry Andric   if (!retval) {
8949f2f44ceSEd Maste     if (log)
895435933ddSDimitry Andric       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
896435933ddSDimitry Andric                   "language a chance.");
897435933ddSDimitry Andric     for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
898435933ddSDimitry Andric       if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
8999f2f44ceSEd Maste         if (lang_category->Get(match_data, retval))
9009f2f44ceSEd Maste           break;
9019f2f44ceSEd Maste       }
9029f2f44ceSEd Maste     }
903435933ddSDimitry Andric     if (retval) {
9049f2f44ceSEd Maste       if (log)
905435933ddSDimitry Andric         log->Printf("[FormatManager::GetValidator] Language search success. "
906435933ddSDimitry Andric                     "Returning.");
9079f2f44ceSEd Maste       return retval;
9089f2f44ceSEd Maste     }
9099f2f44ceSEd Maste   }
910435933ddSDimitry Andric   if (!retval) {
9117aa51b79SEd Maste     if (log)
912435933ddSDimitry Andric       log->Printf("[FormatManager::GetValidator] Search failed. Giving "
913435933ddSDimitry Andric                   "hardcoded a chance.");
9149f2f44ceSEd Maste     retval = GetHardcodedValidator(match_data);
9157aa51b79SEd Maste   }
9161c3bbb01SEd Maste 
917435933ddSDimitry Andric   if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
9187aa51b79SEd Maste     if (log)
9197aa51b79SEd Maste       log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
9207aa51b79SEd Maste                   static_cast<void *>(retval.get()),
9219f2f44ceSEd Maste                   match_data.GetTypeForCache().AsCString("<invalid>"));
9229f2f44ceSEd Maste     m_format_cache.SetValidator(match_data.GetTypeForCache(), retval);
9237aa51b79SEd Maste   }
924f678e45dSDimitry Andric   LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
925435933ddSDimitry Andric             m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
9267aa51b79SEd Maste   return retval;
9277aa51b79SEd Maste }
9287aa51b79SEd Maste 
9297aa51b79SEd Maste lldb::TypeValidatorImplSP
GetHardcodedValidator(FormattersMatchData & match_data)930435933ddSDimitry Andric FormatManager::GetHardcodedValidator(FormattersMatchData &match_data) {
9319f2f44ceSEd Maste   TypeValidatorImplSP retval_sp;
9329f2f44ceSEd Maste 
933435933ddSDimitry Andric   for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
934435933ddSDimitry Andric     if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
9359f2f44ceSEd Maste       if (lang_category->GetHardcoded(*this, match_data, retval_sp))
9369f2f44ceSEd Maste         break;
9377aa51b79SEd Maste     }
9389f2f44ceSEd Maste   }
9399f2f44ceSEd Maste 
9409f2f44ceSEd Maste   return retval_sp;
9417aa51b79SEd Maste }
9427aa51b79SEd Maste 
FormatManager()9434bb0738eSEd Maste FormatManager::FormatManager()
944435933ddSDimitry Andric     : m_last_revision(0), m_format_cache(), m_language_categories_mutex(),
945435933ddSDimitry Andric       m_language_categories_map(), m_named_summaries_map(this),
946435933ddSDimitry Andric       m_categories_map(this), m_default_category_name(ConstString("default")),
947ac7ddfbfSEd Maste       m_system_category_name(ConstString("system")),
948435933ddSDimitry Andric       m_vectortypes_category_name(ConstString("VectorTypes")) {
949ac7ddfbfSEd Maste   LoadSystemFormatters();
9509f2f44ceSEd Maste   LoadVectorFormatters();
951ac7ddfbfSEd Maste 
952435933ddSDimitry Andric   EnableCategory(m_vectortypes_category_name, TypeCategoryMap::Last,
953435933ddSDimitry Andric                  lldb::eLanguageTypeObjC_plus_plus);
954435933ddSDimitry Andric   EnableCategory(m_system_category_name, TypeCategoryMap::Last,
955435933ddSDimitry Andric                  lldb::eLanguageTypeObjC_plus_plus);
956ac7ddfbfSEd Maste }
957ac7ddfbfSEd Maste 
LoadSystemFormatters()958435933ddSDimitry Andric void FormatManager::LoadSystemFormatters() {
959ac7ddfbfSEd Maste   TypeSummaryImpl::Flags string_flags;
960ac7ddfbfSEd Maste   string_flags.SetCascades(true)
961ac7ddfbfSEd Maste       .SetSkipPointers(true)
962ac7ddfbfSEd Maste       .SetSkipReferences(false)
963ac7ddfbfSEd Maste       .SetDontShowChildren(true)
964ac7ddfbfSEd Maste       .SetDontShowValue(false)
965ac7ddfbfSEd Maste       .SetShowMembersOneLiner(false)
966ac7ddfbfSEd Maste       .SetHideItemNames(false);
967ac7ddfbfSEd Maste 
9681c3bbb01SEd Maste   TypeSummaryImpl::Flags string_array_flags;
9699f2f44ceSEd Maste   string_array_flags.SetCascades(true)
970ac7ddfbfSEd Maste       .SetSkipPointers(true)
971ac7ddfbfSEd Maste       .SetSkipReferences(false)
972ac7ddfbfSEd Maste       .SetDontShowChildren(true)
973ac7ddfbfSEd Maste       .SetDontShowValue(true)
974ac7ddfbfSEd Maste       .SetShowMembersOneLiner(false)
9751c3bbb01SEd Maste       .SetHideItemNames(false);
9761c3bbb01SEd Maste 
977435933ddSDimitry Andric   lldb::TypeSummaryImplSP string_format(
978435933ddSDimitry Andric       new StringSummaryFormat(string_flags, "${var%s}"));
9791c3bbb01SEd Maste 
980435933ddSDimitry Andric   lldb::TypeSummaryImplSP string_array_format(
981435933ddSDimitry Andric       new StringSummaryFormat(string_array_flags, "${var%s}"));
9821c3bbb01SEd Maste 
983435933ddSDimitry Andric   lldb::RegularExpressionSP any_size_char_arr(
984435933ddSDimitry Andric       new RegularExpression(llvm::StringRef("char \\[[0-9]+\\]")));
985435933ddSDimitry Andric   lldb::RegularExpressionSP any_size_wchar_arr(
986435933ddSDimitry Andric       new RegularExpression(llvm::StringRef("wchar_t \\[[0-9]+\\]")));
987ac7ddfbfSEd Maste 
988435933ddSDimitry Andric   TypeCategoryImpl::SharedPointer sys_category_sp =
989435933ddSDimitry Andric       GetCategory(m_system_category_name);
990ac7ddfbfSEd Maste 
991435933ddSDimitry Andric   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"),
992435933ddSDimitry Andric                                                     string_format);
993435933ddSDimitry Andric   sys_category_sp->GetTypeSummariesContainer()->Add(
994435933ddSDimitry Andric       ConstString("unsigned char *"), string_format);
995435933ddSDimitry Andric   sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr,
996435933ddSDimitry Andric                                                          string_array_format);
997ac7ddfbfSEd Maste 
998435933ddSDimitry Andric   lldb::TypeSummaryImplSP ostype_summary(
999435933ddSDimitry Andric       new StringSummaryFormat(TypeSummaryImpl::Flags()
1000435933ddSDimitry Andric                                   .SetCascades(false)
1001ac7ddfbfSEd Maste                                   .SetSkipPointers(true)
1002ac7ddfbfSEd Maste                                   .SetSkipReferences(true)
1003ac7ddfbfSEd Maste                                   .SetDontShowChildren(true)
1004ac7ddfbfSEd Maste                                   .SetDontShowValue(false)
1005ac7ddfbfSEd Maste                                   .SetShowMembersOneLiner(false)
1006ac7ddfbfSEd Maste                                   .SetHideItemNames(false),
1007ac7ddfbfSEd Maste                               "${var%O}"));
1008ac7ddfbfSEd Maste 
1009435933ddSDimitry Andric   sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"),
1010435933ddSDimitry Andric                                                     ostype_summary);
1011ac7ddfbfSEd Maste 
1012ac7ddfbfSEd Maste #ifndef LLDB_DISABLE_PYTHON
101335617911SEd Maste   TypeFormatImpl::Flags fourchar_flags;
1014435933ddSDimitry Andric   fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(
1015435933ddSDimitry Andric       true);
101635617911SEd Maste 
1017435933ddSDimitry Andric   AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"),
1018435933ddSDimitry Andric             fourchar_flags);
1019ac7ddfbfSEd Maste #endif
1020ac7ddfbfSEd Maste }
1021ac7ddfbfSEd Maste 
LoadVectorFormatters()1022435933ddSDimitry Andric void FormatManager::LoadVectorFormatters() {
1023435933ddSDimitry Andric   TypeCategoryImpl::SharedPointer vectors_category_sp =
1024435933ddSDimitry Andric       GetCategory(m_vectortypes_category_name);
1025ac7ddfbfSEd Maste 
1026ac7ddfbfSEd Maste   TypeSummaryImpl::Flags vector_flags;
1027ac7ddfbfSEd Maste   vector_flags.SetCascades(true)
1028ac7ddfbfSEd Maste       .SetSkipPointers(true)
1029ac7ddfbfSEd Maste       .SetSkipReferences(false)
1030ac7ddfbfSEd Maste       .SetDontShowChildren(true)
1031ac7ddfbfSEd Maste       .SetDontShowValue(false)
1032ac7ddfbfSEd Maste       .SetShowMembersOneLiner(true)
1033ac7ddfbfSEd Maste       .SetHideItemNames(true);
1034ac7ddfbfSEd Maste 
1035435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "${var.uint128}",
1036435933ddSDimitry Andric                    ConstString("builtin_type_vec128"), vector_flags);
1037ac7ddfbfSEd Maste 
1038435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("float [4]"),
1039ac7ddfbfSEd Maste                    vector_flags);
1040435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("int32_t [4]"),
1041ac7ddfbfSEd Maste                    vector_flags);
1042435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("int16_t [8]"),
1043ac7ddfbfSEd Maste                    vector_flags);
1044435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vDouble"),
1045ac7ddfbfSEd Maste                    vector_flags);
1046435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vFloat"),
1047ac7ddfbfSEd Maste                    vector_flags);
1048435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vSInt8"),
1049ac7ddfbfSEd Maste                    vector_flags);
1050435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vSInt16"),
1051ac7ddfbfSEd Maste                    vector_flags);
1052435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vSInt32"),
1053ac7ddfbfSEd Maste                    vector_flags);
1054435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1055ac7ddfbfSEd Maste                    vector_flags);
1056435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vUInt8"),
1057ac7ddfbfSEd Maste                    vector_flags);
1058435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"),
1059ac7ddfbfSEd Maste                    vector_flags);
1060435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vUInt32"),
1061ac7ddfbfSEd Maste                    vector_flags);
1062435933ddSDimitry Andric   AddStringSummary(vectors_category_sp, "", ConstString("vBool32"),
1063ac7ddfbfSEd Maste                    vector_flags);
1064ac7ddfbfSEd Maste }
1065