blob: f437582fbd2b9b8c49d14658a105e6dd80229296 [file] [log] [blame]
Eugene Zelenkobbd16812016-02-29 19:41:30 +00001//===-- CPlusPlusLanguage.cpp -----------------------------------*- C++ -*-===//
Enrico Granata5f9d3102015-08-27 21:33:50 +00002//
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
10#include "CPlusPlusLanguage.h"
11
Eugene Zelenkobbd16812016-02-29 19:41:30 +000012// C Includes
Eugene Zelenkobbd16812016-02-29 19:41:30 +000013#include <cctype>
Kate Stoneb9c1b512016-09-06 20:57:50 +000014#include <cstring>
Luke Drummondf5bb1d62016-12-19 17:22:44 +000015
16// C++ Includes
Eugene Zelenkobbd16812016-02-29 19:41:30 +000017#include <functional>
Luke Drummondf5bb1d62016-12-19 17:22:44 +000018#include <memory>
Eugene Zelenkobbd16812016-02-29 19:41:30 +000019#include <mutex>
Luke Drummondf5bb1d62016-12-19 17:22:44 +000020#include <set>
Jim Inghamaa816b82015-09-02 01:59:14 +000021
Eugene Zelenkobbd16812016-02-29 19:41:30 +000022// Other libraries and framework includes
Jim Inghamaa816b82015-09-02 01:59:14 +000023#include "llvm/ADT/StringRef.h"
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +000024#include "llvm/Demangle/Demangle.h"
Jim Inghamaa816b82015-09-02 01:59:14 +000025
Eugene Zelenkobbd16812016-02-29 19:41:30 +000026// Project includes
Enrico Granata5f9d3102015-08-27 21:33:50 +000027#include "lldb/Core/PluginManager.h"
Jim Inghamaa816b82015-09-02 01:59:14 +000028#include "lldb/Core/UniqueCStringMap.h"
Enrico Granata7cb59e12015-09-16 18:28:11 +000029#include "lldb/DataFormatters/CXXFunctionPointer.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000030#include "lldb/DataFormatters/DataVisualization.h"
31#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granata7cb59e12015-09-16 18:28:11 +000032#include "lldb/DataFormatters/VectorType.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000033#include "lldb/Utility/ConstString.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000034#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000035#include "lldb/Utility/RegularExpression.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000036
Sean Callananc530ba92016-05-02 21:15:31 +000037#include "BlockPointer.h"
Eugene Zemtsova633ee62017-04-06 22:36:02 +000038#include "CPlusPlusNameParser.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000039#include "CxxStringTypes.h"
40#include "LibCxx.h"
Enrico Granata75995b52016-02-12 22:18:24 +000041#include "LibCxxAtomic.h"
Shafik Yaghmour8306f762018-09-19 18:07:05 +000042#include "LibCxxVariant.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000043#include "LibStdcpp.h"
44
Enrico Granata5f9d3102015-08-27 21:33:50 +000045using namespace lldb;
46using namespace lldb_private;
Enrico Granata33e97e62015-09-04 21:01:18 +000047using namespace lldb_private::formatters;
Enrico Granata5f9d3102015-08-27 21:33:50 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049void CPlusPlusLanguage::Initialize() {
50 PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
51 CreateInstance);
Enrico Granata5f9d3102015-08-27 21:33:50 +000052}
53
Kate Stoneb9c1b512016-09-06 20:57:50 +000054void CPlusPlusLanguage::Terminate() {
55 PluginManager::UnregisterPlugin(CreateInstance);
Enrico Granata5f9d3102015-08-27 21:33:50 +000056}
57
Kate Stoneb9c1b512016-09-06 20:57:50 +000058lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
59 static ConstString g_name("cplusplus");
60 return g_name;
Enrico Granata5f9d3102015-08-27 21:33:50 +000061}
62
Enrico Granata5f9d3102015-08-27 21:33:50 +000063//------------------------------------------------------------------
64// PluginInterface protocol
65//------------------------------------------------------------------
Eugene Zelenkobbd16812016-02-29 19:41:30 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067lldb_private::ConstString CPlusPlusLanguage::GetPluginName() {
68 return GetPluginNameStatic();
Enrico Granata5f9d3102015-08-27 21:33:50 +000069}
70
Kate Stoneb9c1b512016-09-06 20:57:50 +000071uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; }
Enrico Granata5f9d3102015-08-27 21:33:50 +000072
73//------------------------------------------------------------------
74// Static Functions
75//------------------------------------------------------------------
Eugene Zelenkobbd16812016-02-29 19:41:30 +000076
Kate Stoneb9c1b512016-09-06 20:57:50 +000077Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
78 if (Language::LanguageIsCPlusPlus(language))
79 return new CPlusPlusLanguage();
80 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +000081}
Jim Inghamaa816b82015-09-02 01:59:14 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083void CPlusPlusLanguage::MethodName::Clear() {
84 m_full.Clear();
85 m_basename = llvm::StringRef();
86 m_context = llvm::StringRef();
87 m_arguments = llvm::StringRef();
88 m_qualifiers = llvm::StringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 m_parsed = false;
90 m_parse_error = false;
Jim Inghamaa816b82015-09-02 01:59:14 +000091}
92
Eugene Zemtsova633ee62017-04-06 22:36:02 +000093static bool ReverseFindMatchingChars(const llvm::StringRef &s,
94 const llvm::StringRef &left_right_chars,
95 size_t &left_pos, size_t &right_pos,
96 size_t pos = llvm::StringRef::npos) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000097 assert(left_right_chars.size() == 2);
98 left_pos = llvm::StringRef::npos;
99 const char left_char = left_right_chars[0];
100 const char right_char = left_right_chars[1];
101 pos = s.find_last_of(left_right_chars, pos);
102 if (pos == llvm::StringRef::npos || s[pos] == left_char)
103 return false;
104 right_pos = pos;
105 uint32_t depth = 1;
106 while (pos > 0 && depth > 0) {
Jim Inghamaa816b82015-09-02 01:59:14 +0000107 pos = s.find_last_of(left_right_chars, pos);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 if (pos == llvm::StringRef::npos)
109 return false;
110 if (s[pos] == left_char) {
111 if (--depth == 0) {
112 left_pos = pos;
113 return left_pos < right_pos;
114 }
115 } else if (s[pos] == right_char) {
116 ++depth;
Jim Inghamaa816b82015-09-02 01:59:14 +0000117 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118 }
119 return false;
Jim Inghamaa816b82015-09-02 01:59:14 +0000120}
121
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000122static bool IsTrivialBasename(const llvm::StringRef &basename) {
123 // Check that the basename matches with the following regular expression
Adrian Prantl05097242018-04-30 16:49:04 +0000124 // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
125 // because it is significantly more efficient then using the general purpose
126 // regular expression library.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 size_t idx = 0;
128 if (basename.size() > 0 && basename[0] == '~')
129 idx = 1;
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 if (basename.size() <= idx)
132 return false; // Empty string or "~"
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 if (!std::isalpha(basename[idx]) && basename[idx] != '_')
135 return false; // First charater (after removing the possible '~'') isn't in
136 // [A-Za-z_]
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000137
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 // Read all characters matching [A-Za-z_0-9]
139 ++idx;
140 while (idx < basename.size()) {
141 if (!std::isalnum(basename[idx]) && basename[idx] != '_')
142 break;
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000143 ++idx;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 }
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 // We processed all characters. It is a vaild basename.
147 if (idx == basename.size())
148 return true;
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000149
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000150 return false;
151}
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000152
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000153bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
Adrian Prantl05097242018-04-30 16:49:04 +0000154 // This method tries to parse simple method definitions which are presumably
155 // most comman in user programs. Definitions that can be parsed by this
156 // function don't have return types and templates in the name.
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000157 // A::B::C::fun(std::vector<T> &) const
158 size_t arg_start, arg_end;
159 llvm::StringRef full(m_full.GetCString());
160 llvm::StringRef parens("()", 2);
161 if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
162 m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
163 if (arg_end + 1 < full.size())
164 m_qualifiers = full.substr(arg_end + 1).ltrim();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000166 if (arg_start == 0)
167 return false;
168 size_t basename_end = arg_start;
169 size_t context_start = 0;
170 size_t context_end = full.rfind(':', basename_end);
171 if (context_end == llvm::StringRef::npos)
172 m_basename = full.substr(0, basename_end);
173 else {
174 if (context_start < context_end)
175 m_context = full.substr(context_start, context_end - 1 - context_start);
176 const size_t basename_begin = context_end + 1;
177 m_basename = full.substr(basename_begin, basename_end - basename_begin);
178 }
179
180 if (IsTrivialBasename(m_basename)) {
181 return true;
182 } else {
183 // The C++ basename doesn't match our regular expressions so this can't
184 // be a valid C++ method, clear everything out and indicate an error
185 m_context = llvm::StringRef();
186 m_basename = llvm::StringRef();
187 m_arguments = llvm::StringRef();
188 m_qualifiers = llvm::StringRef();
189 return false;
190 }
191 }
192 return false;
Jim Inghamaa816b82015-09-02 01:59:14 +0000193}
194
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195void CPlusPlusLanguage::MethodName::Parse() {
196 if (!m_parsed && m_full) {
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000197 if (TrySimplifiedParse()) {
198 m_parse_error = false;
199 } else {
200 CPlusPlusNameParser parser(m_full.GetStringRef());
201 if (auto function = parser.ParseAsFunctionDefinition()) {
202 m_basename = function.getValue().name.basename;
203 m_context = function.getValue().name.context;
204 m_arguments = function.getValue().arguments;
205 m_qualifiers = function.getValue().qualifiers;
206 m_parse_error = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 } else {
208 m_parse_error = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 }
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000211 m_parsed = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000212 }
213}
214
215llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() {
216 if (!m_parsed)
217 Parse();
218 return m_basename;
219}
220
221llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() {
222 if (!m_parsed)
223 Parse();
224 return m_context;
225}
226
227llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() {
228 if (!m_parsed)
229 Parse();
230 return m_arguments;
231}
232
233llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() {
234 if (!m_parsed)
235 Parse();
236 return m_qualifiers;
237}
238
239std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
240 if (!m_parsed)
241 Parse();
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000242 if (m_context.empty())
243 return m_basename;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244
245 std::string res;
246 res += m_context;
247 res += "::";
248 res += m_basename;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 return res;
250}
251
252bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
Adrian Prantl05097242018-04-30 16:49:04 +0000253 // FIXME!! we should really run through all the known C++ Language plugins
254 // and ask each one if this is a C++ mangled name
Adrian Prantlc53d3682018-08-15 22:48:48 +0000255
Aaron Smithb38799c2018-02-08 23:11:56 +0000256 if (name == nullptr)
257 return false;
Adrian Prantlc53d3682018-08-15 22:48:48 +0000258
259 // MSVC style mangling
Aaron Smithb38799c2018-02-08 23:11:56 +0000260 if (name[0] == '?')
261 return true;
Adrian Prantlc53d3682018-08-15 22:48:48 +0000262
Aaron Smithb38799c2018-02-08 23:11:56 +0000263 return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z');
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264}
265
266bool CPlusPlusLanguage::ExtractContextAndIdentifier(
267 const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000268 CPlusPlusNameParser parser(name);
269 if (auto full_name = parser.ParseAsFullName()) {
270 identifier = full_name.getValue().basename;
271 context = full_name.getValue().context;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272 return true;
273 }
274 return false;
275}
276
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000277/// Given a mangled function `mangled`, replace all the primitive function type
278/// arguments of `search` with type `replace`.
279static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled,
280 llvm::StringRef search,
281 llvm::StringRef replace) {
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000282 class PrimitiveParmSubs {
283 llvm::StringRef mangled;
284 llvm::StringRef search;
285 llvm::StringRef replace;
286 ptrdiff_t read_pos;
287 std::string output;
288 std::back_insert_iterator<std::string> writer;
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000289
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000290 public:
291 PrimitiveParmSubs(llvm::StringRef m, llvm::StringRef s, llvm::StringRef r)
292 : mangled(m), search(s), replace(r), read_pos(0),
293 writer(std::back_inserter(output)) {}
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000294
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000295 void Substitute(llvm::StringRef tail) {
296 assert(tail.data() >= mangled.data() &&
297 tail.data() < mangled.data() + mangled.size() &&
298 "tail must point into range of mangled");
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000299
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000300 if (tail.startswith(search)) {
301 auto reader = mangled.begin() + read_pos;
302 ptrdiff_t read_len = tail.data() - (mangled.data() + read_pos);
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000303
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000304 // First write the unmatched part of the original. Then write the
305 // replacement string. Finally skip the search string in the original.
306 writer = std::copy(reader, reader + read_len, writer);
307 writer = std::copy(replace.begin(), replace.end(), writer);
308 read_pos += read_len + search.size();
309 }
310 }
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000311
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000312 ConstString Finalize() {
313 // If we did a substitution, write the remaining part of the original.
314 if (read_pos > 0) {
315 writer = std::copy(mangled.begin() + read_pos, mangled.end(), writer);
316 read_pos = mangled.size();
317 }
318
319 return ConstString(output);
320 }
321
322 static void Callback(void *context, const char *match) {
323 ((PrimitiveParmSubs *)context)->Substitute(llvm::StringRef(match));
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000324 }
325 };
326
Stefan Granitz44780cc2018-08-14 11:32:51 +0000327 // The demangler will call back for each instance of a primitive type,
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000328 // allowing us to perform substitution
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000329 PrimitiveParmSubs parmSubs(mangled, search, replace);
330 assert(mangled.data()[mangled.size()] == '\0' && "Expect C-String");
331 bool err = llvm::itaniumFindTypesInMangledName(mangled.data(), &parmSubs,
332 PrimitiveParmSubs::Callback);
333 ConstString result = parmSubs.Finalize();
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000334
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000335 if (Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)) {
336 if (err)
337 LLDB_LOG(log, "Failed to substitute mangling in {0}", mangled);
338 else if (result)
339 LLDB_LOG(log, "Substituted mangling {0} -> {1}", mangled, result);
340 }
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000341
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000342 return result;
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000343}
344
345uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
346 const ConstString mangled_name, std::set<ConstString> &alternates) {
347 const auto start_size = alternates.size();
348 /// Get a basic set of alternative manglings for the given symbol `name`, by
349 /// making a few basic possible substitutions on basic types, storage duration
350 /// and `const`ness for the given symbol. The output parameter `alternates`
351 /// is filled with a best-guess, non-exhaustive set of different manglings
352 /// for the given name.
353
354 // Maybe we're looking for a const symbol but the debug info told us it was
355 // non-const...
356 if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
357 strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
358 std::string fixed_scratch("_ZNK");
359 fixed_scratch.append(mangled_name.GetCString() + 3);
360 alternates.insert(ConstString(fixed_scratch));
361 }
362
363 // Maybe we're looking for a static symbol but we thought it was global...
364 if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
365 strncmp(mangled_name.GetCString(), "_ZL", 3)) {
366 std::string fixed_scratch("_ZL");
367 fixed_scratch.append(mangled_name.GetCString() + 2);
368 alternates.insert(ConstString(fixed_scratch));
369 }
370
371 // `char` is implementation defined as either `signed` or `unsigned`. As a
372 // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
373 // char, 'h'-unsigned char. If we're looking for symbols with a signed char
374 // parameter, try finding matches which have the general case 'c'.
375 if (ConstString char_fixup =
376 SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "a", "c"))
377 alternates.insert(char_fixup);
378
379 // long long parameter mangling 'x', may actually just be a long 'l' argument
380 if (ConstString long_fixup =
381 SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "x", "l"))
382 alternates.insert(long_fixup);
383
384 // unsigned long long parameter mangling 'y', may actually just be unsigned
385 // long 'm' argument
386 if (ConstString ulong_fixup =
387 SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "y", "m"))
388 alternates.insert(ulong_fixup);
389
390 return alternates.size() - start_size;
391}
392
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
394 if (!cpp_category_sp)
395 return;
396
397 TypeSummaryImpl::Flags stl_summary_flags;
398 stl_summary_flags.SetCascades(true)
399 .SetSkipPointers(false)
400 .SetSkipReferences(false)
401 .SetDontShowChildren(true)
402 .SetDontShowValue(true)
403 .SetShowMembersOneLiner(false)
404 .SetHideItemNames(false);
405
Enrico Granata33e97e62015-09-04 21:01:18 +0000406#ifndef LLDB_DISABLE_PYTHON
Kate Stoneb9c1b512016-09-06 20:57:50 +0000407 lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(
Shafik Yaghmour693fbf52018-10-26 17:00:48 +0000408 stl_summary_flags,
409 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410 "std::string summary provider"));
Shafik Yaghmour693fbf52018-10-26 17:00:48 +0000411 lldb::TypeSummaryImplSP std_stringu16_summary_sp(new CXXFunctionSummaryFormat(
412 stl_summary_flags,
413 lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
414 "std::u16string summary provider"));
415 lldb::TypeSummaryImplSP std_stringu32_summary_sp(new CXXFunctionSummaryFormat(
416 stl_summary_flags,
417 lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
418 "std::u32string summary provider"));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000419 lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(
420 stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider,
421 "std::wstring summary provider"));
Enrico Granata75995b52016-02-12 22:18:24 +0000422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 cpp_category_sp->GetTypeSummariesContainer()->Add(
424 ConstString("std::__1::string"), std_string_summary_sp);
425 cpp_category_sp->GetTypeSummariesContainer()->Add(
426 ConstString("std::__ndk1::string"), std_string_summary_sp);
427 cpp_category_sp->GetTypeSummariesContainer()->Add(
428 ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, "
429 "std::__1::allocator<char> >"),
430 std_string_summary_sp);
431 cpp_category_sp->GetTypeSummariesContainer()->Add(
Shafik Yaghmour693fbf52018-10-26 17:00:48 +0000432 ConstString(
433 "std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, "
434 "std::__1::allocator<char16_t> >"),
435 std_stringu16_summary_sp);
436 cpp_category_sp->GetTypeSummariesContainer()->Add(
437 ConstString(
438 "std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, "
439 "std::__1::allocator<char32_t> >"),
440 std_stringu32_summary_sp);
441 cpp_category_sp->GetTypeSummariesContainer()->Add(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 ConstString("std::__ndk1::basic_string<char, "
443 "std::__ndk1::char_traits<char>, "
444 "std::__ndk1::allocator<char> >"),
445 std_string_summary_sp);
Enrico Granata1b54bae2016-08-31 21:46:37 +0000446
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 cpp_category_sp->GetTypeSummariesContainer()->Add(
448 ConstString("std::__1::wstring"), std_wstring_summary_sp);
449 cpp_category_sp->GetTypeSummariesContainer()->Add(
450 ConstString("std::__ndk1::wstring"), std_wstring_summary_sp);
451 cpp_category_sp->GetTypeSummariesContainer()->Add(
452 ConstString("std::__1::basic_string<wchar_t, "
453 "std::__1::char_traits<wchar_t>, "
454 "std::__1::allocator<wchar_t> >"),
455 std_wstring_summary_sp);
456 cpp_category_sp->GetTypeSummariesContainer()->Add(
457 ConstString("std::__ndk1::basic_string<wchar_t, "
458 "std::__ndk1::char_traits<wchar_t>, "
459 "std::__ndk1::allocator<wchar_t> >"),
460 std_wstring_summary_sp);
461
462 SyntheticChildren::Flags stl_synth_flags;
463 stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
464 false);
Jim Ingham393fe622018-07-13 19:28:32 +0000465 SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
466 stl_deref_flags.SetFrontEndWantsDereference();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000467
468 AddCXXSynthetic(
469 cpp_category_sp,
Pavel Labath52698752017-11-14 11:15:03 +0000470 lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
471 "libc++ std::bitset synthetic children",
Jim Ingham393fe622018-07-13 19:28:32 +0000472 ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_deref_flags,
Pavel Labath52698752017-11-14 11:15:03 +0000473 true);
474 AddCXXSynthetic(
475 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
477 "libc++ std::vector synthetic children",
Jim Ingham393fe622018-07-13 19:28:32 +0000478 ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_deref_flags,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479 true);
480 AddCXXSynthetic(
481 cpp_category_sp,
Pavel Labath89ac0c72017-10-31 12:27:43 +0000482 lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
483 "libc++ std::forward_list synthetic children",
484 ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"),
485 stl_synth_flags, true);
486 AddCXXSynthetic(
487 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488 lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
489 "libc++ std::list synthetic children",
490 ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true);
491 AddCXXSynthetic(
492 cpp_category_sp,
493 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
494 "libc++ std::map synthetic children",
495 ConstString("^std::__(ndk)?1::map<.+> >(( )?&)?$"), stl_synth_flags,
496 true);
497 AddCXXSynthetic(
498 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000499 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
500 "libc++ std::set synthetic children",
Jim Ingham393fe622018-07-13 19:28:32 +0000501 ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_deref_flags,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502 true);
503 AddCXXSynthetic(
504 cpp_category_sp,
505 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
506 "libc++ std::multiset synthetic children",
Jim Ingham393fe622018-07-13 19:28:32 +0000507 ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_deref_flags,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508 true);
509 AddCXXSynthetic(
510 cpp_category_sp,
511 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
512 "libc++ std::multimap synthetic children",
513 ConstString("^std::__(ndk)?1::multimap<.+> >(( )?&)?$"), stl_synth_flags,
514 true);
515 AddCXXSynthetic(
516 cpp_category_sp,
517 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,
518 "libc++ std::unordered containers synthetic children",
519 ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"),
520 stl_synth_flags, true);
521 AddCXXSynthetic(
522 cpp_category_sp,
523 lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator,
524 "libc++ std::initializer_list synthetic children",
525 ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
526 true);
Pavel Labathe0d51842017-11-01 15:52:08 +0000527 AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
528 "libc++ std::queue synthetic children",
529 ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
530 stl_synth_flags, true);
Pavel Labath333739d2017-11-01 15:19:52 +0000531 AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
532 "libc++ std::tuple synthetic children",
533 ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags,
534 true);
Adrian Prantlc53d3682018-08-15 22:48:48 +0000535 AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator,
536 "libc++ std::optional synthetic children",
537 ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"),
538 stl_synth_flags, true);
Shafik Yaghmour8306f762018-09-19 18:07:05 +0000539 AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
540 "libc++ std::variant synthetic children",
541 ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"),
542 stl_synth_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 AddCXXSynthetic(
544 cpp_category_sp,
545 lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
546 "libc++ std::atomic synthetic children",
547 ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_synth_flags, true);
548
549 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Zachary Turner95eae422016-09-21 16:01:28 +0000550 RegularExpressionSP(new RegularExpression(
551 llvm::StringRef("^(std::__(ndk)?1::)deque<.+>(( )?&)?$"))),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552 SyntheticChildrenSP(new ScriptedSyntheticChildren(
553 stl_synth_flags,
554 "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
555
556 AddCXXSynthetic(
557 cpp_category_sp,
558 lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
559 "shared_ptr synthetic children",
560 ConstString("^(std::__(ndk)?1::)shared_ptr<.+>(( )?&)?$"),
561 stl_synth_flags, true);
562 AddCXXSynthetic(
563 cpp_category_sp,
564 lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
565 "weak_ptr synthetic children",
566 ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags,
567 true);
568
Adrian Prantl6b58fa72018-08-23 17:02:39 +0000569 AddCXXSummary(
570 cpp_category_sp, lldb_private::formatters::LibcxxFunctionSummaryProvider,
571 "libc++ std::function summary provider",
572 ConstString("^std::__(ndk)?1::function<.+>$"), stl_summary_flags, true);
573
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574 stl_summary_flags.SetDontShowChildren(false);
575 stl_summary_flags.SetSkipPointers(false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000576 AddCXXSummary(cpp_category_sp,
577 lldb_private::formatters::LibcxxContainerSummaryProvider,
Pavel Labath52698752017-11-14 11:15:03 +0000578 "libc++ std::bitset summary provider",
579 ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"),
580 stl_summary_flags, true);
581 AddCXXSummary(cpp_category_sp,
582 lldb_private::formatters::LibcxxContainerSummaryProvider,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000583 "libc++ std::vector summary provider",
584 ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"),
585 stl_summary_flags, true);
586 AddCXXSummary(cpp_category_sp,
587 lldb_private::formatters::LibcxxContainerSummaryProvider,
588 "libc++ std::list summary provider",
Pavel Labath89ac0c72017-10-31 12:27:43 +0000589 ConstString("^std::__(ndk)?1::forward_list<.+>(( )?&)?$"),
590 stl_summary_flags, true);
591 AddCXXSummary(cpp_category_sp,
592 lldb_private::formatters::LibcxxContainerSummaryProvider,
593 "libc++ std::list summary provider",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"),
595 stl_summary_flags, true);
596 AddCXXSummary(cpp_category_sp,
597 lldb_private::formatters::LibcxxContainerSummaryProvider,
598 "libc++ std::map summary provider",
599 ConstString("^std::__(ndk)?1::map<.+>(( )?&)?$"),
600 stl_summary_flags, true);
601 AddCXXSummary(cpp_category_sp,
602 lldb_private::formatters::LibcxxContainerSummaryProvider,
603 "libc++ std::deque summary provider",
604 ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"),
605 stl_summary_flags, true);
606 AddCXXSummary(cpp_category_sp,
607 lldb_private::formatters::LibcxxContainerSummaryProvider,
Pavel Labathe0d51842017-11-01 15:52:08 +0000608 "libc++ std::queue summary provider",
609 ConstString("^std::__(ndk)?1::queue<.+>(( )?&)?$"),
610 stl_summary_flags, true);
611 AddCXXSummary(cpp_category_sp,
612 lldb_private::formatters::LibcxxContainerSummaryProvider,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613 "libc++ std::set summary provider",
614 ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"),
615 stl_summary_flags, true);
616 AddCXXSummary(cpp_category_sp,
617 lldb_private::formatters::LibcxxContainerSummaryProvider,
618 "libc++ std::multiset summary provider",
619 ConstString("^std::__(ndk)?1::multiset<.+>(( )?&)?$"),
620 stl_summary_flags, true);
621 AddCXXSummary(cpp_category_sp,
622 lldb_private::formatters::LibcxxContainerSummaryProvider,
623 "libc++ std::multimap summary provider",
624 ConstString("^std::__(ndk)?1::multimap<.+>(( )?&)?$"),
625 stl_summary_flags, true);
626 AddCXXSummary(
627 cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
628 "libc++ std::unordered containers summary provider",
629 ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"),
630 stl_summary_flags, true);
Pavel Labath333739d2017-11-01 15:19:52 +0000631 AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider,
632 "libc++ std::tuple summary provider",
633 ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_summary_flags,
634 true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635 AddCXXSummary(
636 cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider,
637 "libc++ std::atomic summary provider",
638 ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true);
Adrian Prantlc53d3682018-08-15 22:48:48 +0000639 AddCXXSummary(cpp_category_sp,
640 lldb_private::formatters::LibcxxOptionalSummaryProvider,
641 "libc++ std::optional summary provider",
642 ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"),
643 stl_summary_flags, true);
Shafik Yaghmour8306f762018-09-19 18:07:05 +0000644 AddCXXSummary(cpp_category_sp,
645 lldb_private::formatters::LibcxxVariantSummaryProvider,
646 "libc++ std::variant summary provider",
647 ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"),
648 stl_summary_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000649
650 stl_summary_flags.SetSkipPointers(true);
651
652 AddCXXSummary(cpp_category_sp,
653 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
654 "libc++ std::shared_ptr summary provider",
655 ConstString("^std::__(ndk)?1::shared_ptr<.+>(( )?&)?$"),
656 stl_summary_flags, true);
657 AddCXXSummary(cpp_category_sp,
658 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
659 "libc++ std::weak_ptr summary provider",
660 ConstString("^std::__(ndk)?1::weak_ptr<.+>(( )?&)?$"),
661 stl_summary_flags, true);
662
663 AddCXXSynthetic(
664 cpp_category_sp,
665 lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,
666 "std::vector iterator synthetic children",
667 ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true);
668
Kate Stoneb9c1b512016-09-06 20:57:50 +0000669 AddCXXSynthetic(
670 cpp_category_sp,
671 lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,
672 "std::map iterator synthetic children",
673 ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags,
674 true);
Enrico Granata33e97e62015-09-04 21:01:18 +0000675#endif
676}
677
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
679 if (!cpp_category_sp)
680 return;
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000681
Kate Stoneb9c1b512016-09-06 20:57:50 +0000682 TypeSummaryImpl::Flags stl_summary_flags;
683 stl_summary_flags.SetCascades(true)
684 .SetSkipPointers(false)
685 .SetSkipReferences(false)
686 .SetDontShowChildren(true)
687 .SetDontShowValue(true)
688 .SetShowMembersOneLiner(false)
689 .SetHideItemNames(false);
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000690
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691 lldb::TypeSummaryImplSP std_string_summary_sp(
692 new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}"));
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000693
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694 lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(
695 stl_summary_flags, LibStdcppStringSummaryProvider,
696 "libstdc++ c++11 std::string summary provider"));
697 lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(
698 stl_summary_flags, LibStdcppWStringSummaryProvider,
699 "libstdc++ c++11 std::wstring summary provider"));
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000700
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
702 std_string_summary_sp);
703 cpp_category_sp->GetTypeSummariesContainer()->Add(
704 ConstString("std::basic_string<char>"), std_string_summary_sp);
705 cpp_category_sp->GetTypeSummariesContainer()->Add(
706 ConstString("std::basic_string<char,std::char_traits<char>,std::"
707 "allocator<char> >"),
708 std_string_summary_sp);
709 cpp_category_sp->GetTypeSummariesContainer()->Add(
710 ConstString("std::basic_string<char, std::char_traits<char>, "
711 "std::allocator<char> >"),
712 std_string_summary_sp);
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000713
Kate Stoneb9c1b512016-09-06 20:57:50 +0000714 cpp_category_sp->GetTypeSummariesContainer()->Add(
715 ConstString("std::__cxx11::string"), cxx11_string_summary_sp);
716 cpp_category_sp->GetTypeSummariesContainer()->Add(
717 ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, "
718 "std::allocator<char> >"),
719 cxx11_string_summary_sp);
720
721 // making sure we force-pick the summary for printing wstring (_M_p is a
722 // wchar_t*)
723 lldb::TypeSummaryImplSP std_wstring_summary_sp(
724 new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
725
726 cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"),
727 std_wstring_summary_sp);
728 cpp_category_sp->GetTypeSummariesContainer()->Add(
729 ConstString("std::basic_string<wchar_t>"), std_wstring_summary_sp);
730 cpp_category_sp->GetTypeSummariesContainer()->Add(
731 ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::"
732 "allocator<wchar_t> >"),
733 std_wstring_summary_sp);
734 cpp_category_sp->GetTypeSummariesContainer()->Add(
735 ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, "
736 "std::allocator<wchar_t> >"),
737 std_wstring_summary_sp);
738
739 cpp_category_sp->GetTypeSummariesContainer()->Add(
740 ConstString("std::__cxx11::wstring"), cxx11_wstring_summary_sp);
741 cpp_category_sp->GetTypeSummariesContainer()->Add(
742 ConstString("std::__cxx11::basic_string<wchar_t, "
743 "std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
744 cxx11_wstring_summary_sp);
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000745
Enrico Granata33e97e62015-09-04 21:01:18 +0000746#ifndef LLDB_DISABLE_PYTHON
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000747
Kate Stoneb9c1b512016-09-06 20:57:50 +0000748 SyntheticChildren::Flags stl_synth_flags;
749 stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
750 false);
Tamas Berghammer9c6c8e92016-07-06 09:50:00 +0000751
Kate Stoneb9c1b512016-09-06 20:57:50 +0000752 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Zachary Turner95eae422016-09-21 16:01:28 +0000753 RegularExpressionSP(
754 new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 SyntheticChildrenSP(new ScriptedSyntheticChildren(
756 stl_synth_flags,
757 "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
758 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Zachary Turner95eae422016-09-21 16:01:28 +0000759 RegularExpressionSP(
760 new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000761 SyntheticChildrenSP(new ScriptedSyntheticChildren(
762 stl_synth_flags,
763 "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
764 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Zachary Turner95eae422016-09-21 16:01:28 +0000765 RegularExpressionSP(new RegularExpression(
766 llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000767 SyntheticChildrenSP(new ScriptedSyntheticChildren(
768 stl_synth_flags,
769 "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
770 stl_summary_flags.SetDontShowChildren(false);
771 stl_summary_flags.SetSkipPointers(true);
772 cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
Zachary Turner95eae422016-09-21 16:01:28 +0000773 RegularExpressionSP(
774 new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 TypeSummaryImplSP(
776 new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
777 cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
778 RegularExpressionSP(
Zachary Turner95eae422016-09-21 16:01:28 +0000779 new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
780 TypeSummaryImplSP(
781 new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
782 cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
783 RegularExpressionSP(new RegularExpression(
784 llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000785 TypeSummaryImplSP(
786 new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
Tamas Berghammer9c6c8e92016-07-06 09:50:00 +0000787
Kate Stoneb9c1b512016-09-06 20:57:50 +0000788 AddCXXSynthetic(
789 cpp_category_sp,
790 lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,
791 "std::vector iterator synthetic children",
792 ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
Tamas Berghammer9c6c8e92016-07-06 09:50:00 +0000793
Kate Stoneb9c1b512016-09-06 20:57:50 +0000794 AddCXXSynthetic(
795 cpp_category_sp,
796 lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,
797 "std::map iterator synthetic children",
798 ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
799
800 AddCXXSynthetic(
801 cpp_category_sp,
Tamas Berghammerd161b212016-10-21 15:02:44 +0000802 lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
803 "std::unique_ptr synthetic children",
804 ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
805 AddCXXSynthetic(
806 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000807 lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
808 "std::shared_ptr synthetic children",
809 ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
810 AddCXXSynthetic(
811 cpp_category_sp,
812 lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
813 "std::weak_ptr synthetic children",
814 ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
Tamas Berghammer7f15dba2016-10-21 15:02:38 +0000815 AddCXXSynthetic(
816 cpp_category_sp,
817 lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator,
818 "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"),
819 stl_synth_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820
821 AddCXXSummary(cpp_category_sp,
Tamas Berghammerd161b212016-10-21 15:02:44 +0000822 lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
823 "libstdc++ std::unique_ptr summary provider",
824 ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags,
825 true);
826 AddCXXSummary(cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
828 "libstdc++ std::shared_ptr summary provider",
829 ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags,
830 true);
831 AddCXXSummary(cpp_category_sp,
832 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
833 "libstdc++ std::weak_ptr summary provider",
834 ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
835 true);
Enrico Granata33e97e62015-09-04 21:01:18 +0000836#endif
837}
838
Kate Stoneb9c1b512016-09-06 20:57:50 +0000839static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
840 if (!cpp_category_sp)
841 return;
842
843 TypeSummaryImpl::Flags string_flags;
844 string_flags.SetCascades(true)
845 .SetSkipPointers(true)
846 .SetSkipReferences(false)
847 .SetDontShowChildren(true)
848 .SetDontShowValue(false)
849 .SetShowMembersOneLiner(false)
850 .SetHideItemNames(false);
851
852 TypeSummaryImpl::Flags string_array_flags;
853 string_array_flags.SetCascades(true)
854 .SetSkipPointers(true)
855 .SetSkipReferences(false)
856 .SetDontShowChildren(true)
857 .SetDontShowValue(true)
858 .SetShowMembersOneLiner(false)
859 .SetHideItemNames(false);
860
Enrico Granata33e97e62015-09-04 21:01:18 +0000861#ifndef LLDB_DISABLE_PYTHON
Kate Stoneb9c1b512016-09-06 20:57:50 +0000862 // FIXME because of a bug in the FormattersContainer we need to add a summary
863 // for both X* and const X* (<rdar://problem/12717717>)
864 AddCXXSummary(
865 cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
866 "char16_t * summary provider", ConstString("char16_t *"), string_flags);
867 AddCXXSummary(cpp_category_sp,
868 lldb_private::formatters::Char16StringSummaryProvider,
869 "char16_t [] summary provider",
870 ConstString("char16_t \\[[0-9]+\\]"), string_array_flags, true);
871
872 AddCXXSummary(
873 cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider,
874 "char32_t * summary provider", ConstString("char32_t *"), string_flags);
875 AddCXXSummary(cpp_category_sp,
876 lldb_private::formatters::Char32StringSummaryProvider,
877 "char32_t [] summary provider",
878 ConstString("char32_t \\[[0-9]+\\]"), string_array_flags, true);
879
880 AddCXXSummary(
881 cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider,
882 "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
883 AddCXXSummary(cpp_category_sp,
884 lldb_private::formatters::WCharStringSummaryProvider,
885 "wchar_t * summary provider",
886 ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true);
887
888 AddCXXSummary(
889 cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
890 "unichar * summary provider", ConstString("unichar *"), string_flags);
891
892 TypeSummaryImpl::Flags widechar_flags;
893 widechar_flags.SetDontShowValue(true)
894 .SetSkipPointers(true)
895 .SetSkipReferences(false)
896 .SetCascades(true)
897 .SetDontShowChildren(true)
898 .SetHideItemNames(true)
899 .SetShowMembersOneLiner(false);
900
901 AddCXXSummary(
902 cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
903 "char16_t summary provider", ConstString("char16_t"), widechar_flags);
904 AddCXXSummary(
905 cpp_category_sp, lldb_private::formatters::Char32SummaryProvider,
906 "char32_t summary provider", ConstString("char32_t"), widechar_flags);
907 AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,
908 "wchar_t summary provider", ConstString("wchar_t"),
909 widechar_flags);
910
911 AddCXXSummary(
912 cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
913 "unichar summary provider", ConstString("unichar"), widechar_flags);
Enrico Granata33e97e62015-09-04 21:01:18 +0000914#endif
915}
916
Enrico Granatac0464972016-10-27 18:44:45 +0000917std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
Enrico Granata63db2392016-11-01 18:50:49 +0000918 class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
919 public:
920 virtual CompilerType AdjustForInclusion(CompilerType &candidate) override {
921 LanguageType lang_type(candidate.GetMinimumLanguage());
922 if (!Language::LanguageIsC(lang_type) &&
923 !Language::LanguageIsCPlusPlus(lang_type))
924 return CompilerType();
925 if (candidate.IsTypedefType())
926 return candidate.GetTypedefedType();
927 return candidate;
Enrico Granatac0464972016-10-27 18:44:45 +0000928 }
Enrico Granatac0464972016-10-27 18:44:45 +0000929 };
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000930
Enrico Granatac0464972016-10-27 18:44:45 +0000931 return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
932}
933
Kate Stoneb9c1b512016-09-06 20:57:50 +0000934lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000935 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000936 static TypeCategoryImplSP g_category;
937
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000938 llvm::call_once(g_initialize, [this]() -> void {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000939 DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
940 if (g_category) {
941 LoadLibCxxFormatters(g_category);
942 LoadLibStdcppFormatters(g_category);
943 LoadSystemFormatters(g_category);
944 }
945 });
946 return g_category;
Enrico Granata33e97e62015-09-04 21:01:18 +0000947}
948
Enrico Granata7cb59e12015-09-16 18:28:11 +0000949HardcodedFormatters::HardcodedSummaryFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +0000950CPlusPlusLanguage::GetHardcodedSummaries() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000951 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000952 static ConstString g_vectortypes("VectorTypes");
953 static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
954
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000955 llvm::call_once(g_initialize, []() -> void {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000956 g_formatters.push_back(
957 [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
958 FormatManager &) -> TypeSummaryImpl::SharedPointer {
959 static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
960 new CXXFunctionSummaryFormat(
961 TypeSummaryImpl::Flags(),
962 lldb_private::formatters::CXXFunctionPointerSummaryProvider,
963 "Function pointer summary provider"));
964 if (valobj.GetCompilerType().IsFunctionPointerType()) {
965 return formatter_sp;
966 }
967 return nullptr;
968 });
969 g_formatters.push_back(
970 [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
971 FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
972 static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
973 new CXXFunctionSummaryFormat(
974 TypeSummaryImpl::Flags()
975 .SetCascades(true)
976 .SetDontShowChildren(true)
977 .SetHideItemNames(true)
978 .SetShowMembersOneLiner(true)
979 .SetSkipPointers(true)
980 .SetSkipReferences(false),
981 lldb_private::formatters::VectorTypeSummaryProvider,
982 "vector_type pointer summary provider"));
983 if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
984 if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
985 return formatter_sp;
986 }
987 return nullptr;
988 });
989 g_formatters.push_back(
990 [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
991 FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
992 static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
993 new CXXFunctionSummaryFormat(
994 TypeSummaryImpl::Flags()
995 .SetCascades(true)
996 .SetDontShowChildren(true)
997 .SetHideItemNames(true)
998 .SetShowMembersOneLiner(true)
999 .SetSkipPointers(true)
1000 .SetSkipReferences(false),
1001 lldb_private::formatters::BlockPointerSummaryProvider,
1002 "block pointer summary provider"));
1003 if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
1004 return formatter_sp;
1005 }
1006 return nullptr;
1007 });
1008 });
1009
1010 return g_formatters;
Enrico Granata7cb59e12015-09-16 18:28:11 +00001011}
1012
1013HardcodedFormatters::HardcodedSyntheticFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +00001014CPlusPlusLanguage::GetHardcodedSynthetics() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +00001015 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001016 static ConstString g_vectortypes("VectorTypes");
1017 static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
Sean Callananc530ba92016-05-02 21:15:31 +00001018
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +00001019 llvm::call_once(g_initialize, []() -> void {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020 g_formatters.push_back([](lldb_private::ValueObject &valobj,
1021 lldb::DynamicValueType,
1022 FormatManager &
1023 fmt_mgr) -> SyntheticChildren::SharedPointer {
1024 static CXXSyntheticChildren::SharedPointer formatter_sp(
1025 new CXXSyntheticChildren(
1026 SyntheticChildren::Flags()
1027 .SetCascades(true)
1028 .SetSkipPointers(true)
1029 .SetSkipReferences(true)
1030 .SetNonCacheable(true),
1031 "vector_type synthetic children",
1032 lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
1033 if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
1034 if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1035 return formatter_sp;
1036 }
1037 return nullptr;
Enrico Granata7cb59e12015-09-16 18:28:11 +00001038 });
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039 g_formatters.push_back([](lldb_private::ValueObject &valobj,
1040 lldb::DynamicValueType,
1041 FormatManager &
1042 fmt_mgr) -> SyntheticChildren::SharedPointer {
1043 static CXXSyntheticChildren::SharedPointer formatter_sp(
1044 new CXXSyntheticChildren(
1045 SyntheticChildren::Flags()
1046 .SetCascades(true)
1047 .SetSkipPointers(true)
1048 .SetSkipReferences(true)
1049 .SetNonCacheable(true),
1050 "block pointer synthetic children",
1051 lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
1052 if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
1053 return formatter_sp;
1054 }
1055 return nullptr;
1056 });
1057
1058 });
1059
1060 return g_formatters;
Enrico Granata7cb59e12015-09-16 18:28:11 +00001061}
Raphael Isemann566afa02018-08-02 00:30:15 +00001062
1063bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
1064 const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
1065 ".h", ".hh", ".hpp", ".hxx", ".h++"};
1066 for (auto suffix : suffixes) {
1067 if (file_path.endswith_lower(suffix))
1068 return true;
1069 }
1070
1071 // Check if we're in a STL path (where the files usually have no extension
1072 // that we could check for.
1073 return file_path.contains("/usr/include/c++/");
1074}