blob: 03368f2acd99756562ff22247e5a4fe5450966c2 [file] [log] [blame]
Greg Clayton4a33d312011-06-23 17:59:56 +00001//===-- FormatManager.cpp -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Enrico Granata5548cb52013-01-28 23:47:25 +000010#include "lldb/DataFormatters/FormatManager.h"
Greg Clayton4a33d312011-06-23 17:59:56 +000011
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16
Enrico Granataf2bbf712011-07-15 02:26:42 +000017#include "lldb/Core/Debugger.h"
Enrico Granatadf7e79e2015-09-02 01:21:31 +000018#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granata980c0482015-09-01 18:22:39 +000019#include "lldb/DataFormatters/LanguageCategory.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000020#include "lldb/Target/ExecutionContext.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000021#include "lldb/Target/Language.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000022#include "lldb/Target/Platform.h"
Saleem Abdulrasool28606952014-06-27 05:17:41 +000023#include "llvm/ADT/STLExtras.h"
Enrico Granataf2bbf712011-07-15 02:26:42 +000024
Enrico Granata980c0482015-09-01 18:22:39 +000025#include <initializer_list>
26
Greg Clayton4a33d312011-06-23 17:59:56 +000027using namespace lldb;
28using namespace lldb_private;
Enrico Granatadf7e79e2015-09-02 01:21:31 +000029using namespace lldb_private::formatters;
Greg Claytonbb7f31f2011-06-23 21:22:24 +000030
31struct FormatInfo
32{
33 Format format;
34 const char format_char; // One or more format characters that can be used for this format.
35 const char *format_name; // Long format name that can be used to specify the current format
36};
37
38static FormatInfo
39g_format_infos[] =
40{
41 { eFormatDefault , '\0' , "default" },
42 { eFormatBoolean , 'B' , "boolean" },
43 { eFormatBinary , 'b' , "binary" },
44 { eFormatBytes , 'y' , "bytes" },
45 { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
46 { eFormatChar , 'c' , "character" },
47 { eFormatCharPrintable , 'C' , "printable character" },
48 { eFormatComplexFloat , 'F' , "complex float" },
49 { eFormatCString , 's' , "c-string" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000050 { eFormatDecimal , 'd' , "decimal" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000051 { eFormatEnum , 'E' , "enumeration" },
52 { eFormatHex , 'x' , "hex" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000053 { eFormatHexUppercase , 'X' , "uppercase hex" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000054 { eFormatFloat , 'f' , "float" },
55 { eFormatOctal , 'o' , "octal" },
56 { eFormatOSType , 'O' , "OSType" },
57 { eFormatUnicode16 , 'U' , "unicode16" },
58 { eFormatUnicode32 , '\0' , "unicode32" },
59 { eFormatUnsigned , 'u' , "unsigned decimal" },
60 { eFormatPointer , 'p' , "pointer" },
61 { eFormatVectorOfChar , '\0' , "char[]" },
62 { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
63 { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
64 { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
65 { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
Enrico Granatae443ba72011-07-06 15:56:06 +000066 { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
67 { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
68 { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
69 { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000070 { eFormatVectorOfFloat32, '\0' , "float32[]" },
71 { eFormatVectorOfFloat64, '\0' , "float64[]" },
72 { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
73 { eFormatComplexInteger , 'I' , "complex integer" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000074 { eFormatCharArray , 'a' , "character array" },
75 { eFormatAddressInfo , 'A' , "address" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000076 { eFormatHexFloat , '\0' , "hex float" },
Sean Callananbf154da2012-08-08 17:35:10 +000077 { eFormatInstruction , 'i' , "instruction" },
78 { eFormatVoid , 'v' , "void" }
Greg Claytonbb7f31f2011-06-23 21:22:24 +000079};
80
Saleem Abdulrasool28606952014-06-27 05:17:41 +000081static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
Greg Claytonbb7f31f2011-06-23 21:22:24 +000082
83static bool
84GetFormatFromFormatChar (char format_char, Format &format)
85{
86 for (uint32_t i=0; i<g_num_format_infos; ++i)
87 {
88 if (g_format_infos[i].format_char == format_char)
89 {
90 format = g_format_infos[i].format;
91 return true;
92 }
93 }
94 format = eFormatInvalid;
95 return false;
96}
97
98static bool
99GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
100{
101 uint32_t i;
102 for (i=0; i<g_num_format_infos; ++i)
103 {
104 if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
105 {
106 format = g_format_infos[i].format;
107 return true;
108 }
109 }
110
111 if (partial_match_ok)
112 {
113 for (i=0; i<g_num_format_infos; ++i)
114 {
115 if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
116 {
117 format = g_format_infos[i].format;
118 return true;
119 }
120 }
121 }
122 format = eFormatInvalid;
123 return false;
124}
125
126bool
127FormatManager::GetFormatFromCString (const char *format_cstr,
128 bool partial_match_ok,
129 lldb::Format &format)
130{
131 bool success = false;
132 if (format_cstr && format_cstr[0])
133 {
134 if (format_cstr[1] == '\0')
135 {
136 success = GetFormatFromFormatChar (format_cstr[0], format);
137 if (success)
138 return true;
139 }
140
141 success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
142 }
143 if (!success)
144 format = eFormatInvalid;
145 return success;
146}
147
148char
149FormatManager::GetFormatAsFormatChar (lldb::Format format)
150{
151 for (uint32_t i=0; i<g_num_format_infos; ++i)
152 {
153 if (g_format_infos[i].format == format)
154 return g_format_infos[i].format_char;
155 }
156 return '\0';
157}
Greg Claytonbb7f31f2011-06-23 21:22:24 +0000158
159const char *
160FormatManager::GetFormatAsCString (Format format)
161{
162 if (format >= eFormatDefault && format < kNumFormats)
163 return g_format_infos[format].format_name;
164 return NULL;
165}
Enrico Granata0a3958e2011-07-02 00:25:22 +0000166
Enrico Granatade61cec2013-11-22 00:02:13 +0000167void
Enrico Granata33e97e62015-09-04 21:01:18 +0000168FormatManager::EnableAllCategories ()
169{
170 m_categories_map.EnableAllCategories ();
171 Mutex::Locker lang_locker(m_language_categories_mutex);
172 for (auto& iter : m_language_categories_map)
173 {
174 if (iter.second)
175 iter.second->Enable();
176 }
177}
178
179void
180FormatManager::DisableAllCategories ()
181{
182 m_categories_map.DisableAllCategories ();
183 Mutex::Locker lang_locker(m_language_categories_mutex);
184 for (auto& iter : m_language_categories_map)
185 {
186 if (iter.second)
187 iter.second->Disable();
188 }
189}
190
191void
Enrico Granatade61cec2013-11-22 00:02:13 +0000192FormatManager::GetPossibleMatches (ValueObject& valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000193 CompilerType compiler_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000194 uint32_t reason,
195 lldb::DynamicValueType use_dynamic,
196 FormattersMatchVector& entries,
197 bool did_strip_ptr,
198 bool did_strip_ref,
199 bool did_strip_typedef,
200 bool root_level)
201{
Enrico Granatac6bf2e22015-09-23 01:39:46 +0000202 compiler_type = compiler_type.GetTypeForFormatters();
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000203 ConstString type_name(compiler_type.GetConstTypeName());
Enrico Granatade61cec2013-11-22 00:02:13 +0000204 if (valobj.GetBitfieldBitSize() > 0)
205 {
206 StreamString sstring;
207 sstring.Printf("%s:%d",type_name.AsCString(),valobj.GetBitfieldBitSize());
208 ConstString bitfieldname = ConstString(sstring.GetData());
209 entries.push_back({bitfieldname,0,did_strip_ptr,did_strip_ref,did_strip_typedef});
210 reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
211 }
212 entries.push_back({type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000213
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000214 ConstString display_type_name(compiler_type.GetDisplayTypeName());
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000215 if (display_type_name != type_name)
216 entries.push_back({display_type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
217
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000218 for (bool is_rvalue_ref = true, j = true; j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false)
Enrico Granatade61cec2013-11-22 00:02:13 +0000219 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000220 CompilerType non_ref_type = compiler_type.GetNonReferenceType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000221 GetPossibleMatches(valobj,
222 non_ref_type,
223 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
224 use_dynamic,
225 entries,
226 did_strip_ptr,
227 true,
228 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000229 if (non_ref_type.IsTypedefType())
230 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000231 CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
Greg Clayton56939cb2015-09-17 22:23:34 +0000232 deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000233 GetPossibleMatches(valobj,
234 deffed_referenced_type,
235 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
236 use_dynamic,
237 entries,
238 did_strip_ptr,
239 did_strip_ref,
240 true); // this is not exactly the usual meaning of stripping typedefs
241 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000242 }
Enrico Granata1ac62962014-04-10 00:14:07 +0000243
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000244 if (compiler_type.IsPointerType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000245 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000246 CompilerType non_ptr_type = compiler_type.GetPointeeType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000247 GetPossibleMatches(valobj,
248 non_ptr_type,
249 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
250 use_dynamic,
251 entries,
252 true,
253 did_strip_ref,
254 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000255 if (non_ptr_type.IsTypedefType())
256 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000257 CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000258 GetPossibleMatches(valobj,
259 deffed_pointed_type,
260 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
261 use_dynamic,
262 entries,
263 did_strip_ptr,
264 did_strip_ref,
265 true); // this is not exactly the usual meaning of stripping typedefs
266 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000267 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000268
Enrico Granatad3233c12015-09-09 01:10:46 +0000269 for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
Enrico Granatade61cec2013-11-22 00:02:13 +0000270 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000271 if (Language* language = Language::FindPlugin(language_type))
Enrico Granatade61cec2013-11-22 00:02:13 +0000272 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000273 for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
Enrico Granatade61cec2013-11-22 00:02:13 +0000274 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000275 entries.push_back({candidate,
276 reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
277 did_strip_ptr,
278 did_strip_ref,
279 did_strip_typedef});
280 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000281 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000282 }
Enrico Granatad3233c12015-09-09 01:10:46 +0000283
Enrico Granatade61cec2013-11-22 00:02:13 +0000284 // try to strip typedef chains
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000285 if (compiler_type.IsTypedefType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000286 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000287 CompilerType deffed_type = compiler_type.GetTypedefedType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000288 GetPossibleMatches(valobj,
289 deffed_type,
290 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
291 use_dynamic,
292 entries,
293 did_strip_ptr,
294 did_strip_ref,
295 true);
296 }
297
298 if (root_level)
299 {
300 do {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000301 if (!compiler_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000302 break;
303
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000304 CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType();
305 if (!unqual_compiler_ast_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000306 break;
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000307 if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000308 GetPossibleMatches (valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000309 unqual_compiler_ast_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000310 reason,
311 use_dynamic,
312 entries,
313 did_strip_ptr,
314 did_strip_ref,
315 did_strip_typedef);
316 } while(false);
317
318
319 // if all else fails, go to static type
320 if (valobj.IsDynamic())
321 {
322 lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
323 if (static_value_sp)
324 GetPossibleMatches(*static_value_sp.get(),
Greg Clayton99558cc42015-08-24 23:46:31 +0000325 static_value_sp->GetCompilerType(),
Enrico Granatade61cec2013-11-22 00:02:13 +0000326 reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
327 use_dynamic,
328 entries,
329 did_strip_ptr,
330 did_strip_ref,
331 did_strip_typedef,
332 true);
333 }
334 }
335}
336
Enrico Granata852cc952013-10-08 19:03:22 +0000337lldb::TypeFormatImplSP
338FormatManager::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
339{
340 if (!type_sp)
341 return lldb::TypeFormatImplSP();
342 lldb::TypeFormatImplSP format_chosen_sp;
343 uint32_t num_categories = m_categories_map.GetCount();
344 lldb::TypeCategoryImplSP category_sp;
345 uint32_t prio_category = UINT32_MAX;
346 for (uint32_t category_id = 0;
347 category_id < num_categories;
348 category_id++)
349 {
350 category_sp = GetCategoryAtIndex(category_id);
351 if (category_sp->IsEnabled() == false)
352 continue;
353 lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp);
354 if (format_current_sp && (format_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
355 {
356 prio_category = category_sp->GetEnabledPosition();
357 format_chosen_sp = format_current_sp;
358 }
359 }
360 return format_chosen_sp;
361}
362
Enrico Granataa777dc22012-05-08 21:49:57 +0000363lldb::TypeSummaryImplSP
364FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
365{
366 if (!type_sp)
367 return lldb::TypeSummaryImplSP();
368 lldb::TypeSummaryImplSP summary_chosen_sp;
369 uint32_t num_categories = m_categories_map.GetCount();
370 lldb::TypeCategoryImplSP category_sp;
371 uint32_t prio_category = UINT32_MAX;
372 for (uint32_t category_id = 0;
373 category_id < num_categories;
374 category_id++)
375 {
376 category_sp = GetCategoryAtIndex(category_id);
377 if (category_sp->IsEnabled() == false)
378 continue;
379 lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
380 if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
381 {
382 prio_category = category_sp->GetEnabledPosition();
383 summary_chosen_sp = summary_current_sp;
384 }
385 }
386 return summary_chosen_sp;
387}
388
389lldb::TypeFilterImplSP
390FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
391{
392 if (!type_sp)
393 return lldb::TypeFilterImplSP();
394 lldb::TypeFilterImplSP filter_chosen_sp;
395 uint32_t num_categories = m_categories_map.GetCount();
396 lldb::TypeCategoryImplSP category_sp;
397 uint32_t prio_category = UINT32_MAX;
398 for (uint32_t category_id = 0;
399 category_id < num_categories;
400 category_id++)
401 {
402 category_sp = GetCategoryAtIndex(category_id);
403 if (category_sp->IsEnabled() == false)
404 continue;
405 lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
406 if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
407 {
408 prio_category = category_sp->GetEnabledPosition();
409 filter_chosen_sp = filter_current_sp;
410 }
411 }
412 return filter_chosen_sp;
413}
414
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000415#ifndef LLDB_DISABLE_PYTHON
Enrico Granata5548cb52013-01-28 23:47:25 +0000416lldb::ScriptedSyntheticChildrenSP
Enrico Granataa777dc22012-05-08 21:49:57 +0000417FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
418{
419 if (!type_sp)
Enrico Granata5548cb52013-01-28 23:47:25 +0000420 return lldb::ScriptedSyntheticChildrenSP();
421 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
Enrico Granataa777dc22012-05-08 21:49:57 +0000422 uint32_t num_categories = m_categories_map.GetCount();
423 lldb::TypeCategoryImplSP category_sp;
424 uint32_t prio_category = UINT32_MAX;
425 for (uint32_t category_id = 0;
426 category_id < num_categories;
427 category_id++)
428 {
429 category_sp = GetCategoryAtIndex(category_id);
430 if (category_sp->IsEnabled() == false)
431 continue;
Enrico Granata5548cb52013-01-28 23:47:25 +0000432 lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
Enrico Granataa777dc22012-05-08 21:49:57 +0000433 if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
434 {
435 prio_category = category_sp->GetEnabledPosition();
436 synth_chosen_sp = synth_current_sp;
437 }
438 }
439 return synth_chosen_sp;
440}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000441#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000442
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000443#ifndef LLDB_DISABLE_PYTHON
Enrico Granataa777dc22012-05-08 21:49:57 +0000444lldb::SyntheticChildrenSP
445FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
446{
447 if (!type_sp)
448 return lldb::SyntheticChildrenSP();
449 lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
Enrico Granata5548cb52013-01-28 23:47:25 +0000450 lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
Enrico Granataa777dc22012-05-08 21:49:57 +0000451 if (filter_sp->GetRevision() > synth_sp->GetRevision())
452 return lldb::SyntheticChildrenSP(filter_sp.get());
453 else
454 return lldb::SyntheticChildrenSP(synth_sp.get());
455}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000456#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000457
Enrico Granatac5827132014-09-05 20:45:07 +0000458lldb::TypeValidatorImplSP
459FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
460{
461 if (!type_sp)
462 return lldb::TypeValidatorImplSP();
463 lldb::TypeValidatorImplSP validator_chosen_sp;
464 uint32_t num_categories = m_categories_map.GetCount();
465 lldb::TypeCategoryImplSP category_sp;
466 uint32_t prio_category = UINT32_MAX;
467 for (uint32_t category_id = 0;
468 category_id < num_categories;
469 category_id++)
470 {
471 category_sp = GetCategoryAtIndex(category_id);
472 if (category_sp->IsEnabled() == false)
473 continue;
474 lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
475 if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
476 {
477 prio_category = category_sp->GetEnabledPosition();
478 validator_chosen_sp = validator_current_sp;
479 }
480 }
481 return validator_chosen_sp;
482}
483
Enrico Granata980c0482015-09-01 18:22:39 +0000484void
485FormatManager::LoopThroughCategories (CategoryCallback callback, void* param)
486{
487 m_categories_map.LoopThrough(callback, param);
488 Mutex::Locker locker(m_language_categories_mutex);
489 for (const auto& entry : m_language_categories_map)
490 {
491 if (auto category_sp = entry.second->GetCategory())
492 {
493 if (!callback(param, category_sp))
494 break;
495 }
496 }
497}
498
Enrico Granata061858c2012-02-15 02:34:21 +0000499lldb::TypeCategoryImplSP
Enrico Granata9128ee22011-09-06 19:20:51 +0000500FormatManager::GetCategory (const ConstString& category_name,
Enrico Granatadb595cd2015-03-06 19:37:57 +0000501 bool can_create)
Enrico Granatadc940732011-08-23 00:32:52 +0000502{
503 if (!category_name)
Enrico Granata9128ee22011-09-06 19:20:51 +0000504 return GetCategory(m_default_category_name);
Enrico Granata061858c2012-02-15 02:34:21 +0000505 lldb::TypeCategoryImplSP category;
Enrico Granatadc940732011-08-23 00:32:52 +0000506 if (m_categories_map.Get(category_name, category))
507 return category;
508
509 if (!can_create)
Enrico Granata061858c2012-02-15 02:34:21 +0000510 return lldb::TypeCategoryImplSP();
Enrico Granatadc940732011-08-23 00:32:52 +0000511
Enrico Granata061858c2012-02-15 02:34:21 +0000512 m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
Enrico Granata9128ee22011-09-06 19:20:51 +0000513 return GetCategory(category_name);
Enrico Granatadc940732011-08-23 00:32:52 +0000514}
515
Enrico Granataf4efecd2011-07-12 22:56:10 +0000516lldb::Format
517FormatManager::GetSingleItemFormat(lldb::Format vector_format)
518{
519 switch(vector_format)
520 {
521 case eFormatVectorOfChar:
522 return eFormatCharArray;
523
524 case eFormatVectorOfSInt8:
525 case eFormatVectorOfSInt16:
526 case eFormatVectorOfSInt32:
527 case eFormatVectorOfSInt64:
528 return eFormatDecimal;
529
530 case eFormatVectorOfUInt8:
531 case eFormatVectorOfUInt16:
532 case eFormatVectorOfUInt32:
533 case eFormatVectorOfUInt64:
534 case eFormatVectorOfUInt128:
535 return eFormatHex;
536
537 case eFormatVectorOfFloat32:
538 case eFormatVectorOfFloat64:
539 return eFormatFloat;
540
541 default:
542 return lldb::eFormatInvalid;
543 }
Greg Clayton3418c852011-08-10 02:10:13 +0000544}
Enrico Granatac482a192011-08-17 22:13:59 +0000545
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000546bool
547FormatManager::ShouldPrintAsOneLiner (ValueObject& valobj)
548{
Enrico Granata553fad52013-10-25 23:09:40 +0000549 // if settings say no oneline whatsoever
Enrico Granata90a8db32013-10-31 21:01:07 +0000550 if (valobj.GetTargetSP().get() && valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
Enrico Granata553fad52013-10-25 23:09:40 +0000551 return false; // then don't oneline
552
Enrico Granata42fa4af2014-09-11 23:00:27 +0000553 // if this object has a summary, then ask the summary
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000554 if (valobj.GetSummaryFormat().get() != nullptr)
Enrico Granata42fa4af2014-09-11 23:00:27 +0000555 return valobj.GetSummaryFormat()->IsOneLiner();
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000556
557 // no children, no party
558 if (valobj.GetNumChildren() == 0)
559 return false;
560
Enrico Granata9c63f992015-09-23 02:04:34 +0000561 // ask the type if it has any opinion about this
562 // eLazyBoolCalculate == no opinion; other values should be self explanatory
563 CompilerType compiler_type(valobj.GetCompilerType());
564 if (compiler_type.IsValid())
565 {
566 switch (compiler_type.ShouldPrintAsOneLiner())
567 {
568 case eLazyBoolNo:
569 return false;
570 case eLazyBoolYes:
571 return true;
572 case eLazyBoolCalculate:
573 default:
574 break;
575 }
576 }
577
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000578 size_t total_children_name_len = 0;
579
580 for (size_t idx = 0;
581 idx < valobj.GetNumChildren();
582 idx++)
583 {
Enrico Granataddac7612014-10-09 18:47:36 +0000584 bool is_synth_val = false;
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000585 ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
586 // something is wrong here - bail out
587 if (!child_sp)
588 return false;
589 // if we decided to define synthetic children for a type, we probably care enough
590 // to show them, but avoid nesting children in children
591 if (child_sp->GetSyntheticChildren().get() != nullptr)
Enrico Granataddac7612014-10-09 18:47:36 +0000592 {
593 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
594 // wait.. wat? just get out of here..
595 if (!synth_sp)
596 return false;
597 // but if we only have them to provide a value, keep going
598 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
599 is_synth_val = true;
600 else
601 return false;
602 }
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000603
604 total_children_name_len += child_sp->GetName().GetLength();
605
606 // 50 itself is a "randomly" chosen number - the idea is that
607 // overly long structs should not get this treatment
608 // FIXME: maybe make this a user-tweakable setting?
609 if (total_children_name_len > 50)
610 return false;
611
612 // if a summary is there..
613 if (child_sp->GetSummaryFormat())
614 {
615 // and it wants children, then bail out
Enrico Granata8a068e62014-04-23 23:16:25 +0000616 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000617 return false;
618 }
619
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000620 // if this child has children..
621 if (child_sp->GetNumChildren())
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000622 {
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000623 // ...and no summary...
624 // (if it had a summary and the summary wanted children, we would have bailed out anyway
625 // 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 +0000626 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 +0000627 return false; // then bail out
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000628 }
629 }
630 return true;
631}
632
Enrico Granata02b66762011-08-19 01:14:49 +0000633ConstString
634FormatManager::GetValidTypeName (const ConstString& type)
635{
636 return ::GetValidTypeName_Impl(type);
637}
638
Enrico Granata5548cb52013-01-28 23:47:25 +0000639ConstString
Enrico Granata980c0482015-09-01 18:22:39 +0000640FormatManager::GetTypeForCache (ValueObject& valobj,
641 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000642{
643 if (use_dynamic == lldb::eNoDynamicValues)
644 {
645 if (valobj.IsDynamic())
646 {
647 if (valobj.GetStaticValue())
648 return valobj.GetStaticValue()->GetQualifiedTypeName();
649 else
650 return ConstString();
651 }
652 else
653 return valobj.GetQualifiedTypeName();
654 }
655 if (valobj.IsDynamic())
656 return valobj.GetQualifiedTypeName();
657 if (valobj.GetDynamicValue(use_dynamic))
658 return valobj.GetDynamicValue(use_dynamic)->GetQualifiedTypeName();
659 return ConstString();
660}
661
Enrico Granatad3233c12015-09-09 01:10:46 +0000662std::vector<lldb::LanguageType>
663FormatManager::GetCandidateLanguages (ValueObject& valobj)
Enrico Granata980c0482015-09-01 18:22:39 +0000664{
665 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
Enrico Granataac494532015-09-09 22:30:24 +0000666 return GetCandidateLanguages(lang_type);
667}
668
669std::vector<lldb::LanguageType>
670FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
671{
Enrico Granata980c0482015-09-01 18:22:39 +0000672 switch (lang_type)
673 {
Enrico Granata33e97e62015-09-04 21:01:18 +0000674 case lldb::eLanguageTypeC:
675 case lldb::eLanguageTypeC89:
676 case lldb::eLanguageTypeC99:
677 case lldb::eLanguageTypeC11:
678 case lldb::eLanguageTypeC_plus_plus:
679 case lldb::eLanguageTypeC_plus_plus_03:
680 case lldb::eLanguageTypeC_plus_plus_11:
681 case lldb::eLanguageTypeC_plus_plus_14:
Enrico Granata170c3952015-09-14 22:18:32 +0000682 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
Enrico Granata980c0482015-09-01 18:22:39 +0000683 default:
684 return {lang_type};
685 }
686}
687
688LanguageCategory*
689FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
690{
691 Mutex::Locker locker(m_language_categories_mutex);
692 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
693 if (iter != end)
694 return iter->second.get();
695 LanguageCategory* lang_category = new LanguageCategory(lang_type);
696 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
697 return lang_category;
698}
699
Enrico Granataecd02bc2014-08-19 18:47:58 +0000700lldb::TypeFormatImplSP
701FormatManager::GetHardcodedFormat (ValueObject& valobj,
702 lldb::DynamicValueType use_dynamic)
Enrico Granata686f3de2013-10-30 23:46:27 +0000703{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000704 TypeFormatImplSP retval_sp;
705
706 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granataecd02bc2014-08-19 18:47:58 +0000707 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000708 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
709 {
710 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
711 break;
712 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000713 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000714
715 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000716}
717
Enrico Granata852cc952013-10-08 19:03:22 +0000718lldb::TypeFormatImplSP
719FormatManager::GetFormat (ValueObject& valobj,
720 lldb::DynamicValueType use_dynamic)
721{
722 TypeFormatImplSP retval;
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000723 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
724 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
725 if (valobj_type)
726 {
727 if (log)
728 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
729 if (m_format_cache.GetFormat(valobj_type,retval))
730 {
731 if (log)
732 {
733 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
734 if (log->GetDebug())
735 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
736 }
737 return retval;
738 }
739 if (log)
740 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
741 }
Enrico Granata980c0482015-09-01 18:22:39 +0000742
743 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
744
745 retval = m_categories_map.GetFormat(valobj, use_dynamic, matches);
746 if (!retval)
747 {
748 if (log)
749 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
750 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
751 {
752 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
753 {
754 if (lang_category->Get(valobj, use_dynamic, matches, retval))
755 break;
756 }
757 }
758 if (retval)
759 {
760 if (log)
761 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
762 return retval;
763 }
764 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000765 if (!retval)
766 {
767 if (log)
768 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
769 retval = GetHardcodedFormat(valobj, use_dynamic);
770 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000771
772 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000773 {
774 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000775 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
776 static_cast<void*>(retval.get()),
777 valobj_type.AsCString("<invalid>"));
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000778 m_format_cache.SetFormat(valobj_type,retval);
779 }
780 if (log && log->GetDebug())
781 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 +0000782 return retval;
783}
784
Enrico Granataecd02bc2014-08-19 18:47:58 +0000785lldb::TypeSummaryImplSP
786FormatManager::GetHardcodedSummaryFormat (ValueObject& valobj,
787 lldb::DynamicValueType use_dynamic)
Enrico Granata686f3de2013-10-30 23:46:27 +0000788{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000789 TypeSummaryImplSP retval_sp;
790
791 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granataecd02bc2014-08-19 18:47:58 +0000792 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000793 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
794 {
795 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
796 break;
797 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000798 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000799
800 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000801}
802
Enrico Granata5548cb52013-01-28 23:47:25 +0000803lldb::TypeSummaryImplSP
804FormatManager::GetSummaryFormat (ValueObject& valobj,
805 lldb::DynamicValueType use_dynamic)
806{
807 TypeSummaryImplSP retval;
Greg Clayton5160ce52013-03-27 23:08:40 +0000808 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata5548cb52013-01-28 23:47:25 +0000809 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
810 if (valobj_type)
811 {
812 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000813 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000814 if (m_format_cache.GetSummary(valobj_type,retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000815 {
816 if (log)
817 {
818 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000819 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000820 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 +0000821 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000822 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000823 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000824 if (log)
825 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
826 }
Enrico Granata980c0482015-09-01 18:22:39 +0000827
828 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
829
830 retval = m_categories_map.GetSummaryFormat(valobj, use_dynamic, matches);
831 if (!retval)
832 {
833 if (log)
834 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
835 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
836 {
837 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
838 {
839 if (lang_category->Get(valobj, use_dynamic, matches, retval))
840 break;
841 }
842 }
843 if (retval)
844 {
845 if (log)
846 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
847 return retval;
848 }
849 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000850 if (!retval)
851 {
852 if (log)
853 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
854 retval = GetHardcodedSummaryFormat(valobj, use_dynamic);
855 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000856
857 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000858 {
859 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000860 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
861 static_cast<void*>(retval.get()),
862 valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000863 m_format_cache.SetSummary(valobj_type,retval);
864 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000865 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000866 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 +0000867 return retval;
868}
869
870#ifndef LLDB_DISABLE_PYTHON
Enrico Granataecd02bc2014-08-19 18:47:58 +0000871lldb::SyntheticChildrenSP
872FormatManager::GetHardcodedSyntheticChildren (ValueObject& valobj,
873 lldb::DynamicValueType use_dynamic)
Enrico Granata686f3de2013-10-30 23:46:27 +0000874{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000875 SyntheticChildrenSP retval_sp;
876
877 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granataecd02bc2014-08-19 18:47:58 +0000878 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000879 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
880 {
881 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
882 break;
883 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000884 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000885
886 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000887}
888
Enrico Granata5548cb52013-01-28 23:47:25 +0000889lldb::SyntheticChildrenSP
890FormatManager::GetSyntheticChildren (ValueObject& valobj,
Enrico Granatac2a96402013-06-26 01:03:38 +0000891 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000892{
893 SyntheticChildrenSP retval;
Greg Clayton5160ce52013-03-27 23:08:40 +0000894 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata5548cb52013-01-28 23:47:25 +0000895 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
896 if (valobj_type)
897 {
898 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000899 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000900 if (m_format_cache.GetSynthetic(valobj_type,retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000901 {
902 if (log)
903 {
904 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000905 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000906 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 +0000907 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000908 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000909 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000910 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000911 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
Enrico Granata5548cb52013-01-28 23:47:25 +0000912 }
Enrico Granata980c0482015-09-01 18:22:39 +0000913
914 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
915
916 retval = m_categories_map.GetSyntheticChildren(valobj, use_dynamic, matches);
917 if (!retval)
918 {
919 if (log)
920 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
921 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
922 {
923 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
924 {
925 if (lang_category->Get(valobj, use_dynamic, matches, retval))
926 break;
927 }
928 }
929 if (retval)
930 {
931 if (log)
932 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
933 return retval;
934 }
935 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000936 if (!retval)
937 {
938 if (log)
939 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
940 retval = GetHardcodedSyntheticChildren(valobj, use_dynamic);
941 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000942
943 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000944 {
945 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000946 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
947 static_cast<void*>(retval.get()),
948 valobj_type.AsCString("<invalid>"));
Enrico Granata5548cb52013-01-28 23:47:25 +0000949 m_format_cache.SetSynthetic(valobj_type,retval);
950 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000951 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000952 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 +0000953 return retval;
954}
955#endif
Enrico Granata5548cb52013-01-28 23:47:25 +0000956
Enrico Granatac5827132014-09-05 20:45:07 +0000957lldb::TypeValidatorImplSP
958FormatManager::GetValidator (ValueObject& valobj,
959 lldb::DynamicValueType use_dynamic)
960{
961 TypeValidatorImplSP retval;
962 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
963 ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
964 if (valobj_type)
965 {
966 if (log)
967 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
968 if (m_format_cache.GetValidator(valobj_type,retval))
969 {
970 if (log)
971 {
972 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
973 if (log->GetDebug())
974 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
975 }
976 return retval;
977 }
978 if (log)
979 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
980 }
Enrico Granata980c0482015-09-01 18:22:39 +0000981
982 FormattersMatchVector matches = GetPossibleMatches(valobj, use_dynamic);
983
984 retval = m_categories_map.GetValidator(valobj, use_dynamic, matches);
985 if (!retval)
986 {
987 if (log)
988 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
989 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
990 {
991 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
992 {
993 if (lang_category->Get(valobj, use_dynamic, matches, retval))
994 break;
995 }
996 }
997 if (retval)
998 {
999 if (log)
1000 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
1001 return retval;
1002 }
1003 }
Enrico Granatac5827132014-09-05 20:45:07 +00001004 if (!retval)
1005 {
1006 if (log)
1007 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
1008 retval = GetHardcodedValidator(valobj, use_dynamic);
1009 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +00001010
1011 if (valobj_type && (!retval || !retval->NonCacheable()))
Enrico Granatac5827132014-09-05 20:45:07 +00001012 {
1013 if (log)
1014 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
1015 static_cast<void*>(retval.get()),
1016 valobj_type.AsCString("<invalid>"));
1017 m_format_cache.SetValidator(valobj_type,retval);
1018 }
1019 if (log && log->GetDebug())
1020 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1021 return retval;
1022}
1023
1024lldb::TypeValidatorImplSP
1025FormatManager::GetHardcodedValidator (ValueObject& valobj,
1026 lldb::DynamicValueType use_dynamic)
1027{
Enrico Granata7cb59e12015-09-16 18:28:11 +00001028 TypeValidatorImplSP retval_sp;
1029
1030 for (lldb::LanguageType lang_type : GetCandidateLanguages(valobj))
Enrico Granatac5827132014-09-05 20:45:07 +00001031 {
Enrico Granata7cb59e12015-09-16 18:28:11 +00001032 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1033 {
1034 if (lang_category->GetHardcoded(valobj, use_dynamic, *this, retval_sp))
1035 break;
1036 }
Enrico Granatac5827132014-09-05 20:45:07 +00001037 }
Enrico Granata7cb59e12015-09-16 18:28:11 +00001038
1039 return retval_sp;
Enrico Granatac5827132014-09-05 20:45:07 +00001040}
1041
Enrico Granata5548cb52013-01-28 23:47:25 +00001042FormatManager::FormatManager() :
1043 m_format_cache(),
Enrico Granatac482a192011-08-17 22:13:59 +00001044 m_named_summaries_map(this),
1045 m_last_revision(0),
1046 m_categories_map(this),
Enrico Granata980c0482015-09-01 18:22:39 +00001047 m_language_categories_map(),
1048 m_language_categories_mutex(Mutex::eMutexTypeRecursive),
Enrico Granata1d887492011-08-22 18:36:52 +00001049 m_default_category_name(ConstString("default")),
1050 m_system_category_name(ConstString("system")),
Enrico Granata7cb59e12015-09-16 18:28:11 +00001051 m_vectortypes_category_name(ConstString("VectorTypes"))
Enrico Granatac482a192011-08-17 22:13:59 +00001052{
Enrico Granata864e3e82012-02-17 03:18:30 +00001053 LoadSystemFormatters();
Enrico Granata170c3952015-09-14 22:18:32 +00001054 LoadVectorFormatters();
Enrico Granata864e3e82012-02-17 03:18:30 +00001055
Enrico Granatafa6b2782015-09-17 00:14:50 +00001056 EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1057 EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
Enrico Granata864e3e82012-02-17 03:18:30 +00001058}
1059
1060void
Enrico Granata864e3e82012-02-17 03:18:30 +00001061FormatManager::LoadSystemFormatters()
1062{
Enrico Granataf68df122013-01-10 22:08:35 +00001063
1064 TypeSummaryImpl::Flags string_flags;
Enrico Granata0337c272013-02-22 00:37:31 +00001065 string_flags.SetCascades(true)
Enrico Granataf68df122013-01-10 22:08:35 +00001066 .SetSkipPointers(true)
1067 .SetSkipReferences(false)
1068 .SetDontShowChildren(true)
1069 .SetDontShowValue(false)
1070 .SetShowMembersOneLiner(false)
1071 .SetHideItemNames(false);
1072
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001073 TypeSummaryImpl::Flags string_array_flags;
Enrico Granatad2911632015-07-28 02:13:03 +00001074 string_array_flags.SetCascades(true)
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001075 .SetSkipPointers(true)
1076 .SetSkipReferences(false)
1077 .SetDontShowChildren(true)
1078 .SetDontShowValue(true)
1079 .SetShowMembersOneLiner(false)
1080 .SetHideItemNames(false);
1081
Enrico Granataf68df122013-01-10 22:08:35 +00001082 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001083
1084
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001085 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
Enrico Granata061858c2012-02-15 02:34:21 +00001086 "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001087
1088 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001089 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
Enrico Granatac482a192011-08-17 22:13:59 +00001090
Enrico Granata061858c2012-02-15 02:34:21 +00001091 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
Enrico Granatac482a192011-08-17 22:13:59 +00001092
Enrico Granatab72a5012013-12-20 09:38:13 +00001093 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1094 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1095 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
Enrico Granataaff65652013-10-21 17:29:51 +00001096
Enrico Granata4ed7ef12012-07-13 18:54:40 +00001097 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1098 .SetSkipPointers(true)
1099 .SetSkipReferences(true)
1100 .SetDontShowChildren(true)
1101 .SetDontShowValue(false)
1102 .SetShowMembersOneLiner(false)
1103 .SetHideItemNames(false),
1104 "${var%O}"));
1105
Enrico Granatab72a5012013-12-20 09:38:13 +00001106 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
Enrico Granatad3d444f2012-02-23 23:10:03 +00001107
Jason Molenda1a100cd2013-01-12 04:24:50 +00001108#ifndef LLDB_DISABLE_PYTHON
Enrico Granata4cc21772013-10-08 20:59:02 +00001109 TypeFormatImpl::Flags fourchar_flags;
1110 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1111
1112 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
Jason Molenda1a100cd2013-01-12 04:24:50 +00001113#endif
Enrico Granatad3d444f2012-02-23 23:10:03 +00001114}
Enrico Granatab2698cd2012-09-13 18:27:09 +00001115
Enrico Granata864e3e82012-02-17 03:18:30 +00001116void
Enrico Granata170c3952015-09-14 22:18:32 +00001117FormatManager::LoadVectorFormatters()
Enrico Granata864e3e82012-02-17 03:18:30 +00001118{
Enrico Granata864e3e82012-02-17 03:18:30 +00001119 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
Enrico Granata170c3952015-09-14 22:18:32 +00001120
Enrico Granata864e3e82012-02-17 03:18:30 +00001121 TypeSummaryImpl::Flags vector_flags;
1122 vector_flags.SetCascades(true)
1123 .SetSkipPointers(true)
1124 .SetSkipReferences(false)
1125 .SetDontShowChildren(true)
1126 .SetDontShowValue(false)
1127 .SetShowMembersOneLiner(true)
1128 .SetHideItemNames(true);
1129
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001130 AddStringSummary(vectors_category_sp,
1131 "${var.uint128}",
1132 ConstString("builtin_type_vec128"),
Enrico Granata170c3952015-09-14 22:18:32 +00001133 vector_flags);
1134
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001135 AddStringSummary(vectors_category_sp,
1136 "",
1137 ConstString("float [4]"),
1138 vector_flags);
1139 AddStringSummary(vectors_category_sp,
1140 "",
1141 ConstString("int32_t [4]"),
1142 vector_flags);
1143 AddStringSummary(vectors_category_sp,
1144 "",
1145 ConstString("int16_t [8]"),
1146 vector_flags);
1147 AddStringSummary(vectors_category_sp,
1148 "",
1149 ConstString("vDouble"),
1150 vector_flags);
1151 AddStringSummary(vectors_category_sp,
1152 "",
1153 ConstString("vFloat"),
1154 vector_flags);
1155 AddStringSummary(vectors_category_sp,
1156 "",
1157 ConstString("vSInt8"),
1158 vector_flags);
1159 AddStringSummary(vectors_category_sp,
1160 "",
1161 ConstString("vSInt16"),
1162 vector_flags);
1163 AddStringSummary(vectors_category_sp,
1164 "",
1165 ConstString("vSInt32"),
1166 vector_flags);
1167 AddStringSummary(vectors_category_sp,
1168 "",
1169 ConstString("vUInt16"),
1170 vector_flags);
1171 AddStringSummary(vectors_category_sp,
1172 "",
1173 ConstString("vUInt8"),
1174 vector_flags);
1175 AddStringSummary(vectors_category_sp,
1176 "",
1177 ConstString("vUInt16"),
1178 vector_flags);
1179 AddStringSummary(vectors_category_sp,
1180 "",
1181 ConstString("vUInt32"),
1182 vector_flags);
1183 AddStringSummary(vectors_category_sp,
1184 "",
1185 ConstString("vBool32"),
1186 vector_flags);
Greg Claytond4e25522011-10-12 00:53:29 +00001187}