blob: 12838931f2b35a4b6b1b25f22432123a27ab011b [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 {
571 switch (compiler_type.ShouldPrintAsOneLiner())
572 {
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;
593 // if we decided to define synthetic children for a type, we probably care enough
594 // to show them, but avoid nesting children in children
595 if (child_sp->GetSyntheticChildren().get() != nullptr)
Enrico Granataddac7612014-10-09 18:47:36 +0000596 {
597 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
598 // wait.. wat? just get out of here..
599 if (!synth_sp)
600 return false;
601 // but if we only have them to provide a value, keep going
602 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
603 is_synth_val = true;
604 else
605 return false;
606 }
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000607
608 total_children_name_len += child_sp->GetName().GetLength();
609
610 // 50 itself is a "randomly" chosen number - the idea is that
611 // overly long structs should not get this treatment
612 // FIXME: maybe make this a user-tweakable setting?
613 if (total_children_name_len > 50)
614 return false;
615
616 // if a summary is there..
617 if (child_sp->GetSummaryFormat())
618 {
619 // and it wants children, then bail out
Enrico Granata8a068e62014-04-23 23:16:25 +0000620 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000621 return false;
622 }
623
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000624 // if this child has children..
625 if (child_sp->GetNumChildren())
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000626 {
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000627 // ...and no summary...
628 // (if it had a summary and the summary wanted children, we would have bailed out anyway
629 // 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 +0000630 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 +0000631 return false; // then bail out
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000632 }
633 }
634 return true;
635}
636
Enrico Granata02b66762011-08-19 01:14:49 +0000637ConstString
638FormatManager::GetValidTypeName (const ConstString& type)
639{
640 return ::GetValidTypeName_Impl(type);
641}
642
Enrico Granata5548cb52013-01-28 23:47:25 +0000643ConstString
Enrico Granata980c0482015-09-01 18:22:39 +0000644FormatManager::GetTypeForCache (ValueObject& valobj,
645 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000646{
Enrico Granatab3f0c342015-10-20 00:13:19 +0000647 ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(use_dynamic, valobj.IsSynthetic());
648 if (valobj_sp && valobj_sp->GetCompilerType().IsValid())
Enrico Granata5548cb52013-01-28 23:47:25 +0000649 {
Enrico Granatab3f0c342015-10-20 00:13:19 +0000650 if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
651 return valobj_sp->GetQualifiedTypeName();
Enrico Granata5548cb52013-01-28 23:47:25 +0000652 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000653 return ConstString();
654}
655
Enrico Granatad3233c12015-09-09 01:10:46 +0000656std::vector<lldb::LanguageType>
657FormatManager::GetCandidateLanguages (ValueObject& valobj)
Enrico Granata980c0482015-09-01 18:22:39 +0000658{
659 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
Enrico Granataac494532015-09-09 22:30:24 +0000660 return GetCandidateLanguages(lang_type);
661}
662
663std::vector<lldb::LanguageType>
664FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
665{
Enrico Granata980c0482015-09-01 18:22:39 +0000666 switch (lang_type)
667 {
Enrico Granata33e97e62015-09-04 21:01:18 +0000668 case lldb::eLanguageTypeC:
669 case lldb::eLanguageTypeC89:
670 case lldb::eLanguageTypeC99:
671 case lldb::eLanguageTypeC11:
672 case lldb::eLanguageTypeC_plus_plus:
673 case lldb::eLanguageTypeC_plus_plus_03:
674 case lldb::eLanguageTypeC_plus_plus_11:
675 case lldb::eLanguageTypeC_plus_plus_14:
Enrico Granata170c3952015-09-14 22:18:32 +0000676 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
Enrico Granata980c0482015-09-01 18:22:39 +0000677 default:
678 return {lang_type};
679 }
680}
681
682LanguageCategory*
683FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
684{
685 Mutex::Locker locker(m_language_categories_mutex);
686 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
687 if (iter != end)
688 return iter->second.get();
689 LanguageCategory* lang_category = new LanguageCategory(lang_type);
690 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
691 return lang_category;
692}
693
Enrico Granataecd02bc2014-08-19 18:47:58 +0000694lldb::TypeFormatImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000695FormatManager::GetHardcodedFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000696{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000697 TypeFormatImplSP retval_sp;
698
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000699 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000700 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000701 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
702 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000703 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000704 break;
705 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000706 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000707
708 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000709}
710
Enrico Granata852cc952013-10-08 19:03:22 +0000711lldb::TypeFormatImplSP
712FormatManager::GetFormat (ValueObject& valobj,
713 lldb::DynamicValueType use_dynamic)
714{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000715 FormattersMatchData match_data(valobj, use_dynamic);
716
Enrico Granata852cc952013-10-08 19:03:22 +0000717 TypeFormatImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000718 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000719 if (match_data.GetTypeForCache())
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000720 {
721 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000722 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
723 if (m_format_cache.GetFormat(match_data.GetTypeForCache(),retval))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000724 {
725 if (log)
726 {
727 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
728 if (log->GetDebug())
729 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
730 }
731 return retval;
732 }
733 if (log)
734 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
735 }
Enrico Granata980c0482015-09-01 18:22:39 +0000736
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000737 retval = m_categories_map.GetFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000738 if (!retval)
739 {
740 if (log)
741 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000742 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000743 {
744 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
745 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000746 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000747 break;
748 }
749 }
750 if (retval)
751 {
752 if (log)
753 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
754 return retval;
755 }
756 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000757 if (!retval)
758 {
759 if (log)
760 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000761 retval = GetHardcodedFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000762 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000763
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000764 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000765 {
766 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000767 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
768 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000769 match_data.GetTypeForCache().AsCString("<invalid>"));
770 m_format_cache.SetFormat(match_data.GetTypeForCache(),retval);
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000771 }
772 if (log && log->GetDebug())
773 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 +0000774 return retval;
775}
776
Enrico Granataecd02bc2014-08-19 18:47:58 +0000777lldb::TypeSummaryImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000778FormatManager::GetHardcodedSummaryFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000779{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000780 TypeSummaryImplSP retval_sp;
781
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000782 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000783 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000784 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
785 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000786 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000787 break;
788 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000789 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000790
791 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000792}
793
Enrico Granata5548cb52013-01-28 23:47:25 +0000794lldb::TypeSummaryImplSP
795FormatManager::GetSummaryFormat (ValueObject& valobj,
796 lldb::DynamicValueType use_dynamic)
797{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000798 FormattersMatchData match_data(valobj, use_dynamic);
799
Enrico Granata5548cb52013-01-28 23:47:25 +0000800 TypeSummaryImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000801 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000802 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000803 {
804 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000805 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
806 if (m_format_cache.GetSummary(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000807 {
808 if (log)
809 {
810 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000811 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000812 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 +0000813 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000814 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000815 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000816 if (log)
817 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
818 }
Enrico Granata980c0482015-09-01 18:22:39 +0000819
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000820 retval = m_categories_map.GetSummaryFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000821 if (!retval)
822 {
823 if (log)
824 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000825 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000826 {
827 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
828 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000829 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000830 break;
831 }
832 }
833 if (retval)
834 {
835 if (log)
836 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
837 return retval;
838 }
839 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000840 if (!retval)
841 {
842 if (log)
843 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000844 retval = GetHardcodedSummaryFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000845 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000846
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000847 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000848 {
849 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000850 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
851 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000852 match_data.GetTypeForCache().AsCString("<invalid>"));
853 m_format_cache.SetSummary(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000854 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000855 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000856 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 +0000857 return retval;
858}
859
860#ifndef LLDB_DISABLE_PYTHON
Enrico Granataecd02bc2014-08-19 18:47:58 +0000861lldb::SyntheticChildrenSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000862FormatManager::GetHardcodedSyntheticChildren (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000863{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000864 SyntheticChildrenSP retval_sp;
865
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000866 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000867 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000868 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
869 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000870 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000871 break;
872 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000873 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000874
875 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000876}
877
Enrico Granata5548cb52013-01-28 23:47:25 +0000878lldb::SyntheticChildrenSP
879FormatManager::GetSyntheticChildren (ValueObject& valobj,
Enrico Granatac2a96402013-06-26 01:03:38 +0000880 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000881{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000882 FormattersMatchData match_data(valobj, use_dynamic);
883
Enrico Granata5548cb52013-01-28 23:47:25 +0000884 SyntheticChildrenSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000885 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000886 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000887 {
888 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000889 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
890 if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000891 {
892 if (log)
893 {
894 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000895 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000896 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 +0000897 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000898 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000899 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000900 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000901 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
Enrico Granata5548cb52013-01-28 23:47:25 +0000902 }
Enrico Granata980c0482015-09-01 18:22:39 +0000903
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000904 retval = m_categories_map.GetSyntheticChildren(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000905 if (!retval)
906 {
907 if (log)
908 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000909 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000910 {
911 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
912 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000913 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000914 break;
915 }
916 }
917 if (retval)
918 {
919 if (log)
920 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
921 return retval;
922 }
923 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000924 if (!retval)
925 {
926 if (log)
927 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000928 retval = GetHardcodedSyntheticChildren(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000929 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000930
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000931 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000932 {
933 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000934 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
935 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000936 match_data.GetTypeForCache().AsCString("<invalid>"));
937 m_format_cache.SetSynthetic(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000938 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000939 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000940 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 +0000941 return retval;
942}
943#endif
Enrico Granata5548cb52013-01-28 23:47:25 +0000944
Enrico Granatac5827132014-09-05 20:45:07 +0000945lldb::TypeValidatorImplSP
946FormatManager::GetValidator (ValueObject& valobj,
947 lldb::DynamicValueType use_dynamic)
948{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000949 FormattersMatchData match_data(valobj, use_dynamic);
950
Enrico Granatac5827132014-09-05 20:45:07 +0000951 TypeValidatorImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000952 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000953 if (match_data.GetTypeForCache())
Enrico Granatac5827132014-09-05 20:45:07 +0000954 {
955 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000956 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
957 if (m_format_cache.GetValidator(match_data.GetTypeForCache(),retval))
Enrico Granatac5827132014-09-05 20:45:07 +0000958 {
959 if (log)
960 {
961 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
962 if (log->GetDebug())
963 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
964 }
965 return retval;
966 }
967 if (log)
968 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
969 }
Enrico Granata980c0482015-09-01 18:22:39 +0000970
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000971 retval = m_categories_map.GetValidator(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000972 if (!retval)
973 {
974 if (log)
975 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000976 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000977 {
978 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
979 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000980 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000981 break;
982 }
983 }
984 if (retval)
985 {
986 if (log)
987 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
988 return retval;
989 }
990 }
Enrico Granatac5827132014-09-05 20:45:07 +0000991 if (!retval)
992 {
993 if (log)
994 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000995 retval = GetHardcodedValidator(match_data);
Enrico Granatac5827132014-09-05 20:45:07 +0000996 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000997
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000998 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granatac5827132014-09-05 20:45:07 +0000999 {
1000 if (log)
1001 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
1002 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001003 match_data.GetTypeForCache().AsCString("<invalid>"));
1004 m_format_cache.SetValidator(match_data.GetTypeForCache(),retval);
Enrico Granatac5827132014-09-05 20:45:07 +00001005 }
1006 if (log && log->GetDebug())
1007 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1008 return retval;
1009}
1010
1011lldb::TypeValidatorImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001012FormatManager::GetHardcodedValidator (FormattersMatchData& match_data)
Enrico Granatac5827132014-09-05 20:45:07 +00001013{
Enrico Granata7cb59e12015-09-16 18:28:11 +00001014 TypeValidatorImplSP retval_sp;
1015
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001016 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granatac5827132014-09-05 20:45:07 +00001017 {
Enrico Granata7cb59e12015-09-16 18:28:11 +00001018 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1019 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001020 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +00001021 break;
1022 }
Enrico Granatac5827132014-09-05 20:45:07 +00001023 }
Enrico Granata7cb59e12015-09-16 18:28:11 +00001024
1025 return retval_sp;
Enrico Granatac5827132014-09-05 20:45:07 +00001026}
1027
Enrico Granata5548cb52013-01-28 23:47:25 +00001028FormatManager::FormatManager() :
1029 m_format_cache(),
Enrico Granatac482a192011-08-17 22:13:59 +00001030 m_named_summaries_map(this),
1031 m_last_revision(0),
1032 m_categories_map(this),
Enrico Granata980c0482015-09-01 18:22:39 +00001033 m_language_categories_map(),
1034 m_language_categories_mutex(Mutex::eMutexTypeRecursive),
Enrico Granata1d887492011-08-22 18:36:52 +00001035 m_default_category_name(ConstString("default")),
1036 m_system_category_name(ConstString("system")),
Enrico Granata7cb59e12015-09-16 18:28:11 +00001037 m_vectortypes_category_name(ConstString("VectorTypes"))
Enrico Granatac482a192011-08-17 22:13:59 +00001038{
Enrico Granata864e3e82012-02-17 03:18:30 +00001039 LoadSystemFormatters();
Enrico Granata170c3952015-09-14 22:18:32 +00001040 LoadVectorFormatters();
Enrico Granata864e3e82012-02-17 03:18:30 +00001041
Enrico Granatafa6b2782015-09-17 00:14:50 +00001042 EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1043 EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
Enrico Granata864e3e82012-02-17 03:18:30 +00001044}
1045
1046void
Enrico Granata864e3e82012-02-17 03:18:30 +00001047FormatManager::LoadSystemFormatters()
1048{
Enrico Granataf68df122013-01-10 22:08:35 +00001049
1050 TypeSummaryImpl::Flags string_flags;
Enrico Granata0337c272013-02-22 00:37:31 +00001051 string_flags.SetCascades(true)
Enrico Granataf68df122013-01-10 22:08:35 +00001052 .SetSkipPointers(true)
1053 .SetSkipReferences(false)
1054 .SetDontShowChildren(true)
1055 .SetDontShowValue(false)
1056 .SetShowMembersOneLiner(false)
1057 .SetHideItemNames(false);
1058
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001059 TypeSummaryImpl::Flags string_array_flags;
Enrico Granatad2911632015-07-28 02:13:03 +00001060 string_array_flags.SetCascades(true)
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001061 .SetSkipPointers(true)
1062 .SetSkipReferences(false)
1063 .SetDontShowChildren(true)
1064 .SetDontShowValue(true)
1065 .SetShowMembersOneLiner(false)
1066 .SetHideItemNames(false);
1067
Enrico Granataf68df122013-01-10 22:08:35 +00001068 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001069
1070
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001071 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
Enrico Granata061858c2012-02-15 02:34:21 +00001072 "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001073
1074 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001075 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
Enrico Granatac482a192011-08-17 22:13:59 +00001076
Enrico Granata061858c2012-02-15 02:34:21 +00001077 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
Enrico Granatac482a192011-08-17 22:13:59 +00001078
Enrico Granatab72a5012013-12-20 09:38:13 +00001079 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1080 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1081 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
Enrico Granataaff65652013-10-21 17:29:51 +00001082
Enrico Granata4ed7ef12012-07-13 18:54:40 +00001083 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1084 .SetSkipPointers(true)
1085 .SetSkipReferences(true)
1086 .SetDontShowChildren(true)
1087 .SetDontShowValue(false)
1088 .SetShowMembersOneLiner(false)
1089 .SetHideItemNames(false),
1090 "${var%O}"));
1091
Enrico Granatab72a5012013-12-20 09:38:13 +00001092 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
Enrico Granatad3d444f2012-02-23 23:10:03 +00001093
Jason Molenda1a100cd2013-01-12 04:24:50 +00001094#ifndef LLDB_DISABLE_PYTHON
Enrico Granata4cc21772013-10-08 20:59:02 +00001095 TypeFormatImpl::Flags fourchar_flags;
1096 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1097
1098 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
Jason Molenda1a100cd2013-01-12 04:24:50 +00001099#endif
Enrico Granatad3d444f2012-02-23 23:10:03 +00001100}
Enrico Granatab2698cd2012-09-13 18:27:09 +00001101
Enrico Granata864e3e82012-02-17 03:18:30 +00001102void
Enrico Granata170c3952015-09-14 22:18:32 +00001103FormatManager::LoadVectorFormatters()
Enrico Granata864e3e82012-02-17 03:18:30 +00001104{
Enrico Granata864e3e82012-02-17 03:18:30 +00001105 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
Enrico Granata170c3952015-09-14 22:18:32 +00001106
Enrico Granata864e3e82012-02-17 03:18:30 +00001107 TypeSummaryImpl::Flags vector_flags;
1108 vector_flags.SetCascades(true)
1109 .SetSkipPointers(true)
1110 .SetSkipReferences(false)
1111 .SetDontShowChildren(true)
1112 .SetDontShowValue(false)
1113 .SetShowMembersOneLiner(true)
1114 .SetHideItemNames(true);
1115
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001116 AddStringSummary(vectors_category_sp,
1117 "${var.uint128}",
1118 ConstString("builtin_type_vec128"),
Enrico Granata170c3952015-09-14 22:18:32 +00001119 vector_flags);
1120
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001121 AddStringSummary(vectors_category_sp,
1122 "",
1123 ConstString("float [4]"),
1124 vector_flags);
1125 AddStringSummary(vectors_category_sp,
1126 "",
1127 ConstString("int32_t [4]"),
1128 vector_flags);
1129 AddStringSummary(vectors_category_sp,
1130 "",
1131 ConstString("int16_t [8]"),
1132 vector_flags);
1133 AddStringSummary(vectors_category_sp,
1134 "",
1135 ConstString("vDouble"),
1136 vector_flags);
1137 AddStringSummary(vectors_category_sp,
1138 "",
1139 ConstString("vFloat"),
1140 vector_flags);
1141 AddStringSummary(vectors_category_sp,
1142 "",
1143 ConstString("vSInt8"),
1144 vector_flags);
1145 AddStringSummary(vectors_category_sp,
1146 "",
1147 ConstString("vSInt16"),
1148 vector_flags);
1149 AddStringSummary(vectors_category_sp,
1150 "",
1151 ConstString("vSInt32"),
1152 vector_flags);
1153 AddStringSummary(vectors_category_sp,
1154 "",
1155 ConstString("vUInt16"),
1156 vector_flags);
1157 AddStringSummary(vectors_category_sp,
1158 "",
1159 ConstString("vUInt8"),
1160 vector_flags);
1161 AddStringSummary(vectors_category_sp,
1162 "",
1163 ConstString("vUInt16"),
1164 vector_flags);
1165 AddStringSummary(vectors_category_sp,
1166 "",
1167 ConstString("vUInt32"),
1168 vector_flags);
1169 AddStringSummary(vectors_category_sp,
1170 "",
1171 ConstString("vBool32"),
1172 vector_flags);
Greg Claytond4e25522011-10-12 00:53:29 +00001173}