blob: 9267c61b3c14dde4b0a591d4a3f3166b2c62952d [file] [log] [blame]
Raphael Isemann80814282020-01-24 08:23:27 +01001//===-- CPlusPlusLanguage.cpp ---------------------------------------------===//
Enrico Granata5f9d3102015-08-27 21:33:50 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Enrico Granata5f9d3102015-08-27 21:33:50 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "CPlusPlusLanguage.h"
10
Eugene Zelenkobbd16812016-02-29 19:41:30 +000011#include <cctype>
Kate Stoneb9c1b512016-09-06 20:57:50 +000012#include <cstring>
Luke Drummondf5bb1d62016-12-19 17:22:44 +000013
Eugene Zelenkobbd16812016-02-29 19:41:30 +000014#include <functional>
Luke Drummondf5bb1d62016-12-19 17:22:44 +000015#include <memory>
Eugene Zelenkobbd16812016-02-29 19:41:30 +000016#include <mutex>
Luke Drummondf5bb1d62016-12-19 17:22:44 +000017#include <set>
Jim Inghamaa816b82015-09-02 01:59:14 +000018
19#include "llvm/ADT/StringRef.h"
Pavel Labathe0d27332018-11-06 15:41:37 +000020#include "llvm/Demangle/ItaniumDemangle.h"
Jim Inghamaa816b82015-09-02 01:59:14 +000021
shafik83393d22019-11-06 14:06:56 -080022#include "lldb/Core/Mangled.h"
Enrico Granata5f9d3102015-08-27 21:33:50 +000023#include "lldb/Core/PluginManager.h"
Jim Inghamaa816b82015-09-02 01:59:14 +000024#include "lldb/Core/UniqueCStringMap.h"
Enrico Granata7cb59e12015-09-16 18:28:11 +000025#include "lldb/DataFormatters/CXXFunctionPointer.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000026#include "lldb/DataFormatters/DataVisualization.h"
27#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granata7cb59e12015-09-16 18:28:11 +000028#include "lldb/DataFormatters/VectorType.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000029#include "lldb/Utility/ConstString.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000030#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000031#include "lldb/Utility/RegularExpression.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000032
Sean Callananc530ba92016-05-02 21:15:31 +000033#include "BlockPointer.h"
Eugene Zemtsova633ee62017-04-06 22:36:02 +000034#include "CPlusPlusNameParser.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000035#include "CxxStringTypes.h"
36#include "LibCxx.h"
Enrico Granata75995b52016-02-12 22:18:24 +000037#include "LibCxxAtomic.h"
Shafik Yaghmour8306f762018-09-19 18:07:05 +000038#include "LibCxxVariant.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000039#include "LibStdcpp.h"
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +000040#include "MSVCUndecoratedNameParser.h"
Enrico Granata33e97e62015-09-04 21:01:18 +000041
Enrico Granata5f9d3102015-08-27 21:33:50 +000042using namespace lldb;
43using namespace lldb_private;
Enrico Granata33e97e62015-09-04 21:01:18 +000044using namespace lldb_private::formatters;
Enrico Granata5f9d3102015-08-27 21:33:50 +000045
Kate Stoneb9c1b512016-09-06 20:57:50 +000046void CPlusPlusLanguage::Initialize() {
47 PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
48 CreateInstance);
Enrico Granata5f9d3102015-08-27 21:33:50 +000049}
50
Kate Stoneb9c1b512016-09-06 20:57:50 +000051void CPlusPlusLanguage::Terminate() {
52 PluginManager::UnregisterPlugin(CreateInstance);
Enrico Granata5f9d3102015-08-27 21:33:50 +000053}
54
Kate Stoneb9c1b512016-09-06 20:57:50 +000055lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
56 static ConstString g_name("cplusplus");
57 return g_name;
Enrico Granata5f9d3102015-08-27 21:33:50 +000058}
59
Enrico Granata5f9d3102015-08-27 21:33:50 +000060// PluginInterface protocol
Eugene Zelenkobbd16812016-02-29 19:41:30 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062lldb_private::ConstString CPlusPlusLanguage::GetPluginName() {
63 return GetPluginNameStatic();
Enrico Granata5f9d3102015-08-27 21:33:50 +000064}
65
Kate Stoneb9c1b512016-09-06 20:57:50 +000066uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; }
Enrico Granata5f9d3102015-08-27 21:33:50 +000067
Enrico Granata5f9d3102015-08-27 21:33:50 +000068// Static Functions
Eugene Zelenkobbd16812016-02-29 19:41:30 +000069
Kate Stoneb9c1b512016-09-06 20:57:50 +000070Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
71 if (Language::LanguageIsCPlusPlus(language))
72 return new CPlusPlusLanguage();
73 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +000074}
Jim Inghamaa816b82015-09-02 01:59:14 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076void CPlusPlusLanguage::MethodName::Clear() {
77 m_full.Clear();
78 m_basename = llvm::StringRef();
79 m_context = llvm::StringRef();
80 m_arguments = llvm::StringRef();
81 m_qualifiers = llvm::StringRef();
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 m_parsed = false;
83 m_parse_error = false;
Jim Inghamaa816b82015-09-02 01:59:14 +000084}
85
Eugene Zemtsova633ee62017-04-06 22:36:02 +000086static bool ReverseFindMatchingChars(const llvm::StringRef &s,
87 const llvm::StringRef &left_right_chars,
88 size_t &left_pos, size_t &right_pos,
89 size_t pos = llvm::StringRef::npos) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 assert(left_right_chars.size() == 2);
91 left_pos = llvm::StringRef::npos;
92 const char left_char = left_right_chars[0];
93 const char right_char = left_right_chars[1];
94 pos = s.find_last_of(left_right_chars, pos);
95 if (pos == llvm::StringRef::npos || s[pos] == left_char)
96 return false;
97 right_pos = pos;
98 uint32_t depth = 1;
99 while (pos > 0 && depth > 0) {
Jim Inghamaa816b82015-09-02 01:59:14 +0000100 pos = s.find_last_of(left_right_chars, pos);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 if (pos == llvm::StringRef::npos)
102 return false;
103 if (s[pos] == left_char) {
104 if (--depth == 0) {
105 left_pos = pos;
106 return left_pos < right_pos;
107 }
108 } else if (s[pos] == right_char) {
109 ++depth;
Jim Inghamaa816b82015-09-02 01:59:14 +0000110 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 }
112 return false;
Jim Inghamaa816b82015-09-02 01:59:14 +0000113}
114
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000115static bool IsTrivialBasename(const llvm::StringRef &basename) {
116 // Check that the basename matches with the following regular expression
Adrian Prantl05097242018-04-30 16:49:04 +0000117 // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
118 // because it is significantly more efficient then using the general purpose
119 // regular expression library.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 size_t idx = 0;
121 if (basename.size() > 0 && basename[0] == '~')
122 idx = 1;
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 if (basename.size() <= idx)
125 return false; // Empty string or "~"
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 if (!std::isalpha(basename[idx]) && basename[idx] != '_')
128 return false; // First charater (after removing the possible '~'') isn't in
129 // [A-Za-z_]
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 // Read all characters matching [A-Za-z_0-9]
132 ++idx;
133 while (idx < basename.size()) {
134 if (!std::isalnum(basename[idx]) && basename[idx] != '_')
135 break;
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000136 ++idx;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 }
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000138
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 // We processed all characters. It is a vaild basename.
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000140 return idx == basename.size();
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000141}
Tamas Berghammer9fa11472015-10-27 10:43:27 +0000142
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000143bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
Adrian Prantl05097242018-04-30 16:49:04 +0000144 // This method tries to parse simple method definitions which are presumably
145 // most comman in user programs. Definitions that can be parsed by this
146 // function don't have return types and templates in the name.
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000147 // A::B::C::fun(std::vector<T> &) const
148 size_t arg_start, arg_end;
149 llvm::StringRef full(m_full.GetCString());
150 llvm::StringRef parens("()", 2);
151 if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
152 m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
153 if (arg_end + 1 < full.size())
154 m_qualifiers = full.substr(arg_end + 1).ltrim();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000156 if (arg_start == 0)
157 return false;
158 size_t basename_end = arg_start;
159 size_t context_start = 0;
160 size_t context_end = full.rfind(':', basename_end);
161 if (context_end == llvm::StringRef::npos)
162 m_basename = full.substr(0, basename_end);
163 else {
164 if (context_start < context_end)
165 m_context = full.substr(context_start, context_end - 1 - context_start);
166 const size_t basename_begin = context_end + 1;
167 m_basename = full.substr(basename_begin, basename_end - basename_begin);
168 }
169
170 if (IsTrivialBasename(m_basename)) {
171 return true;
172 } else {
173 // The C++ basename doesn't match our regular expressions so this can't
174 // be a valid C++ method, clear everything out and indicate an error
175 m_context = llvm::StringRef();
176 m_basename = llvm::StringRef();
177 m_arguments = llvm::StringRef();
178 m_qualifiers = llvm::StringRef();
179 return false;
180 }
181 }
182 return false;
Jim Inghamaa816b82015-09-02 01:59:14 +0000183}
184
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185void CPlusPlusLanguage::MethodName::Parse() {
186 if (!m_parsed && m_full) {
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000187 if (TrySimplifiedParse()) {
188 m_parse_error = false;
189 } else {
190 CPlusPlusNameParser parser(m_full.GetStringRef());
191 if (auto function = parser.ParseAsFunctionDefinition()) {
192 m_basename = function.getValue().name.basename;
193 m_context = function.getValue().name.context;
194 m_arguments = function.getValue().arguments;
195 m_qualifiers = function.getValue().qualifiers;
196 m_parse_error = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 } else {
198 m_parse_error = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 }
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000201 m_parsed = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 }
203}
204
205llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() {
206 if (!m_parsed)
207 Parse();
208 return m_basename;
209}
210
211llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() {
212 if (!m_parsed)
213 Parse();
214 return m_context;
215}
216
217llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() {
218 if (!m_parsed)
219 Parse();
220 return m_arguments;
221}
222
223llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() {
224 if (!m_parsed)
225 Parse();
226 return m_qualifiers;
227}
228
229std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
230 if (!m_parsed)
231 Parse();
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000232 if (m_context.empty())
233 return m_basename;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234
235 std::string res;
236 res += m_context;
237 res += "::";
238 res += m_basename;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239 return res;
240}
241
shafik83393d22019-11-06 14:06:56 -0800242bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) {
Adrian Prantl05097242018-04-30 16:49:04 +0000243 // FIXME!! we should really run through all the known C++ Language plugins
244 // and ask each one if this is a C++ mangled name
Adrian Prantlc53d3682018-08-15 22:48:48 +0000245
shafik83393d22019-11-06 14:06:56 -0800246 Mangled::ManglingScheme scheme = Mangled::GetManglingScheme(name);
247
248 if (scheme == Mangled::eManglingSchemeNone)
Aaron Smithb38799c2018-02-08 23:11:56 +0000249 return false;
Adrian Prantlc53d3682018-08-15 22:48:48 +0000250
shafik83393d22019-11-06 14:06:56 -0800251 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252}
253
254bool CPlusPlusLanguage::ExtractContextAndIdentifier(
255 const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
Aleksandr Urakovc1e530e2018-11-06 08:02:55 +0000256 if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))
257 return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,
258 identifier);
259
Eugene Zemtsova633ee62017-04-06 22:36:02 +0000260 CPlusPlusNameParser parser(name);
261 if (auto full_name = parser.ParseAsFullName()) {
262 identifier = full_name.getValue().basename;
263 context = full_name.getValue().context;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264 return true;
265 }
266 return false;
267}
268
Pavel Labathe0d27332018-11-06 15:41:37 +0000269namespace {
270class NodeAllocator {
271 llvm::BumpPtrAllocator Alloc;
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000272
Pavel Labathe0d27332018-11-06 15:41:37 +0000273public:
274 void reset() { Alloc.Reset(); }
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000275
Pavel Labathe0d27332018-11-06 15:41:37 +0000276 template <typename T, typename... Args> T *makeNode(Args &&... args) {
277 return new (Alloc.Allocate(sizeof(T), alignof(T)))
278 T(std::forward<Args>(args)...);
Stefan Granitz5e6bd2f2018-08-13 16:45:06 +0000279 }
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000280
Pavel Labathe0d27332018-11-06 15:41:37 +0000281 void *allocateNodeArray(size_t sz) {
282 return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,
283 alignof(llvm::itanium_demangle::Node *));
284 }
285};
286
Pavel Labathc16f0b12019-11-26 16:36:09 +0100287template <typename Derived>
288class ManglingSubstitutor
289 : public llvm::itanium_demangle::AbstractManglingParser<Derived,
Pavel Labathe0d27332018-11-06 15:41:37 +0000290 NodeAllocator> {
Pavel Labathc16f0b12019-11-26 16:36:09 +0100291 using Base =
292 llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
Pavel Labathe0d27332018-11-06 15:41:37 +0000293
Pavel Labathc16f0b12019-11-26 16:36:09 +0100294public:
295 ManglingSubstitutor() : Base(nullptr, nullptr) {}
Pavel Labathe0d27332018-11-06 15:41:37 +0000296
Pavel Labathc16f0b12019-11-26 16:36:09 +0100297 template<typename... Ts>
298 ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) {
299 this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...);
300 return substituteImpl(Mangled);
301 }
Pavel Labathe0d27332018-11-06 15:41:37 +0000302
Pavel Labathc16f0b12019-11-26 16:36:09 +0100303
304protected:
305 void reset(llvm::StringRef Mangled) {
306 Base::reset(Mangled.begin(), Mangled.end());
Pavel Labathe0d27332018-11-06 15:41:37 +0000307 Written = Mangled.begin();
Pavel Labathe0d27332018-11-06 15:41:37 +0000308 Result.clear();
309 Substituted = false;
310 }
311
Pavel Labathc16f0b12019-11-26 16:36:09 +0100312 ConstString substituteImpl(llvm::StringRef Mangled) {
Pavel Labathe0d27332018-11-06 15:41:37 +0000313 Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
Pavel Labathc16f0b12019-11-26 16:36:09 +0100314 if (this->parse() == nullptr) {
Pavel Labathe0d27332018-11-06 15:41:37 +0000315 LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled);
316 return ConstString();
317 }
318 if (!Substituted)
319 return ConstString();
320
321 // Append any trailing unmodified input.
322 appendUnchangedInput();
323 LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
324 return ConstString(Result);
325 }
326
Pavel Labathc16f0b12019-11-26 16:36:09 +0100327 void trySubstitute(llvm::StringRef From, llvm::StringRef To) {
328 if (!llvm::StringRef(currentParserPos(), this->numLeft()).startswith(From))
329 return;
Pavel Labathe0d27332018-11-06 15:41:37 +0000330
Pavel Labathc16f0b12019-11-26 16:36:09 +0100331 // We found a match. Append unmodified input up to this point.
332 appendUnchangedInput();
333
334 // And then perform the replacement.
335 Result += To;
336 Written += From.size();
337 Substituted = true;
338 }
339
340private:
341 /// Input character until which we have constructed the respective output
342 /// already.
343 const char *Written;
344
345 llvm::SmallString<128> Result;
346
347 /// Whether we have performed any substitutions.
348 bool Substituted;
349
350 const char *currentParserPos() const { return this->First; }
351
352 void appendUnchangedInput() {
353 Result +=
354 llvm::StringRef(Written, std::distance(Written, currentParserPos()));
355 Written = currentParserPos();
356 }
357
358};
359
360/// Given a mangled function `Mangled`, replace all the primitive function type
361/// arguments of `Search` with type `Replace`.
362class TypeSubstitutor : public ManglingSubstitutor<TypeSubstitutor> {
363 llvm::StringRef Search;
364 llvm::StringRef Replace;
365
366public:
367 void reset(llvm::StringRef Mangled, llvm::StringRef Search,
368 llvm::StringRef Replace) {
369 ManglingSubstitutor::reset(Mangled);
370 this->Search = Search;
371 this->Replace = Replace;
372 }
373
374 llvm::itanium_demangle::Node *parseType() {
375 trySubstitute(Search, Replace);
376 return ManglingSubstitutor::parseType();
Pavel Labathe0d27332018-11-06 15:41:37 +0000377 }
378};
Pavel Labathc16f0b12019-11-26 16:36:09 +0100379
380class CtorDtorSubstitutor : public ManglingSubstitutor<CtorDtorSubstitutor> {
381public:
382 llvm::itanium_demangle::Node *
383 parseCtorDtorName(llvm::itanium_demangle::Node *&SoFar, NameState *State) {
384 trySubstitute("C1", "C2");
385 trySubstitute("D1", "D2");
386 return ManglingSubstitutor::parseCtorDtorName(SoFar, State);
387 }
388};
389} // namespace
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000390
391uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
392 const ConstString mangled_name, std::set<ConstString> &alternates) {
393 const auto start_size = alternates.size();
394 /// Get a basic set of alternative manglings for the given symbol `name`, by
395 /// making a few basic possible substitutions on basic types, storage duration
396 /// and `const`ness for the given symbol. The output parameter `alternates`
397 /// is filled with a best-guess, non-exhaustive set of different manglings
398 /// for the given name.
399
400 // Maybe we're looking for a const symbol but the debug info told us it was
401 // non-const...
402 if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
403 strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
404 std::string fixed_scratch("_ZNK");
405 fixed_scratch.append(mangled_name.GetCString() + 3);
406 alternates.insert(ConstString(fixed_scratch));
407 }
408
409 // Maybe we're looking for a static symbol but we thought it was global...
410 if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
411 strncmp(mangled_name.GetCString(), "_ZL", 3)) {
412 std::string fixed_scratch("_ZL");
413 fixed_scratch.append(mangled_name.GetCString() + 2);
414 alternates.insert(ConstString(fixed_scratch));
415 }
416
Pavel Labathe0d27332018-11-06 15:41:37 +0000417 TypeSubstitutor TS;
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000418 // `char` is implementation defined as either `signed` or `unsigned`. As a
419 // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
420 // char, 'h'-unsigned char. If we're looking for symbols with a signed char
421 // parameter, try finding matches which have the general case 'c'.
422 if (ConstString char_fixup =
Pavel Labathe0d27332018-11-06 15:41:37 +0000423 TS.substitute(mangled_name.GetStringRef(), "a", "c"))
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000424 alternates.insert(char_fixup);
425
426 // long long parameter mangling 'x', may actually just be a long 'l' argument
427 if (ConstString long_fixup =
Pavel Labathe0d27332018-11-06 15:41:37 +0000428 TS.substitute(mangled_name.GetStringRef(), "x", "l"))
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000429 alternates.insert(long_fixup);
430
431 // unsigned long long parameter mangling 'y', may actually just be unsigned
432 // long 'm' argument
433 if (ConstString ulong_fixup =
Pavel Labathe0d27332018-11-06 15:41:37 +0000434 TS.substitute(mangled_name.GetStringRef(), "y", "m"))
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000435 alternates.insert(ulong_fixup);
436
Pavel Labathc16f0b12019-11-26 16:36:09 +0100437 if (ConstString ctor_fixup =
438 CtorDtorSubstitutor().substitute(mangled_name.GetStringRef()))
439 alternates.insert(ctor_fixup);
440
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000441 return alternates.size() - start_size;
442}
443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
445 if (!cpp_category_sp)
446 return;
447
448 TypeSummaryImpl::Flags stl_summary_flags;
449 stl_summary_flags.SetCascades(true)
450 .SetSkipPointers(false)
451 .SetSkipReferences(false)
452 .SetDontShowChildren(true)
453 .SetDontShowValue(true)
454 .SetShowMembersOneLiner(false)
455 .SetHideItemNames(false);
456
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000457 AddCXXSummary(cpp_category_sp,
458 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
459 "std::string summary provider",
460 ConstString("^std::__[[:alnum:]]+::string$"), stl_summary_flags,
461 true);
462 AddCXXSummary(cpp_category_sp,
463 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
464 "std::string summary provider",
465 ConstString("^std::__[[:alnum:]]+::basic_string<char, "
466 "std::__[[:alnum:]]+::char_traits<char>, "
467 "std::__[[:alnum:]]+::allocator<char> >$"),
468 stl_summary_flags, true);
Jordan Rupprecht506144d2019-11-22 10:25:03 -0800469 AddCXXSummary(cpp_category_sp,
470 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
471 "std::string summary provider",
472 ConstString("^std::__[[:alnum:]]+::basic_string<unsigned char, "
473 "std::__[[:alnum:]]+::char_traits<unsigned char>, "
474 "std::__[[:alnum:]]+::allocator<unsigned char> >$"),
475 stl_summary_flags, true);
Enrico Granata75995b52016-02-12 22:18:24 +0000476
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000477 AddCXXSummary(cpp_category_sp,
478 lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
479 "std::u16string summary provider",
480 ConstString(
481 "^std::__[[:alnum:]]+::basic_string<char16_t, "
482 "std::__[[:alnum:]]+::char_traits<char16_t>, "
483 "std::__[[:alnum:]]+::allocator<char16_t> >$"),
484 stl_summary_flags, true);
Enrico Granata1b54bae2016-08-31 21:46:37 +0000485
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000486 AddCXXSummary(cpp_category_sp,
487 lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
488 "std::u32string summary provider",
489 ConstString(
490 "^std::__[[:alnum:]]+::basic_string<char32_t, "
491 "std::__[[:alnum:]]+::char_traits<char32_t>, "
492 "std::__[[:alnum:]]+::allocator<char32_t> >$"),
493 stl_summary_flags, true);
494
495 AddCXXSummary(cpp_category_sp,
496 lldb_private::formatters::LibcxxWStringSummaryProvider,
497 "std::wstring summary provider",
498 ConstString("^std::__[[:alnum:]]+::wstring$"),
499 stl_summary_flags, true);
500 AddCXXSummary(cpp_category_sp,
501 lldb_private::formatters::LibcxxWStringSummaryProvider,
502 "std::wstring summary provider",
503 ConstString("^std::__[[:alnum:]]+::basic_string<wchar_t, "
504 "std::__[[:alnum:]]+::char_traits<wchar_t>, "
505 "std::__[[:alnum:]]+::allocator<wchar_t> >$"),
506 stl_summary_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000507
508 SyntheticChildren::Flags stl_synth_flags;
509 stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
510 false);
Jim Ingham393fe622018-07-13 19:28:32 +0000511 SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
512 stl_deref_flags.SetFrontEndWantsDereference();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513
514 AddCXXSynthetic(
515 cpp_category_sp,
Pavel Labath52698752017-11-14 11:15:03 +0000516 lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
517 "libc++ std::bitset synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000518 ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"), stl_deref_flags,
Pavel Labath52698752017-11-14 11:15:03 +0000519 true);
520 AddCXXSynthetic(
521 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522 lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
523 "libc++ std::vector synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000524 ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"), stl_deref_flags,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 true);
526 AddCXXSynthetic(
527 cpp_category_sp,
Pavel Labath89ac0c72017-10-31 12:27:43 +0000528 lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
529 "libc++ std::forward_list synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000530 ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
Pavel Labath89ac0c72017-10-31 12:27:43 +0000531 stl_synth_flags, true);
532 AddCXXSynthetic(
533 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
535 "libc++ std::list synthetic children",
Jan Kratochvilb17d6c52019-08-22 14:29:52 +0000536 // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
537 // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
538 ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
539 "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
540 stl_deref_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 AddCXXSynthetic(
542 cpp_category_sp,
543 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
544 "libc++ std::map synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000545 ConstString("^std::__[[:alnum:]]+::map<.+> >(( )?&)?$"), stl_synth_flags,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546 true);
547 AddCXXSynthetic(
548 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
550 "libc++ std::set synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000551 ConstString("^std::__[[:alnum:]]+::set<.+> >(( )?&)?$"), stl_deref_flags,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552 true);
553 AddCXXSynthetic(
554 cpp_category_sp,
555 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
556 "libc++ std::multiset synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000557 ConstString("^std::__[[:alnum:]]+::multiset<.+> >(( )?&)?$"),
558 stl_deref_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000559 AddCXXSynthetic(
560 cpp_category_sp,
561 lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
562 "libc++ std::multimap synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000563 ConstString("^std::__[[:alnum:]]+::multimap<.+> >(( )?&)?$"),
564 stl_synth_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000565 AddCXXSynthetic(
566 cpp_category_sp,
567 lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,
568 "libc++ std::unordered containers synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000569 ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 stl_synth_flags, true);
571 AddCXXSynthetic(
572 cpp_category_sp,
573 lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator,
574 "libc++ std::initializer_list synthetic children",
575 ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
576 true);
Pavel Labathe0d51842017-11-01 15:52:08 +0000577 AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
578 "libc++ std::queue synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000579 ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
Pavel Labathe0d51842017-11-01 15:52:08 +0000580 stl_synth_flags, true);
Pavel Labath333739d2017-11-01 15:19:52 +0000581 AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
582 "libc++ std::tuple synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000583 ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
584 stl_synth_flags, true);
Adrian Prantlc53d3682018-08-15 22:48:48 +0000585 AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator,
586 "libc++ std::optional synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000587 ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
Adrian Prantlc53d3682018-08-15 22:48:48 +0000588 stl_synth_flags, true);
Shafik Yaghmour8306f762018-09-19 18:07:05 +0000589 AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
590 "libc++ std::variant synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000591 ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
Shafik Yaghmour8306f762018-09-19 18:07:05 +0000592 stl_synth_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 AddCXXSynthetic(
594 cpp_category_sp,
595 lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
596 "libc++ std::atomic synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000597 ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598
599 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Jan Kratochvil5aa1d812019-09-04 09:47:18 +0000600 RegularExpression(
601 llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$")),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000602 SyntheticChildrenSP(new ScriptedSyntheticChildren(
603 stl_synth_flags,
604 "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
605
606 AddCXXSynthetic(
607 cpp_category_sp,
608 lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
609 "shared_ptr synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000610 ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611 stl_synth_flags, true);
612 AddCXXSynthetic(
613 cpp_category_sp,
614 lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
615 "weak_ptr synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000616 ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"),
617 stl_synth_flags, true);
shafik91e94a72019-11-12 11:23:38 -0800618 AddCXXSummary(cpp_category_sp,
619 lldb_private::formatters::LibcxxFunctionSummaryProvider,
620 "libc++ std::function summary provider",
621 ConstString("^std::__[[:alnum:]]+::function<.+>$"),
622 stl_summary_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623
624 stl_summary_flags.SetDontShowChildren(false);
625 stl_summary_flags.SetSkipPointers(false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000626 AddCXXSummary(cpp_category_sp,
627 lldb_private::formatters::LibcxxContainerSummaryProvider,
Pavel Labath52698752017-11-14 11:15:03 +0000628 "libc++ std::bitset summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000629 ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"),
Pavel Labath52698752017-11-14 11:15:03 +0000630 stl_summary_flags, true);
631 AddCXXSummary(cpp_category_sp,
632 lldb_private::formatters::LibcxxContainerSummaryProvider,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633 "libc++ std::vector summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000634 ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635 stl_summary_flags, true);
636 AddCXXSummary(cpp_category_sp,
637 lldb_private::formatters::LibcxxContainerSummaryProvider,
638 "libc++ std::list summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000639 ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
Pavel Labath89ac0c72017-10-31 12:27:43 +0000640 stl_summary_flags, true);
Jan Kratochvilb17d6c52019-08-22 14:29:52 +0000641 AddCXXSummary(
642 cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
643 "libc++ std::list summary provider",
644 // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
645 // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
646 ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
647 "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
648 stl_summary_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000649 AddCXXSummary(cpp_category_sp,
650 lldb_private::formatters::LibcxxContainerSummaryProvider,
651 "libc++ std::map summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000652 ConstString("^std::__[[:alnum:]]+::map<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653 stl_summary_flags, true);
654 AddCXXSummary(cpp_category_sp,
655 lldb_private::formatters::LibcxxContainerSummaryProvider,
656 "libc++ std::deque summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000657 ConstString("^std::__[[:alnum:]]+::deque<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658 stl_summary_flags, true);
659 AddCXXSummary(cpp_category_sp,
660 lldb_private::formatters::LibcxxContainerSummaryProvider,
Pavel Labathe0d51842017-11-01 15:52:08 +0000661 "libc++ std::queue summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000662 ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
Pavel Labathe0d51842017-11-01 15:52:08 +0000663 stl_summary_flags, true);
664 AddCXXSummary(cpp_category_sp,
665 lldb_private::formatters::LibcxxContainerSummaryProvider,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000666 "libc++ std::set summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000667 ConstString("^std::__[[:alnum:]]+::set<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668 stl_summary_flags, true);
669 AddCXXSummary(cpp_category_sp,
670 lldb_private::formatters::LibcxxContainerSummaryProvider,
671 "libc++ std::multiset summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000672 ConstString("^std::__[[:alnum:]]+::multiset<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000673 stl_summary_flags, true);
674 AddCXXSummary(cpp_category_sp,
675 lldb_private::formatters::LibcxxContainerSummaryProvider,
676 "libc++ std::multimap summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000677 ConstString("^std::__[[:alnum:]]+::multimap<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678 stl_summary_flags, true);
679 AddCXXSummary(
680 cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
681 "libc++ std::unordered containers summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000682 ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000683 stl_summary_flags, true);
Pavel Labath333739d2017-11-01 15:19:52 +0000684 AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider,
685 "libc++ std::tuple summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000686 ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
687 stl_summary_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688 AddCXXSummary(
689 cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider,
690 "libc++ std::atomic summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000691 ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_summary_flags,
692 true);
Adrian Prantlc53d3682018-08-15 22:48:48 +0000693 AddCXXSummary(cpp_category_sp,
694 lldb_private::formatters::LibcxxOptionalSummaryProvider,
695 "libc++ std::optional summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000696 ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
Adrian Prantlc53d3682018-08-15 22:48:48 +0000697 stl_summary_flags, true);
Shafik Yaghmour8306f762018-09-19 18:07:05 +0000698 AddCXXSummary(cpp_category_sp,
699 lldb_private::formatters::LibcxxVariantSummaryProvider,
700 "libc++ std::variant summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000701 ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
Shafik Yaghmour8306f762018-09-19 18:07:05 +0000702 stl_summary_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703
704 stl_summary_flags.SetSkipPointers(true);
705
706 AddCXXSummary(cpp_category_sp,
707 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
708 "libc++ std::shared_ptr summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000709 ConstString("^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000710 stl_summary_flags, true);
711 AddCXXSummary(cpp_category_sp,
712 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
713 "libc++ std::weak_ptr summary provider",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000714 ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000715 stl_summary_flags, true);
716
717 AddCXXSynthetic(
718 cpp_category_sp,
719 lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,
720 "std::vector iterator synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000721 ConstString("^std::__[[:alnum:]]+::__wrap_iter<.+>$"), stl_synth_flags,
722 true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723
Kate Stoneb9c1b512016-09-06 20:57:50 +0000724 AddCXXSynthetic(
725 cpp_category_sp,
726 lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,
727 "std::map iterator synthetic children",
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +0000728 ConstString("^std::__[[:alnum:]]+::__map_iterator<.+>$"), stl_synth_flags,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000729 true);
Enrico Granata33e97e62015-09-04 21:01:18 +0000730}
731
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
733 if (!cpp_category_sp)
734 return;
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000735
Kate Stoneb9c1b512016-09-06 20:57:50 +0000736 TypeSummaryImpl::Flags stl_summary_flags;
737 stl_summary_flags.SetCascades(true)
738 .SetSkipPointers(false)
739 .SetSkipReferences(false)
740 .SetDontShowChildren(true)
741 .SetDontShowValue(true)
742 .SetShowMembersOneLiner(false)
743 .SetHideItemNames(false);
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000744
Kate Stoneb9c1b512016-09-06 20:57:50 +0000745 lldb::TypeSummaryImplSP std_string_summary_sp(
746 new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}"));
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000747
Kate Stoneb9c1b512016-09-06 20:57:50 +0000748 lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(
749 stl_summary_flags, LibStdcppStringSummaryProvider,
750 "libstdc++ c++11 std::string summary provider"));
751 lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(
752 stl_summary_flags, LibStdcppWStringSummaryProvider,
753 "libstdc++ c++11 std::wstring summary provider"));
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000754
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
756 std_string_summary_sp);
757 cpp_category_sp->GetTypeSummariesContainer()->Add(
758 ConstString("std::basic_string<char>"), std_string_summary_sp);
759 cpp_category_sp->GetTypeSummariesContainer()->Add(
760 ConstString("std::basic_string<char,std::char_traits<char>,std::"
761 "allocator<char> >"),
762 std_string_summary_sp);
763 cpp_category_sp->GetTypeSummariesContainer()->Add(
764 ConstString("std::basic_string<char, std::char_traits<char>, "
765 "std::allocator<char> >"),
766 std_string_summary_sp);
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000767
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 cpp_category_sp->GetTypeSummariesContainer()->Add(
769 ConstString("std::__cxx11::string"), cxx11_string_summary_sp);
770 cpp_category_sp->GetTypeSummariesContainer()->Add(
771 ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, "
772 "std::allocator<char> >"),
773 cxx11_string_summary_sp);
Jordan Rupprecht506144d2019-11-22 10:25:03 -0800774 cpp_category_sp->GetTypeSummariesContainer()->Add(
775 ConstString("std::__cxx11::basic_string<unsigned char, std::char_traits<unsigned char>, "
776 "std::allocator<unsigned char> >"),
777 cxx11_string_summary_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000778
779 // making sure we force-pick the summary for printing wstring (_M_p is a
780 // wchar_t*)
781 lldb::TypeSummaryImplSP std_wstring_summary_sp(
782 new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
783
784 cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"),
785 std_wstring_summary_sp);
786 cpp_category_sp->GetTypeSummariesContainer()->Add(
787 ConstString("std::basic_string<wchar_t>"), std_wstring_summary_sp);
788 cpp_category_sp->GetTypeSummariesContainer()->Add(
789 ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::"
790 "allocator<wchar_t> >"),
791 std_wstring_summary_sp);
792 cpp_category_sp->GetTypeSummariesContainer()->Add(
793 ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, "
794 "std::allocator<wchar_t> >"),
795 std_wstring_summary_sp);
796
797 cpp_category_sp->GetTypeSummariesContainer()->Add(
798 ConstString("std::__cxx11::wstring"), cxx11_wstring_summary_sp);
799 cpp_category_sp->GetTypeSummariesContainer()->Add(
800 ConstString("std::__cxx11::basic_string<wchar_t, "
801 "std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
802 cxx11_wstring_summary_sp);
Todd Fiala82ffb8e2015-10-22 00:23:38 +0000803
Kate Stoneb9c1b512016-09-06 20:57:50 +0000804 SyntheticChildren::Flags stl_synth_flags;
805 stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
806 false);
Tamas Berghammer9c6c8e92016-07-06 09:50:00 +0000807
Kate Stoneb9c1b512016-09-06 20:57:50 +0000808 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Jan Kratochvil5aa1d812019-09-04 09:47:18 +0000809 RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 SyntheticChildrenSP(new ScriptedSyntheticChildren(
811 stl_synth_flags,
812 "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
813 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Jan Kratochvil5aa1d812019-09-04 09:47:18 +0000814 RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000815 SyntheticChildrenSP(new ScriptedSyntheticChildren(
816 stl_synth_flags,
817 "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
818 cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
Jan Kratochvil5aa1d812019-09-04 09:47:18 +0000819 RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820 SyntheticChildrenSP(new ScriptedSyntheticChildren(
821 stl_synth_flags,
822 "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
823 stl_summary_flags.SetDontShowChildren(false);
824 stl_summary_flags.SetSkipPointers(true);
825 cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
Jan Kratochvil5aa1d812019-09-04 09:47:18 +0000826 RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827 TypeSummaryImplSP(
828 new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
829 cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
Jan Kratochvil5aa1d812019-09-04 09:47:18 +0000830 RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
Zachary Turner95eae422016-09-21 16:01:28 +0000831 TypeSummaryImplSP(
832 new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
833 cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
Jan Kratochvil5aa1d812019-09-04 09:47:18 +0000834 RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000835 TypeSummaryImplSP(
836 new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
Tamas Berghammer9c6c8e92016-07-06 09:50:00 +0000837
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 AddCXXSynthetic(
839 cpp_category_sp,
840 lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,
841 "std::vector iterator synthetic children",
842 ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
Tamas Berghammer9c6c8e92016-07-06 09:50:00 +0000843
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 AddCXXSynthetic(
845 cpp_category_sp,
846 lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,
847 "std::map iterator synthetic children",
848 ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
849
850 AddCXXSynthetic(
851 cpp_category_sp,
Tamas Berghammerd161b212016-10-21 15:02:44 +0000852 lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
853 "std::unique_ptr synthetic children",
854 ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
855 AddCXXSynthetic(
856 cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000857 lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
858 "std::shared_ptr synthetic children",
859 ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
860 AddCXXSynthetic(
861 cpp_category_sp,
862 lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
863 "std::weak_ptr synthetic children",
864 ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
Tamas Berghammer7f15dba2016-10-21 15:02:38 +0000865 AddCXXSynthetic(
866 cpp_category_sp,
867 lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator,
868 "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"),
869 stl_synth_flags, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870
871 AddCXXSummary(cpp_category_sp,
Tamas Berghammerd161b212016-10-21 15:02:44 +0000872 lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
873 "libstdc++ std::unique_ptr summary provider",
874 ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags,
875 true);
876 AddCXXSummary(cpp_category_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000877 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
878 "libstdc++ std::shared_ptr summary provider",
879 ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags,
880 true);
881 AddCXXSummary(cpp_category_sp,
882 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
883 "libstdc++ std::weak_ptr summary provider",
884 ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
885 true);
Enrico Granata33e97e62015-09-04 21:01:18 +0000886}
887
Kate Stoneb9c1b512016-09-06 20:57:50 +0000888static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
889 if (!cpp_category_sp)
890 return;
891
892 TypeSummaryImpl::Flags string_flags;
893 string_flags.SetCascades(true)
894 .SetSkipPointers(true)
895 .SetSkipReferences(false)
896 .SetDontShowChildren(true)
897 .SetDontShowValue(false)
898 .SetShowMembersOneLiner(false)
899 .SetHideItemNames(false);
900
901 TypeSummaryImpl::Flags string_array_flags;
902 string_array_flags.SetCascades(true)
903 .SetSkipPointers(true)
904 .SetSkipReferences(false)
905 .SetDontShowChildren(true)
906 .SetDontShowValue(true)
907 .SetShowMembersOneLiner(false)
908 .SetHideItemNames(false);
909
Kate Stoneb9c1b512016-09-06 20:57:50 +0000910 // FIXME because of a bug in the FormattersContainer we need to add a summary
911 // for both X* and const X* (<rdar://problem/12717717>)
912 AddCXXSummary(
Jonas Devliegherec46d39b2019-08-21 21:30:55 +0000913 cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider,
914 "char8_t * summary provider", ConstString("char8_t *"), string_flags);
915 AddCXXSummary(cpp_category_sp,
916 lldb_private::formatters::Char8StringSummaryProvider,
917 "char8_t [] summary provider",
918 ConstString("char8_t \\[[0-9]+\\]"), string_array_flags, true);
919
920 AddCXXSummary(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000921 cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
922 "char16_t * summary provider", ConstString("char16_t *"), string_flags);
923 AddCXXSummary(cpp_category_sp,
924 lldb_private::formatters::Char16StringSummaryProvider,
925 "char16_t [] summary provider",
926 ConstString("char16_t \\[[0-9]+\\]"), string_array_flags, true);
927
928 AddCXXSummary(
929 cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider,
930 "char32_t * summary provider", ConstString("char32_t *"), string_flags);
931 AddCXXSummary(cpp_category_sp,
932 lldb_private::formatters::Char32StringSummaryProvider,
933 "char32_t [] summary provider",
934 ConstString("char32_t \\[[0-9]+\\]"), string_array_flags, true);
935
936 AddCXXSummary(
937 cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider,
938 "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
939 AddCXXSummary(cpp_category_sp,
940 lldb_private::formatters::WCharStringSummaryProvider,
941 "wchar_t * summary provider",
942 ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true);
943
944 AddCXXSummary(
945 cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
946 "unichar * summary provider", ConstString("unichar *"), string_flags);
947
948 TypeSummaryImpl::Flags widechar_flags;
949 widechar_flags.SetDontShowValue(true)
950 .SetSkipPointers(true)
951 .SetSkipReferences(false)
952 .SetCascades(true)
953 .SetDontShowChildren(true)
954 .SetHideItemNames(true)
955 .SetShowMembersOneLiner(false);
956
Jonas Devliegherec46d39b2019-08-21 21:30:55 +0000957 AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
958 "char8_t summary provider", ConstString("char8_t"),
959 widechar_flags);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000960 AddCXXSummary(
961 cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
962 "char16_t summary provider", ConstString("char16_t"), widechar_flags);
963 AddCXXSummary(
964 cpp_category_sp, lldb_private::formatters::Char32SummaryProvider,
965 "char32_t summary provider", ConstString("char32_t"), widechar_flags);
966 AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,
967 "wchar_t summary provider", ConstString("wchar_t"),
968 widechar_flags);
969
970 AddCXXSummary(
971 cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
972 "unichar summary provider", ConstString("unichar"), widechar_flags);
Enrico Granata33e97e62015-09-04 21:01:18 +0000973}
974
Enrico Granatac0464972016-10-27 18:44:45 +0000975std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
Enrico Granata63db2392016-11-01 18:50:49 +0000976 class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
977 public:
Raphael Isemann17566302019-05-03 10:03:28 +0000978 CompilerType AdjustForInclusion(CompilerType &candidate) override {
Enrico Granata63db2392016-11-01 18:50:49 +0000979 LanguageType lang_type(candidate.GetMinimumLanguage());
980 if (!Language::LanguageIsC(lang_type) &&
981 !Language::LanguageIsCPlusPlus(lang_type))
982 return CompilerType();
983 if (candidate.IsTypedefType())
984 return candidate.GetTypedefedType();
985 return candidate;
Enrico Granatac0464972016-10-27 18:44:45 +0000986 }
Enrico Granatac0464972016-10-27 18:44:45 +0000987 };
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000988
Enrico Granatac0464972016-10-27 18:44:45 +0000989 return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
990}
991
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000993 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994 static TypeCategoryImplSP g_category;
995
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000996 llvm::call_once(g_initialize, [this]() -> void {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000997 DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
998 if (g_category) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 LoadLibStdcppFormatters(g_category);
Thomas Anderson7ba2d3e2019-02-01 19:10:39 +00001000 LoadLibCxxFormatters(g_category);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001001 LoadSystemFormatters(g_category);
1002 }
1003 });
1004 return g_category;
Enrico Granata33e97e62015-09-04 21:01:18 +00001005}
1006
Enrico Granata7cb59e12015-09-16 18:28:11 +00001007HardcodedFormatters::HardcodedSummaryFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008CPlusPlusLanguage::GetHardcodedSummaries() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +00001009 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001010 static ConstString g_vectortypes("VectorTypes");
1011 static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
1012
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +00001013 llvm::call_once(g_initialize, []() -> void {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001014 g_formatters.push_back(
1015 [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1016 FormatManager &) -> TypeSummaryImpl::SharedPointer {
1017 static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1018 new CXXFunctionSummaryFormat(
1019 TypeSummaryImpl::Flags(),
1020 lldb_private::formatters::CXXFunctionPointerSummaryProvider,
1021 "Function pointer summary provider"));
1022 if (valobj.GetCompilerType().IsFunctionPointerType()) {
1023 return formatter_sp;
1024 }
1025 return nullptr;
1026 });
1027 g_formatters.push_back(
1028 [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1029 FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1030 static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1031 new CXXFunctionSummaryFormat(
1032 TypeSummaryImpl::Flags()
1033 .SetCascades(true)
1034 .SetDontShowChildren(true)
1035 .SetHideItemNames(true)
1036 .SetShowMembersOneLiner(true)
1037 .SetSkipPointers(true)
1038 .SetSkipReferences(false),
1039 lldb_private::formatters::VectorTypeSummaryProvider,
1040 "vector_type pointer summary provider"));
1041 if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
1042 if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1043 return formatter_sp;
1044 }
1045 return nullptr;
1046 });
1047 g_formatters.push_back(
1048 [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1049 FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1050 static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1051 new CXXFunctionSummaryFormat(
1052 TypeSummaryImpl::Flags()
1053 .SetCascades(true)
1054 .SetDontShowChildren(true)
1055 .SetHideItemNames(true)
1056 .SetShowMembersOneLiner(true)
1057 .SetSkipPointers(true)
1058 .SetSkipReferences(false),
1059 lldb_private::formatters::BlockPointerSummaryProvider,
1060 "block pointer summary provider"));
1061 if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
1062 return formatter_sp;
1063 }
1064 return nullptr;
1065 });
1066 });
1067
1068 return g_formatters;
Enrico Granata7cb59e12015-09-16 18:28:11 +00001069}
1070
1071HardcodedFormatters::HardcodedSyntheticFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +00001072CPlusPlusLanguage::GetHardcodedSynthetics() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +00001073 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001074 static ConstString g_vectortypes("VectorTypes");
1075 static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
Sean Callananc530ba92016-05-02 21:15:31 +00001076
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +00001077 llvm::call_once(g_initialize, []() -> void {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001078 g_formatters.push_back([](lldb_private::ValueObject &valobj,
1079 lldb::DynamicValueType,
1080 FormatManager &
1081 fmt_mgr) -> SyntheticChildren::SharedPointer {
1082 static CXXSyntheticChildren::SharedPointer formatter_sp(
1083 new CXXSyntheticChildren(
1084 SyntheticChildren::Flags()
1085 .SetCascades(true)
1086 .SetSkipPointers(true)
1087 .SetSkipReferences(true)
1088 .SetNonCacheable(true),
1089 "vector_type synthetic children",
1090 lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
1091 if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
1092 if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1093 return formatter_sp;
1094 }
1095 return nullptr;
Enrico Granata7cb59e12015-09-16 18:28:11 +00001096 });
Kate Stoneb9c1b512016-09-06 20:57:50 +00001097 g_formatters.push_back([](lldb_private::ValueObject &valobj,
1098 lldb::DynamicValueType,
1099 FormatManager &
1100 fmt_mgr) -> SyntheticChildren::SharedPointer {
1101 static CXXSyntheticChildren::SharedPointer formatter_sp(
1102 new CXXSyntheticChildren(
1103 SyntheticChildren::Flags()
1104 .SetCascades(true)
1105 .SetSkipPointers(true)
1106 .SetSkipReferences(true)
1107 .SetNonCacheable(true),
1108 "block pointer synthetic children",
1109 lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
1110 if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
1111 return formatter_sp;
1112 }
1113 return nullptr;
1114 });
1115
1116 });
1117
1118 return g_formatters;
Enrico Granata7cb59e12015-09-16 18:28:11 +00001119}
Raphael Isemann566afa02018-08-02 00:30:15 +00001120
1121bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
1122 const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
1123 ".h", ".hh", ".hpp", ".hxx", ".h++"};
1124 for (auto suffix : suffixes) {
1125 if (file_path.endswith_lower(suffix))
1126 return true;
1127 }
1128
1129 // Check if we're in a STL path (where the files usually have no extension
1130 // that we could check for.
1131 return file_path.contains("/usr/include/c++/");
1132}