blob: 2362ba525268e4b51b7a365690651bbb159616e9 [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
Enrico Granatad717cc92015-10-20 04:50:09 +000012#include "llvm/ADT/STLExtras.h"
13
Greg Clayton4a33d312011-06-23 17:59:56 +000014// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18
Enrico Granataf2bbf712011-07-15 02:26:42 +000019#include "lldb/Core/Debugger.h"
Enrico Granatad717cc92015-10-20 04:50:09 +000020#include "lldb/Core/Log.h"
Enrico Granatadf7e79e2015-09-02 01:21:31 +000021#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granata980c0482015-09-01 18:22:39 +000022#include "lldb/DataFormatters/LanguageCategory.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000023#include "lldb/Target/ExecutionContext.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000024#include "lldb/Target/Language.h"
Enrico Granata980c0482015-09-01 18:22:39 +000025
Greg Clayton4a33d312011-06-23 17:59:56 +000026using namespace lldb;
27using namespace lldb_private;
Enrico Granatadf7e79e2015-09-02 01:21:31 +000028using namespace lldb_private::formatters;
Greg Claytonbb7f31f2011-06-23 21:22:24 +000029
30struct FormatInfo
31{
32 Format format;
33 const char format_char; // One or more format characters that can be used for this format.
34 const char *format_name; // Long format name that can be used to specify the current format
35};
36
37static FormatInfo
38g_format_infos[] =
39{
40 { eFormatDefault , '\0' , "default" },
41 { eFormatBoolean , 'B' , "boolean" },
42 { eFormatBinary , 'b' , "binary" },
43 { eFormatBytes , 'y' , "bytes" },
44 { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
45 { eFormatChar , 'c' , "character" },
46 { eFormatCharPrintable , 'C' , "printable character" },
47 { eFormatComplexFloat , 'F' , "complex float" },
48 { eFormatCString , 's' , "c-string" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000049 { eFormatDecimal , 'd' , "decimal" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000050 { eFormatEnum , 'E' , "enumeration" },
51 { eFormatHex , 'x' , "hex" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000052 { eFormatHexUppercase , 'X' , "uppercase hex" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000053 { eFormatFloat , 'f' , "float" },
54 { eFormatOctal , 'o' , "octal" },
55 { eFormatOSType , 'O' , "OSType" },
56 { eFormatUnicode16 , 'U' , "unicode16" },
57 { eFormatUnicode32 , '\0' , "unicode32" },
58 { eFormatUnsigned , 'u' , "unsigned decimal" },
59 { eFormatPointer , 'p' , "pointer" },
60 { eFormatVectorOfChar , '\0' , "char[]" },
61 { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
62 { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
63 { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
64 { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
Enrico Granatae443ba72011-07-06 15:56:06 +000065 { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
66 { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
67 { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
68 { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
Ewan Crawforda0f08672015-10-16 08:28:47 +000069 { eFormatVectorOfFloat16, '\0' , "float16[]" },
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 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000212
Enrico Granatab3f0c342015-10-20 00:13:19 +0000213 if (!compiler_type.IsMeaninglessWithoutDynamicResolution())
214 {
215 entries.push_back({type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
216
217 ConstString display_type_name(compiler_type.GetDisplayTypeName());
218 if (display_type_name != type_name)
219 entries.push_back({display_type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
220 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000221
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000222 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 +0000223 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000224 CompilerType non_ref_type = compiler_type.GetNonReferenceType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000225 GetPossibleMatches(valobj,
226 non_ref_type,
227 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
228 use_dynamic,
229 entries,
230 did_strip_ptr,
231 true,
232 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000233 if (non_ref_type.IsTypedefType())
234 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000235 CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
Greg Clayton56939cb2015-09-17 22:23:34 +0000236 deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000237 GetPossibleMatches(valobj,
238 deffed_referenced_type,
239 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
240 use_dynamic,
241 entries,
242 did_strip_ptr,
243 did_strip_ref,
244 true); // this is not exactly the usual meaning of stripping typedefs
245 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000246 }
Enrico Granata1ac62962014-04-10 00:14:07 +0000247
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000248 if (compiler_type.IsPointerType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000249 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000250 CompilerType non_ptr_type = compiler_type.GetPointeeType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000251 GetPossibleMatches(valobj,
252 non_ptr_type,
253 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
254 use_dynamic,
255 entries,
256 true,
257 did_strip_ref,
258 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000259 if (non_ptr_type.IsTypedefType())
260 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000261 CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000262 GetPossibleMatches(valobj,
263 deffed_pointed_type,
264 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
265 use_dynamic,
266 entries,
267 did_strip_ptr,
268 did_strip_ref,
269 true); // this is not exactly the usual meaning of stripping typedefs
270 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000271 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000272
Enrico Granatad3233c12015-09-09 01:10:46 +0000273 for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
Enrico Granatade61cec2013-11-22 00:02:13 +0000274 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000275 if (Language* language = Language::FindPlugin(language_type))
Enrico Granatade61cec2013-11-22 00:02:13 +0000276 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000277 for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
Enrico Granatade61cec2013-11-22 00:02:13 +0000278 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000279 entries.push_back({candidate,
280 reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
281 did_strip_ptr,
282 did_strip_ref,
283 did_strip_typedef});
284 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000285 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000286 }
Enrico Granatad3233c12015-09-09 01:10:46 +0000287
Enrico Granatade61cec2013-11-22 00:02:13 +0000288 // try to strip typedef chains
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000289 if (compiler_type.IsTypedefType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000290 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000291 CompilerType deffed_type = compiler_type.GetTypedefedType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000292 GetPossibleMatches(valobj,
293 deffed_type,
294 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
295 use_dynamic,
296 entries,
297 did_strip_ptr,
298 did_strip_ref,
299 true);
300 }
301
302 if (root_level)
303 {
304 do {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000305 if (!compiler_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000306 break;
307
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000308 CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType();
309 if (!unqual_compiler_ast_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000310 break;
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000311 if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000312 GetPossibleMatches (valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000313 unqual_compiler_ast_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000314 reason,
315 use_dynamic,
316 entries,
317 did_strip_ptr,
318 did_strip_ref,
319 did_strip_typedef);
320 } while(false);
321
322
323 // if all else fails, go to static type
324 if (valobj.IsDynamic())
325 {
326 lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
327 if (static_value_sp)
328 GetPossibleMatches(*static_value_sp.get(),
Greg Clayton99558cc42015-08-24 23:46:31 +0000329 static_value_sp->GetCompilerType(),
Enrico Granatade61cec2013-11-22 00:02:13 +0000330 reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
331 use_dynamic,
332 entries,
333 did_strip_ptr,
334 did_strip_ref,
335 did_strip_typedef,
336 true);
337 }
338 }
339}
340
Enrico Granata852cc952013-10-08 19:03:22 +0000341lldb::TypeFormatImplSP
342FormatManager::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
343{
344 if (!type_sp)
345 return lldb::TypeFormatImplSP();
346 lldb::TypeFormatImplSP format_chosen_sp;
347 uint32_t num_categories = m_categories_map.GetCount();
348 lldb::TypeCategoryImplSP category_sp;
349 uint32_t prio_category = UINT32_MAX;
350 for (uint32_t category_id = 0;
351 category_id < num_categories;
352 category_id++)
353 {
354 category_sp = GetCategoryAtIndex(category_id);
355 if (category_sp->IsEnabled() == false)
356 continue;
357 lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp);
358 if (format_current_sp && (format_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
359 {
360 prio_category = category_sp->GetEnabledPosition();
361 format_chosen_sp = format_current_sp;
362 }
363 }
364 return format_chosen_sp;
365}
366
Enrico Granataa777dc22012-05-08 21:49:57 +0000367lldb::TypeSummaryImplSP
368FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
369{
370 if (!type_sp)
371 return lldb::TypeSummaryImplSP();
372 lldb::TypeSummaryImplSP summary_chosen_sp;
373 uint32_t num_categories = m_categories_map.GetCount();
374 lldb::TypeCategoryImplSP category_sp;
375 uint32_t prio_category = UINT32_MAX;
376 for (uint32_t category_id = 0;
377 category_id < num_categories;
378 category_id++)
379 {
380 category_sp = GetCategoryAtIndex(category_id);
381 if (category_sp->IsEnabled() == false)
382 continue;
383 lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
384 if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
385 {
386 prio_category = category_sp->GetEnabledPosition();
387 summary_chosen_sp = summary_current_sp;
388 }
389 }
390 return summary_chosen_sp;
391}
392
393lldb::TypeFilterImplSP
394FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
395{
396 if (!type_sp)
397 return lldb::TypeFilterImplSP();
398 lldb::TypeFilterImplSP filter_chosen_sp;
399 uint32_t num_categories = m_categories_map.GetCount();
400 lldb::TypeCategoryImplSP category_sp;
401 uint32_t prio_category = UINT32_MAX;
402 for (uint32_t category_id = 0;
403 category_id < num_categories;
404 category_id++)
405 {
406 category_sp = GetCategoryAtIndex(category_id);
407 if (category_sp->IsEnabled() == false)
408 continue;
409 lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
410 if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
411 {
412 prio_category = category_sp->GetEnabledPosition();
413 filter_chosen_sp = filter_current_sp;
414 }
415 }
416 return filter_chosen_sp;
417}
418
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000419#ifndef LLDB_DISABLE_PYTHON
Enrico Granata5548cb52013-01-28 23:47:25 +0000420lldb::ScriptedSyntheticChildrenSP
Enrico Granataa777dc22012-05-08 21:49:57 +0000421FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
422{
423 if (!type_sp)
Enrico Granata5548cb52013-01-28 23:47:25 +0000424 return lldb::ScriptedSyntheticChildrenSP();
425 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
Enrico Granataa777dc22012-05-08 21:49:57 +0000426 uint32_t num_categories = m_categories_map.GetCount();
427 lldb::TypeCategoryImplSP category_sp;
428 uint32_t prio_category = UINT32_MAX;
429 for (uint32_t category_id = 0;
430 category_id < num_categories;
431 category_id++)
432 {
433 category_sp = GetCategoryAtIndex(category_id);
434 if (category_sp->IsEnabled() == false)
435 continue;
Enrico Granata5548cb52013-01-28 23:47:25 +0000436 lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
Enrico Granataa777dc22012-05-08 21:49:57 +0000437 if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
438 {
439 prio_category = category_sp->GetEnabledPosition();
440 synth_chosen_sp = synth_current_sp;
441 }
442 }
443 return synth_chosen_sp;
444}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000445#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000446
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000447#ifndef LLDB_DISABLE_PYTHON
Enrico Granataa777dc22012-05-08 21:49:57 +0000448lldb::SyntheticChildrenSP
449FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
450{
451 if (!type_sp)
452 return lldb::SyntheticChildrenSP();
453 lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
Enrico Granata5548cb52013-01-28 23:47:25 +0000454 lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
Enrico Granataa777dc22012-05-08 21:49:57 +0000455 if (filter_sp->GetRevision() > synth_sp->GetRevision())
456 return lldb::SyntheticChildrenSP(filter_sp.get());
457 else
458 return lldb::SyntheticChildrenSP(synth_sp.get());
459}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000460#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000461
Enrico Granatac5827132014-09-05 20:45:07 +0000462lldb::TypeValidatorImplSP
463FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
464{
465 if (!type_sp)
466 return lldb::TypeValidatorImplSP();
467 lldb::TypeValidatorImplSP validator_chosen_sp;
468 uint32_t num_categories = m_categories_map.GetCount();
469 lldb::TypeCategoryImplSP category_sp;
470 uint32_t prio_category = UINT32_MAX;
471 for (uint32_t category_id = 0;
472 category_id < num_categories;
473 category_id++)
474 {
475 category_sp = GetCategoryAtIndex(category_id);
476 if (category_sp->IsEnabled() == false)
477 continue;
478 lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
479 if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
480 {
481 prio_category = category_sp->GetEnabledPosition();
482 validator_chosen_sp = validator_current_sp;
483 }
484 }
485 return validator_chosen_sp;
486}
487
Enrico Granata980c0482015-09-01 18:22:39 +0000488void
489FormatManager::LoopThroughCategories (CategoryCallback callback, void* param)
490{
491 m_categories_map.LoopThrough(callback, param);
492 Mutex::Locker locker(m_language_categories_mutex);
493 for (const auto& entry : m_language_categories_map)
494 {
495 if (auto category_sp = entry.second->GetCategory())
496 {
497 if (!callback(param, category_sp))
498 break;
499 }
500 }
501}
502
Enrico Granata061858c2012-02-15 02:34:21 +0000503lldb::TypeCategoryImplSP
Enrico Granata9128ee22011-09-06 19:20:51 +0000504FormatManager::GetCategory (const ConstString& category_name,
Enrico Granatadb595cd2015-03-06 19:37:57 +0000505 bool can_create)
Enrico Granatadc940732011-08-23 00:32:52 +0000506{
507 if (!category_name)
Enrico Granata9128ee22011-09-06 19:20:51 +0000508 return GetCategory(m_default_category_name);
Enrico Granata061858c2012-02-15 02:34:21 +0000509 lldb::TypeCategoryImplSP category;
Enrico Granatadc940732011-08-23 00:32:52 +0000510 if (m_categories_map.Get(category_name, category))
511 return category;
512
513 if (!can_create)
Enrico Granata061858c2012-02-15 02:34:21 +0000514 return lldb::TypeCategoryImplSP();
Enrico Granatadc940732011-08-23 00:32:52 +0000515
Enrico Granata061858c2012-02-15 02:34:21 +0000516 m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
Enrico Granata9128ee22011-09-06 19:20:51 +0000517 return GetCategory(category_name);
Enrico Granatadc940732011-08-23 00:32:52 +0000518}
519
Enrico Granataf4efecd2011-07-12 22:56:10 +0000520lldb::Format
521FormatManager::GetSingleItemFormat(lldb::Format vector_format)
522{
523 switch(vector_format)
524 {
525 case eFormatVectorOfChar:
526 return eFormatCharArray;
527
528 case eFormatVectorOfSInt8:
529 case eFormatVectorOfSInt16:
530 case eFormatVectorOfSInt32:
531 case eFormatVectorOfSInt64:
532 return eFormatDecimal;
533
534 case eFormatVectorOfUInt8:
535 case eFormatVectorOfUInt16:
536 case eFormatVectorOfUInt32:
537 case eFormatVectorOfUInt64:
538 case eFormatVectorOfUInt128:
539 return eFormatHex;
540
Ewan Crawforda0f08672015-10-16 08:28:47 +0000541 case eFormatVectorOfFloat16:
Enrico Granataf4efecd2011-07-12 22:56:10 +0000542 case eFormatVectorOfFloat32:
543 case eFormatVectorOfFloat64:
544 return eFormatFloat;
545
546 default:
547 return lldb::eFormatInvalid;
548 }
Greg Clayton3418c852011-08-10 02:10:13 +0000549}
Enrico Granatac482a192011-08-17 22:13:59 +0000550
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000551bool
552FormatManager::ShouldPrintAsOneLiner (ValueObject& valobj)
553{
Enrico Granata553fad52013-10-25 23:09:40 +0000554 // if settings say no oneline whatsoever
Enrico Granata90a8db32013-10-31 21:01:07 +0000555 if (valobj.GetTargetSP().get() && valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
Enrico Granata553fad52013-10-25 23:09:40 +0000556 return false; // then don't oneline
557
Enrico Granata42fa4af2014-09-11 23:00:27 +0000558 // if this object has a summary, then ask the summary
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000559 if (valobj.GetSummaryFormat().get() != nullptr)
Enrico Granata42fa4af2014-09-11 23:00:27 +0000560 return valobj.GetSummaryFormat()->IsOneLiner();
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000561
562 // no children, no party
563 if (valobj.GetNumChildren() == 0)
564 return false;
565
Enrico Granata9c63f992015-09-23 02:04:34 +0000566 // ask the type if it has any opinion about this
567 // eLazyBoolCalculate == no opinion; other values should be self explanatory
568 CompilerType compiler_type(valobj.GetCompilerType());
569 if (compiler_type.IsValid())
570 {
Enrico Granata65000612015-11-09 21:28:55 +0000571 switch (compiler_type.ShouldPrintAsOneLiner(&valobj))
Enrico Granata9c63f992015-09-23 02:04:34 +0000572 {
573 case eLazyBoolNo:
574 return false;
575 case eLazyBoolYes:
576 return true;
577 case eLazyBoolCalculate:
Enrico Granata9c63f992015-09-23 02:04:34 +0000578 break;
579 }
580 }
581
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000582 size_t total_children_name_len = 0;
583
584 for (size_t idx = 0;
585 idx < valobj.GetNumChildren();
586 idx++)
587 {
Enrico Granataddac7612014-10-09 18:47:36 +0000588 bool is_synth_val = false;
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000589 ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
590 // something is wrong here - bail out
591 if (!child_sp)
592 return false;
Enrico Granata65000612015-11-09 21:28:55 +0000593
594 // also ask the child's type if it has any opinion
595 CompilerType child_compiler_type(child_sp->GetCompilerType());
596 if (child_compiler_type.IsValid())
597 {
598 switch (child_compiler_type.ShouldPrintAsOneLiner(child_sp.get()))
599 {
600 case eLazyBoolYes:
601 // an opinion of yes is only binding for the child, so keep going
602 case eLazyBoolCalculate:
603 break;
604 case eLazyBoolNo:
605 // but if the child says no, then it's a veto on the whole thing
606 return false;
607 }
608 }
609
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000610 // if we decided to define synthetic children for a type, we probably care enough
611 // to show them, but avoid nesting children in children
612 if (child_sp->GetSyntheticChildren().get() != nullptr)
Enrico Granataddac7612014-10-09 18:47:36 +0000613 {
614 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
615 // wait.. wat? just get out of here..
616 if (!synth_sp)
617 return false;
618 // but if we only have them to provide a value, keep going
619 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
620 is_synth_val = true;
621 else
622 return false;
623 }
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000624
625 total_children_name_len += child_sp->GetName().GetLength();
626
627 // 50 itself is a "randomly" chosen number - the idea is that
628 // overly long structs should not get this treatment
629 // FIXME: maybe make this a user-tweakable setting?
630 if (total_children_name_len > 50)
631 return false;
632
633 // if a summary is there..
634 if (child_sp->GetSummaryFormat())
635 {
636 // and it wants children, then bail out
Enrico Granata8a068e62014-04-23 23:16:25 +0000637 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000638 return false;
639 }
640
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000641 // if this child has children..
642 if (child_sp->GetNumChildren())
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000643 {
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000644 // ...and no summary...
645 // (if it had a summary and the summary wanted children, we would have bailed out anyway
646 // 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 +0000647 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 +0000648 return false; // then bail out
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000649 }
650 }
651 return true;
652}
653
Enrico Granata02b66762011-08-19 01:14:49 +0000654ConstString
655FormatManager::GetValidTypeName (const ConstString& type)
656{
657 return ::GetValidTypeName_Impl(type);
658}
659
Enrico Granata5548cb52013-01-28 23:47:25 +0000660ConstString
Enrico Granata980c0482015-09-01 18:22:39 +0000661FormatManager::GetTypeForCache (ValueObject& valobj,
662 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000663{
Enrico Granatab3f0c342015-10-20 00:13:19 +0000664 ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(use_dynamic, valobj.IsSynthetic());
665 if (valobj_sp && valobj_sp->GetCompilerType().IsValid())
Enrico Granata5548cb52013-01-28 23:47:25 +0000666 {
Enrico Granatab3f0c342015-10-20 00:13:19 +0000667 if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
668 return valobj_sp->GetQualifiedTypeName();
Enrico Granata5548cb52013-01-28 23:47:25 +0000669 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000670 return ConstString();
671}
672
Enrico Granatad3233c12015-09-09 01:10:46 +0000673std::vector<lldb::LanguageType>
674FormatManager::GetCandidateLanguages (ValueObject& valobj)
Enrico Granata980c0482015-09-01 18:22:39 +0000675{
676 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
Enrico Granataac494532015-09-09 22:30:24 +0000677 return GetCandidateLanguages(lang_type);
678}
679
680std::vector<lldb::LanguageType>
681FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
682{
Enrico Granata980c0482015-09-01 18:22:39 +0000683 switch (lang_type)
684 {
Enrico Granata33e97e62015-09-04 21:01:18 +0000685 case lldb::eLanguageTypeC:
686 case lldb::eLanguageTypeC89:
687 case lldb::eLanguageTypeC99:
688 case lldb::eLanguageTypeC11:
689 case lldb::eLanguageTypeC_plus_plus:
690 case lldb::eLanguageTypeC_plus_plus_03:
691 case lldb::eLanguageTypeC_plus_plus_11:
692 case lldb::eLanguageTypeC_plus_plus_14:
Enrico Granata170c3952015-09-14 22:18:32 +0000693 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
Enrico Granata980c0482015-09-01 18:22:39 +0000694 default:
695 return {lang_type};
696 }
697}
698
699LanguageCategory*
700FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
701{
702 Mutex::Locker locker(m_language_categories_mutex);
703 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
704 if (iter != end)
705 return iter->second.get();
706 LanguageCategory* lang_category = new LanguageCategory(lang_type);
707 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
708 return lang_category;
709}
710
Enrico Granataecd02bc2014-08-19 18:47:58 +0000711lldb::TypeFormatImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000712FormatManager::GetHardcodedFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000713{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000714 TypeFormatImplSP retval_sp;
715
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000716 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000717 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000718 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
719 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000720 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000721 break;
722 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000723 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000724
725 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000726}
727
Enrico Granata852cc952013-10-08 19:03:22 +0000728lldb::TypeFormatImplSP
729FormatManager::GetFormat (ValueObject& valobj,
730 lldb::DynamicValueType use_dynamic)
731{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000732 FormattersMatchData match_data(valobj, use_dynamic);
733
Enrico Granata852cc952013-10-08 19:03:22 +0000734 TypeFormatImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000735 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000736 if (match_data.GetTypeForCache())
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000737 {
738 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000739 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
740 if (m_format_cache.GetFormat(match_data.GetTypeForCache(),retval))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000741 {
742 if (log)
743 {
744 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
745 if (log->GetDebug())
746 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
747 }
748 return retval;
749 }
750 if (log)
751 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
752 }
Enrico Granata980c0482015-09-01 18:22:39 +0000753
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000754 retval = m_categories_map.GetFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000755 if (!retval)
756 {
757 if (log)
758 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000759 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000760 {
761 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
762 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000763 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000764 break;
765 }
766 }
767 if (retval)
768 {
769 if (log)
770 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
771 return retval;
772 }
773 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000774 if (!retval)
775 {
776 if (log)
777 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000778 retval = GetHardcodedFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000779 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000780
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000781 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000782 {
783 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000784 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
785 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000786 match_data.GetTypeForCache().AsCString("<invalid>"));
787 m_format_cache.SetFormat(match_data.GetTypeForCache(),retval);
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000788 }
789 if (log && log->GetDebug())
790 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 +0000791 return retval;
792}
793
Enrico Granataecd02bc2014-08-19 18:47:58 +0000794lldb::TypeSummaryImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000795FormatManager::GetHardcodedSummaryFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000796{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000797 TypeSummaryImplSP retval_sp;
798
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000799 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000800 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000801 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
802 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000803 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000804 break;
805 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000806 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000807
808 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000809}
810
Enrico Granata5548cb52013-01-28 23:47:25 +0000811lldb::TypeSummaryImplSP
812FormatManager::GetSummaryFormat (ValueObject& valobj,
813 lldb::DynamicValueType use_dynamic)
814{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000815 FormattersMatchData match_data(valobj, use_dynamic);
816
Enrico Granata5548cb52013-01-28 23:47:25 +0000817 TypeSummaryImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000818 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000819 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000820 {
821 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000822 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
823 if (m_format_cache.GetSummary(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000824 {
825 if (log)
826 {
827 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000828 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000829 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 +0000830 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000831 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000832 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000833 if (log)
834 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
835 }
Enrico Granata980c0482015-09-01 18:22:39 +0000836
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000837 retval = m_categories_map.GetSummaryFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000838 if (!retval)
839 {
840 if (log)
841 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000842 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000843 {
844 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
845 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000846 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000847 break;
848 }
849 }
850 if (retval)
851 {
852 if (log)
853 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
854 return retval;
855 }
856 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000857 if (!retval)
858 {
859 if (log)
860 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000861 retval = GetHardcodedSummaryFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000862 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000863
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000864 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000865 {
866 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000867 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
868 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000869 match_data.GetTypeForCache().AsCString("<invalid>"));
870 m_format_cache.SetSummary(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000871 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000872 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000873 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 +0000874 return retval;
875}
876
877#ifndef LLDB_DISABLE_PYTHON
Enrico Granataecd02bc2014-08-19 18:47:58 +0000878lldb::SyntheticChildrenSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000879FormatManager::GetHardcodedSyntheticChildren (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000880{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000881 SyntheticChildrenSP retval_sp;
882
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000883 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000884 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000885 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
886 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000887 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000888 break;
889 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000890 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000891
892 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000893}
894
Enrico Granata5548cb52013-01-28 23:47:25 +0000895lldb::SyntheticChildrenSP
896FormatManager::GetSyntheticChildren (ValueObject& valobj,
Enrico Granatac2a96402013-06-26 01:03:38 +0000897 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000898{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000899 FormattersMatchData match_data(valobj, use_dynamic);
900
Enrico Granata5548cb52013-01-28 23:47:25 +0000901 SyntheticChildrenSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000902 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000903 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000904 {
905 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000906 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
907 if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000908 {
909 if (log)
910 {
911 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000912 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000913 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 +0000914 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000915 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000916 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000917 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000918 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
Enrico Granata5548cb52013-01-28 23:47:25 +0000919 }
Enrico Granata980c0482015-09-01 18:22:39 +0000920
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000921 retval = m_categories_map.GetSyntheticChildren(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000922 if (!retval)
923 {
924 if (log)
925 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000926 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000927 {
928 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
929 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000930 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000931 break;
932 }
933 }
934 if (retval)
935 {
936 if (log)
937 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
938 return retval;
939 }
940 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000941 if (!retval)
942 {
943 if (log)
944 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000945 retval = GetHardcodedSyntheticChildren(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000946 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000947
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000948 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000949 {
950 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000951 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
952 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000953 match_data.GetTypeForCache().AsCString("<invalid>"));
954 m_format_cache.SetSynthetic(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000955 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000956 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000957 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 +0000958 return retval;
959}
960#endif
Enrico Granata5548cb52013-01-28 23:47:25 +0000961
Enrico Granatac5827132014-09-05 20:45:07 +0000962lldb::TypeValidatorImplSP
963FormatManager::GetValidator (ValueObject& valobj,
964 lldb::DynamicValueType use_dynamic)
965{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000966 FormattersMatchData match_data(valobj, use_dynamic);
967
Enrico Granatac5827132014-09-05 20:45:07 +0000968 TypeValidatorImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000969 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000970 if (match_data.GetTypeForCache())
Enrico Granatac5827132014-09-05 20:45:07 +0000971 {
972 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000973 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
974 if (m_format_cache.GetValidator(match_data.GetTypeForCache(),retval))
Enrico Granatac5827132014-09-05 20:45:07 +0000975 {
976 if (log)
977 {
978 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
979 if (log->GetDebug())
980 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
981 }
982 return retval;
983 }
984 if (log)
985 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
986 }
Enrico Granata980c0482015-09-01 18:22:39 +0000987
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000988 retval = m_categories_map.GetValidator(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000989 if (!retval)
990 {
991 if (log)
992 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000993 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000994 {
995 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
996 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000997 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000998 break;
999 }
1000 }
1001 if (retval)
1002 {
1003 if (log)
1004 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
1005 return retval;
1006 }
1007 }
Enrico Granatac5827132014-09-05 20:45:07 +00001008 if (!retval)
1009 {
1010 if (log)
1011 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001012 retval = GetHardcodedValidator(match_data);
Enrico Granatac5827132014-09-05 20:45:07 +00001013 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +00001014
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001015 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granatac5827132014-09-05 20:45:07 +00001016 {
1017 if (log)
1018 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
1019 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001020 match_data.GetTypeForCache().AsCString("<invalid>"));
1021 m_format_cache.SetValidator(match_data.GetTypeForCache(),retval);
Enrico Granatac5827132014-09-05 20:45:07 +00001022 }
1023 if (log && log->GetDebug())
1024 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1025 return retval;
1026}
1027
1028lldb::TypeValidatorImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001029FormatManager::GetHardcodedValidator (FormattersMatchData& match_data)
Enrico Granatac5827132014-09-05 20:45:07 +00001030{
Enrico Granata7cb59e12015-09-16 18:28:11 +00001031 TypeValidatorImplSP retval_sp;
1032
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001033 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granatac5827132014-09-05 20:45:07 +00001034 {
Enrico Granata7cb59e12015-09-16 18:28:11 +00001035 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1036 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001037 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +00001038 break;
1039 }
Enrico Granatac5827132014-09-05 20:45:07 +00001040 }
Enrico Granata7cb59e12015-09-16 18:28:11 +00001041
1042 return retval_sp;
Enrico Granatac5827132014-09-05 20:45:07 +00001043}
1044
Enrico Granata5548cb52013-01-28 23:47:25 +00001045FormatManager::FormatManager() :
1046 m_format_cache(),
Enrico Granatac482a192011-08-17 22:13:59 +00001047 m_named_summaries_map(this),
1048 m_last_revision(0),
1049 m_categories_map(this),
Enrico Granata980c0482015-09-01 18:22:39 +00001050 m_language_categories_map(),
1051 m_language_categories_mutex(Mutex::eMutexTypeRecursive),
Enrico Granata1d887492011-08-22 18:36:52 +00001052 m_default_category_name(ConstString("default")),
1053 m_system_category_name(ConstString("system")),
Enrico Granata7cb59e12015-09-16 18:28:11 +00001054 m_vectortypes_category_name(ConstString("VectorTypes"))
Enrico Granatac482a192011-08-17 22:13:59 +00001055{
Enrico Granata864e3e82012-02-17 03:18:30 +00001056 LoadSystemFormatters();
Enrico Granata170c3952015-09-14 22:18:32 +00001057 LoadVectorFormatters();
Enrico Granata864e3e82012-02-17 03:18:30 +00001058
Enrico Granatafa6b2782015-09-17 00:14:50 +00001059 EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1060 EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
Enrico Granata864e3e82012-02-17 03:18:30 +00001061}
1062
1063void
Enrico Granata864e3e82012-02-17 03:18:30 +00001064FormatManager::LoadSystemFormatters()
1065{
Enrico Granataf68df122013-01-10 22:08:35 +00001066
1067 TypeSummaryImpl::Flags string_flags;
Enrico Granata0337c272013-02-22 00:37:31 +00001068 string_flags.SetCascades(true)
Enrico Granataf68df122013-01-10 22:08:35 +00001069 .SetSkipPointers(true)
1070 .SetSkipReferences(false)
1071 .SetDontShowChildren(true)
1072 .SetDontShowValue(false)
1073 .SetShowMembersOneLiner(false)
1074 .SetHideItemNames(false);
1075
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001076 TypeSummaryImpl::Flags string_array_flags;
Enrico Granatad2911632015-07-28 02:13:03 +00001077 string_array_flags.SetCascades(true)
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001078 .SetSkipPointers(true)
1079 .SetSkipReferences(false)
1080 .SetDontShowChildren(true)
1081 .SetDontShowValue(true)
1082 .SetShowMembersOneLiner(false)
1083 .SetHideItemNames(false);
1084
Enrico Granataf68df122013-01-10 22:08:35 +00001085 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001086
1087
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001088 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
Enrico Granata061858c2012-02-15 02:34:21 +00001089 "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001090
1091 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001092 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
Enrico Granatac482a192011-08-17 22:13:59 +00001093
Enrico Granata061858c2012-02-15 02:34:21 +00001094 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
Enrico Granatac482a192011-08-17 22:13:59 +00001095
Enrico Granatab72a5012013-12-20 09:38:13 +00001096 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1097 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1098 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
Enrico Granataaff65652013-10-21 17:29:51 +00001099
Enrico Granata4ed7ef12012-07-13 18:54:40 +00001100 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1101 .SetSkipPointers(true)
1102 .SetSkipReferences(true)
1103 .SetDontShowChildren(true)
1104 .SetDontShowValue(false)
1105 .SetShowMembersOneLiner(false)
1106 .SetHideItemNames(false),
1107 "${var%O}"));
1108
Enrico Granatab72a5012013-12-20 09:38:13 +00001109 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
Enrico Granatad3d444f2012-02-23 23:10:03 +00001110
Jason Molenda1a100cd2013-01-12 04:24:50 +00001111#ifndef LLDB_DISABLE_PYTHON
Enrico Granata4cc21772013-10-08 20:59:02 +00001112 TypeFormatImpl::Flags fourchar_flags;
1113 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1114
1115 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
Jason Molenda1a100cd2013-01-12 04:24:50 +00001116#endif
Enrico Granatad3d444f2012-02-23 23:10:03 +00001117}
Enrico Granatab2698cd2012-09-13 18:27:09 +00001118
Enrico Granata864e3e82012-02-17 03:18:30 +00001119void
Enrico Granata170c3952015-09-14 22:18:32 +00001120FormatManager::LoadVectorFormatters()
Enrico Granata864e3e82012-02-17 03:18:30 +00001121{
Enrico Granata864e3e82012-02-17 03:18:30 +00001122 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
Enrico Granata170c3952015-09-14 22:18:32 +00001123
Enrico Granata864e3e82012-02-17 03:18:30 +00001124 TypeSummaryImpl::Flags vector_flags;
1125 vector_flags.SetCascades(true)
1126 .SetSkipPointers(true)
1127 .SetSkipReferences(false)
1128 .SetDontShowChildren(true)
1129 .SetDontShowValue(false)
1130 .SetShowMembersOneLiner(true)
1131 .SetHideItemNames(true);
1132
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001133 AddStringSummary(vectors_category_sp,
1134 "${var.uint128}",
1135 ConstString("builtin_type_vec128"),
Enrico Granata170c3952015-09-14 22:18:32 +00001136 vector_flags);
1137
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001138 AddStringSummary(vectors_category_sp,
1139 "",
1140 ConstString("float [4]"),
1141 vector_flags);
1142 AddStringSummary(vectors_category_sp,
1143 "",
1144 ConstString("int32_t [4]"),
1145 vector_flags);
1146 AddStringSummary(vectors_category_sp,
1147 "",
1148 ConstString("int16_t [8]"),
1149 vector_flags);
1150 AddStringSummary(vectors_category_sp,
1151 "",
1152 ConstString("vDouble"),
1153 vector_flags);
1154 AddStringSummary(vectors_category_sp,
1155 "",
1156 ConstString("vFloat"),
1157 vector_flags);
1158 AddStringSummary(vectors_category_sp,
1159 "",
1160 ConstString("vSInt8"),
1161 vector_flags);
1162 AddStringSummary(vectors_category_sp,
1163 "",
1164 ConstString("vSInt16"),
1165 vector_flags);
1166 AddStringSummary(vectors_category_sp,
1167 "",
1168 ConstString("vSInt32"),
1169 vector_flags);
1170 AddStringSummary(vectors_category_sp,
1171 "",
1172 ConstString("vUInt16"),
1173 vector_flags);
1174 AddStringSummary(vectors_category_sp,
1175 "",
1176 ConstString("vUInt8"),
1177 vector_flags);
1178 AddStringSummary(vectors_category_sp,
1179 "",
1180 ConstString("vUInt16"),
1181 vector_flags);
1182 AddStringSummary(vectors_category_sp,
1183 "",
1184 ConstString("vUInt32"),
1185 vector_flags);
1186 AddStringSummary(vectors_category_sp,
1187 "",
1188 ConstString("vBool32"),
1189 vector_flags);
Greg Claytond4e25522011-10-12 00:53:29 +00001190}