blob: 12e8ef43bfd617c2185c2450c07eebb9be74e426 [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[]" },
Ewan Crawforda0f08672015-10-16 08:28:47 +000070 { eFormatVectorOfFloat16, '\0' , "float16[]" },
Greg Claytonbb7f31f2011-06-23 21:22:24 +000071 { eFormatVectorOfFloat32, '\0' , "float32[]" },
72 { eFormatVectorOfFloat64, '\0' , "float64[]" },
73 { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
74 { eFormatComplexInteger , 'I' , "complex integer" },
Greg Clayton5009f9d2011-10-27 17:55:14 +000075 { eFormatCharArray , 'a' , "character array" },
76 { eFormatAddressInfo , 'A' , "address" },
Enrico Granata7ec18e32012-08-09 19:33:34 +000077 { eFormatHexFloat , '\0' , "hex float" },
Sean Callananbf154da2012-08-08 17:35:10 +000078 { eFormatInstruction , 'i' , "instruction" },
79 { eFormatVoid , 'v' , "void" }
Greg Claytonbb7f31f2011-06-23 21:22:24 +000080};
81
Saleem Abdulrasool28606952014-06-27 05:17:41 +000082static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
Greg Claytonbb7f31f2011-06-23 21:22:24 +000083
84static bool
85GetFormatFromFormatChar (char format_char, Format &format)
86{
87 for (uint32_t i=0; i<g_num_format_infos; ++i)
88 {
89 if (g_format_infos[i].format_char == format_char)
90 {
91 format = g_format_infos[i].format;
92 return true;
93 }
94 }
95 format = eFormatInvalid;
96 return false;
97}
98
99static bool
100GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
101{
102 uint32_t i;
103 for (i=0; i<g_num_format_infos; ++i)
104 {
105 if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
106 {
107 format = g_format_infos[i].format;
108 return true;
109 }
110 }
111
112 if (partial_match_ok)
113 {
114 for (i=0; i<g_num_format_infos; ++i)
115 {
116 if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
117 {
118 format = g_format_infos[i].format;
119 return true;
120 }
121 }
122 }
123 format = eFormatInvalid;
124 return false;
125}
126
127bool
128FormatManager::GetFormatFromCString (const char *format_cstr,
129 bool partial_match_ok,
130 lldb::Format &format)
131{
132 bool success = false;
133 if (format_cstr && format_cstr[0])
134 {
135 if (format_cstr[1] == '\0')
136 {
137 success = GetFormatFromFormatChar (format_cstr[0], format);
138 if (success)
139 return true;
140 }
141
142 success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
143 }
144 if (!success)
145 format = eFormatInvalid;
146 return success;
147}
148
149char
150FormatManager::GetFormatAsFormatChar (lldb::Format format)
151{
152 for (uint32_t i=0; i<g_num_format_infos; ++i)
153 {
154 if (g_format_infos[i].format == format)
155 return g_format_infos[i].format_char;
156 }
157 return '\0';
158}
Greg Claytonbb7f31f2011-06-23 21:22:24 +0000159
160const char *
161FormatManager::GetFormatAsCString (Format format)
162{
163 if (format >= eFormatDefault && format < kNumFormats)
164 return g_format_infos[format].format_name;
165 return NULL;
166}
Enrico Granata0a3958e2011-07-02 00:25:22 +0000167
Enrico Granatade61cec2013-11-22 00:02:13 +0000168void
Enrico Granata33e97e62015-09-04 21:01:18 +0000169FormatManager::EnableAllCategories ()
170{
171 m_categories_map.EnableAllCategories ();
172 Mutex::Locker lang_locker(m_language_categories_mutex);
173 for (auto& iter : m_language_categories_map)
174 {
175 if (iter.second)
176 iter.second->Enable();
177 }
178}
179
180void
181FormatManager::DisableAllCategories ()
182{
183 m_categories_map.DisableAllCategories ();
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->Disable();
189 }
190}
191
192void
Enrico Granatade61cec2013-11-22 00:02:13 +0000193FormatManager::GetPossibleMatches (ValueObject& valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000194 CompilerType compiler_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000195 uint32_t reason,
196 lldb::DynamicValueType use_dynamic,
197 FormattersMatchVector& entries,
198 bool did_strip_ptr,
199 bool did_strip_ref,
200 bool did_strip_typedef,
201 bool root_level)
202{
Enrico Granatac6bf2e22015-09-23 01:39:46 +0000203 compiler_type = compiler_type.GetTypeForFormatters();
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000204 ConstString type_name(compiler_type.GetConstTypeName());
Enrico Granatade61cec2013-11-22 00:02:13 +0000205 if (valobj.GetBitfieldBitSize() > 0)
206 {
207 StreamString sstring;
208 sstring.Printf("%s:%d",type_name.AsCString(),valobj.GetBitfieldBitSize());
209 ConstString bitfieldname = ConstString(sstring.GetData());
210 entries.push_back({bitfieldname,0,did_strip_ptr,did_strip_ref,did_strip_typedef});
211 reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
212 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000213
Enrico Granatab3f0c342015-10-20 00:13:19 +0000214 if (!compiler_type.IsMeaninglessWithoutDynamicResolution())
215 {
216 entries.push_back({type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
217
218 ConstString display_type_name(compiler_type.GetDisplayTypeName());
219 if (display_type_name != type_name)
220 entries.push_back({display_type_name,reason,did_strip_ptr,did_strip_ref,did_strip_typedef});
221 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000222
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000223 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 +0000224 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000225 CompilerType non_ref_type = compiler_type.GetNonReferenceType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000226 GetPossibleMatches(valobj,
227 non_ref_type,
228 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
229 use_dynamic,
230 entries,
231 did_strip_ptr,
232 true,
233 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000234 if (non_ref_type.IsTypedefType())
235 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000236 CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
Greg Clayton56939cb2015-09-17 22:23:34 +0000237 deffed_referenced_type = is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType() : deffed_referenced_type.GetLValueReferenceType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000238 GetPossibleMatches(valobj,
239 deffed_referenced_type,
240 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
241 use_dynamic,
242 entries,
243 did_strip_ptr,
244 did_strip_ref,
245 true); // this is not exactly the usual meaning of stripping typedefs
246 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000247 }
Enrico Granata1ac62962014-04-10 00:14:07 +0000248
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000249 if (compiler_type.IsPointerType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000250 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000251 CompilerType non_ptr_type = compiler_type.GetPointeeType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000252 GetPossibleMatches(valobj,
253 non_ptr_type,
254 reason | lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
255 use_dynamic,
256 entries,
257 true,
258 did_strip_ref,
259 did_strip_typedef);
Enrico Granata1ac62962014-04-10 00:14:07 +0000260 if (non_ptr_type.IsTypedefType())
261 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000262 CompilerType deffed_pointed_type = non_ptr_type.GetTypedefedType().GetPointerType();
Enrico Granata1ac62962014-04-10 00:14:07 +0000263 GetPossibleMatches(valobj,
264 deffed_pointed_type,
265 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
266 use_dynamic,
267 entries,
268 did_strip_ptr,
269 did_strip_ref,
270 true); // this is not exactly the usual meaning of stripping typedefs
271 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000272 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000273
Enrico Granatad3233c12015-09-09 01:10:46 +0000274 for (lldb::LanguageType language_type : GetCandidateLanguages(valobj))
Enrico Granatade61cec2013-11-22 00:02:13 +0000275 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000276 if (Language* language = Language::FindPlugin(language_type))
Enrico Granatade61cec2013-11-22 00:02:13 +0000277 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000278 for (ConstString candidate : language->GetPossibleFormattersMatches(valobj, use_dynamic))
Enrico Granatade61cec2013-11-22 00:02:13 +0000279 {
Enrico Granatad3233c12015-09-09 01:10:46 +0000280 entries.push_back({candidate,
281 reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
282 did_strip_ptr,
283 did_strip_ref,
284 did_strip_typedef});
285 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000286 }
Enrico Granatade61cec2013-11-22 00:02:13 +0000287 }
Enrico Granatad3233c12015-09-09 01:10:46 +0000288
Enrico Granatade61cec2013-11-22 00:02:13 +0000289 // try to strip typedef chains
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000290 if (compiler_type.IsTypedefType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000291 {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000292 CompilerType deffed_type = compiler_type.GetTypedefedType();
Enrico Granatade61cec2013-11-22 00:02:13 +0000293 GetPossibleMatches(valobj,
294 deffed_type,
295 reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
296 use_dynamic,
297 entries,
298 did_strip_ptr,
299 did_strip_ref,
300 true);
301 }
302
303 if (root_level)
304 {
305 do {
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000306 if (!compiler_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000307 break;
308
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000309 CompilerType unqual_compiler_ast_type = compiler_type.GetFullyUnqualifiedType();
310 if (!unqual_compiler_ast_type.IsValid())
Enrico Granatade61cec2013-11-22 00:02:13 +0000311 break;
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000312 if (unqual_compiler_ast_type.GetOpaqueQualType() != compiler_type.GetOpaqueQualType())
Enrico Granatade61cec2013-11-22 00:02:13 +0000313 GetPossibleMatches (valobj,
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000314 unqual_compiler_ast_type,
Enrico Granatade61cec2013-11-22 00:02:13 +0000315 reason,
316 use_dynamic,
317 entries,
318 did_strip_ptr,
319 did_strip_ref,
320 did_strip_typedef);
321 } while(false);
322
323
324 // if all else fails, go to static type
325 if (valobj.IsDynamic())
326 {
327 lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
328 if (static_value_sp)
329 GetPossibleMatches(*static_value_sp.get(),
Greg Clayton99558cc42015-08-24 23:46:31 +0000330 static_value_sp->GetCompilerType(),
Enrico Granatade61cec2013-11-22 00:02:13 +0000331 reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
332 use_dynamic,
333 entries,
334 did_strip_ptr,
335 did_strip_ref,
336 did_strip_typedef,
337 true);
338 }
339 }
340}
341
Enrico Granata852cc952013-10-08 19:03:22 +0000342lldb::TypeFormatImplSP
343FormatManager::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
344{
345 if (!type_sp)
346 return lldb::TypeFormatImplSP();
347 lldb::TypeFormatImplSP format_chosen_sp;
348 uint32_t num_categories = m_categories_map.GetCount();
349 lldb::TypeCategoryImplSP category_sp;
350 uint32_t prio_category = UINT32_MAX;
351 for (uint32_t category_id = 0;
352 category_id < num_categories;
353 category_id++)
354 {
355 category_sp = GetCategoryAtIndex(category_id);
356 if (category_sp->IsEnabled() == false)
357 continue;
358 lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp);
359 if (format_current_sp && (format_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
360 {
361 prio_category = category_sp->GetEnabledPosition();
362 format_chosen_sp = format_current_sp;
363 }
364 }
365 return format_chosen_sp;
366}
367
Enrico Granataa777dc22012-05-08 21:49:57 +0000368lldb::TypeSummaryImplSP
369FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
370{
371 if (!type_sp)
372 return lldb::TypeSummaryImplSP();
373 lldb::TypeSummaryImplSP summary_chosen_sp;
374 uint32_t num_categories = m_categories_map.GetCount();
375 lldb::TypeCategoryImplSP category_sp;
376 uint32_t prio_category = UINT32_MAX;
377 for (uint32_t category_id = 0;
378 category_id < num_categories;
379 category_id++)
380 {
381 category_sp = GetCategoryAtIndex(category_id);
382 if (category_sp->IsEnabled() == false)
383 continue;
384 lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
385 if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
386 {
387 prio_category = category_sp->GetEnabledPosition();
388 summary_chosen_sp = summary_current_sp;
389 }
390 }
391 return summary_chosen_sp;
392}
393
394lldb::TypeFilterImplSP
395FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
396{
397 if (!type_sp)
398 return lldb::TypeFilterImplSP();
399 lldb::TypeFilterImplSP filter_chosen_sp;
400 uint32_t num_categories = m_categories_map.GetCount();
401 lldb::TypeCategoryImplSP category_sp;
402 uint32_t prio_category = UINT32_MAX;
403 for (uint32_t category_id = 0;
404 category_id < num_categories;
405 category_id++)
406 {
407 category_sp = GetCategoryAtIndex(category_id);
408 if (category_sp->IsEnabled() == false)
409 continue;
410 lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
411 if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
412 {
413 prio_category = category_sp->GetEnabledPosition();
414 filter_chosen_sp = filter_current_sp;
415 }
416 }
417 return filter_chosen_sp;
418}
419
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000420#ifndef LLDB_DISABLE_PYTHON
Enrico Granata5548cb52013-01-28 23:47:25 +0000421lldb::ScriptedSyntheticChildrenSP
Enrico Granataa777dc22012-05-08 21:49:57 +0000422FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
423{
424 if (!type_sp)
Enrico Granata5548cb52013-01-28 23:47:25 +0000425 return lldb::ScriptedSyntheticChildrenSP();
426 lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
Enrico Granataa777dc22012-05-08 21:49:57 +0000427 uint32_t num_categories = m_categories_map.GetCount();
428 lldb::TypeCategoryImplSP category_sp;
429 uint32_t prio_category = UINT32_MAX;
430 for (uint32_t category_id = 0;
431 category_id < num_categories;
432 category_id++)
433 {
434 category_sp = GetCategoryAtIndex(category_id);
435 if (category_sp->IsEnabled() == false)
436 continue;
Enrico Granata5548cb52013-01-28 23:47:25 +0000437 lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
Enrico Granataa777dc22012-05-08 21:49:57 +0000438 if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
439 {
440 prio_category = category_sp->GetEnabledPosition();
441 synth_chosen_sp = synth_current_sp;
442 }
443 }
444 return synth_chosen_sp;
445}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000446#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000447
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000448#ifndef LLDB_DISABLE_PYTHON
Enrico Granataa777dc22012-05-08 21:49:57 +0000449lldb::SyntheticChildrenSP
450FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
451{
452 if (!type_sp)
453 return lldb::SyntheticChildrenSP();
454 lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
Enrico Granata5548cb52013-01-28 23:47:25 +0000455 lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
Enrico Granataa777dc22012-05-08 21:49:57 +0000456 if (filter_sp->GetRevision() > synth_sp->GetRevision())
457 return lldb::SyntheticChildrenSP(filter_sp.get());
458 else
459 return lldb::SyntheticChildrenSP(synth_sp.get());
460}
Jason Molenda7a9a72b2012-05-16 00:38:08 +0000461#endif
Enrico Granataa777dc22012-05-08 21:49:57 +0000462
Enrico Granatac5827132014-09-05 20:45:07 +0000463lldb::TypeValidatorImplSP
464FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
465{
466 if (!type_sp)
467 return lldb::TypeValidatorImplSP();
468 lldb::TypeValidatorImplSP validator_chosen_sp;
469 uint32_t num_categories = m_categories_map.GetCount();
470 lldb::TypeCategoryImplSP category_sp;
471 uint32_t prio_category = UINT32_MAX;
472 for (uint32_t category_id = 0;
473 category_id < num_categories;
474 category_id++)
475 {
476 category_sp = GetCategoryAtIndex(category_id);
477 if (category_sp->IsEnabled() == false)
478 continue;
479 lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
480 if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
481 {
482 prio_category = category_sp->GetEnabledPosition();
483 validator_chosen_sp = validator_current_sp;
484 }
485 }
486 return validator_chosen_sp;
487}
488
Enrico Granata980c0482015-09-01 18:22:39 +0000489void
490FormatManager::LoopThroughCategories (CategoryCallback callback, void* param)
491{
492 m_categories_map.LoopThrough(callback, param);
493 Mutex::Locker locker(m_language_categories_mutex);
494 for (const auto& entry : m_language_categories_map)
495 {
496 if (auto category_sp = entry.second->GetCategory())
497 {
498 if (!callback(param, category_sp))
499 break;
500 }
501 }
502}
503
Enrico Granata061858c2012-02-15 02:34:21 +0000504lldb::TypeCategoryImplSP
Enrico Granata9128ee22011-09-06 19:20:51 +0000505FormatManager::GetCategory (const ConstString& category_name,
Enrico Granatadb595cd2015-03-06 19:37:57 +0000506 bool can_create)
Enrico Granatadc940732011-08-23 00:32:52 +0000507{
508 if (!category_name)
Enrico Granata9128ee22011-09-06 19:20:51 +0000509 return GetCategory(m_default_category_name);
Enrico Granata061858c2012-02-15 02:34:21 +0000510 lldb::TypeCategoryImplSP category;
Enrico Granatadc940732011-08-23 00:32:52 +0000511 if (m_categories_map.Get(category_name, category))
512 return category;
513
514 if (!can_create)
Enrico Granata061858c2012-02-15 02:34:21 +0000515 return lldb::TypeCategoryImplSP();
Enrico Granatadc940732011-08-23 00:32:52 +0000516
Enrico Granata061858c2012-02-15 02:34:21 +0000517 m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
Enrico Granata9128ee22011-09-06 19:20:51 +0000518 return GetCategory(category_name);
Enrico Granatadc940732011-08-23 00:32:52 +0000519}
520
Enrico Granataf4efecd2011-07-12 22:56:10 +0000521lldb::Format
522FormatManager::GetSingleItemFormat(lldb::Format vector_format)
523{
524 switch(vector_format)
525 {
526 case eFormatVectorOfChar:
527 return eFormatCharArray;
528
529 case eFormatVectorOfSInt8:
530 case eFormatVectorOfSInt16:
531 case eFormatVectorOfSInt32:
532 case eFormatVectorOfSInt64:
533 return eFormatDecimal;
534
535 case eFormatVectorOfUInt8:
536 case eFormatVectorOfUInt16:
537 case eFormatVectorOfUInt32:
538 case eFormatVectorOfUInt64:
539 case eFormatVectorOfUInt128:
540 return eFormatHex;
541
Ewan Crawforda0f08672015-10-16 08:28:47 +0000542 case eFormatVectorOfFloat16:
Enrico Granataf4efecd2011-07-12 22:56:10 +0000543 case eFormatVectorOfFloat32:
544 case eFormatVectorOfFloat64:
545 return eFormatFloat;
546
547 default:
548 return lldb::eFormatInvalid;
549 }
Greg Clayton3418c852011-08-10 02:10:13 +0000550}
Enrico Granatac482a192011-08-17 22:13:59 +0000551
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000552bool
553FormatManager::ShouldPrintAsOneLiner (ValueObject& valobj)
554{
Enrico Granata553fad52013-10-25 23:09:40 +0000555 // if settings say no oneline whatsoever
Enrico Granata90a8db32013-10-31 21:01:07 +0000556 if (valobj.GetTargetSP().get() && valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false)
Enrico Granata553fad52013-10-25 23:09:40 +0000557 return false; // then don't oneline
558
Enrico Granata42fa4af2014-09-11 23:00:27 +0000559 // if this object has a summary, then ask the summary
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000560 if (valobj.GetSummaryFormat().get() != nullptr)
Enrico Granata42fa4af2014-09-11 23:00:27 +0000561 return valobj.GetSummaryFormat()->IsOneLiner();
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000562
563 // no children, no party
564 if (valobj.GetNumChildren() == 0)
565 return false;
566
Enrico Granata9c63f992015-09-23 02:04:34 +0000567 // ask the type if it has any opinion about this
568 // eLazyBoolCalculate == no opinion; other values should be self explanatory
569 CompilerType compiler_type(valobj.GetCompilerType());
570 if (compiler_type.IsValid())
571 {
572 switch (compiler_type.ShouldPrintAsOneLiner())
573 {
574 case eLazyBoolNo:
575 return false;
576 case eLazyBoolYes:
577 return true;
578 case eLazyBoolCalculate:
Enrico Granata9c63f992015-09-23 02:04:34 +0000579 break;
580 }
581 }
582
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000583 size_t total_children_name_len = 0;
584
585 for (size_t idx = 0;
586 idx < valobj.GetNumChildren();
587 idx++)
588 {
Enrico Granataddac7612014-10-09 18:47:36 +0000589 bool is_synth_val = false;
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000590 ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true));
591 // something is wrong here - bail out
592 if (!child_sp)
593 return false;
594 // if we decided to define synthetic children for a type, we probably care enough
595 // to show them, but avoid nesting children in children
596 if (child_sp->GetSyntheticChildren().get() != nullptr)
Enrico Granataddac7612014-10-09 18:47:36 +0000597 {
598 ValueObjectSP synth_sp(child_sp->GetSyntheticValue());
599 // wait.. wat? just get out of here..
600 if (!synth_sp)
601 return false;
602 // but if we only have them to provide a value, keep going
603 if (synth_sp->MightHaveChildren() == false && synth_sp->DoesProvideSyntheticValue())
604 is_synth_val = true;
605 else
606 return false;
607 }
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000608
609 total_children_name_len += child_sp->GetName().GetLength();
610
611 // 50 itself is a "randomly" chosen number - the idea is that
612 // overly long structs should not get this treatment
613 // FIXME: maybe make this a user-tweakable setting?
614 if (total_children_name_len > 50)
615 return false;
616
617 // if a summary is there..
618 if (child_sp->GetSummaryFormat())
619 {
620 // and it wants children, then bail out
Enrico Granata8a068e62014-04-23 23:16:25 +0000621 if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get()))
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000622 return false;
623 }
624
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000625 // if this child has children..
626 if (child_sp->GetNumChildren())
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000627 {
Enrico Granatac89e4ca2013-10-23 01:34:31 +0000628 // ...and no summary...
629 // (if it had a summary and the summary wanted children, we would have bailed out anyway
630 // 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 +0000631 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 +0000632 return false; // then bail out
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000633 }
634 }
635 return true;
636}
637
Enrico Granata02b66762011-08-19 01:14:49 +0000638ConstString
639FormatManager::GetValidTypeName (const ConstString& type)
640{
641 return ::GetValidTypeName_Impl(type);
642}
643
Enrico Granata5548cb52013-01-28 23:47:25 +0000644ConstString
Enrico Granata980c0482015-09-01 18:22:39 +0000645FormatManager::GetTypeForCache (ValueObject& valobj,
646 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000647{
Enrico Granatab3f0c342015-10-20 00:13:19 +0000648 ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(use_dynamic, valobj.IsSynthetic());
649 if (valobj_sp && valobj_sp->GetCompilerType().IsValid())
Enrico Granata5548cb52013-01-28 23:47:25 +0000650 {
Enrico Granatab3f0c342015-10-20 00:13:19 +0000651 if (!valobj_sp->GetCompilerType().IsMeaninglessWithoutDynamicResolution())
652 return valobj_sp->GetQualifiedTypeName();
Enrico Granata5548cb52013-01-28 23:47:25 +0000653 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000654 return ConstString();
655}
656
Enrico Granatad3233c12015-09-09 01:10:46 +0000657std::vector<lldb::LanguageType>
658FormatManager::GetCandidateLanguages (ValueObject& valobj)
Enrico Granata980c0482015-09-01 18:22:39 +0000659{
660 lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage();
Enrico Granataac494532015-09-09 22:30:24 +0000661 return GetCandidateLanguages(lang_type);
662}
663
664std::vector<lldb::LanguageType>
665FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type)
666{
Enrico Granata980c0482015-09-01 18:22:39 +0000667 switch (lang_type)
668 {
Enrico Granata33e97e62015-09-04 21:01:18 +0000669 case lldb::eLanguageTypeC:
670 case lldb::eLanguageTypeC89:
671 case lldb::eLanguageTypeC99:
672 case lldb::eLanguageTypeC11:
673 case lldb::eLanguageTypeC_plus_plus:
674 case lldb::eLanguageTypeC_plus_plus_03:
675 case lldb::eLanguageTypeC_plus_plus_11:
676 case lldb::eLanguageTypeC_plus_plus_14:
Enrico Granata170c3952015-09-14 22:18:32 +0000677 return {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC};
Enrico Granata980c0482015-09-01 18:22:39 +0000678 default:
679 return {lang_type};
680 }
681}
682
683LanguageCategory*
684FormatManager::GetCategoryForLanguage (lldb::LanguageType lang_type)
685{
686 Mutex::Locker locker(m_language_categories_mutex);
687 auto iter = m_language_categories_map.find(lang_type), end = m_language_categories_map.end();
688 if (iter != end)
689 return iter->second.get();
690 LanguageCategory* lang_category = new LanguageCategory(lang_type);
691 m_language_categories_map[lang_type] = LanguageCategory::UniquePointer(lang_category);
692 return lang_category;
693}
694
Enrico Granataecd02bc2014-08-19 18:47:58 +0000695lldb::TypeFormatImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000696FormatManager::GetHardcodedFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000697{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000698 TypeFormatImplSP retval_sp;
699
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000700 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000701 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000702 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
703 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000704 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000705 break;
706 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000707 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000708
709 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000710}
711
Enrico Granata852cc952013-10-08 19:03:22 +0000712lldb::TypeFormatImplSP
713FormatManager::GetFormat (ValueObject& valobj,
714 lldb::DynamicValueType use_dynamic)
715{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000716 FormattersMatchData match_data(valobj, use_dynamic);
717
Enrico Granata852cc952013-10-08 19:03:22 +0000718 TypeFormatImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000719 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000720 if (match_data.GetTypeForCache())
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000721 {
722 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000723 log->Printf("\n\n[FormatManager::GetFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
724 if (m_format_cache.GetFormat(match_data.GetTypeForCache(),retval))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000725 {
726 if (log)
727 {
728 log->Printf("[FormatManager::GetFormat] Cache search success. Returning.");
729 if (log->GetDebug())
730 log->Printf("[FormatManager::GetFormat] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
731 }
732 return retval;
733 }
734 if (log)
735 log->Printf("[FormatManager::GetFormat] Cache search failed. Going normal route");
736 }
Enrico Granata980c0482015-09-01 18:22:39 +0000737
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000738 retval = m_categories_map.GetFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000739 if (!retval)
740 {
741 if (log)
742 log->Printf("[FormatManager::GetFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000743 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000744 {
745 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
746 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000747 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000748 break;
749 }
750 }
751 if (retval)
752 {
753 if (log)
754 log->Printf("[FormatManager::GetFormat] Language search success. Returning.");
755 return retval;
756 }
757 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000758 if (!retval)
759 {
760 if (log)
761 log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000762 retval = GetHardcodedFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000763 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000764
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000765 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000766 {
767 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000768 log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
769 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000770 match_data.GetTypeForCache().AsCString("<invalid>"));
771 m_format_cache.SetFormat(match_data.GetTypeForCache(),retval);
Enrico Granata52b4b6c2013-10-17 22:27:19 +0000772 }
773 if (log && log->GetDebug())
774 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 +0000775 return retval;
776}
777
Enrico Granataecd02bc2014-08-19 18:47:58 +0000778lldb::TypeSummaryImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000779FormatManager::GetHardcodedSummaryFormat (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000780{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000781 TypeSummaryImplSP retval_sp;
782
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000783 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000784 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000785 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
786 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000787 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000788 break;
789 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000790 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000791
792 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000793}
794
Enrico Granata5548cb52013-01-28 23:47:25 +0000795lldb::TypeSummaryImplSP
796FormatManager::GetSummaryFormat (ValueObject& valobj,
797 lldb::DynamicValueType use_dynamic)
798{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000799 FormattersMatchData match_data(valobj, use_dynamic);
800
Enrico Granata5548cb52013-01-28 23:47:25 +0000801 TypeSummaryImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000802 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000803 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000804 {
805 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000806 log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
807 if (m_format_cache.GetSummary(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000808 {
809 if (log)
810 {
811 log->Printf("[FormatManager::GetSummaryFormat] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000812 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000813 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 +0000814 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000815 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000816 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000817 if (log)
818 log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
819 }
Enrico Granata980c0482015-09-01 18:22:39 +0000820
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000821 retval = m_categories_map.GetSummaryFormat(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000822 if (!retval)
823 {
824 if (log)
825 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000826 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000827 {
828 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
829 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000830 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000831 break;
832 }
833 }
834 if (retval)
835 {
836 if (log)
837 log->Printf("[FormatManager::GetSummaryFormat] Language search success. Returning.");
838 return retval;
839 }
840 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000841 if (!retval)
842 {
843 if (log)
844 log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000845 retval = GetHardcodedSummaryFormat(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000846 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000847
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000848 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000849 {
850 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000851 log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
852 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000853 match_data.GetTypeForCache().AsCString("<invalid>"));
854 m_format_cache.SetSummary(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000855 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000856 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000857 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 +0000858 return retval;
859}
860
861#ifndef LLDB_DISABLE_PYTHON
Enrico Granataecd02bc2014-08-19 18:47:58 +0000862lldb::SyntheticChildrenSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000863FormatManager::GetHardcodedSyntheticChildren (FormattersMatchData& match_data)
Enrico Granata686f3de2013-10-30 23:46:27 +0000864{
Enrico Granata7cb59e12015-09-16 18:28:11 +0000865 SyntheticChildrenSP retval_sp;
866
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000867 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granataecd02bc2014-08-19 18:47:58 +0000868 {
Enrico Granata7cb59e12015-09-16 18:28:11 +0000869 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
870 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000871 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +0000872 break;
873 }
Enrico Granataecd02bc2014-08-19 18:47:58 +0000874 }
Enrico Granata7cb59e12015-09-16 18:28:11 +0000875
876 return retval_sp;
Enrico Granata686f3de2013-10-30 23:46:27 +0000877}
878
Enrico Granata5548cb52013-01-28 23:47:25 +0000879lldb::SyntheticChildrenSP
880FormatManager::GetSyntheticChildren (ValueObject& valobj,
Enrico Granatac2a96402013-06-26 01:03:38 +0000881 lldb::DynamicValueType use_dynamic)
Enrico Granata5548cb52013-01-28 23:47:25 +0000882{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000883 FormattersMatchData match_data(valobj, use_dynamic);
884
Enrico Granata5548cb52013-01-28 23:47:25 +0000885 SyntheticChildrenSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000886 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000887 if (match_data.GetTypeForCache())
Enrico Granata5548cb52013-01-28 23:47:25 +0000888 {
889 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000890 log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
891 if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(),retval))
Enrico Granata68ae4112013-06-18 18:23:07 +0000892 {
893 if (log)
894 {
895 log->Printf("[FormatManager::GetSyntheticChildren] Cache search success. Returning.");
Enrico Granatac2a96402013-06-26 01:03:38 +0000896 if (log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000897 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 +0000898 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000899 return retval;
Enrico Granata68ae4112013-06-18 18:23:07 +0000900 }
Enrico Granata5548cb52013-01-28 23:47:25 +0000901 if (log)
Enrico Granata68ae4112013-06-18 18:23:07 +0000902 log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route");
Enrico Granata5548cb52013-01-28 23:47:25 +0000903 }
Enrico Granata980c0482015-09-01 18:22:39 +0000904
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000905 retval = m_categories_map.GetSyntheticChildren(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000906 if (!retval)
907 {
908 if (log)
909 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000910 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000911 {
912 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
913 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000914 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000915 break;
916 }
917 }
918 if (retval)
919 {
920 if (log)
921 log->Printf("[FormatManager::GetSyntheticChildren] Language search success. Returning.");
922 return retval;
923 }
924 }
Enrico Granata686f3de2013-10-30 23:46:27 +0000925 if (!retval)
926 {
927 if (log)
928 log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000929 retval = GetHardcodedSyntheticChildren(match_data);
Enrico Granata686f3de2013-10-30 23:46:27 +0000930 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000931
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000932 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granata5548cb52013-01-28 23:47:25 +0000933 {
934 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000935 log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s",
936 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000937 match_data.GetTypeForCache().AsCString("<invalid>"));
938 m_format_cache.SetSynthetic(match_data.GetTypeForCache(),retval);
Enrico Granata5548cb52013-01-28 23:47:25 +0000939 }
Enrico Granatac2a96402013-06-26 01:03:38 +0000940 if (log && log->GetDebug())
Michael Sartain89c862f2013-08-07 19:05:15 +0000941 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 +0000942 return retval;
943}
944#endif
Enrico Granata5548cb52013-01-28 23:47:25 +0000945
Enrico Granatac5827132014-09-05 20:45:07 +0000946lldb::TypeValidatorImplSP
947FormatManager::GetValidator (ValueObject& valobj,
948 lldb::DynamicValueType use_dynamic)
949{
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000950 FormattersMatchData match_data(valobj, use_dynamic);
951
Enrico Granatac5827132014-09-05 20:45:07 +0000952 TypeValidatorImplSP retval;
Enrico Granata4edfef42015-10-06 17:55:14 +0000953 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000954 if (match_data.GetTypeForCache())
Enrico Granatac5827132014-09-05 20:45:07 +0000955 {
956 if (log)
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000957 log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", match_data.GetTypeForCache().AsCString("<invalid>"));
958 if (m_format_cache.GetValidator(match_data.GetTypeForCache(),retval))
Enrico Granatac5827132014-09-05 20:45:07 +0000959 {
960 if (log)
961 {
962 log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
963 if (log->GetDebug())
964 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
965 }
966 return retval;
967 }
968 if (log)
969 log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
970 }
Enrico Granata980c0482015-09-01 18:22:39 +0000971
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000972 retval = m_categories_map.GetValidator(match_data);
Enrico Granata980c0482015-09-01 18:22:39 +0000973 if (!retval)
974 {
975 if (log)
976 log->Printf("[FormatManager::GetValidator] Search failed. Giving language a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000977 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granata980c0482015-09-01 18:22:39 +0000978 {
979 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
980 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000981 if (lang_category->Get(match_data, retval))
Enrico Granata980c0482015-09-01 18:22:39 +0000982 break;
983 }
984 }
985 if (retval)
986 {
987 if (log)
988 log->Printf("[FormatManager::GetValidator] Language search success. Returning.");
989 return retval;
990 }
991 }
Enrico Granatac5827132014-09-05 20:45:07 +0000992 if (!retval)
993 {
994 if (log)
995 log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000996 retval = GetHardcodedValidator(match_data);
Enrico Granatac5827132014-09-05 20:45:07 +0000997 }
Enrico Granatad4cb1dd2015-07-01 20:06:40 +0000998
Enrico Granata8a9a8f32015-10-06 01:02:47 +0000999 if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable()))
Enrico Granatac5827132014-09-05 20:45:07 +00001000 {
1001 if (log)
1002 log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
1003 static_cast<void*>(retval.get()),
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001004 match_data.GetTypeForCache().AsCString("<invalid>"));
1005 m_format_cache.SetValidator(match_data.GetTypeForCache(),retval);
Enrico Granatac5827132014-09-05 20:45:07 +00001006 }
1007 if (log && log->GetDebug())
1008 log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
1009 return retval;
1010}
1011
1012lldb::TypeValidatorImplSP
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001013FormatManager::GetHardcodedValidator (FormattersMatchData& match_data)
Enrico Granatac5827132014-09-05 20:45:07 +00001014{
Enrico Granata7cb59e12015-09-16 18:28:11 +00001015 TypeValidatorImplSP retval_sp;
1016
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001017 for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages())
Enrico Granatac5827132014-09-05 20:45:07 +00001018 {
Enrico Granata7cb59e12015-09-16 18:28:11 +00001019 if (LanguageCategory* lang_category = GetCategoryForLanguage(lang_type))
1020 {
Enrico Granata8a9a8f32015-10-06 01:02:47 +00001021 if (lang_category->GetHardcoded(*this, match_data, retval_sp))
Enrico Granata7cb59e12015-09-16 18:28:11 +00001022 break;
1023 }
Enrico Granatac5827132014-09-05 20:45:07 +00001024 }
Enrico Granata7cb59e12015-09-16 18:28:11 +00001025
1026 return retval_sp;
Enrico Granatac5827132014-09-05 20:45:07 +00001027}
1028
Enrico Granata5548cb52013-01-28 23:47:25 +00001029FormatManager::FormatManager() :
1030 m_format_cache(),
Enrico Granatac482a192011-08-17 22:13:59 +00001031 m_named_summaries_map(this),
1032 m_last_revision(0),
1033 m_categories_map(this),
Enrico Granata980c0482015-09-01 18:22:39 +00001034 m_language_categories_map(),
1035 m_language_categories_mutex(Mutex::eMutexTypeRecursive),
Enrico Granata1d887492011-08-22 18:36:52 +00001036 m_default_category_name(ConstString("default")),
1037 m_system_category_name(ConstString("system")),
Enrico Granata7cb59e12015-09-16 18:28:11 +00001038 m_vectortypes_category_name(ConstString("VectorTypes"))
Enrico Granatac482a192011-08-17 22:13:59 +00001039{
Enrico Granata864e3e82012-02-17 03:18:30 +00001040 LoadSystemFormatters();
Enrico Granata170c3952015-09-14 22:18:32 +00001041 LoadVectorFormatters();
Enrico Granata864e3e82012-02-17 03:18:30 +00001042
Enrico Granatafa6b2782015-09-17 00:14:50 +00001043 EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
1044 EnableCategory(m_system_category_name,TypeCategoryMap::Last, lldb::eLanguageTypeObjC_plus_plus);
Enrico Granata864e3e82012-02-17 03:18:30 +00001045}
1046
1047void
Enrico Granata864e3e82012-02-17 03:18:30 +00001048FormatManager::LoadSystemFormatters()
1049{
Enrico Granataf68df122013-01-10 22:08:35 +00001050
1051 TypeSummaryImpl::Flags string_flags;
Enrico Granata0337c272013-02-22 00:37:31 +00001052 string_flags.SetCascades(true)
Enrico Granataf68df122013-01-10 22:08:35 +00001053 .SetSkipPointers(true)
1054 .SetSkipReferences(false)
1055 .SetDontShowChildren(true)
1056 .SetDontShowValue(false)
1057 .SetShowMembersOneLiner(false)
1058 .SetHideItemNames(false);
1059
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001060 TypeSummaryImpl::Flags string_array_flags;
Enrico Granatad2911632015-07-28 02:13:03 +00001061 string_array_flags.SetCascades(true)
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001062 .SetSkipPointers(true)
1063 .SetSkipReferences(false)
1064 .SetDontShowChildren(true)
1065 .SetDontShowValue(true)
1066 .SetShowMembersOneLiner(false)
1067 .SetHideItemNames(false);
1068
Enrico Granataf68df122013-01-10 22:08:35 +00001069 lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001070
1071
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001072 lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(string_array_flags,
Enrico Granata061858c2012-02-15 02:34:21 +00001073 "${var%s}"));
Enrico Granatac482a192011-08-17 22:13:59 +00001074
1075 lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
Enrico Granatabc2c2b02015-06-15 23:01:47 +00001076 lldb::RegularExpressionSP any_size_wchar_arr(new RegularExpression("wchar_t \\[[0-9]+\\]"));
Enrico Granatac482a192011-08-17 22:13:59 +00001077
Enrico Granata061858c2012-02-15 02:34:21 +00001078 TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
Enrico Granatac482a192011-08-17 22:13:59 +00001079
Enrico Granatab72a5012013-12-20 09:38:13 +00001080 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("char *"), string_format);
1081 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("unsigned char *"), string_format);
1082 sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr, string_array_format);
Enrico Granataaff65652013-10-21 17:29:51 +00001083
Enrico Granata4ed7ef12012-07-13 18:54:40 +00001084 lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
1085 .SetSkipPointers(true)
1086 .SetSkipReferences(true)
1087 .SetDontShowChildren(true)
1088 .SetDontShowValue(false)
1089 .SetShowMembersOneLiner(false)
1090 .SetHideItemNames(false),
1091 "${var%O}"));
1092
Enrico Granatab72a5012013-12-20 09:38:13 +00001093 sys_category_sp->GetTypeSummariesContainer()->Add(ConstString("OSType"), ostype_summary);
Enrico Granatad3d444f2012-02-23 23:10:03 +00001094
Jason Molenda1a100cd2013-01-12 04:24:50 +00001095#ifndef LLDB_DISABLE_PYTHON
Enrico Granata4cc21772013-10-08 20:59:02 +00001096 TypeFormatImpl::Flags fourchar_flags;
1097 fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences(true);
1098
1099 AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), fourchar_flags);
Jason Molenda1a100cd2013-01-12 04:24:50 +00001100#endif
Enrico Granatad3d444f2012-02-23 23:10:03 +00001101}
Enrico Granatab2698cd2012-09-13 18:27:09 +00001102
Enrico Granata864e3e82012-02-17 03:18:30 +00001103void
Enrico Granata170c3952015-09-14 22:18:32 +00001104FormatManager::LoadVectorFormatters()
Enrico Granata864e3e82012-02-17 03:18:30 +00001105{
Enrico Granata864e3e82012-02-17 03:18:30 +00001106 TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
Enrico Granata170c3952015-09-14 22:18:32 +00001107
Enrico Granata864e3e82012-02-17 03:18:30 +00001108 TypeSummaryImpl::Flags vector_flags;
1109 vector_flags.SetCascades(true)
1110 .SetSkipPointers(true)
1111 .SetSkipReferences(false)
1112 .SetDontShowChildren(true)
1113 .SetDontShowValue(false)
1114 .SetShowMembersOneLiner(true)
1115 .SetHideItemNames(true);
1116
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001117 AddStringSummary(vectors_category_sp,
1118 "${var.uint128}",
1119 ConstString("builtin_type_vec128"),
Enrico Granata170c3952015-09-14 22:18:32 +00001120 vector_flags);
1121
Enrico Granatae6a6d9a2012-12-10 23:30:25 +00001122 AddStringSummary(vectors_category_sp,
1123 "",
1124 ConstString("float [4]"),
1125 vector_flags);
1126 AddStringSummary(vectors_category_sp,
1127 "",
1128 ConstString("int32_t [4]"),
1129 vector_flags);
1130 AddStringSummary(vectors_category_sp,
1131 "",
1132 ConstString("int16_t [8]"),
1133 vector_flags);
1134 AddStringSummary(vectors_category_sp,
1135 "",
1136 ConstString("vDouble"),
1137 vector_flags);
1138 AddStringSummary(vectors_category_sp,
1139 "",
1140 ConstString("vFloat"),
1141 vector_flags);
1142 AddStringSummary(vectors_category_sp,
1143 "",
1144 ConstString("vSInt8"),
1145 vector_flags);
1146 AddStringSummary(vectors_category_sp,
1147 "",
1148 ConstString("vSInt16"),
1149 vector_flags);
1150 AddStringSummary(vectors_category_sp,
1151 "",
1152 ConstString("vSInt32"),
1153 vector_flags);
1154 AddStringSummary(vectors_category_sp,
1155 "",
1156 ConstString("vUInt16"),
1157 vector_flags);
1158 AddStringSummary(vectors_category_sp,
1159 "",
1160 ConstString("vUInt8"),
1161 vector_flags);
1162 AddStringSummary(vectors_category_sp,
1163 "",
1164 ConstString("vUInt16"),
1165 vector_flags);
1166 AddStringSummary(vectors_category_sp,
1167 "",
1168 ConstString("vUInt32"),
1169 vector_flags);
1170 AddStringSummary(vectors_category_sp,
1171 "",
1172 ConstString("vBool32"),
1173 vector_flags);
Greg Claytond4e25522011-10-12 00:53:29 +00001174}