blob: 7c241e196d8e70c3e088baa57a6ca4bcf6ab8d06 [file] [log] [blame]
Greg Clayton4a33d312011-06-23 17:59:56 +00001//===-- FormatManager.cpp -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Enrico Granata5548cb52013-01-28 23:47:25 +000010#include "lldb/DataFormatters/FormatManager.h"
Greg Clayton4a33d312011-06-23 17:59:56 +000011
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16
Enrico Granataf2bbf712011-07-15 02:26:42 +000017#include "lldb/Core/Debugger.h"
Enrico Granatadf7e79e2015-09-02 01:21:31 +000018#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granata980c0482015-09-01 18:22:39 +000019#include "lldb/DataFormatters/LanguageCategory.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000020#include "lldb/Target/ExecutionContext.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000021#include "lldb/Target/Language.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000022#include "lldb/Target/Platform.h"
Saleem Abdulrasool28606952014-06-27 05:17:41 +000023#include "llvm/ADT/STLExtras.h"
Enrico Granataf2bbf712011-07-15 02:26:42 +000024
Enrico Granata980c0482015-09-01 18:22:39 +000025#include <initializer_list>
26
Greg Clayton4a33d312011-06-23 17:59:56 +000027using namespace lldb;
28using namespace lldb_private;
Enrico Granatadf7e79e2015-09-02 01:21:31 +000029using namespace lldb_private::formatters;
Greg Claytonbb7f31f2011-06-23 21:22:24 +000030
31struct FormatInfo
32{
33 Format format;
34 const char format_char; // One or more format characters that can be used for this format.
35 const char *format_name; // Long format name that can be used to specify the current format
36};
37
38static FormatInfo
39g_format_infos[] =
40{
41 { eFormatDefault , '\0' , "default" },
42 { eFormatBoolean , 'B' , "boolean" },
43 { eFormatBinary , 'b' , "binary" },
44 { eFormatBytes , 'y' , "bytes" },
45 { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
46 { eFormatChar , 'c' , "character" },
47 { eFormatCharPrintable , 'C' , "printable character" },
48 { eFormatComplexFloat , 'F' , "complex float" },
49 { eFormatCString , 's' , "c-string" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000050 { eFormatDecimal , 'd' , "decimal" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000051 { eFormatEnum , 'E' , "enumeration" },
52 { eFormatHex , 'x' , "hex" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000053 { eFormatHexUppercase , 'X' , "uppercase hex" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000054 { eFormatFloat , 'f' , "float" },
55 { eFormatOctal , 'o' , "octal" },
56 { eFormatOSType , 'O' , "OSType" },
57 { eFormatUnicode16 , 'U' , "unicode16" },
58 { eFormatUnicode32 , '\0' , "unicode32" },
59 { eFormatUnsigned , 'u' , "unsigned decimal" },
60 { eFormatPointer , 'p' , "pointer" },
61 { eFormatVectorOfChar , '\0' , "char[]" },
62 { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
63 { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
64 { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
65 { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
Enrico Granatae443ba72011-07-06 15:56:06 +000066 { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
67 { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
68 { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
69 { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000070 { eFormatVectorOfFloat32, '\0' , "float32[]" },
71 { eFormatVectorOfFloat64, '\0' , "float64[]" },
72 { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
73 { eFormatComplexInteger , 'I' , "complex integer" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000074 { eFormatCharArray , 'a' , "character array" },
75 { eFormatAddressInfo , 'A' , "address" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000076 { eFormatHexFloat , '\0' , "hex float" },
Sean Callananbf154da2012-08-08 17:35:10 +000077 { eFormatInstruction , 'i' , "instruction" },
78 { eFormatVoid , 'v' , "void" }
Greg Claytonbb7f31f2011-06-23 21:22:24 +000079};
80
Saleem Abdulrasool28606952014-06-27 05:17:41 +000081static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
Greg Claytonbb7f31f2011-06-23 21:22:24 +000082
83static bool
84GetFormatFromFormatChar (char format_char, Format &format)
85{
86 for (uint32_t i=0; i<g_num_format_infos; ++i)
87 {
88 if (g_format_infos[i].format_char == format_char)
89 {
90 format = g_format_infos[i].format;
91 return true;
92 }
93 }
94 format = eFormatInvalid;
95 return false;
96}
97
98static bool
99GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
100{
101 uint32_t i;
102 for (i=0; i<g_num_format_infos; ++i)
103 {
104 if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
105 {
106 format = g_format_infos[i].format;
107 return true;
108 }
109 }
110
111 if (partial_match_ok)
112 {
113 for (i=0; i<g_num_format_infos; ++i)
114 {
115 if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
116 {
117 format = g_format_infos[i].format;
118 return true;
119 }
120 }
121 }
122 format = eFormatInvalid;
123 return false;
124}
125
126bool
127FormatManager::GetFormatFromCString (const char *format_cstr,
128 bool partial_match_ok,
129 lldb::Format &format)
130{
131 bool success = false;
132 if (format_cstr && format_cstr[0])
133 {
134 if (format_cstr[1] == '\0')
135 {
136 success = GetFormatFromFormatChar (format_cstr[0], format);
137 if (success)
138 return true;
139 }
140
141 success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
142 }
143 if (!success)
144 format = eFormatInvalid;
145 return success;
146}
147
148char
149FormatManager::GetFormatAsFormatChar (lldb::Format format)
150{
151 for (uint32_t i=0; i<g_num_format_infos; ++i)
152 {
153 if (g_format_infos[i].format == format)
154 return g_format_infos[i].format_char;
155 }
156 return '\0';
157}
Greg Claytonbb7f31f2011-06-23 21:22:24 +0000158
159const char *
160FormatManager::GetFormatAsCString (Format format)
161{
162 if (format >= eFormatDefault && format < kNumFormats)
163 return g_format_infos[format].format_name;
164 return NULL;
165}
Enrico Granata0a3958e2011-07-02 00:25:22 +0000166
Enrico Granatade61cec2013-11-22 00:02:13 +0000167void
Enrico Granata33e97e62015-09-04 21:01:18 +0000168FormatManager::EnableAllCategories ()
169{
170 m_categories_map.EnableAllCategories ();
171 Mutex::Locker lang_locker(m_language_categories_mutex);
172 for (auto& iter : m_language_categories_map)
173 {
174 if (iter.second)
175 iter.second->Enable();
176 }
177}
178
179void
180FormatManager::DisableAllCategories ()
181{
182 m_categories_map.DisableAllCategories ();
183 Mutex::Locker lang_locker(m_language_categories_mutex);
184 for (auto& iter : m_language_categories_map)
185 {
186 if (iter.second)
187 iter.second->Disable();
188 }
189}
190
191void
Enrico Granatade61cec2013-11-22 00:02:13 +0000192FormatManager::GetPossibleMatches (ValueObject& valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000193 CompilerType compiler_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000194 uint32_t reason,
195 lldb::DynamicValueType use_dynamic,
196 FormattersMatchVector& entries,
197 bool did_strip_ptr,
198 bool did_strip_ref,
199 bool did_strip_typedef,
200 bool root_level)
201{
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000202 compiler_type = ClangASTContext::RemoveFastQualifiers(compiler_type);
203 ConstString type_name(compiler_type.GetConstTypeName());
Enrico Granatade61cec2013-11-22 00:02:13 +0000204 if (valobj.GetBitfieldBitSize() > 0)
205 {
206 StreamString sstring;
207 sstring.Printf("%s:%d",type_name.AsCString(),valobj.GetBitfieldBitSize());
208 ConstString bitfieldname = ConstString(sstring.GetData());
209 entries.push_back({bitfieldname,0,did_strip_ptr,did_strip_ref,did_strip_typedef});
210 reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
211 }
212 entries.push_back({type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000213
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000214 ConstString display_type_name(compiler_type.GetDisplayTypeName());
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000215 if (display_type_name != type_name)
216 entries.push_back({display_type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
217
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000218 for (bool is_rvalue_ref = true, j = true; j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false)
Enrico Granatade61cec2013-11-22 00:02:13 +0000219 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000220 CompilerType non_ref_type = compiler_type.GetNonReferenceType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000221 GetPossibleMatches(valobj,
222 non_ref_type,
223 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
224 use_dynamic,
225 entries,
226 did_strip_ptr,
227 true,
228 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000229 if (non_ref_type.IsTypedefType())
230 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000231 CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
Greg Clayton56939cb2015-09-17 22:23:34 +0000232 deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000233 GetPossibleMatches(valobj,
234 deffed_referenced_type,
235 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
236 use_dynamic,
237 entries,
238 did_strip_ptr,
239 did_strip_ref,
240 true); // this is not exactly the usual meaning of stripping typedefs
241 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000242 }
Enrico Granata1ac62962014-04-10 00:14:07 +0000243
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000244 if (compiler_type.IsPointerType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000245 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000246 CompilerType non_ptr_type = compiler_type.GetPointeeType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000247 GetPossibleMatches(valobj,
248 non_ptr_type,
249 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
250 use_dynamic,
251 entries,
252 true,
253 did_strip_ref,
254 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000255 if (non_ptr_type.IsTypedefType())
256 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000257 CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000258 GetPossibleMatches(valobj,
259 deffed_pointed_type,
260 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
261 use_dynamic,
262 entries,
263 did_strip_ptr,
264 did_strip_ref,
265 true); // this is not exactly the usual meaning of stripping typedefs
266 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000267 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000268
Enrico Granatad3233c12015-09-09 01:10:46 +0000269 for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
Enrico Granatade61cec2013-11-22 00:02:13 +0000270 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000271 if (Language* language = Language::FindPlugin(language_type))
Enrico Granatade61cec2013-11-22 00:02:13 +0000272 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000273 for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
Enrico Granatade61cec2013-11-22 00:02:13 +0000274 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000275 entries.push_back({candidate,
276 reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
277 did_strip_ptr,
278 did_strip_ref,
279 did_strip_typedef});
280 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000281 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000282 }
Enrico Granatad3233c12015-09-09 01:10:46 +0000283
Enrico Granatade61cec2013-11-22 00:02:13 +0000284 // try to strip typedef chains
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000285 if (compiler_type.IsTypedefType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000286 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000287 CompilerType deffed_type = compiler_type.GetTypedefedType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000288 GetPossibleMatches(valobj,
289 deffed_type,
290 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
291 use_dynamic,
292 entries,
293 did_strip_ptr,
294 did_strip_ref,
295 true);
296 }
297
298 if (root_level)
299 {
300 do {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000301 if (!compiler_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000302 break;
303
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000304 CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType();
305 if (!unqual_compiler_ast_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000306 break;
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000307 if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000308 GetPossibleMatches (valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000309 unqual_compiler_ast_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000310 reason,
311 use_dynamic,
312 entries,
313 did_strip_ptr,
314 did_strip_ref,
315 did_strip_typedef);
316 } while(false);
317
318
319 // if all else fails, go to static type
320 if (valobj.IsDynamic())
321 {
322 lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
323 if (static_value_sp)
324 GetPossibleMatches(*static_value_sp.get(),
Greg Clayton99558cc42015-08-24 23:46:31 +0000325 static_value_sp->GetCompilerType(),
Enrico Granatade61cec2013-11-22 00:02:13 +0000326 reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
327 use_dynamic,
328 entries,
329 did_strip_ptr,
330 did_strip_ref,
331 did_strip_typedef,
332 true);
333 }
334 }
335}
336
Enrico Granata852cc952013-10-08 19:03:22 +0000337lldb::TypeFormatImplSP
338FormatManager::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
339{
340 if (!type_sp)
341 return lldb::TypeFormatImplSP();
342 lldb::TypeFormatImplSP format_chosen_sp;
343 uint32_t num_categories = m_categories_map.GetCount();
344 lldb::TypeCategoryImplSP category_sp;
345 uint32_t prio_category = UINT32_MAX;
346 for (uint32_t category_id = 0;
347 category_id < num_categories;
348 category_id++)
349 {
350 category_sp = GetCategoryAtIndex(category_id);
351 if (category_sp->IsEnabled() == false)
352 continue;
353 lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp);
354 if (format_current_sp && (format_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
355 {
356 prio_category = category_sp->GetEnabledPosition();
357 format_chosen_sp = format_current_sp;
358 }
359 }
360 return format_chosen_sp;
361}
362
Enrico Granataa777dc22012-05-08 21:49:57 +0000363lldb::TypeSummaryImplSP
364FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
365{
366 if (!type_sp)
367 return lldb::TypeSummaryImplSP();
368 lldb::TypeSummaryImplSP summary_chosen_sp;
369 uint32_t num_categories = m_categories_map.GetCount();
370 lldb::TypeCategoryImplSP category_sp;
371 uint32_t prio_category = UINT32_MAX;
372 for (uint32_t category_id = 0;
373 category_id < num_categories;
374 category_id++)
375 {
376 category_sp = GetCategoryAtIndex(category_id);
377 if (category_sp->IsEnabled() == false)
378 continue;
379 lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
380 if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
381 {
382 prio_category = category_sp->GetEnabledPosition();
383 summary_chosen_sp = summary_current_sp;
384 }
385 }
386 return summary_chosen_sp;
387}
388
389lldb::TypeFilterImplSP
390FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
391{
392 if (!type_sp)
393 return lldb::TypeFilterImplSP();
394 lldb::TypeFilterImplSP filter_chosen_sp;
395 uint32_t num_categories = m_categories_map.GetCount();
396 lldb::TypeCategoryImplSP category_sp;
397 uint32_t prio_category = UINT32_MAX;
398 for (uint32_t category_id = 0;
399 category_id < num_categories;
400 category_id++)
401 {
402 category_sp = GetCategoryAtIndex(category_id);
403 if (category_sp->IsEnabled() == false)
404 continue;
405 lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
406 if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
407 {
408 prio_category = category_sp->GetEnabledPosition();
409 filter_chosen_sp = filter_current_sp;
410 }
411 }
412 return filter_chosen_sp;
413}
414
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000415#ifndef LLDB_DISABLE_PYTHON
Enrico Granata5548cb52013-01-28 23:47:25 +0000416lldb::ScriptedSyntheticChildrenSP
Enrico Granataa777dc22012-05-08 21:49:57 +0000417FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
418{
419 if (!type_sp)
Enrico Granata5548cb52013-01-28 23:47:25 +0000420 return lldb::ScriptedSyntheticChildrenSP();
421 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
Enrico Granataa777dc22012-05-08 21:49:57 +0000422 uint32_t num_categories = m_categories_map.GetCount();
423 lldb::TypeCategoryImplSP category_sp;
424 uint32_t prio_category = UINT32_MAX;
425 for (uint32_t category_id = 0;
426 category_id < num_categories;
427 category_id++)
428 {
429 category_sp = GetCategoryAtIndex(category_id);
430 if (category_sp->IsEnabled() == false)
431 continue;
Enrico Granata5548cb52013-01-28 23:47:25 +0000432 lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
Enrico Granataa777dc22012-05-08 21:49:57 +0000433 if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
434 {
435 prio_category = category_sp->GetEnabledPosition();
436 synth_chosen_sp = synth_current_sp;
437 }
438 }
439 return synth_chosen_sp;
440}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000441#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000442
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000443#ifndef LLDB_DISABLE_PYTHON
Enrico Granataa777dc22012-05-08 21:49:57 +0000444lldb::SyntheticChildrenSP
445FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
446{
447 if (!type_sp)
448 return lldb::SyntheticChildrenSP();
449 lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
Enrico Granata5548cb52013-01-28 23:47:25 +0000450 lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
Enrico Granataa777dc22012-05-08 21:49:57 +0000451 if (filter_sp->GetRevision() > synth_sp->GetRevision())
452 return lldb::SyntheticChildrenSP(filter_sp.get());
453 else
454 return lldb::SyntheticChildrenSP(synth_sp.get());
455}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000456#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000457
Enrico Granatac5827132014-09-05 20:45:07 +0000458lldb::TypeValidatorImplSP
459FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
460{
461 if (!type_sp)
462 return lldb::TypeValidatorImplSP();
463 lldb::TypeValidatorImplSP validator_chosen_sp;
464 uint32_t num_categories = m_categories_map.GetCount();
465 lldb::TypeCategoryImplSP category_sp;
466 uint32_t prio_category = UINT32_MAX;
467 for (uint32_t category_id = 0;
468 category_id < num_categories;
469 category_id++)
470 {
471 category_sp = GetCategoryAtIndex(category_id);
472 if (category_sp->IsEnabled() == false)
473 continue;
474 lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
475 if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
476 {
477 prio_category = category_sp->GetEnabledPosition();
478 validator_chosen_sp = validator_current_sp;
479 }
480 }
481 return validator_chosen_sp;
482}
483
Enrico Granata980c0482015-09-01 18:22:39 +0000484void
485FormatManager::LoopThroughCategories (CategoryCallback callback, void* param)
486{
487 m_categories_map.LoopThrough(callback, param);
488 Mutex::Locker locker(m_language_categories_mutex);
489 for (const auto& entry : m_language_categories_map)
490 {
491 if (auto category_sp = entry.second->GetCategory())
492 {
493 if (!callback(param, category_sp))
494 break;
495 }
496 }
497}
498
Enrico Granata061858c2012-02-15 02:34:21 +0000499lldb::TypeCategoryImplSP
Enrico Granata9128ee22011-09-06 19:20:51 +0000500FormatManager::GetCategory (const ConstString& category_name,
Enrico Granatadb595cd2015-03-06 19:37:57 +0000501 bool can_create)
Enrico Granatadc940732011-08-23 00:32:52 +0000502{
503 if (!category_name)
Enrico Granata9128ee22011-09-06 19:20:51 +0000504 return GetCategory(m_default_category_name);
Enrico Granata061858c2012-02-15 02:34:21 +0000505 lldb::TypeCategoryImplSP category;
Enrico Granatadc940732011-08-23 00:32:52 +0000506 if (m_categories_map.Get(category_name, category))
507 return category;
508
509 if (!can_create)
Enrico Granata061858c2012-02-15 02:34:21 +0000510 return lldb::TypeCategoryImplSP();
Enrico Granatadc940732011-08-23 00:32:52 +0000511
Enrico Granata061858c2012-02-15 02:34:21 +0000512 m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
Enrico Granata9128ee22011-09-06 19:20:51 +0000513 return GetCategory(category_name);
Enrico Granatadc940732011-08-23 00:32:52 +0000514}
515
Enrico Granataf4efecd2011-07-12 22:56:10 +0000516lldb::Format
517FormatManager::GetSingleItemFormat(lldb::Format vector_format)
518{
519 switch(vector_format)
520 {
521 case eFormatVectorOfChar:
522 return eFormatCharArray;
523
524 case eFormatVectorOfSInt8:
525 case eFormatVectorOfSInt16:
526 case eFormatVectorOfSInt32:
527 case eFormatVectorOfSInt64:
528 return eFormatDecimal;
529
530 case eFormatVectorOfUInt8:
531 case eFormatVectorOfUInt16:
532 case eFormatVectorOfUInt32:
533 case eFormatVectorOfUInt64:
534 case eFormatVectorOfUInt128:
535 return eFormatHex;
536
537 case eFormatVectorOfFloat32:
538 case eFormatVectorOfFloat64:
539 return eFormatFloat;
540
541 default:
542 return lldb::eFormatInvalid;
543 }
Greg Clayton3418c852011-08-10 02:10:13 +0000544}
Enrico Granatac482a192011-08-17 22:13:59 +0000545
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000546bool
547FormatManager::ShouldPrintAsOneLiner (ValueObject& valobj)
548{
Enrico Granata553fad52013-10-25 23:09:40 +0000549 // if settings say no oneline whatsoever
Enrico Granata90a8db32013-10-31 21:01:07 +0000550 if (valobj.GetTargetSP().get() && valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
Enrico Granata553fad52013-10-25 23:09:40 +0000551 return false; // then don't oneline
552
Enrico Granata42fa4af2014-09-11 23:00:27 +0000553 // if this object has a summary, then ask the summary
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000554 if (valobj.GetSummaryFormat().get() != nullptr)
Enrico Granata42fa4af2014-09-11 23:00:27 +0000555 return valobj.GetSummaryFormat()->IsOneLiner();
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000556
557 // no children, no party
558 if (valobj.GetNumChildren() == 0)
559 return false;
560
561 size_t total_children_name_len = 0;
562
563 for (size_t idx = 0;
564 idx < valobj.GetNumChildren();
565 idx++)
566 {
Enrico Granataddac7612014-10-09 18:47:36 +0000567 bool is_synth_val = false;
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000568 ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
569 // something is wrong here - bail out
570 if (!child_sp)
571 return false;
572 // if we decided to define synthetic children for a type, we probably care enough
573 // to show them, but avoid nesting children in children
574 if (child_sp->GetSyntheticChildren().get() != nullptr)
Enrico Granataddac7612014-10-09 18:47:36 +0000575 {
576 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
577 // wait.. wat? just get out of here..
578 if (!synth_sp)
579 return false;
580 // but if we only have them to provide a value, keep going
581 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
582 is_synth_val = true;
583 else
584 return false;
585 }
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000586
587 total_children_name_len += child_sp->GetName().GetLength();
588
589 // 50 itself is a "randomly" chosen number - the idea is that
590 // overly long structs should not get this treatment
591 // FIXME: maybe make this a user-tweakable setting?
592 if (total_children_name_len > 50)
593 return false;
594
595 // if a summary is there..
596 if (child_sp->GetSummaryFormat())
597 {
598 // and it wants children, then bail out
Enrico Granata8a068e62014-04-23 23:16:25 +0000599 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000600 return false;
601 }
602
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000603 // if this child has children..
604 if (child_sp->GetNumChildren())
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000605 {
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000606 // ...and no summary...
607 // (if it had a summary and the summary wanted children, we would have bailed out anyway
608 // 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 +0000609 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 +0000610 return false; // then bail out
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000611 }
612 }
613 return true;
614}
615
Enrico Granata02b66762011-08-19 01:14:49 +0000616ConstString
617FormatManager::GetValidTypeName (const ConstString& type)
618{
619 return ::GetValidTypeName_Impl(type);
620}
621
Enrico Granata5548cb52013-01-28 23:47:25 +0000622ConstString
Enrico Granata980c0482015-09-01 18:22:39 +0000623FormatManager::GetTypeForCache (ValueObject& valobj,
624 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000625{
626 if (use_dynamic == lldb::eNoDynamicValues)
627 {
628 if (valobj.IsDynamic())
629 {
630 if (valobj.GetStaticValue())
631 return valobj.GetStaticValue()->GetQualifiedTypeName();
632 else
633 return ConstString();
634 }
635 else
636 return valobj.GetQualifiedTypeName();
637 }
638 if (valobj.IsDynamic())
639 return valobj.GetQualifiedTypeName();
640 if (valobj.GetDynamicValue(use_dynamic))
641 return valobj.GetDynamicValue(use_dynamic)->GetQualifiedTypeName();
642 return ConstString();
643}
644
Enrico Granatad3233c12015-09-09 01:10:46 +0000645std::vector<lldb::LanguageType>
646FormatManager::GetCandidateLanguages (ValueObject& valobj)
Enrico Granata980c0482015-09-01 18:22:39 +0000647{
648 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
Enrico Granataac494532015-09-09 22:30:24 +0000649 return GetCandidateLanguages(lang_type);
650}
651
652std::vector<lldb::LanguageType>
653FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
654{
Enrico Granata980c0482015-09-01 18:22:39 +0000655 switch (lang_type)
656 {
Enrico Granata33e97e62015-09-04 21:01:18 +0000657 case lldb::eLanguageTypeC:
658 case lldb::eLanguageTypeC89:
659 case lldb::eLanguageTypeC99:
660 case lldb::eLanguageTypeC11:
661 case lldb::eLanguageTypeC_plus_plus:
662 case lldb::eLanguageTypeC_plus_plus_03:
663 case lldb::eLanguageTypeC_plus_plus_11:
664 case lldb::eLanguageTypeC_plus_plus_14:
Enrico Granata170c3952015-09-14 22:18:32 +0000665 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
Enrico Granata980c0482015-09-01 18:22:39 +0000666 default:
667 return {lang_type};
668 }
669}
670
671LanguageCategory*
672FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
673{
674 Mutex::Locker locker(m_language_categories_mutex);
675 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
676 if (iter != end)
677 return iter->second.get();
678 LanguageCategory* lang_category = new LanguageCategory(lang_type);
679 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
680 return lang_category;
681}
682
Enrico Granataecd02bc2014-08-19 18:47:58 +0000683lldb::TypeFormatImplSP
684FormatManager::GetHardcodedFormat (ValueObject& valobj,
685 lldb::DynamicValueType use_dynamic)
Enrico Granata686f3de2013-10-30 23:46:27 +0000686{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000687 TypeFormatImplSP retval_sp;
688
689 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granataecd02bc2014-08-19 18:47:58 +0000690 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000691 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
692 {
693 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
694 break;
695 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000696 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000697
698 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000699}
700
Enrico Granata852cc952013-10-08 19:03:22 +0000701lldb::TypeFormatImplSP
702FormatManager::GetFormat (ValueObject& valobj,
703 lldb::DynamicValueType use_dynamic)
704{
705 TypeFormatImplSP retval;
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000706 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
707 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
708 if (valobj_type)
709 {
710 if (log)
711 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
712 if (m_format_cache.GetFormat(valobj_type,retval))
713 {
714 if (log)
715 {
716 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
717 if (log->GetDebug())
718 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
719 }
720 return retval;
721 }
722 if (log)
723 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
724 }
Enrico Granata980c0482015-09-01 18:22:39 +0000725
726 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
727
728 retval = m_categories_map.GetFormat(valobj, use_dynamic, matches);
729 if (!retval)
730 {
731 if (log)
732 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
733 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
734 {
735 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
736 {
737 if (lang_category->Get(valobj, use_dynamic, matches, retval))
738 break;
739 }
740 }
741 if (retval)
742 {
743 if (log)
744 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
745 return retval;
746 }
747 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000748 if (!retval)
749 {
750 if (log)
751 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
752 retval = GetHardcodedFormat(valobj, use_dynamic);
753 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000754
755 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000756 {
757 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000758 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
759 static_cast<void*>(retval.get()),
760 valobj_type.AsCString("<invalid>"));
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000761 m_format_cache.SetFormat(valobj_type,retval);
762 }
763 if (log && log->GetDebug())
764 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 +0000765 return retval;
766}
767
Enrico Granataecd02bc2014-08-19 18:47:58 +0000768lldb::TypeSummaryImplSP
769FormatManager::GetHardcodedSummaryFormat (ValueObject& valobj,
770 lldb::DynamicValueType use_dynamic)
Enrico Granata686f3de2013-10-30 23:46:27 +0000771{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000772 TypeSummaryImplSP retval_sp;
773
774 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granataecd02bc2014-08-19 18:47:58 +0000775 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000776 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
777 {
778 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
779 break;
780 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000781 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000782
783 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000784}
785
Enrico Granata5548cb52013-01-28 23:47:25 +0000786lldb::TypeSummaryImplSP
787FormatManager::GetSummaryFormat (ValueObject& valobj,
788 lldb::DynamicValueType use_dynamic)
789{
790 TypeSummaryImplSP retval;
Greg Clayton5160ce52013-03-27 23:08:40 +0000791 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata5548cb52013-01-28 23:47:25 +0000792 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
793 if (valobj_type)
794 {
795 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000796 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000797 if (m_format_cache.GetSummary(valobj_type,retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000798 {
799 if (log)
800 {
801 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000802 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000803 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 +0000804 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000805 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000806 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000807 if (log)
808 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
809 }
Enrico Granata980c0482015-09-01 18:22:39 +0000810
811 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
812
813 retval = m_categories_map.GetSummaryFormat(valobj, use_dynamic, matches);
814 if (!retval)
815 {
816 if (log)
817 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
818 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
819 {
820 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
821 {
822 if (lang_category->Get(valobj, use_dynamic, matches, retval))
823 break;
824 }
825 }
826 if (retval)
827 {
828 if (log)
829 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
830 return retval;
831 }
832 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000833 if (!retval)
834 {
835 if (log)
836 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
837 retval = GetHardcodedSummaryFormat(valobj, use_dynamic);
838 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000839
840 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000841 {
842 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000843 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
844 static_cast<void*>(retval.get()),
845 valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000846 m_format_cache.SetSummary(valobj_type,retval);
847 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000848 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000849 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 +0000850 return retval;
851}
852
853#ifndef LLDB_DISABLE_PYTHON
Enrico Granataecd02bc2014-08-19 18:47:58 +0000854lldb::SyntheticChildrenSP
855FormatManager::GetHardcodedSyntheticChildren (ValueObject& valobj,
856 lldb::DynamicValueType use_dynamic)
Enrico Granata686f3de2013-10-30 23:46:27 +0000857{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000858 SyntheticChildrenSP retval_sp;
859
860 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granataecd02bc2014-08-19 18:47:58 +0000861 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000862 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
863 {
864 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
865 break;
866 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000867 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000868
869 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000870}
871
Enrico Granata5548cb52013-01-28 23:47:25 +0000872lldb::SyntheticChildrenSP
873FormatManager::GetSyntheticChildren (ValueObject& valobj,
Enrico Granatac2a96402013-06-26 01:03:38 +0000874 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000875{
876 SyntheticChildrenSP retval;
Greg Clayton5160ce52013-03-27 23:08:40 +0000877 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata5548cb52013-01-28 23:47:25 +0000878 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
879 if (valobj_type)
880 {
881 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000882 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000883 if (m_format_cache.GetSynthetic(valobj_type,retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000884 {
885 if (log)
886 {
887 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000888 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000889 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 +0000890 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000891 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000892 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000893 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000894 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
Enrico Granata5548cb52013-01-28 23:47:25 +0000895 }
Enrico Granata980c0482015-09-01 18:22:39 +0000896
897 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
898
899 retval = m_categories_map.GetSyntheticChildren(valobj, use_dynamic, matches);
900 if (!retval)
901 {
902 if (log)
903 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
904 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
905 {
906 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
907 {
908 if (lang_category->Get(valobj, use_dynamic, matches, retval))
909 break;
910 }
911 }
912 if (retval)
913 {
914 if (log)
915 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
916 return retval;
917 }
918 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000919 if (!retval)
920 {
921 if (log)
922 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
923 retval = GetHardcodedSyntheticChildren(valobj, use_dynamic);
924 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000925
926 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000927 {
928 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000929 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
930 static_cast<void*>(retval.get()),
931 valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000932 m_format_cache.SetSynthetic(valobj_type,retval);
933 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000934 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000935 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 +0000936 return retval;
937}
938#endif
Enrico Granata5548cb52013-01-28 23:47:25 +0000939
Enrico Granatac5827132014-09-05 20:45:07 +0000940lldb::TypeValidatorImplSP
941FormatManager::GetValidator (ValueObject& valobj,
942 lldb::DynamicValueType use_dynamic)
943{
944 TypeValidatorImplSP retval;
945 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
946 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
947 if (valobj_type)
948 {
949 if (log)
950 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
951 if (m_format_cache.GetValidator(valobj_type,retval))
952 {
953 if (log)
954 {
955 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
956 if (log->GetDebug())
957 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
958 }
959 return retval;
960 }
961 if (log)
962 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
963 }
Enrico Granata980c0482015-09-01 18:22:39 +0000964
965 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
966
967 retval = m_categories_map.GetValidator(valobj, use_dynamic, matches);
968 if (!retval)
969 {
970 if (log)
971 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
972 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
973 {
974 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
975 {
976 if (lang_category->Get(valobj, use_dynamic, matches, retval))
977 break;
978 }
979 }
980 if (retval)
981 {
982 if (log)
983 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
984 return retval;
985 }
986 }
Enrico Granatac5827132014-09-05 20:45:07 +0000987 if (!retval)
988 {
989 if (log)
990 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
991 retval = GetHardcodedValidator(valobj, use_dynamic);
992 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000993
994 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granatac5827132014-09-05 20:45:07 +0000995 {
996 if (log)
997 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
998 static_cast<void*>(retval.get()),
999 valobj_type.AsCString("<invalid>"));
1000 m_format_cache.SetValidator(valobj_type,retval);
1001 }
1002 if (log && log->GetDebug())
1003 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1004 return retval;
1005}
1006
1007lldb::TypeValidatorImplSP
1008FormatManager::GetHardcodedValidator (ValueObject& valobj,
1009 lldb::DynamicValueType use_dynamic)
1010{
Enrico Granata7cb59e12015-09-16 18:28:11 +00001011 TypeValidatorImplSP retval_sp;
1012
1013 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granatac5827132014-09-05 20:45:07 +00001014 {
Enrico Granata7cb59e12015-09-16 18:28:11 +00001015 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1016 {
1017 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
1018 break;
1019 }
Enrico Granatac5827132014-09-05 20:45:07 +00001020 }
Enrico Granata7cb59e12015-09-16 18:28:11 +00001021
1022 return retval_sp;
Enrico Granatac5827132014-09-05 20:45:07 +00001023}
1024
Enrico Granata5548cb52013-01-28 23:47:25 +00001025FormatManager::FormatManager() :
1026 m_format_cache(),
Enrico Granatac482a192011-08-17 22:13:59 +00001027 m_named_summaries_map(this),
1028 m_last_revision(0),
1029 m_categories_map(this),
Enrico Granata980c0482015-09-01 18:22:39 +00001030 m_language_categories_map(),
1031 m_language_categories_mutex(Mutex::eMutexTypeRecursive),
Enrico Granata1d887492011-08-22 18:36:52 +00001032 m_default_category_name(ConstString("default")),
1033 m_system_category_name(ConstString("system")),
Enrico Granata7cb59e12015-09-16 18:28:11 +00001034 m_vectortypes_category_name(ConstString("VectorTypes"))
Enrico Granatac482a192011-08-17 22:13:59 +00001035{
Enrico Granata864e3e82012-02-17 03:18:30 +00001036 LoadSystemFormatters();
Enrico Granata170c3952015-09-14 22:18:32 +00001037 LoadVectorFormatters();
Enrico Granata864e3e82012-02-17 03:18:30 +00001038
Enrico Granatafa6b2782015-09-17 00:14:50 +00001039 EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1040 EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
Enrico Granata864e3e82012-02-17 03:18:30 +00001041}
1042
1043void
Enrico Granata864e3e82012-02-17 03:18:30 +00001044FormatManager::LoadSystemFormatters()
1045{
Enrico Granataf68df122013-01-10 22:08:35 +00001046
1047 TypeSummaryImpl::Flags string_flags;
Enrico Granata0337c272013-02-22 00:37:31 +00001048 string_flags.SetCascades(true)
Enrico Granataf68df122013-01-10 22:08:35 +00001049 .SetSkipPointers(true)
1050 .SetSkipReferences(false)
1051 .SetDontShowChildren(true)
1052 .SetDontShowValue(false)
1053 .SetShowMembersOneLiner(false)
1054 .SetHideItemNames(false);
1055
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001056 TypeSummaryImpl::Flags string_array_flags;
Enrico Granatad2911632015-07-28 02:13:03 +00001057 string_array_flags.SetCascades(true)
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001058 .SetSkipPointers(true)
1059 .SetSkipReferences(false)
1060 .SetDontShowChildren(true)
1061 .SetDontShowValue(true)
1062 .SetShowMembersOneLiner(false)
1063 .SetHideItemNames(false);
1064
Enrico Granataf68df122013-01-10 22:08:35 +00001065 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001066
1067
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001068 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
Enrico Granata061858c2012-02-15 02:34:21 +00001069 "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001070
1071 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001072 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
Enrico Granatac482a192011-08-17 22:13:59 +00001073
Enrico Granata061858c2012-02-15 02:34:21 +00001074 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
Enrico Granatac482a192011-08-17 22:13:59 +00001075
Enrico Granatab72a5012013-12-20 09:38:13 +00001076 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1077 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1078 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
Enrico Granataaff65652013-10-21 17:29:51 +00001079
Enrico Granata4ed7ef12012-07-13 18:54:40 +00001080 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1081 .SetSkipPointers(true)
1082 .SetSkipReferences(true)
1083 .SetDontShowChildren(true)
1084 .SetDontShowValue(false)
1085 .SetShowMembersOneLiner(false)
1086 .SetHideItemNames(false),
1087 "${var%O}"));
1088
Enrico Granatab72a5012013-12-20 09:38:13 +00001089 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
Enrico Granatad3d444f2012-02-23 23:10:03 +00001090
Jason Molenda1a100cd2013-01-12 04:24:50 +00001091#ifndef LLDB_DISABLE_PYTHON
Enrico Granata4cc21772013-10-08 20:59:02 +00001092 TypeFormatImpl::Flags fourchar_flags;
1093 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1094
1095 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
Jason Molenda1a100cd2013-01-12 04:24:50 +00001096#endif
Enrico Granatad3d444f2012-02-23 23:10:03 +00001097}
Enrico Granatab2698cd2012-09-13 18:27:09 +00001098
Enrico Granata864e3e82012-02-17 03:18:30 +00001099void
Enrico Granata170c3952015-09-14 22:18:32 +00001100FormatManager::LoadVectorFormatters()
Enrico Granata864e3e82012-02-17 03:18:30 +00001101{
Enrico Granata864e3e82012-02-17 03:18:30 +00001102 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
Enrico Granata170c3952015-09-14 22:18:32 +00001103
Enrico Granata864e3e82012-02-17 03:18:30 +00001104 TypeSummaryImpl::Flags vector_flags;
1105 vector_flags.SetCascades(true)
1106 .SetSkipPointers(true)
1107 .SetSkipReferences(false)
1108 .SetDontShowChildren(true)
1109 .SetDontShowValue(false)
1110 .SetShowMembersOneLiner(true)
1111 .SetHideItemNames(true);
1112
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001113 AddStringSummary(vectors_category_sp,
1114 "${var.uint128}",
1115 ConstString("builtin_type_vec128"),
Enrico Granata170c3952015-09-14 22:18:32 +00001116 vector_flags);
1117
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001118 AddStringSummary(vectors_category_sp,
1119 "",
1120 ConstString("float [4]"),
1121 vector_flags);
1122 AddStringSummary(vectors_category_sp,
1123 "",
1124 ConstString("int32_t [4]"),
1125 vector_flags);
1126 AddStringSummary(vectors_category_sp,
1127 "",
1128 ConstString("int16_t [8]"),
1129 vector_flags);
1130 AddStringSummary(vectors_category_sp,
1131 "",
1132 ConstString("vDouble"),
1133 vector_flags);
1134 AddStringSummary(vectors_category_sp,
1135 "",
1136 ConstString("vFloat"),
1137 vector_flags);
1138 AddStringSummary(vectors_category_sp,
1139 "",
1140 ConstString("vSInt8"),
1141 vector_flags);
1142 AddStringSummary(vectors_category_sp,
1143 "",
1144 ConstString("vSInt16"),
1145 vector_flags);
1146 AddStringSummary(vectors_category_sp,
1147 "",
1148 ConstString("vSInt32"),
1149 vector_flags);
1150 AddStringSummary(vectors_category_sp,
1151 "",
1152 ConstString("vUInt16"),
1153 vector_flags);
1154 AddStringSummary(vectors_category_sp,
1155 "",
1156 ConstString("vUInt8"),
1157 vector_flags);
1158 AddStringSummary(vectors_category_sp,
1159 "",
1160 ConstString("vUInt16"),
1161 vector_flags);
1162 AddStringSummary(vectors_category_sp,
1163 "",
1164 ConstString("vUInt32"),
1165 vector_flags);
1166 AddStringSummary(vectors_category_sp,
1167 "",
1168 ConstString("vBool32"),
1169 vector_flags);
Greg Claytond4e25522011-10-12 00:53:29 +00001170}