blob: 35a0468306fa9f93a98ad1497c11895ce403d5d8 [file] [log] [blame]
Greg Clayton4a33d312011-06-23 17:59:56 +00001//===-- FormatManager.cpp -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Enrico Granata5548cb52013-01-28 23:47:25 +000010#include "lldb/DataFormatters/FormatManager.h"
Greg Clayton4a33d312011-06-23 17:59:56 +000011
Enrico Granatad717cc92015-10-20 04:50:09 +000012#include "llvm/ADT/STLExtras.h"
13
Greg Clayton4a33d312011-06-23 17:59:56 +000014// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18
Enrico Granataf2bbf712011-07-15 02:26:42 +000019#include "lldb/Core/Debugger.h"
Enrico Granatad717cc92015-10-20 04:50:09 +000020#include "lldb/Core/Log.h"
Enrico Granatadf7e79e2015-09-02 01:21:31 +000021#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granata980c0482015-09-01 18:22:39 +000022#include "lldb/DataFormatters/LanguageCategory.h"
Enrico Granata5548cb52013-01-28 23:47:25 +000023#include "lldb/Target/ExecutionContext.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000024#include "lldb/Target/Language.h"
Enrico Granata980c0482015-09-01 18:22:39 +000025
Greg Clayton4a33d312011-06-23 17:59:56 +000026using namespace lldb;
27using namespace lldb_private;
Enrico Granatadf7e79e2015-09-02 01:21:31 +000028using namespace lldb_private::formatters;
Greg Claytonbb7f31f2011-06-23 21:22:24 +000029
30struct FormatInfo
31{
32 Format format;
33 const char format_char; // One or more format characters that can be used for this format.
34 const char *format_name; // Long format name that can be used to specify the current format
35};
36
37static FormatInfo
38g_format_infos[] =
39{
40 { eFormatDefault , '\0' , "default" },
41 { eFormatBoolean , 'B' , "boolean" },
42 { eFormatBinary , 'b' , "binary" },
43 { eFormatBytes , 'y' , "bytes" },
44 { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
45 { eFormatChar , 'c' , "character" },
46 { eFormatCharPrintable , 'C' , "printable character" },
47 { eFormatComplexFloat , 'F' , "complex float" },
48 { eFormatCString , 's' , "c-string" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000049 { eFormatDecimal , 'd' , "decimal" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000050 { eFormatEnum , 'E' , "enumeration" },
51 { eFormatHex , 'x' , "hex" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000052 { eFormatHexUppercase , 'X' , "uppercase hex" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000053 { eFormatFloat , 'f' , "float" },
54 { eFormatOctal , 'o' , "octal" },
55 { eFormatOSType , 'O' , "OSType" },
56 { eFormatUnicode16 , 'U' , "unicode16" },
57 { eFormatUnicode32 , '\0' , "unicode32" },
58 { eFormatUnsigned , 'u' , "unsigned decimal" },
59 { eFormatPointer , 'p' , "pointer" },
60 { eFormatVectorOfChar , '\0' , "char[]" },
61 { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
62 { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
63 { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
64 { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
Enrico Granatae443ba72011-07-06 15:56:06 +000065 { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
66 { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
67 { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
68 { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
Ewan Crawforda0f08672015-10-16 08:28:47 +000069 { eFormatVectorOfFloat16, '\0' , "float16[]" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000070 { eFormatVectorOfFloat32, '\0' , "float32[]" },
71 { eFormatVectorOfFloat64, '\0' , "float64[]" },
72 { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
73 { eFormatComplexInteger , 'I' , "complex integer" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000074 { eFormatCharArray , 'a' , "character array" },
75 { eFormatAddressInfo , 'A' , "address" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000076 { eFormatHexFloat , '\0' , "hex float" },
Sean Callananbf154da2012-08-08 17:35:10 +000077 { eFormatInstruction , 'i' , "instruction" },
78 { eFormatVoid , 'v' , "void" }
Greg Claytonbb7f31f2011-06-23 21:22:24 +000079};
80
Saleem Abdulrasool28606952014-06-27 05:17:41 +000081static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
Greg Claytonbb7f31f2011-06-23 21:22:24 +000082
83static bool
84GetFormatFromFormatChar (char format_char, Format &format)
85{
86 for (uint32_t i=0; i<g_num_format_infos; ++i)
87 {
88 if (g_format_infos[i].format_char == format_char)
89 {
90 format = g_format_infos[i].format;
91 return true;
92 }
93 }
94 format = eFormatInvalid;
95 return false;
96}
97
98static bool
99GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
100{
101 uint32_t i;
102 for (i=0; i<g_num_format_infos; ++i)
103 {
104 if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
105 {
106 format = g_format_infos[i].format;
107 return true;
108 }
109 }
110
111 if (partial_match_ok)
112 {
113 for (i=0; i<g_num_format_infos; ++i)
114 {
115 if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
116 {
117 format = g_format_infos[i].format;
118 return true;
119 }
120 }
121 }
122 format = eFormatInvalid;
123 return false;
124}
125
Enrico Granatabd5eab82015-12-15 02:20:48 +0000126void
127FormatManager::Changed ()
128{
129 ++m_last_revision;
130 m_format_cache.Clear ();
131 Mutex::Locker lang_locker(m_language_categories_mutex);
132 for (auto& iter : m_language_categories_map)
133 {
134 if (iter.second)
135 iter.second->GetFormatCache().Clear();
136 }
137}
138
Greg Claytonbb7f31f2011-06-23 21:22:24 +0000139bool
140FormatManager::GetFormatFromCString (const char *format_cstr,
141 bool partial_match_ok,
142 lldb::Format &format)
143{
144 bool success = false;
145 if (format_cstr && format_cstr[0])
146 {
147 if (format_cstr[1] == '\0')
148 {
149 success = GetFormatFromFormatChar (format_cstr[0], format);
150 if (success)
151 return true;
152 }
153
154 success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
155 }
156 if (!success)
157 format = eFormatInvalid;
158 return success;
159}
160
161char
162FormatManager::GetFormatAsFormatChar (lldb::Format format)
163{
164 for (uint32_t i=0; i<g_num_format_infos; ++i)
165 {
166 if (g_format_infos[i].format == format)
167 return g_format_infos[i].format_char;
168 }
169 return '\0';
170}
Greg Claytonbb7f31f2011-06-23 21:22:24 +0000171
172const char *
173FormatManager::GetFormatAsCString (Format format)
174{
175 if (format >= eFormatDefault && format < kNumFormats)
176 return g_format_infos[format].format_name;
177 return NULL;
178}
Enrico Granata0a3958e2011-07-02 00:25:22 +0000179
Enrico Granatade61cec2013-11-22 00:02:13 +0000180void
Enrico Granata33e97e62015-09-04 21:01:18 +0000181FormatManager::EnableAllCategories ()
182{
183 m_categories_map.EnableAllCategories ();
184 Mutex::Locker lang_locker(m_language_categories_mutex);
185 for (auto& iter : m_language_categories_map)
186 {
187 if (iter.second)
188 iter.second->Enable();
189 }
190}
191
192void
193FormatManager::DisableAllCategories ()
194{
195 m_categories_map.DisableAllCategories ();
196 Mutex::Locker lang_locker(m_language_categories_mutex);
197 for (auto& iter : m_language_categories_map)
198 {
199 if (iter.second)
200 iter.second->Disable();
201 }
202}
203
204void
Enrico Granatade61cec2013-11-22 00:02:13 +0000205FormatManager::GetPossibleMatches (ValueObject& valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000206 CompilerType compiler_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000207 uint32_t reason,
208 lldb::DynamicValueType use_dynamic,
209 FormattersMatchVector& entries,
210 bool did_strip_ptr,
211 bool did_strip_ref,
212 bool did_strip_typedef,
213 bool root_level)
214{
Enrico Granatac6bf2e22015-09-23 01:39:46 +0000215 compiler_type = compiler_type.GetTypeForFormatters();
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000216 ConstString type_name(compiler_type.GetConstTypeName());
Enrico Granatade61cec2013-11-22 00:02:13 +0000217 if (valobj.GetBitfieldBitSize() > 0)
218 {
219 StreamString sstring;
220 sstring.Printf("%s:%d",type_name.AsCString(),valobj.GetBitfieldBitSize());
221 ConstString bitfieldname = ConstString(sstring.GetData());
222 entries.push_back({bitfieldname,0,did_strip_ptr,did_strip_ref,did_strip_typedef});
223 reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
224 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000225
Enrico Granatab3f0c342015-10-20 00:13:19 +0000226 if (!compiler_type.IsMeaninglessWithoutDynamicResolution())
227 {
228 entries.push_back({type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
229
230 ConstString display_type_name(compiler_type.GetDisplayTypeName());
231 if (display_type_name != type_name)
232 entries.push_back({display_type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
233 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000234
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000235 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 +0000236 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000237 CompilerType non_ref_type = compiler_type.GetNonReferenceType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000238 GetPossibleMatches(valobj,
239 non_ref_type,
240 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
241 use_dynamic,
242 entries,
243 did_strip_ptr,
244 true,
245 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000246 if (non_ref_type.IsTypedefType())
247 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000248 CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
Greg Clayton56939cb2015-09-17 22:23:34 +0000249 deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000250 GetPossibleMatches(valobj,
251 deffed_referenced_type,
252 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
253 use_dynamic,
254 entries,
255 did_strip_ptr,
256 did_strip_ref,
257 true); // this is not exactly the usual meaning of stripping typedefs
258 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000259 }
Enrico Granata1ac62962014-04-10 00:14:07 +0000260
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000261 if (compiler_type.IsPointerType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000262 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000263 CompilerType non_ptr_type = compiler_type.GetPointeeType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000264 GetPossibleMatches(valobj,
265 non_ptr_type,
266 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
267 use_dynamic,
268 entries,
269 true,
270 did_strip_ref,
271 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000272 if (non_ptr_type.IsTypedefType())
273 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000274 CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000275 GetPossibleMatches(valobj,
276 deffed_pointed_type,
277 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
278 use_dynamic,
279 entries,
280 did_strip_ptr,
281 did_strip_ref,
282 true); // this is not exactly the usual meaning of stripping typedefs
283 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000284 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000285
Enrico Granatad3233c12015-09-09 01:10:46 +0000286 for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
Enrico Granatade61cec2013-11-22 00:02:13 +0000287 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000288 if (Language* language = Language::FindPlugin(language_type))
Enrico Granatade61cec2013-11-22 00:02:13 +0000289 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000290 for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
Enrico Granatade61cec2013-11-22 00:02:13 +0000291 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000292 entries.push_back({candidate,
293 reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
294 did_strip_ptr,
295 did_strip_ref,
296 did_strip_typedef});
297 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000298 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000299 }
Enrico Granatad3233c12015-09-09 01:10:46 +0000300
Enrico Granatade61cec2013-11-22 00:02:13 +0000301 // try to strip typedef chains
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000302 if (compiler_type.IsTypedefType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000303 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000304 CompilerType deffed_type = compiler_type.GetTypedefedType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000305 GetPossibleMatches(valobj,
306 deffed_type,
307 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
308 use_dynamic,
309 entries,
310 did_strip_ptr,
311 did_strip_ref,
312 true);
313 }
314
315 if (root_level)
316 {
317 do {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000318 if (!compiler_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000319 break;
320
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000321 CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType();
322 if (!unqual_compiler_ast_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000323 break;
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000324 if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000325 GetPossibleMatches (valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000326 unqual_compiler_ast_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000327 reason,
328 use_dynamic,
329 entries,
330 did_strip_ptr,
331 did_strip_ref,
332 did_strip_typedef);
333 } while(false);
334
335
336 // if all else fails, go to static type
337 if (valobj.IsDynamic())
338 {
339 lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
340 if (static_value_sp)
341 GetPossibleMatches(*static_value_sp.get(),
Greg Clayton99558cc42015-08-24 23:46:31 +0000342 static_value_sp->GetCompilerType(),
Enrico Granatade61cec2013-11-22 00:02:13 +0000343 reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
344 use_dynamic,
345 entries,
346 did_strip_ptr,
347 did_strip_ref,
348 did_strip_typedef,
349 true);
350 }
351 }
352}
353
Enrico Granata852cc952013-10-08 19:03:22 +0000354lldb::TypeFormatImplSP
355FormatManager::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
356{
357 if (!type_sp)
358 return lldb::TypeFormatImplSP();
359 lldb::TypeFormatImplSP format_chosen_sp;
360 uint32_t num_categories = m_categories_map.GetCount();
361 lldb::TypeCategoryImplSP category_sp;
362 uint32_t prio_category = UINT32_MAX;
363 for (uint32_t category_id = 0;
364 category_id < num_categories;
365 category_id++)
366 {
367 category_sp = GetCategoryAtIndex(category_id);
368 if (category_sp->IsEnabled() == false)
369 continue;
370 lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp);
371 if (format_current_sp && (format_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
372 {
373 prio_category = category_sp->GetEnabledPosition();
374 format_chosen_sp = format_current_sp;
375 }
376 }
377 return format_chosen_sp;
378}
379
Enrico Granataa777dc22012-05-08 21:49:57 +0000380lldb::TypeSummaryImplSP
381FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
382{
383 if (!type_sp)
384 return lldb::TypeSummaryImplSP();
385 lldb::TypeSummaryImplSP summary_chosen_sp;
386 uint32_t num_categories = m_categories_map.GetCount();
387 lldb::TypeCategoryImplSP category_sp;
388 uint32_t prio_category = UINT32_MAX;
389 for (uint32_t category_id = 0;
390 category_id < num_categories;
391 category_id++)
392 {
393 category_sp = GetCategoryAtIndex(category_id);
394 if (category_sp->IsEnabled() == false)
395 continue;
396 lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
397 if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
398 {
399 prio_category = category_sp->GetEnabledPosition();
400 summary_chosen_sp = summary_current_sp;
401 }
402 }
403 return summary_chosen_sp;
404}
405
406lldb::TypeFilterImplSP
407FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
408{
409 if (!type_sp)
410 return lldb::TypeFilterImplSP();
411 lldb::TypeFilterImplSP filter_chosen_sp;
412 uint32_t num_categories = m_categories_map.GetCount();
413 lldb::TypeCategoryImplSP category_sp;
414 uint32_t prio_category = UINT32_MAX;
415 for (uint32_t category_id = 0;
416 category_id < num_categories;
417 category_id++)
418 {
419 category_sp = GetCategoryAtIndex(category_id);
420 if (category_sp->IsEnabled() == false)
421 continue;
422 lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
423 if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
424 {
425 prio_category = category_sp->GetEnabledPosition();
426 filter_chosen_sp = filter_current_sp;
427 }
428 }
429 return filter_chosen_sp;
430}
431
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000432#ifndef LLDB_DISABLE_PYTHON
Enrico Granata5548cb52013-01-28 23:47:25 +0000433lldb::ScriptedSyntheticChildrenSP
Enrico Granataa777dc22012-05-08 21:49:57 +0000434FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
435{
436 if (!type_sp)
Enrico Granata5548cb52013-01-28 23:47:25 +0000437 return lldb::ScriptedSyntheticChildrenSP();
438 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
Enrico Granataa777dc22012-05-08 21:49:57 +0000439 uint32_t num_categories = m_categories_map.GetCount();
440 lldb::TypeCategoryImplSP category_sp;
441 uint32_t prio_category = UINT32_MAX;
442 for (uint32_t category_id = 0;
443 category_id < num_categories;
444 category_id++)
445 {
446 category_sp = GetCategoryAtIndex(category_id);
447 if (category_sp->IsEnabled() == false)
448 continue;
Enrico Granata5548cb52013-01-28 23:47:25 +0000449 lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
Enrico Granataa777dc22012-05-08 21:49:57 +0000450 if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
451 {
452 prio_category = category_sp->GetEnabledPosition();
453 synth_chosen_sp = synth_current_sp;
454 }
455 }
456 return synth_chosen_sp;
457}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000458#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000459
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000460#ifndef LLDB_DISABLE_PYTHON
Enrico Granataa777dc22012-05-08 21:49:57 +0000461lldb::SyntheticChildrenSP
462FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
463{
464 if (!type_sp)
465 return lldb::SyntheticChildrenSP();
466 lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
Enrico Granata5548cb52013-01-28 23:47:25 +0000467 lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
Enrico Granataa777dc22012-05-08 21:49:57 +0000468 if (filter_sp->GetRevision() > synth_sp->GetRevision())
469 return lldb::SyntheticChildrenSP(filter_sp.get());
470 else
471 return lldb::SyntheticChildrenSP(synth_sp.get());
472}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000473#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000474
Enrico Granatac5827132014-09-05 20:45:07 +0000475lldb::TypeValidatorImplSP
476FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
477{
478 if (!type_sp)
479 return lldb::TypeValidatorImplSP();
480 lldb::TypeValidatorImplSP validator_chosen_sp;
481 uint32_t num_categories = m_categories_map.GetCount();
482 lldb::TypeCategoryImplSP category_sp;
483 uint32_t prio_category = UINT32_MAX;
484 for (uint32_t category_id = 0;
485 category_id < num_categories;
486 category_id++)
487 {
488 category_sp = GetCategoryAtIndex(category_id);
489 if (category_sp->IsEnabled() == false)
490 continue;
491 lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
492 if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
493 {
494 prio_category = category_sp->GetEnabledPosition();
495 validator_chosen_sp = validator_current_sp;
496 }
497 }
498 return validator_chosen_sp;
499}
500
Enrico Granata980c0482015-09-01 18:22:39 +0000501void
Enrico Granatab56d0102015-11-14 05:44:23 +0000502FormatManager::ForEachCategory(TypeCategoryMap::ForEachCallback callback)
503{
504 m_categories_map.ForEach(callback);
505 Mutex::Locker locker(m_language_categories_mutex);
506 for (const auto& entry : m_language_categories_map)
507 {
508 if (auto category_sp = entry.second->GetCategory())
509 {
510 if (!callback(category_sp))
511 break;
512 }
513 }
514}
515
Enrico Granata061858c2012-02-15 02:34:21 +0000516lldb::TypeCategoryImplSP
Enrico Granata9128ee22011-09-06 19:20:51 +0000517FormatManager::GetCategory (const ConstString& category_name,
Enrico Granatadb595cd2015-03-06 19:37:57 +0000518 bool can_create)
Enrico Granatadc940732011-08-23 00:32:52 +0000519{
520 if (!category_name)
Enrico Granata9128ee22011-09-06 19:20:51 +0000521 return GetCategory(m_default_category_name);
Enrico Granata061858c2012-02-15 02:34:21 +0000522 lldb::TypeCategoryImplSP category;
Enrico Granatadc940732011-08-23 00:32:52 +0000523 if (m_categories_map.Get(category_name, category))
524 return category;
525
526 if (!can_create)
Enrico Granata061858c2012-02-15 02:34:21 +0000527 return lldb::TypeCategoryImplSP();
Enrico Granatadc940732011-08-23 00:32:52 +0000528
Enrico Granata061858c2012-02-15 02:34:21 +0000529 m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
Enrico Granata9128ee22011-09-06 19:20:51 +0000530 return GetCategory(category_name);
Enrico Granatadc940732011-08-23 00:32:52 +0000531}
532
Enrico Granataf4efecd2011-07-12 22:56:10 +0000533lldb::Format
534FormatManager::GetSingleItemFormat(lldb::Format vector_format)
535{
536 switch(vector_format)
537 {
538 case eFormatVectorOfChar:
539 return eFormatCharArray;
540
541 case eFormatVectorOfSInt8:
542 case eFormatVectorOfSInt16:
543 case eFormatVectorOfSInt32:
544 case eFormatVectorOfSInt64:
545 return eFormatDecimal;
546
547 case eFormatVectorOfUInt8:
548 case eFormatVectorOfUInt16:
549 case eFormatVectorOfUInt32:
550 case eFormatVectorOfUInt64:
551 case eFormatVectorOfUInt128:
552 return eFormatHex;
553
Ewan Crawforda0f08672015-10-16 08:28:47 +0000554 case eFormatVectorOfFloat16:
Enrico Granataf4efecd2011-07-12 22:56:10 +0000555 case eFormatVectorOfFloat32:
556 case eFormatVectorOfFloat64:
557 return eFormatFloat;
558
559 default:
560 return lldb::eFormatInvalid;
561 }
Greg Clayton3418c852011-08-10 02:10:13 +0000562}
Enrico Granatac482a192011-08-17 22:13:59 +0000563
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000564bool
565FormatManager::ShouldPrintAsOneLiner (ValueObject& valobj)
566{
Enrico Granata553fad52013-10-25 23:09:40 +0000567 // if settings say no oneline whatsoever
Enrico Granata90a8db32013-10-31 21:01:07 +0000568 if (valobj.GetTargetSP().get() && valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
Enrico Granata553fad52013-10-25 23:09:40 +0000569 return false; // then don't oneline
570
Enrico Granata42fa4af2014-09-11 23:00:27 +0000571 // if this object has a summary, then ask the summary
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000572 if (valobj.GetSummaryFormat().get() != nullptr)
Enrico Granata42fa4af2014-09-11 23:00:27 +0000573 return valobj.GetSummaryFormat()->IsOneLiner();
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000574
575 // no children, no party
576 if (valobj.GetNumChildren() == 0)
577 return false;
578
Enrico Granata9c63f992015-09-23 02:04:34 +0000579 // ask the type if it has any opinion about this
580 // eLazyBoolCalculate == no opinion; other values should be self explanatory
581 CompilerType compiler_type(valobj.GetCompilerType());
582 if (compiler_type.IsValid())
583 {
Enrico Granata65000612015-11-09 21:28:55 +0000584 switch (compiler_type.ShouldPrintAsOneLiner(&valobj))
Enrico Granata9c63f992015-09-23 02:04:34 +0000585 {
586 case eLazyBoolNo:
587 return false;
588 case eLazyBoolYes:
589 return true;
590 case eLazyBoolCalculate:
Enrico Granata9c63f992015-09-23 02:04:34 +0000591 break;
592 }
593 }
594
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000595 size_t total_children_name_len = 0;
596
597 for (size_t idx = 0;
598 idx < valobj.GetNumChildren();
599 idx++)
600 {
Enrico Granataddac7612014-10-09 18:47:36 +0000601 bool is_synth_val = false;
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000602 ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
603 // something is wrong here - bail out
604 if (!child_sp)
605 return false;
Enrico Granata65000612015-11-09 21:28:55 +0000606
607 // also ask the child's type if it has any opinion
608 CompilerType child_compiler_type(child_sp->GetCompilerType());
609 if (child_compiler_type.IsValid())
610 {
611 switch (child_compiler_type.ShouldPrintAsOneLiner(child_sp.get()))
612 {
613 case eLazyBoolYes:
614 // an opinion of yes is only binding for the child, so keep going
615 case eLazyBoolCalculate:
616 break;
617 case eLazyBoolNo:
618 // but if the child says no, then it's a veto on the whole thing
619 return false;
620 }
621 }
622
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000623 // if we decided to define synthetic children for a type, we probably care enough
624 // to show them, but avoid nesting children in children
625 if (child_sp->GetSyntheticChildren().get() != nullptr)
Enrico Granataddac7612014-10-09 18:47:36 +0000626 {
627 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
628 // wait.. wat? just get out of here..
629 if (!synth_sp)
630 return false;
631 // but if we only have them to provide a value, keep going
632 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
633 is_synth_val = true;
634 else
635 return false;
636 }
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000637
638 total_children_name_len += child_sp->GetName().GetLength();
639
640 // 50 itself is a "randomly" chosen number - the idea is that
641 // overly long structs should not get this treatment
642 // FIXME: maybe make this a user-tweakable setting?
643 if (total_children_name_len > 50)
644 return false;
645
646 // if a summary is there..
647 if (child_sp->GetSummaryFormat())
648 {
649 // and it wants children, then bail out
Enrico Granata8a068e62014-04-23 23:16:25 +0000650 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000651 return false;
652 }
653
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000654 // if this child has children..
655 if (child_sp->GetNumChildren())
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000656 {
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000657 // ...and no summary...
658 // (if it had a summary and the summary wanted children, we would have bailed out anyway
659 // 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 +0000660 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 +0000661 return false; // then bail out
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000662 }
663 }
664 return true;
665}
666
Enrico Granata02b66762011-08-19 01:14:49 +0000667ConstString
668FormatManager::GetValidTypeName (const ConstString& type)
669{
670 return ::GetValidTypeName_Impl(type);
671}
672
Enrico Granata5548cb52013-01-28 23:47:25 +0000673ConstString
Enrico Granata980c0482015-09-01 18:22:39 +0000674FormatManager::GetTypeForCache (ValueObject& valobj,
675 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000676{
Enrico Granatab3f0c342015-10-20 00:13:19 +0000677 ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(use_dynamic, valobj.IsSynthetic());
678 if (valobj_sp && valobj_sp->GetCompilerType().IsValid())
Enrico Granata5548cb52013-01-28 23:47:25 +0000679 {
Enrico Granatab3f0c342015-10-20 00:13:19 +0000680 if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
681 return valobj_sp->GetQualifiedTypeName();
Enrico Granata5548cb52013-01-28 23:47:25 +0000682 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000683 return ConstString();
684}
685
Enrico Granatad3233c12015-09-09 01:10:46 +0000686std::vector<lldb::LanguageType>
687FormatManager::GetCandidateLanguages (ValueObject& valobj)
Enrico Granata980c0482015-09-01 18:22:39 +0000688{
689 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
Enrico Granataac494532015-09-09 22:30:24 +0000690 return GetCandidateLanguages(lang_type);
691}
692
693std::vector<lldb::LanguageType>
694FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
695{
Enrico Granata980c0482015-09-01 18:22:39 +0000696 switch (lang_type)
697 {
Enrico Granata33e97e62015-09-04 21:01:18 +0000698 case lldb::eLanguageTypeC:
699 case lldb::eLanguageTypeC89:
700 case lldb::eLanguageTypeC99:
701 case lldb::eLanguageTypeC11:
702 case lldb::eLanguageTypeC_plus_plus:
703 case lldb::eLanguageTypeC_plus_plus_03:
704 case lldb::eLanguageTypeC_plus_plus_11:
705 case lldb::eLanguageTypeC_plus_plus_14:
Enrico Granata170c3952015-09-14 22:18:32 +0000706 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
Enrico Granata980c0482015-09-01 18:22:39 +0000707 default:
708 return {lang_type};
709 }
710}
711
712LanguageCategory*
713FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
714{
715 Mutex::Locker locker(m_language_categories_mutex);
716 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
717 if (iter != end)
718 return iter->second.get();
719 LanguageCategory* lang_category = new LanguageCategory(lang_type);
720 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
721 return lang_category;
722}
723
Enrico Granataecd02bc2014-08-19 18:47:58 +0000724lldb::TypeFormatImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000725FormatManager::GetHardcodedFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000726{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000727 TypeFormatImplSP retval_sp;
728
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000729 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000730 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000731 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
732 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000733 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000734 break;
735 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000736 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000737
738 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000739}
740
Enrico Granata852cc952013-10-08 19:03:22 +0000741lldb::TypeFormatImplSP
742FormatManager::GetFormat (ValueObject& valobj,
743 lldb::DynamicValueType use_dynamic)
744{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000745 FormattersMatchData match_data(valobj, use_dynamic);
746
Enrico Granata852cc952013-10-08 19:03:22 +0000747 TypeFormatImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000748 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000749 if (match_data.GetTypeForCache())
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000750 {
751 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000752 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
753 if (m_format_cache.GetFormat(match_data.GetTypeForCache(),retval))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000754 {
755 if (log)
756 {
757 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
758 if (log->GetDebug())
759 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
760 }
761 return retval;
762 }
763 if (log)
764 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
765 }
Enrico Granata980c0482015-09-01 18:22:39 +0000766
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000767 retval = m_categories_map.GetFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000768 if (!retval)
769 {
770 if (log)
771 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000772 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000773 {
774 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
775 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000776 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000777 break;
778 }
779 }
780 if (retval)
781 {
782 if (log)
783 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
784 return retval;
785 }
786 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000787 if (!retval)
788 {
789 if (log)
790 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000791 retval = GetHardcodedFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000792 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000793
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000794 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000795 {
796 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000797 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
798 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000799 match_data.GetTypeForCache().AsCString("<invalid>"));
800 m_format_cache.SetFormat(match_data.GetTypeForCache(),retval);
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000801 }
802 if (log && log->GetDebug())
803 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 +0000804 return retval;
805}
806
Enrico Granataecd02bc2014-08-19 18:47:58 +0000807lldb::TypeSummaryImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000808FormatManager::GetHardcodedSummaryFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000809{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000810 TypeSummaryImplSP retval_sp;
811
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000812 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000813 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000814 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
815 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000816 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000817 break;
818 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000819 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000820
821 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000822}
823
Enrico Granata5548cb52013-01-28 23:47:25 +0000824lldb::TypeSummaryImplSP
825FormatManager::GetSummaryFormat (ValueObject& valobj,
826 lldb::DynamicValueType use_dynamic)
827{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000828 FormattersMatchData match_data(valobj, use_dynamic);
829
Enrico Granata5548cb52013-01-28 23:47:25 +0000830 TypeSummaryImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000831 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000832 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000833 {
834 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000835 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
836 if (m_format_cache.GetSummary(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000837 {
838 if (log)
839 {
840 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000841 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000842 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 +0000843 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000844 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000845 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000846 if (log)
847 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
848 }
Enrico Granata980c0482015-09-01 18:22:39 +0000849
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000850 retval = m_categories_map.GetSummaryFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000851 if (!retval)
852 {
853 if (log)
854 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000855 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000856 {
857 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
858 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000859 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000860 break;
861 }
862 }
863 if (retval)
864 {
865 if (log)
866 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
867 return retval;
868 }
869 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000870 if (!retval)
871 {
872 if (log)
873 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000874 retval = GetHardcodedSummaryFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000875 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000876
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000877 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000878 {
879 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000880 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
881 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000882 match_data.GetTypeForCache().AsCString("<invalid>"));
883 m_format_cache.SetSummary(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000884 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000885 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000886 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 +0000887 return retval;
888}
889
890#ifndef LLDB_DISABLE_PYTHON
Enrico Granataecd02bc2014-08-19 18:47:58 +0000891lldb::SyntheticChildrenSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000892FormatManager::GetHardcodedSyntheticChildren (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000893{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000894 SyntheticChildrenSP retval_sp;
895
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000896 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000897 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000898 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
899 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000900 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000901 break;
902 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000903 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000904
905 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000906}
907
Enrico Granata5548cb52013-01-28 23:47:25 +0000908lldb::SyntheticChildrenSP
909FormatManager::GetSyntheticChildren (ValueObject& valobj,
Enrico Granatac2a96402013-06-26 01:03:38 +0000910 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000911{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000912 FormattersMatchData match_data(valobj, use_dynamic);
913
Enrico Granata5548cb52013-01-28 23:47:25 +0000914 SyntheticChildrenSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000915 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000916 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000917 {
918 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000919 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
920 if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000921 {
922 if (log)
923 {
924 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000925 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000926 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 +0000927 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000928 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000929 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000930 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000931 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
Enrico Granata5548cb52013-01-28 23:47:25 +0000932 }
Enrico Granata980c0482015-09-01 18:22:39 +0000933
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000934 retval = m_categories_map.GetSyntheticChildren(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000935 if (!retval)
936 {
937 if (log)
938 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000939 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000940 {
941 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
942 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000943 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000944 break;
945 }
946 }
947 if (retval)
948 {
949 if (log)
950 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
951 return retval;
952 }
953 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000954 if (!retval)
955 {
956 if (log)
957 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000958 retval = GetHardcodedSyntheticChildren(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000959 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000960
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000961 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000962 {
963 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000964 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
965 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000966 match_data.GetTypeForCache().AsCString("<invalid>"));
967 m_format_cache.SetSynthetic(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000968 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000969 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000970 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 +0000971 return retval;
972}
973#endif
Enrico Granata5548cb52013-01-28 23:47:25 +0000974
Enrico Granatac5827132014-09-05 20:45:07 +0000975lldb::TypeValidatorImplSP
976FormatManager::GetValidator (ValueObject& valobj,
977 lldb::DynamicValueType use_dynamic)
978{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000979 FormattersMatchData match_data(valobj, use_dynamic);
980
Enrico Granatac5827132014-09-05 20:45:07 +0000981 TypeValidatorImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000982 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000983 if (match_data.GetTypeForCache())
Enrico Granatac5827132014-09-05 20:45:07 +0000984 {
985 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000986 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
987 if (m_format_cache.GetValidator(match_data.GetTypeForCache(),retval))
Enrico Granatac5827132014-09-05 20:45:07 +0000988 {
989 if (log)
990 {
991 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
992 if (log->GetDebug())
993 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
994 }
995 return retval;
996 }
997 if (log)
998 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
999 }
Enrico Granata980c0482015-09-01 18:22:39 +00001000
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001001 retval = m_categories_map.GetValidator(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +00001002 if (!retval)
1003 {
1004 if (log)
1005 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001006 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +00001007 {
1008 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1009 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001010 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +00001011 break;
1012 }
1013 }
1014 if (retval)
1015 {
1016 if (log)
1017 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
1018 return retval;
1019 }
1020 }
Enrico Granatac5827132014-09-05 20:45:07 +00001021 if (!retval)
1022 {
1023 if (log)
1024 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001025 retval = GetHardcodedValidator(match_data);
Enrico Granatac5827132014-09-05 20:45:07 +00001026 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +00001027
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001028 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granatac5827132014-09-05 20:45:07 +00001029 {
1030 if (log)
1031 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
1032 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001033 match_data.GetTypeForCache().AsCString("<invalid>"));
1034 m_format_cache.SetValidator(match_data.GetTypeForCache(),retval);
Enrico Granatac5827132014-09-05 20:45:07 +00001035 }
1036 if (log && log->GetDebug())
1037 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1038 return retval;
1039}
1040
1041lldb::TypeValidatorImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001042FormatManager::GetHardcodedValidator (FormattersMatchData& match_data)
Enrico Granatac5827132014-09-05 20:45:07 +00001043{
Enrico Granata7cb59e12015-09-16 18:28:11 +00001044 TypeValidatorImplSP retval_sp;
1045
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001046 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granatac5827132014-09-05 20:45:07 +00001047 {
Enrico Granata7cb59e12015-09-16 18:28:11 +00001048 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1049 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001050 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +00001051 break;
1052 }
Enrico Granatac5827132014-09-05 20:45:07 +00001053 }
Enrico Granata7cb59e12015-09-16 18:28:11 +00001054
1055 return retval_sp;
Enrico Granatac5827132014-09-05 20:45:07 +00001056}
1057
Enrico Granata5548cb52013-01-28 23:47:25 +00001058FormatManager::FormatManager() :
Enrico Granatac482a192011-08-17 22:13:59 +00001059 m_last_revision(0),
Enrico Granatabd5eab82015-12-15 02:20:48 +00001060 m_format_cache(),
Enrico Granata980c0482015-09-01 18:22:39 +00001061 m_language_categories_mutex(Mutex::eMutexTypeRecursive),
Enrico Granatabd5eab82015-12-15 02:20:48 +00001062 m_language_categories_map(),
1063 m_named_summaries_map(this),
1064 m_categories_map(this),
Enrico Granata1d887492011-08-22 18:36:52 +00001065 m_default_category_name(ConstString("default")),
1066 m_system_category_name(ConstString("system")),
Enrico Granata7cb59e12015-09-16 18:28:11 +00001067 m_vectortypes_category_name(ConstString("VectorTypes"))
Enrico Granatac482a192011-08-17 22:13:59 +00001068{
Enrico Granata864e3e82012-02-17 03:18:30 +00001069 LoadSystemFormatters();
Enrico Granata170c3952015-09-14 22:18:32 +00001070 LoadVectorFormatters();
Enrico Granata864e3e82012-02-17 03:18:30 +00001071
Enrico Granatafa6b2782015-09-17 00:14:50 +00001072 EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1073 EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
Enrico Granata864e3e82012-02-17 03:18:30 +00001074}
1075
1076void
Enrico Granata864e3e82012-02-17 03:18:30 +00001077FormatManager::LoadSystemFormatters()
1078{
Enrico Granataf68df122013-01-10 22:08:35 +00001079 TypeSummaryImpl::Flags string_flags;
Enrico Granata0337c272013-02-22 00:37:31 +00001080 string_flags.SetCascades(true)
Enrico Granataf68df122013-01-10 22:08:35 +00001081 .SetSkipPointers(true)
1082 .SetSkipReferences(false)
1083 .SetDontShowChildren(true)
1084 .SetDontShowValue(false)
1085 .SetShowMembersOneLiner(false)
1086 .SetHideItemNames(false);
1087
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001088 TypeSummaryImpl::Flags string_array_flags;
Enrico Granatad2911632015-07-28 02:13:03 +00001089 string_array_flags.SetCascades(true)
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001090 .SetSkipPointers(true)
1091 .SetSkipReferences(false)
1092 .SetDontShowChildren(true)
1093 .SetDontShowValue(true)
1094 .SetShowMembersOneLiner(false)
1095 .SetHideItemNames(false);
1096
Enrico Granataf68df122013-01-10 22:08:35 +00001097 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001098
1099
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001100 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
Enrico Granata061858c2012-02-15 02:34:21 +00001101 "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001102
1103 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001104 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
Enrico Granatac482a192011-08-17 22:13:59 +00001105
Enrico Granata061858c2012-02-15 02:34:21 +00001106 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
Enrico Granatac482a192011-08-17 22:13:59 +00001107
Enrico Granatab72a5012013-12-20 09:38:13 +00001108 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1109 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1110 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
Enrico Granataaff65652013-10-21 17:29:51 +00001111
Enrico Granata4ed7ef12012-07-13 18:54:40 +00001112 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1113 .SetSkipPointers(true)
1114 .SetSkipReferences(true)
1115 .SetDontShowChildren(true)
1116 .SetDontShowValue(false)
1117 .SetShowMembersOneLiner(false)
1118 .SetHideItemNames(false),
1119 "${var%O}"));
1120
Enrico Granatab72a5012013-12-20 09:38:13 +00001121 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
Enrico Granatad3d444f2012-02-23 23:10:03 +00001122
Jason Molenda1a100cd2013-01-12 04:24:50 +00001123#ifndef LLDB_DISABLE_PYTHON
Enrico Granata4cc21772013-10-08 20:59:02 +00001124 TypeFormatImpl::Flags fourchar_flags;
1125 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1126
1127 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
Jason Molenda1a100cd2013-01-12 04:24:50 +00001128#endif
Enrico Granatad3d444f2012-02-23 23:10:03 +00001129}
Enrico Granatab2698cd2012-09-13 18:27:09 +00001130
Enrico Granata864e3e82012-02-17 03:18:30 +00001131void
Enrico Granata170c3952015-09-14 22:18:32 +00001132FormatManager::LoadVectorFormatters()
Enrico Granata864e3e82012-02-17 03:18:30 +00001133{
Enrico Granata864e3e82012-02-17 03:18:30 +00001134 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
Enrico Granata170c3952015-09-14 22:18:32 +00001135
Enrico Granata864e3e82012-02-17 03:18:30 +00001136 TypeSummaryImpl::Flags vector_flags;
1137 vector_flags.SetCascades(true)
1138 .SetSkipPointers(true)
1139 .SetSkipReferences(false)
1140 .SetDontShowChildren(true)
1141 .SetDontShowValue(false)
1142 .SetShowMembersOneLiner(true)
1143 .SetHideItemNames(true);
1144
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001145 AddStringSummary(vectors_category_sp,
1146 "${var.uint128}",
1147 ConstString("builtin_type_vec128"),
Enrico Granata170c3952015-09-14 22:18:32 +00001148 vector_flags);
1149
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001150 AddStringSummary(vectors_category_sp,
1151 "",
1152 ConstString("float [4]"),
1153 vector_flags);
1154 AddStringSummary(vectors_category_sp,
1155 "",
1156 ConstString("int32_t [4]"),
1157 vector_flags);
1158 AddStringSummary(vectors_category_sp,
1159 "",
1160 ConstString("int16_t [8]"),
1161 vector_flags);
1162 AddStringSummary(vectors_category_sp,
1163 "",
1164 ConstString("vDouble"),
1165 vector_flags);
1166 AddStringSummary(vectors_category_sp,
1167 "",
1168 ConstString("vFloat"),
1169 vector_flags);
1170 AddStringSummary(vectors_category_sp,
1171 "",
1172 ConstString("vSInt8"),
1173 vector_flags);
1174 AddStringSummary(vectors_category_sp,
1175 "",
1176 ConstString("vSInt16"),
1177 vector_flags);
1178 AddStringSummary(vectors_category_sp,
1179 "",
1180 ConstString("vSInt32"),
1181 vector_flags);
1182 AddStringSummary(vectors_category_sp,
1183 "",
1184 ConstString("vUInt16"),
1185 vector_flags);
1186 AddStringSummary(vectors_category_sp,
1187 "",
1188 ConstString("vUInt8"),
1189 vector_flags);
1190 AddStringSummary(vectors_category_sp,
1191 "",
1192 ConstString("vUInt16"),
1193 vector_flags);
1194 AddStringSummary(vectors_category_sp,
1195 "",
1196 ConstString("vUInt32"),
1197 vector_flags);
1198 AddStringSummary(vectors_category_sp,
1199 "",
1200 ConstString("vBool32"),
1201 vector_flags);
Greg Claytond4e25522011-10-12 00:53:29 +00001202}