blob: 3a5664f7c5c32946ee801db5e4de000fc0f14f77 [file] [log] [blame]
Greg Clayton4a33d312011-06-23 17:59:56 +00001//===-- 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
Enrico Granata5548cb52013-01-28 23:47:25 +000010#include "lldb/DataFormatters/FormatManager.h"
Greg Clayton4a33d312011-06-23 17:59:56 +000011
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16
Enrico Granataf2bbf712011-07-15 02:26:42 +000017#include "lldb/Core/Debugger.h"
Enrico Granatadf7e79e2015-09-02 01:21:31 +000018#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granata980c0482015-09-01 18:22:39 +000019#include "lldb/DataFormatters/LanguageCategory.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000020#include "lldb/Target/ExecutionContext.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000021#include "lldb/Target/Language.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000022#include "lldb/Target/Platform.h"
Saleem Abdulrasool28606952014-06-27 05:17:41 +000023#include "llvm/ADT/STLExtras.h"
Enrico Granataf2bbf712011-07-15 02:26:42 +000024
Enrico Granata980c0482015-09-01 18:22:39 +000025#include <initializer_list>
26
Greg Clayton4a33d312011-06-23 17:59:56 +000027using namespace lldb;
28using namespace lldb_private;
Enrico Granatadf7e79e2015-09-02 01:21:31 +000029using namespace lldb_private::formatters;
Greg Claytonbb7f31f2011-06-23 21:22:24 +000030
31struct FormatInfo
32{
33 Format format;
34 const char format_char; // One or more format characters that can be used for this format.
35 const char *format_name; // Long format name that can be used to specify the current format
36};
37
38static FormatInfo
39g_format_infos[] =
40{
41 { eFormatDefault , '\0' , "default" },
42 { eFormatBoolean , 'B' , "boolean" },
43 { eFormatBinary , 'b' , "binary" },
44 { eFormatBytes , 'y' , "bytes" },
45 { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
46 { eFormatChar , 'c' , "character" },
47 { eFormatCharPrintable , 'C' , "printable character" },
48 { eFormatComplexFloat , 'F' , "complex float" },
49 { eFormatCString , 's' , "c-string" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000050 { eFormatDecimal , 'd' , "decimal" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000051 { eFormatEnum , 'E' , "enumeration" },
52 { eFormatHex , 'x' , "hex" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000053 { eFormatHexUppercase , 'X' , "uppercase hex" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000054 { eFormatFloat , 'f' , "float" },
55 { eFormatOctal , 'o' , "octal" },
56 { eFormatOSType , 'O' , "OSType" },
57 { eFormatUnicode16 , 'U' , "unicode16" },
58 { eFormatUnicode32 , '\0' , "unicode32" },
59 { eFormatUnsigned , 'u' , "unsigned decimal" },
60 { eFormatPointer , 'p' , "pointer" },
61 { eFormatVectorOfChar , '\0' , "char[]" },
62 { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
63 { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
64 { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
65 { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
Enrico Granatae443ba72011-07-06 15:56:06 +000066 { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
67 { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
68 { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
69 { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000070 { eFormatVectorOfFloat32, '\0' , "float32[]" },
71 { eFormatVectorOfFloat64, '\0' , "float64[]" },
72 { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
73 { eFormatComplexInteger , 'I' , "complex integer" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000074 { eFormatCharArray , 'a' , "character array" },
75 { eFormatAddressInfo , 'A' , "address" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000076 { eFormatHexFloat , '\0' , "hex float" },
Sean Callananbf154da2012-08-08 17:35:10 +000077 { eFormatInstruction , 'i' , "instruction" },
78 { eFormatVoid , 'v' , "void" }
Greg Claytonbb7f31f2011-06-23 21:22:24 +000079};
80
Saleem Abdulrasool28606952014-06-27 05:17:41 +000081static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
Greg Claytonbb7f31f2011-06-23 21:22:24 +000082
83static bool
84GetFormatFromFormatChar (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
98static bool
99GetFormatFromFormatName (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
126bool
127FormatManager::GetFormatFromCString (const char *format_cstr,
128 bool partial_match_ok,
129 lldb::Format &format)
130{
131 bool success = false;
132 if (format_cstr && format_cstr[0])
133 {
134 if (format_cstr[1] == '\0')
135 {
136 success = GetFormatFromFormatChar (format_cstr[0], format);
137 if (success)
138 return true;
139 }
140
141 success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
142 }
143 if (!success)
144 format = eFormatInvalid;
145 return success;
146}
147
148char
149FormatManager::GetFormatAsFormatChar (lldb::Format format)
150{
151 for (uint32_t i=0; i<g_num_format_infos; ++i)
152 {
153 if (g_format_infos[i].format == format)
154 return g_format_infos[i].format_char;
155 }
156 return '\0';
157}
Greg Claytonbb7f31f2011-06-23 21:22:24 +0000158
159const char *
160FormatManager::GetFormatAsCString (Format format)
161{
162 if (format >= eFormatDefault && format < kNumFormats)
163 return g_format_infos[format].format_name;
164 return NULL;
165}
Enrico Granata0a3958e2011-07-02 00:25:22 +0000166
Enrico Granatade61cec2013-11-22 00:02:13 +0000167void
Enrico Granata33e97e62015-09-04 21:01:18 +0000168FormatManager::EnableAllCategories ()
169{
170 m_categories_map.EnableAllCategories ();
171 Mutex::Locker lang_locker(m_language_categories_mutex);
172 for (auto& iter : m_language_categories_map)
173 {
174 if (iter.second)
175 iter.second->Enable();
176 }
177}
178
179void
180FormatManager::DisableAllCategories ()
181{
182 m_categories_map.DisableAllCategories ();
183 Mutex::Locker lang_locker(m_language_categories_mutex);
184 for (auto& iter : m_language_categories_map)
185 {
186 if (iter.second)
187 iter.second->Disable();
188 }
189}
190
191void
Enrico Granatade61cec2013-11-22 00:02:13 +0000192FormatManager::GetPossibleMatches (ValueObject& valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000193 CompilerType compiler_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000194 uint32_t reason,
195 lldb::DynamicValueType use_dynamic,
196 FormattersMatchVector& entries,
197 bool did_strip_ptr,
198 bool did_strip_ref,
199 bool did_strip_typedef,
200 bool root_level)
201{
Enrico Granatac6bf2e22015-09-23 01:39:46 +0000202 compiler_type = compiler_type.GetTypeForFormatters();
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000203 ConstString type_name(compiler_type.GetConstTypeName());
Enrico Granatade61cec2013-11-22 00:02:13 +0000204 if (valobj.GetBitfieldBitSize() > 0)
205 {
206 StreamString sstring;
207 sstring.Printf("%s:%d",type_name.AsCString(),valobj.GetBitfieldBitSize());
208 ConstString bitfieldname = ConstString(sstring.GetData());
209 entries.push_back({bitfieldname,0,did_strip_ptr,did_strip_ref,did_strip_typedef});
210 reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
211 }
212 entries.push_back({type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000213
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000214 ConstString display_type_name(compiler_type.GetDisplayTypeName());
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000215 if (display_type_name != type_name)
216 entries.push_back({display_type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
217
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000218 for (bool is_rvalue_ref = true, j = true; j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false)
Enrico Granatade61cec2013-11-22 00:02:13 +0000219 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000220 CompilerType non_ref_type = compiler_type.GetNonReferenceType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000221 GetPossibleMatches(valobj,
222 non_ref_type,
223 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
224 use_dynamic,
225 entries,
226 did_strip_ptr,
227 true,
228 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000229 if (non_ref_type.IsTypedefType())
230 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000231 CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
Greg Clayton56939cb2015-09-17 22:23:34 +0000232 deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000233 GetPossibleMatches(valobj,
234 deffed_referenced_type,
235 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
236 use_dynamic,
237 entries,
238 did_strip_ptr,
239 did_strip_ref,
240 true); // this is not exactly the usual meaning of stripping typedefs
241 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000242 }
Enrico Granata1ac62962014-04-10 00:14:07 +0000243
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000244 if (compiler_type.IsPointerType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000245 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000246 CompilerType non_ptr_type = compiler_type.GetPointeeType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000247 GetPossibleMatches(valobj,
248 non_ptr_type,
249 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
250 use_dynamic,
251 entries,
252 true,
253 did_strip_ref,
254 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000255 if (non_ptr_type.IsTypedefType())
256 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000257 CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000258 GetPossibleMatches(valobj,
259 deffed_pointed_type,
260 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
261 use_dynamic,
262 entries,
263 did_strip_ptr,
264 did_strip_ref,
265 true); // this is not exactly the usual meaning of stripping typedefs
266 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000267 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000268
Enrico Granatad3233c12015-09-09 01:10:46 +0000269 for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
Enrico Granatade61cec2013-11-22 00:02:13 +0000270 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000271 if (Language* language = Language::FindPlugin(language_type))
Enrico Granatade61cec2013-11-22 00:02:13 +0000272 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000273 for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
Enrico Granatade61cec2013-11-22 00:02:13 +0000274 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000275 entries.push_back({candidate,
276 reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
277 did_strip_ptr,
278 did_strip_ref,
279 did_strip_typedef});
280 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000281 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000282 }
Enrico Granatad3233c12015-09-09 01:10:46 +0000283
Enrico Granatade61cec2013-11-22 00:02:13 +0000284 // try to strip typedef chains
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000285 if (compiler_type.IsTypedefType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000286 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000287 CompilerType deffed_type = compiler_type.GetTypedefedType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000288 GetPossibleMatches(valobj,
289 deffed_type,
290 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
291 use_dynamic,
292 entries,
293 did_strip_ptr,
294 did_strip_ref,
295 true);
296 }
297
298 if (root_level)
299 {
300 do {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000301 if (!compiler_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000302 break;
303
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000304 CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType();
305 if (!unqual_compiler_ast_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000306 break;
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000307 if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000308 GetPossibleMatches (valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000309 unqual_compiler_ast_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000310 reason,
311 use_dynamic,
312 entries,
313 did_strip_ptr,
314 did_strip_ref,
315 did_strip_typedef);
316 } while(false);
317
318
319 // if all else fails, go to static type
320 if (valobj.IsDynamic())
321 {
322 lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
323 if (static_value_sp)
324 GetPossibleMatches(*static_value_sp.get(),
Greg Clayton99558cc42015-08-24 23:46:31 +0000325 static_value_sp->GetCompilerType(),
Enrico Granatade61cec2013-11-22 00:02:13 +0000326 reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
327 use_dynamic,
328 entries,
329 did_strip_ptr,
330 did_strip_ref,
331 did_strip_typedef,
332 true);
333 }
334 }
335}
336
Enrico Granata852cc952013-10-08 19:03:22 +0000337lldb::TypeFormatImplSP
338FormatManager::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
339{
340 if (!type_sp)
341 return lldb::TypeFormatImplSP();
342 lldb::TypeFormatImplSP format_chosen_sp;
343 uint32_t num_categories = m_categories_map.GetCount();
344 lldb::TypeCategoryImplSP category_sp;
345 uint32_t prio_category = UINT32_MAX;
346 for (uint32_t category_id = 0;
347 category_id < num_categories;
348 category_id++)
349 {
350 category_sp = GetCategoryAtIndex(category_id);
351 if (category_sp->IsEnabled() == false)
352 continue;
353 lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp);
354 if (format_current_sp && (format_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
355 {
356 prio_category = category_sp->GetEnabledPosition();
357 format_chosen_sp = format_current_sp;
358 }
359 }
360 return format_chosen_sp;
361}
362
Enrico Granataa777dc22012-05-08 21:49:57 +0000363lldb::TypeSummaryImplSP
364FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
365{
366 if (!type_sp)
367 return lldb::TypeSummaryImplSP();
368 lldb::TypeSummaryImplSP summary_chosen_sp;
369 uint32_t num_categories = m_categories_map.GetCount();
370 lldb::TypeCategoryImplSP category_sp;
371 uint32_t prio_category = UINT32_MAX;
372 for (uint32_t category_id = 0;
373 category_id < num_categories;
374 category_id++)
375 {
376 category_sp = GetCategoryAtIndex(category_id);
377 if (category_sp->IsEnabled() == false)
378 continue;
379 lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
380 if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
381 {
382 prio_category = category_sp->GetEnabledPosition();
383 summary_chosen_sp = summary_current_sp;
384 }
385 }
386 return summary_chosen_sp;
387}
388
389lldb::TypeFilterImplSP
390FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
391{
392 if (!type_sp)
393 return lldb::TypeFilterImplSP();
394 lldb::TypeFilterImplSP filter_chosen_sp;
395 uint32_t num_categories = m_categories_map.GetCount();
396 lldb::TypeCategoryImplSP category_sp;
397 uint32_t prio_category = UINT32_MAX;
398 for (uint32_t category_id = 0;
399 category_id < num_categories;
400 category_id++)
401 {
402 category_sp = GetCategoryAtIndex(category_id);
403 if (category_sp->IsEnabled() == false)
404 continue;
405 lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
406 if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
407 {
408 prio_category = category_sp->GetEnabledPosition();
409 filter_chosen_sp = filter_current_sp;
410 }
411 }
412 return filter_chosen_sp;
413}
414
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000415#ifndef LLDB_DISABLE_PYTHON
Enrico Granata5548cb52013-01-28 23:47:25 +0000416lldb::ScriptedSyntheticChildrenSP
Enrico Granataa777dc22012-05-08 21:49:57 +0000417FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
418{
419 if (!type_sp)
Enrico Granata5548cb52013-01-28 23:47:25 +0000420 return lldb::ScriptedSyntheticChildrenSP();
421 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
Enrico Granataa777dc22012-05-08 21:49:57 +0000422 uint32_t num_categories = m_categories_map.GetCount();
423 lldb::TypeCategoryImplSP category_sp;
424 uint32_t prio_category = UINT32_MAX;
425 for (uint32_t category_id = 0;
426 category_id < num_categories;
427 category_id++)
428 {
429 category_sp = GetCategoryAtIndex(category_id);
430 if (category_sp->IsEnabled() == false)
431 continue;
Enrico Granata5548cb52013-01-28 23:47:25 +0000432 lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
Enrico Granataa777dc22012-05-08 21:49:57 +0000433 if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
434 {
435 prio_category = category_sp->GetEnabledPosition();
436 synth_chosen_sp = synth_current_sp;
437 }
438 }
439 return synth_chosen_sp;
440}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000441#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000442
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000443#ifndef LLDB_DISABLE_PYTHON
Enrico Granataa777dc22012-05-08 21:49:57 +0000444lldb::SyntheticChildrenSP
445FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
446{
447 if (!type_sp)
448 return lldb::SyntheticChildrenSP();
449 lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
Enrico Granata5548cb52013-01-28 23:47:25 +0000450 lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
Enrico Granataa777dc22012-05-08 21:49:57 +0000451 if (filter_sp->GetRevision() > synth_sp->GetRevision())
452 return lldb::SyntheticChildrenSP(filter_sp.get());
453 else
454 return lldb::SyntheticChildrenSP(synth_sp.get());
455}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000456#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000457
Enrico Granatac5827132014-09-05 20:45:07 +0000458lldb::TypeValidatorImplSP
459FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
460{
461 if (!type_sp)
462 return lldb::TypeValidatorImplSP();
463 lldb::TypeValidatorImplSP validator_chosen_sp;
464 uint32_t num_categories = m_categories_map.GetCount();
465 lldb::TypeCategoryImplSP category_sp;
466 uint32_t prio_category = UINT32_MAX;
467 for (uint32_t category_id = 0;
468 category_id < num_categories;
469 category_id++)
470 {
471 category_sp = GetCategoryAtIndex(category_id);
472 if (category_sp->IsEnabled() == false)
473 continue;
474 lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
475 if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
476 {
477 prio_category = category_sp->GetEnabledPosition();
478 validator_chosen_sp = validator_current_sp;
479 }
480 }
481 return validator_chosen_sp;
482}
483
Enrico Granata980c0482015-09-01 18:22:39 +0000484void
485FormatManager::LoopThroughCategories (CategoryCallback callback, void* param)
486{
487 m_categories_map.LoopThrough(callback, param);
488 Mutex::Locker locker(m_language_categories_mutex);
489 for (const auto& entry : m_language_categories_map)
490 {
491 if (auto category_sp = entry.second->GetCategory())
492 {
493 if (!callback(param, category_sp))
494 break;
495 }
496 }
497}
498
Enrico Granata061858c2012-02-15 02:34:21 +0000499lldb::TypeCategoryImplSP
Enrico Granata9128ee22011-09-06 19:20:51 +0000500FormatManager::GetCategory (const ConstString& category_name,
Enrico Granatadb595cd2015-03-06 19:37:57 +0000501 bool can_create)
Enrico Granatadc940732011-08-23 00:32:52 +0000502{
503 if (!category_name)
Enrico Granata9128ee22011-09-06 19:20:51 +0000504 return GetCategory(m_default_category_name);
Enrico Granata061858c2012-02-15 02:34:21 +0000505 lldb::TypeCategoryImplSP category;
Enrico Granatadc940732011-08-23 00:32:52 +0000506 if (m_categories_map.Get(category_name, category))
507 return category;
508
509 if (!can_create)
Enrico Granata061858c2012-02-15 02:34:21 +0000510 return lldb::TypeCategoryImplSP();
Enrico Granatadc940732011-08-23 00:32:52 +0000511
Enrico Granata061858c2012-02-15 02:34:21 +0000512 m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
Enrico Granata9128ee22011-09-06 19:20:51 +0000513 return GetCategory(category_name);
Enrico Granatadc940732011-08-23 00:32:52 +0000514}
515
Enrico Granataf4efecd2011-07-12 22:56:10 +0000516lldb::Format
517FormatManager::GetSingleItemFormat(lldb::Format vector_format)
518{
519 switch(vector_format)
520 {
521 case eFormatVectorOfChar:
522 return eFormatCharArray;
523
524 case eFormatVectorOfSInt8:
525 case eFormatVectorOfSInt16:
526 case eFormatVectorOfSInt32:
527 case eFormatVectorOfSInt64:
528 return eFormatDecimal;
529
530 case eFormatVectorOfUInt8:
531 case eFormatVectorOfUInt16:
532 case eFormatVectorOfUInt32:
533 case eFormatVectorOfUInt64:
534 case eFormatVectorOfUInt128:
535 return eFormatHex;
536
537 case eFormatVectorOfFloat32:
538 case eFormatVectorOfFloat64:
539 return eFormatFloat;
540
541 default:
542 return lldb::eFormatInvalid;
543 }
Greg Clayton3418c852011-08-10 02:10:13 +0000544}
Enrico Granatac482a192011-08-17 22:13:59 +0000545
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000546bool
547FormatManager::ShouldPrintAsOneLiner (ValueObject& valobj)
548{
Enrico Granata553fad52013-10-25 23:09:40 +0000549 // if settings say no oneline whatsoever
Enrico Granata90a8db32013-10-31 21:01:07 +0000550 if (valobj.GetTargetSP().get() && valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
Enrico Granata553fad52013-10-25 23:09:40 +0000551 return false; // then don't oneline
552
Enrico Granata42fa4af2014-09-11 23:00:27 +0000553 // if this object has a summary, then ask the summary
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000554 if (valobj.GetSummaryFormat().get() != nullptr)
Enrico Granata42fa4af2014-09-11 23:00:27 +0000555 return valobj.GetSummaryFormat()->IsOneLiner();
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000556
557 // no children, no party
558 if (valobj.GetNumChildren() == 0)
559 return false;
560
Enrico Granata9c63f992015-09-23 02:04:34 +0000561 // ask the type if it has any opinion about this
562 // eLazyBoolCalculate == no opinion; other values should be self explanatory
563 CompilerType compiler_type(valobj.GetCompilerType());
564 if (compiler_type.IsValid())
565 {
566 switch (compiler_type.ShouldPrintAsOneLiner())
567 {
568 case eLazyBoolNo:
569 return false;
570 case eLazyBoolYes:
571 return true;
572 case eLazyBoolCalculate:
Enrico Granata9c63f992015-09-23 02:04:34 +0000573 break;
574 }
575 }
576
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000577 size_t total_children_name_len = 0;
578
579 for (size_t idx = 0;
580 idx < valobj.GetNumChildren();
581 idx++)
582 {
Enrico Granataddac7612014-10-09 18:47:36 +0000583 bool is_synth_val = false;
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000584 ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
585 // something is wrong here - bail out
586 if (!child_sp)
587 return false;
588 // if we decided to define synthetic children for a type, we probably care enough
589 // to show them, but avoid nesting children in children
590 if (child_sp->GetSyntheticChildren().get() != nullptr)
Enrico Granataddac7612014-10-09 18:47:36 +0000591 {
592 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
593 // wait.. wat? just get out of here..
594 if (!synth_sp)
595 return false;
596 // but if we only have them to provide a value, keep going
597 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
598 is_synth_val = true;
599 else
600 return false;
601 }
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000602
603 total_children_name_len += child_sp->GetName().GetLength();
604
605 // 50 itself is a "randomly" chosen number - the idea is that
606 // overly long structs should not get this treatment
607 // FIXME: maybe make this a user-tweakable setting?
608 if (total_children_name_len > 50)
609 return false;
610
611 // if a summary is there..
612 if (child_sp->GetSummaryFormat())
613 {
614 // and it wants children, then bail out
Enrico Granata8a068e62014-04-23 23:16:25 +0000615 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000616 return false;
617 }
618
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000619 // if this child has children..
620 if (child_sp->GetNumChildren())
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000621 {
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000622 // ...and no summary...
623 // (if it had a summary and the summary wanted children, we would have bailed out anyway
624 // so this only makes us bail out if this has no summary and we would then print children)
Enrico Granataddac7612014-10-09 18:47:36 +0000625 if (!child_sp->GetSummaryFormat() && !is_synth_val) // but again only do that if not a synthetic valued child
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000626 return false; // then bail out
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000627 }
628 }
629 return true;
630}
631
Enrico Granata02b66762011-08-19 01:14:49 +0000632ConstString
633FormatManager::GetValidTypeName (const ConstString& type)
634{
635 return ::GetValidTypeName_Impl(type);
636}
637
Enrico Granata5548cb52013-01-28 23:47:25 +0000638ConstString
Enrico Granata980c0482015-09-01 18:22:39 +0000639FormatManager::GetTypeForCache (ValueObject& valobj,
640 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000641{
642 if (use_dynamic == lldb::eNoDynamicValues)
643 {
644 if (valobj.IsDynamic())
645 {
646 if (valobj.GetStaticValue())
647 return valobj.GetStaticValue()->GetQualifiedTypeName();
648 else
649 return ConstString();
650 }
651 else
652 return valobj.GetQualifiedTypeName();
653 }
654 if (valobj.IsDynamic())
655 return valobj.GetQualifiedTypeName();
656 if (valobj.GetDynamicValue(use_dynamic))
657 return valobj.GetDynamicValue(use_dynamic)->GetQualifiedTypeName();
658 return ConstString();
659}
660
Enrico Granatad3233c12015-09-09 01:10:46 +0000661std::vector<lldb::LanguageType>
662FormatManager::GetCandidateLanguages (ValueObject& valobj)
Enrico Granata980c0482015-09-01 18:22:39 +0000663{
664 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
Enrico Granataac494532015-09-09 22:30:24 +0000665 return GetCandidateLanguages(lang_type);
666}
667
668std::vector<lldb::LanguageType>
669FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
670{
Enrico Granata980c0482015-09-01 18:22:39 +0000671 switch (lang_type)
672 {
Enrico Granata33e97e62015-09-04 21:01:18 +0000673 case lldb::eLanguageTypeC:
674 case lldb::eLanguageTypeC89:
675 case lldb::eLanguageTypeC99:
676 case lldb::eLanguageTypeC11:
677 case lldb::eLanguageTypeC_plus_plus:
678 case lldb::eLanguageTypeC_plus_plus_03:
679 case lldb::eLanguageTypeC_plus_plus_11:
680 case lldb::eLanguageTypeC_plus_plus_14:
Enrico Granata170c3952015-09-14 22:18:32 +0000681 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
Enrico Granata980c0482015-09-01 18:22:39 +0000682 default:
683 return {lang_type};
684 }
685}
686
687LanguageCategory*
688FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
689{
690 Mutex::Locker locker(m_language_categories_mutex);
691 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
692 if (iter != end)
693 return iter->second.get();
694 LanguageCategory* lang_category = new LanguageCategory(lang_type);
695 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
696 return lang_category;
697}
698
Enrico Granataecd02bc2014-08-19 18:47:58 +0000699lldb::TypeFormatImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000700FormatManager::GetHardcodedFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000701{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000702 TypeFormatImplSP retval_sp;
703
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000704 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000705 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000706 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
707 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000708 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000709 break;
710 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000711 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000712
713 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000714}
715
Enrico Granata852cc952013-10-08 19:03:22 +0000716lldb::TypeFormatImplSP
717FormatManager::GetFormat (ValueObject& valobj,
718 lldb::DynamicValueType use_dynamic)
719{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000720 FormattersMatchData match_data(valobj, use_dynamic);
721
Enrico Granata852cc952013-10-08 19:03:22 +0000722 TypeFormatImplSP retval;
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000723 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000724 if (match_data.GetTypeForCache())
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000725 {
726 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000727 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
728 if (m_format_cache.GetFormat(match_data.GetTypeForCache(),retval))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000729 {
730 if (log)
731 {
732 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
733 if (log->GetDebug())
734 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
735 }
736 return retval;
737 }
738 if (log)
739 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
740 }
Enrico Granata980c0482015-09-01 18:22:39 +0000741
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000742 retval = m_categories_map.GetFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000743 if (!retval)
744 {
745 if (log)
746 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000747 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000748 {
749 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
750 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000751 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000752 break;
753 }
754 }
755 if (retval)
756 {
757 if (log)
758 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
759 return retval;
760 }
761 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000762 if (!retval)
763 {
764 if (log)
765 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000766 retval = GetHardcodedFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000767 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000768
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000769 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000770 {
771 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000772 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
773 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000774 match_data.GetTypeForCache().AsCString("<invalid>"));
775 m_format_cache.SetFormat(match_data.GetTypeForCache(),retval);
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000776 }
777 if (log && log->GetDebug())
778 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
Enrico Granata852cc952013-10-08 19:03:22 +0000779 return retval;
780}
781
Enrico Granataecd02bc2014-08-19 18:47:58 +0000782lldb::TypeSummaryImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000783FormatManager::GetHardcodedSummaryFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000784{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000785 TypeSummaryImplSP retval_sp;
786
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000787 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000788 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000789 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
790 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000791 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000792 break;
793 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000794 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000795
796 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000797}
798
Enrico Granata5548cb52013-01-28 23:47:25 +0000799lldb::TypeSummaryImplSP
800FormatManager::GetSummaryFormat (ValueObject& valobj,
801 lldb::DynamicValueType use_dynamic)
802{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000803 FormattersMatchData match_data(valobj, use_dynamic);
804
Enrico Granata5548cb52013-01-28 23:47:25 +0000805 TypeSummaryImplSP retval;
Greg Clayton5160ce52013-03-27 23:08:40 +0000806 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000807 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000808 {
809 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000810 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
811 if (m_format_cache.GetSummary(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000812 {
813 if (log)
814 {
815 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000816 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000817 log->Printf("[FormatManager::GetSummaryFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
Enrico Granata68ae4112013-06-18 18:23:07 +0000818 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000819 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000820 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000821 if (log)
822 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
823 }
Enrico Granata980c0482015-09-01 18:22:39 +0000824
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000825 retval = m_categories_map.GetSummaryFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000826 if (!retval)
827 {
828 if (log)
829 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000830 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000831 {
832 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
833 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000834 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000835 break;
836 }
837 }
838 if (retval)
839 {
840 if (log)
841 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
842 return retval;
843 }
844 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000845 if (!retval)
846 {
847 if (log)
848 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000849 retval = GetHardcodedSummaryFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000850 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000851
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000852 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000853 {
854 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000855 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
856 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000857 match_data.GetTypeForCache().AsCString("<invalid>"));
858 m_format_cache.SetSummary(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000859 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000860 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000861 log->Printf("[FormatManager::GetSummaryFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
Enrico Granata5548cb52013-01-28 23:47:25 +0000862 return retval;
863}
864
865#ifndef LLDB_DISABLE_PYTHON
Enrico Granataecd02bc2014-08-19 18:47:58 +0000866lldb::SyntheticChildrenSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000867FormatManager::GetHardcodedSyntheticChildren (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000868{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000869 SyntheticChildrenSP retval_sp;
870
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000871 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000872 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000873 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
874 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000875 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000876 break;
877 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000878 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000879
880 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000881}
882
Enrico Granata5548cb52013-01-28 23:47:25 +0000883lldb::SyntheticChildrenSP
884FormatManager::GetSyntheticChildren (ValueObject& valobj,
Enrico Granatac2a96402013-06-26 01:03:38 +0000885 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000886{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000887 FormattersMatchData match_data(valobj, use_dynamic);
888
Enrico Granata5548cb52013-01-28 23:47:25 +0000889 SyntheticChildrenSP retval;
Greg Clayton5160ce52013-03-27 23:08:40 +0000890 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000891 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000892 {
893 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000894 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
895 if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000896 {
897 if (log)
898 {
899 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000900 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000901 log->Printf("[FormatManager::GetSyntheticChildren] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
Enrico Granata68ae4112013-06-18 18:23:07 +0000902 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000903 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000904 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000905 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000906 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
Enrico Granata5548cb52013-01-28 23:47:25 +0000907 }
Enrico Granata980c0482015-09-01 18:22:39 +0000908
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000909 retval = m_categories_map.GetSyntheticChildren(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000910 if (!retval)
911 {
912 if (log)
913 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000914 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000915 {
916 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
917 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000918 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000919 break;
920 }
921 }
922 if (retval)
923 {
924 if (log)
925 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
926 return retval;
927 }
928 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000929 if (!retval)
930 {
931 if (log)
932 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000933 retval = GetHardcodedSyntheticChildren(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000934 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000935
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000936 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000937 {
938 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000939 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
940 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000941 match_data.GetTypeForCache().AsCString("<invalid>"));
942 m_format_cache.SetSynthetic(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000943 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000944 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000945 log->Printf("[FormatManager::GetSyntheticChildren] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
Enrico Granata5548cb52013-01-28 23:47:25 +0000946 return retval;
947}
948#endif
Enrico Granata5548cb52013-01-28 23:47:25 +0000949
Enrico Granatac5827132014-09-05 20:45:07 +0000950lldb::TypeValidatorImplSP
951FormatManager::GetValidator (ValueObject& valobj,
952 lldb::DynamicValueType use_dynamic)
953{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000954 FormattersMatchData match_data(valobj, use_dynamic);
955
Enrico Granatac5827132014-09-05 20:45:07 +0000956 TypeValidatorImplSP retval;
957 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000958 if (match_data.GetTypeForCache())
Enrico Granatac5827132014-09-05 20:45:07 +0000959 {
960 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000961 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
962 if (m_format_cache.GetValidator(match_data.GetTypeForCache(),retval))
Enrico Granatac5827132014-09-05 20:45:07 +0000963 {
964 if (log)
965 {
966 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
967 if (log->GetDebug())
968 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
969 }
970 return retval;
971 }
972 if (log)
973 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
974 }
Enrico Granata980c0482015-09-01 18:22:39 +0000975
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000976 retval = m_categories_map.GetValidator(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000977 if (!retval)
978 {
979 if (log)
980 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000981 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000982 {
983 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
984 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000985 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000986 break;
987 }
988 }
989 if (retval)
990 {
991 if (log)
992 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
993 return retval;
994 }
995 }
Enrico Granatac5827132014-09-05 20:45:07 +0000996 if (!retval)
997 {
998 if (log)
999 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001000 retval = GetHardcodedValidator(match_data);
Enrico Granatac5827132014-09-05 20:45:07 +00001001 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +00001002
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001003 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granatac5827132014-09-05 20:45:07 +00001004 {
1005 if (log)
1006 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
1007 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001008 match_data.GetTypeForCache().AsCString("<invalid>"));
1009 m_format_cache.SetValidator(match_data.GetTypeForCache(),retval);
Enrico Granatac5827132014-09-05 20:45:07 +00001010 }
1011 if (log && log->GetDebug())
1012 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1013 return retval;
1014}
1015
1016lldb::TypeValidatorImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001017FormatManager::GetHardcodedValidator (FormattersMatchData& match_data)
Enrico Granatac5827132014-09-05 20:45:07 +00001018{
Enrico Granata7cb59e12015-09-16 18:28:11 +00001019 TypeValidatorImplSP retval_sp;
1020
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001021 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granatac5827132014-09-05 20:45:07 +00001022 {
Enrico Granata7cb59e12015-09-16 18:28:11 +00001023 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1024 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001025 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +00001026 break;
1027 }
Enrico Granatac5827132014-09-05 20:45:07 +00001028 }
Enrico Granata7cb59e12015-09-16 18:28:11 +00001029
1030 return retval_sp;
Enrico Granatac5827132014-09-05 20:45:07 +00001031}
1032
Enrico Granata5548cb52013-01-28 23:47:25 +00001033FormatManager::FormatManager() :
1034 m_format_cache(),
Enrico Granatac482a192011-08-17 22:13:59 +00001035 m_named_summaries_map(this),
1036 m_last_revision(0),
1037 m_categories_map(this),
Enrico Granata980c0482015-09-01 18:22:39 +00001038 m_language_categories_map(),
1039 m_language_categories_mutex(Mutex::eMutexTypeRecursive),
Enrico Granata1d887492011-08-22 18:36:52 +00001040 m_default_category_name(ConstString("default")),
1041 m_system_category_name(ConstString("system")),
Enrico Granata7cb59e12015-09-16 18:28:11 +00001042 m_vectortypes_category_name(ConstString("VectorTypes"))
Enrico Granatac482a192011-08-17 22:13:59 +00001043{
Enrico Granata864e3e82012-02-17 03:18:30 +00001044 LoadSystemFormatters();
Enrico Granata170c3952015-09-14 22:18:32 +00001045 LoadVectorFormatters();
Enrico Granata864e3e82012-02-17 03:18:30 +00001046
Enrico Granatafa6b2782015-09-17 00:14:50 +00001047 EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1048 EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
Enrico Granata864e3e82012-02-17 03:18:30 +00001049}
1050
1051void
Enrico Granata864e3e82012-02-17 03:18:30 +00001052FormatManager::LoadSystemFormatters()
1053{
Enrico Granataf68df122013-01-10 22:08:35 +00001054
1055 TypeSummaryImpl::Flags string_flags;
Enrico Granata0337c272013-02-22 00:37:31 +00001056 string_flags.SetCascades(true)
Enrico Granataf68df122013-01-10 22:08:35 +00001057 .SetSkipPointers(true)
1058 .SetSkipReferences(false)
1059 .SetDontShowChildren(true)
1060 .SetDontShowValue(false)
1061 .SetShowMembersOneLiner(false)
1062 .SetHideItemNames(false);
1063
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001064 TypeSummaryImpl::Flags string_array_flags;
Enrico Granatad2911632015-07-28 02:13:03 +00001065 string_array_flags.SetCascades(true)
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001066 .SetSkipPointers(true)
1067 .SetSkipReferences(false)
1068 .SetDontShowChildren(true)
1069 .SetDontShowValue(true)
1070 .SetShowMembersOneLiner(false)
1071 .SetHideItemNames(false);
1072
Enrico Granataf68df122013-01-10 22:08:35 +00001073 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001074
1075
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001076 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
Enrico Granata061858c2012-02-15 02:34:21 +00001077 "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001078
1079 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001080 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
Enrico Granatac482a192011-08-17 22:13:59 +00001081
Enrico Granata061858c2012-02-15 02:34:21 +00001082 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
Enrico Granatac482a192011-08-17 22:13:59 +00001083
Enrico Granatab72a5012013-12-20 09:38:13 +00001084 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1085 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1086 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
Enrico Granataaff65652013-10-21 17:29:51 +00001087
Enrico Granata4ed7ef12012-07-13 18:54:40 +00001088 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1089 .SetSkipPointers(true)
1090 .SetSkipReferences(true)
1091 .SetDontShowChildren(true)
1092 .SetDontShowValue(false)
1093 .SetShowMembersOneLiner(false)
1094 .SetHideItemNames(false),
1095 "${var%O}"));
1096
Enrico Granatab72a5012013-12-20 09:38:13 +00001097 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
Enrico Granatad3d444f2012-02-23 23:10:03 +00001098
Jason Molenda1a100cd2013-01-12 04:24:50 +00001099#ifndef LLDB_DISABLE_PYTHON
Enrico Granata4cc21772013-10-08 20:59:02 +00001100 TypeFormatImpl::Flags fourchar_flags;
1101 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1102
1103 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
Jason Molenda1a100cd2013-01-12 04:24:50 +00001104#endif
Enrico Granatad3d444f2012-02-23 23:10:03 +00001105}
Enrico Granatab2698cd2012-09-13 18:27:09 +00001106
Enrico Granata864e3e82012-02-17 03:18:30 +00001107void
Enrico Granata170c3952015-09-14 22:18:32 +00001108FormatManager::LoadVectorFormatters()
Enrico Granata864e3e82012-02-17 03:18:30 +00001109{
Enrico Granata864e3e82012-02-17 03:18:30 +00001110 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
Enrico Granata170c3952015-09-14 22:18:32 +00001111
Enrico Granata864e3e82012-02-17 03:18:30 +00001112 TypeSummaryImpl::Flags vector_flags;
1113 vector_flags.SetCascades(true)
1114 .SetSkipPointers(true)
1115 .SetSkipReferences(false)
1116 .SetDontShowChildren(true)
1117 .SetDontShowValue(false)
1118 .SetShowMembersOneLiner(true)
1119 .SetHideItemNames(true);
1120
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001121 AddStringSummary(vectors_category_sp,
1122 "${var.uint128}",
1123 ConstString("builtin_type_vec128"),
Enrico Granata170c3952015-09-14 22:18:32 +00001124 vector_flags);
1125
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001126 AddStringSummary(vectors_category_sp,
1127 "",
1128 ConstString("float [4]"),
1129 vector_flags);
1130 AddStringSummary(vectors_category_sp,
1131 "",
1132 ConstString("int32_t [4]"),
1133 vector_flags);
1134 AddStringSummary(vectors_category_sp,
1135 "",
1136 ConstString("int16_t [8]"),
1137 vector_flags);
1138 AddStringSummary(vectors_category_sp,
1139 "",
1140 ConstString("vDouble"),
1141 vector_flags);
1142 AddStringSummary(vectors_category_sp,
1143 "",
1144 ConstString("vFloat"),
1145 vector_flags);
1146 AddStringSummary(vectors_category_sp,
1147 "",
1148 ConstString("vSInt8"),
1149 vector_flags);
1150 AddStringSummary(vectors_category_sp,
1151 "",
1152 ConstString("vSInt16"),
1153 vector_flags);
1154 AddStringSummary(vectors_category_sp,
1155 "",
1156 ConstString("vSInt32"),
1157 vector_flags);
1158 AddStringSummary(vectors_category_sp,
1159 "",
1160 ConstString("vUInt16"),
1161 vector_flags);
1162 AddStringSummary(vectors_category_sp,
1163 "",
1164 ConstString("vUInt8"),
1165 vector_flags);
1166 AddStringSummary(vectors_category_sp,
1167 "",
1168 ConstString("vUInt16"),
1169 vector_flags);
1170 AddStringSummary(vectors_category_sp,
1171 "",
1172 ConstString("vUInt32"),
1173 vector_flags);
1174 AddStringSummary(vectors_category_sp,
1175 "",
1176 ConstString("vBool32"),
1177 vector_flags);
Greg Claytond4e25522011-10-12 00:53:29 +00001178}