180814287SRaphael Isemann //===-- CPlusPlusLanguage.cpp ---------------------------------------------===//
25f9d3106SEnrico Granata //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f9d3106SEnrico Granata //
75f9d3106SEnrico Granata //===----------------------------------------------------------------------===//
85f9d3106SEnrico Granata 
95f9d3106SEnrico Granata #include "CPlusPlusLanguage.h"
105f9d3106SEnrico Granata 
11bbd16815SEugene Zelenko #include <cctype>
12b9c1b51eSKate Stone #include <cstring>
13f5bb1d6cSLuke Drummond 
14bbd16815SEugene Zelenko #include <functional>
15f5bb1d6cSLuke Drummond #include <memory>
16bbd16815SEugene Zelenko #include <mutex>
17f5bb1d6cSLuke Drummond #include <set>
18aa816b8fSJim Ingham 
19aa816b8fSJim Ingham #include "llvm/ADT/StringRef.h"
20e0d2733bSPavel Labath #include "llvm/Demangle/ItaniumDemangle.h"
21aa816b8fSJim Ingham 
2283393d27Sshafik #include "lldb/Core/Mangled.h"
23385b2189SAlex Langford #include "lldb/Core/Module.h"
245f9d3106SEnrico Granata #include "lldb/Core/PluginManager.h"
25aa816b8fSJim Ingham #include "lldb/Core/UniqueCStringMap.h"
267cb59e1aSEnrico Granata #include "lldb/DataFormatters/CXXFunctionPointer.h"
2733e97e63SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
2833e97e63SEnrico Granata #include "lldb/DataFormatters/FormattersHelpers.h"
297cb59e1aSEnrico Granata #include "lldb/DataFormatters/VectorType.h"
30385b2189SAlex Langford #include "lldb/Symbol/SymbolFile.h"
31bf9a7730SZachary Turner #include "lldb/Utility/ConstString.h"
326f9e6901SZachary Turner #include "lldb/Utility/Log.h"
33bf9a7730SZachary Turner #include "lldb/Utility/RegularExpression.h"
3433e97e63SEnrico Granata 
35c530ba98SSean Callanan #include "BlockPointer.h"
36a633ee6eSEugene Zemtsov #include "CPlusPlusNameParser.h"
3733e97e63SEnrico Granata #include "CxxStringTypes.h"
3833e97e63SEnrico Granata #include "LibCxx.h"
3975995b5eSEnrico Granata #include "LibCxxAtomic.h"
408306f76eSShafik Yaghmour #include "LibCxxVariant.h"
4133e97e63SEnrico Granata #include "LibStdcpp.h"
42c1e530eeSAleksandr Urakov #include "MSVCUndecoratedNameParser.h"
4333e97e63SEnrico Granata 
445f9d3106SEnrico Granata using namespace lldb;
455f9d3106SEnrico Granata using namespace lldb_private;
4633e97e63SEnrico Granata using namespace lldb_private::formatters;
475f9d3106SEnrico Granata 
48bba9ba8dSJonas Devlieghere LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)
49fbb4d1e4SJonas Devlieghere 
50b9c1b51eSKate Stone void CPlusPlusLanguage::Initialize() {
51b9c1b51eSKate Stone   PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
525f9d3106SEnrico Granata                                 CreateInstance);
535f9d3106SEnrico Granata }
545f9d3106SEnrico Granata 
55b9c1b51eSKate Stone void CPlusPlusLanguage::Terminate() {
565f9d3106SEnrico Granata   PluginManager::UnregisterPlugin(CreateInstance);
575f9d3106SEnrico Granata }
585f9d3106SEnrico Granata 
59b9c1b51eSKate Stone lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
605f9d3106SEnrico Granata   static ConstString g_name("cplusplus");
615f9d3106SEnrico Granata   return g_name;
625f9d3106SEnrico Granata }
635f9d3106SEnrico Granata 
64ecfca427SRaphael Isemann bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
65ecfca427SRaphael Isemann   const char *mangled_name = mangled.GetMangledName().GetCString();
66ecfca427SRaphael Isemann   return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name);
67ecfca427SRaphael Isemann }
68ecfca427SRaphael Isemann 
69993220a9SAlex Langford ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments(
70993220a9SAlex Langford     Mangled mangled) const {
71993220a9SAlex Langford   const char *mangled_name_cstr = mangled.GetMangledName().GetCString();
72993220a9SAlex Langford   ConstString demangled_name = mangled.GetDemangledName();
73993220a9SAlex Langford   if (demangled_name && mangled_name_cstr && mangled_name_cstr[0]) {
74993220a9SAlex Langford     if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
75993220a9SAlex Langford         (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
76993220a9SAlex Langford                                         // typeinfo structure, and typeinfo
77993220a9SAlex Langford                                         // mangled_name
78993220a9SAlex Langford          mangled_name_cstr[2] != 'G' && // avoid guard variables
79993220a9SAlex Langford          mangled_name_cstr[2] != 'Z'))  // named local entities (if we
80993220a9SAlex Langford                                         // eventually handle eSymbolTypeData,
81993220a9SAlex Langford                                         // we will want this back)
82993220a9SAlex Langford     {
83993220a9SAlex Langford       CPlusPlusLanguage::MethodName cxx_method(demangled_name);
84993220a9SAlex Langford       if (!cxx_method.GetBasename().empty()) {
85993220a9SAlex Langford         std::string shortname;
86993220a9SAlex Langford         if (!cxx_method.GetContext().empty())
87993220a9SAlex Langford           shortname = cxx_method.GetContext().str() + "::";
88993220a9SAlex Langford         shortname += cxx_method.GetBasename().str();
89993220a9SAlex Langford         return ConstString(shortname);
90993220a9SAlex Langford       }
91993220a9SAlex Langford     }
92993220a9SAlex Langford   }
93993220a9SAlex Langford   if (demangled_name)
94993220a9SAlex Langford     return demangled_name;
95993220a9SAlex Langford   return mangled.GetMangledName();
96993220a9SAlex Langford }
97993220a9SAlex Langford 
985f9d3106SEnrico Granata // Static Functions
99bbd16815SEugene Zelenko 
100b9c1b51eSKate Stone Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
1018340fbb9SRaphael Isemann   // Use plugin for C++ but not for Objective-C++ (which has its own plugin).
1028340fbb9SRaphael Isemann   if (Language::LanguageIsCPlusPlus(language) &&
1038340fbb9SRaphael Isemann       language != eLanguageTypeObjC_plus_plus)
1045f9d3106SEnrico Granata     return new CPlusPlusLanguage();
1055f9d3106SEnrico Granata   return nullptr;
1065f9d3106SEnrico Granata }
107aa816b8fSJim Ingham 
108b9c1b51eSKate Stone void CPlusPlusLanguage::MethodName::Clear() {
109aa816b8fSJim Ingham   m_full.Clear();
110aa816b8fSJim Ingham   m_basename = llvm::StringRef();
111aa816b8fSJim Ingham   m_context = llvm::StringRef();
112aa816b8fSJim Ingham   m_arguments = llvm::StringRef();
113aa816b8fSJim Ingham   m_qualifiers = llvm::StringRef();
114aa816b8fSJim Ingham   m_parsed = false;
115aa816b8fSJim Ingham   m_parse_error = false;
116aa816b8fSJim Ingham }
117aa816b8fSJim Ingham 
118a633ee6eSEugene Zemtsov static bool ReverseFindMatchingChars(const llvm::StringRef &s,
119aa816b8fSJim Ingham                                      const llvm::StringRef &left_right_chars,
120b9c1b51eSKate Stone                                      size_t &left_pos, size_t &right_pos,
121b9c1b51eSKate Stone                                      size_t pos = llvm::StringRef::npos) {
122aa816b8fSJim Ingham   assert(left_right_chars.size() == 2);
123aa816b8fSJim Ingham   left_pos = llvm::StringRef::npos;
124aa816b8fSJim Ingham   const char left_char = left_right_chars[0];
125aa816b8fSJim Ingham   const char right_char = left_right_chars[1];
126aa816b8fSJim Ingham   pos = s.find_last_of(left_right_chars, pos);
127aa816b8fSJim Ingham   if (pos == llvm::StringRef::npos || s[pos] == left_char)
128aa816b8fSJim Ingham     return false;
129aa816b8fSJim Ingham   right_pos = pos;
130aa816b8fSJim Ingham   uint32_t depth = 1;
131b9c1b51eSKate Stone   while (pos > 0 && depth > 0) {
132aa816b8fSJim Ingham     pos = s.find_last_of(left_right_chars, pos);
133aa816b8fSJim Ingham     if (pos == llvm::StringRef::npos)
134aa816b8fSJim Ingham       return false;
135b9c1b51eSKate Stone     if (s[pos] == left_char) {
136b9c1b51eSKate Stone       if (--depth == 0) {
137aa816b8fSJim Ingham         left_pos = pos;
138aa816b8fSJim Ingham         return left_pos < right_pos;
139aa816b8fSJim Ingham       }
140b9c1b51eSKate Stone     } else if (s[pos] == right_char) {
141aa816b8fSJim Ingham       ++depth;
142aa816b8fSJim Ingham     }
143aa816b8fSJim Ingham   }
144aa816b8fSJim Ingham   return false;
145aa816b8fSJim Ingham }
146aa816b8fSJim Ingham 
147a633ee6eSEugene Zemtsov static bool IsTrivialBasename(const llvm::StringRef &basename) {
148a633ee6eSEugene Zemtsov   // Check that the basename matches with the following regular expression
14905097246SAdrian Prantl   // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
15005097246SAdrian Prantl   // because it is significantly more efficient then using the general purpose
15105097246SAdrian Prantl   // regular expression library.
1529fa11470STamas Berghammer   size_t idx = 0;
1539fa11470STamas Berghammer   if (basename.size() > 0 && basename[0] == '~')
1549fa11470STamas Berghammer     idx = 1;
1559fa11470STamas Berghammer 
1569fa11470STamas Berghammer   if (basename.size() <= idx)
1579fa11470STamas Berghammer     return false; // Empty string or "~"
1589fa11470STamas Berghammer 
1599fa11470STamas Berghammer   if (!std::isalpha(basename[idx]) && basename[idx] != '_')
160e9264b74SKazuaki Ishizaki     return false; // First character (after removing the possible '~'') isn't in
161b9c1b51eSKate Stone                   // [A-Za-z_]
1629fa11470STamas Berghammer 
1639fa11470STamas Berghammer   // Read all characters matching [A-Za-z_0-9]
1649fa11470STamas Berghammer   ++idx;
165b9c1b51eSKate Stone   while (idx < basename.size()) {
1669fa11470STamas Berghammer     if (!std::isalnum(basename[idx]) && basename[idx] != '_')
1679fa11470STamas Berghammer       break;
1689fa11470STamas Berghammer     ++idx;
1699fa11470STamas Berghammer   }
1709fa11470STamas Berghammer 
1719fa11470STamas Berghammer   // We processed all characters. It is a vaild basename.
172a6682a41SJonas Devlieghere   return idx == basename.size();
1739fa11470STamas Berghammer }
174aa816b8fSJim Ingham 
175a633ee6eSEugene Zemtsov bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
17605097246SAdrian Prantl   // This method tries to parse simple method definitions which are presumably
17705097246SAdrian Prantl   // most comman in user programs. Definitions that can be parsed by this
17805097246SAdrian Prantl   // function don't have return types and templates in the name.
179a633ee6eSEugene Zemtsov   // A::B::C::fun(std::vector<T> &) const
1809645a629SJim Ingham   size_t arg_start, arg_end;
181a633ee6eSEugene Zemtsov   llvm::StringRef full(m_full.GetCString());
182aa816b8fSJim Ingham   llvm::StringRef parens("()", 2);
183b9c1b51eSKate Stone   if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
184aa816b8fSJim Ingham     m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
185aa816b8fSJim Ingham     if (arg_end + 1 < full.size())
186a633ee6eSEugene Zemtsov       m_qualifiers = full.substr(arg_end + 1).ltrim();
187a633ee6eSEugene Zemtsov 
188a633ee6eSEugene Zemtsov     if (arg_start == 0)
189a633ee6eSEugene Zemtsov       return false;
190aa816b8fSJim Ingham     size_t basename_end = arg_start;
191aa816b8fSJim Ingham     size_t context_start = 0;
192a633ee6eSEugene Zemtsov     size_t context_end = full.rfind(':', basename_end);
193aa816b8fSJim Ingham     if (context_end == llvm::StringRef::npos)
194aa816b8fSJim Ingham       m_basename = full.substr(0, basename_end);
195b9c1b51eSKate Stone     else {
196aa816b8fSJim Ingham       if (context_start < context_end)
197a633ee6eSEugene Zemtsov         m_context = full.substr(context_start, context_end - 1 - context_start);
198aa816b8fSJim Ingham       const size_t basename_begin = context_end + 1;
199a633ee6eSEugene Zemtsov       m_basename = full.substr(basename_begin, basename_end - basename_begin);
200aa816b8fSJim Ingham     }
201aa816b8fSJim Ingham 
202a633ee6eSEugene Zemtsov     if (IsTrivialBasename(m_basename)) {
203a633ee6eSEugene Zemtsov       return true;
204a633ee6eSEugene Zemtsov     } else {
205aa816b8fSJim Ingham       // The C++ basename doesn't match our regular expressions so this can't
206aa816b8fSJim Ingham       // be a valid C++ method, clear everything out and indicate an error
207aa816b8fSJim Ingham       m_context = llvm::StringRef();
208aa816b8fSJim Ingham       m_basename = llvm::StringRef();
209aa816b8fSJim Ingham       m_arguments = llvm::StringRef();
210aa816b8fSJim Ingham       m_qualifiers = llvm::StringRef();
211a633ee6eSEugene Zemtsov       return false;
212aa816b8fSJim Ingham     }
213a633ee6eSEugene Zemtsov   }
214a633ee6eSEugene Zemtsov   return false;
215a633ee6eSEugene Zemtsov }
216a633ee6eSEugene Zemtsov 
217a633ee6eSEugene Zemtsov void CPlusPlusLanguage::MethodName::Parse() {
218a633ee6eSEugene Zemtsov   if (!m_parsed && m_full) {
219a633ee6eSEugene Zemtsov     if (TrySimplifiedParse()) {
220a633ee6eSEugene Zemtsov       m_parse_error = false;
221a633ee6eSEugene Zemtsov     } else {
222a633ee6eSEugene Zemtsov       CPlusPlusNameParser parser(m_full.GetStringRef());
223a633ee6eSEugene Zemtsov       if (auto function = parser.ParseAsFunctionDefinition()) {
224a633ee6eSEugene Zemtsov         m_basename = function.getValue().name.basename;
225a633ee6eSEugene Zemtsov         m_context = function.getValue().name.context;
226a633ee6eSEugene Zemtsov         m_arguments = function.getValue().arguments;
227a633ee6eSEugene Zemtsov         m_qualifiers = function.getValue().qualifiers;
228a633ee6eSEugene Zemtsov         m_parse_error = false;
229b9c1b51eSKate Stone       } else {
230aa816b8fSJim Ingham         m_parse_error = true;
231aa816b8fSJim Ingham       }
232aa816b8fSJim Ingham     }
233a633ee6eSEugene Zemtsov     m_parsed = true;
234a633ee6eSEugene Zemtsov   }
235aa816b8fSJim Ingham }
236aa816b8fSJim Ingham 
237b9c1b51eSKate Stone llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() {
238aa816b8fSJim Ingham   if (!m_parsed)
239aa816b8fSJim Ingham     Parse();
240aa816b8fSJim Ingham   return m_basename;
241aa816b8fSJim Ingham }
242aa816b8fSJim Ingham 
243b9c1b51eSKate Stone llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() {
244aa816b8fSJim Ingham   if (!m_parsed)
245aa816b8fSJim Ingham     Parse();
246aa816b8fSJim Ingham   return m_context;
247aa816b8fSJim Ingham }
248aa816b8fSJim Ingham 
249b9c1b51eSKate Stone llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() {
250aa816b8fSJim Ingham   if (!m_parsed)
251aa816b8fSJim Ingham     Parse();
252aa816b8fSJim Ingham   return m_arguments;
253aa816b8fSJim Ingham }
254aa816b8fSJim Ingham 
255b9c1b51eSKate Stone llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() {
256aa816b8fSJim Ingham   if (!m_parsed)
257aa816b8fSJim Ingham     Parse();
258aa816b8fSJim Ingham   return m_qualifiers;
259aa816b8fSJim Ingham }
260aa816b8fSJim Ingham 
261b9c1b51eSKate Stone std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
2629293fc41SSiva Chandra   if (!m_parsed)
2639293fc41SSiva Chandra     Parse();
264a633ee6eSEugene Zemtsov   if (m_context.empty())
265adcd0268SBenjamin Kramer     return std::string(m_basename);
2669293fc41SSiva Chandra 
2679293fc41SSiva Chandra   std::string res;
2689293fc41SSiva Chandra   res += m_context;
2699293fc41SSiva Chandra   res += "::";
2709293fc41SSiva Chandra   res += m_basename;
2719293fc41SSiva Chandra   return res;
2729293fc41SSiva Chandra }
2739293fc41SSiva Chandra 
27483393d27Sshafik bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) {
27505097246SAdrian Prantl   // FIXME!! we should really run through all the known C++ Language plugins
27605097246SAdrian Prantl   // and ask each one if this is a C++ mangled name
277aa816b8fSJim Ingham 
27883393d27Sshafik   Mangled::ManglingScheme scheme = Mangled::GetManglingScheme(name);
27983393d27Sshafik 
28083393d27Sshafik   if (scheme == Mangled::eManglingSchemeNone)
281b38799c1SAaron Smith     return false;
282b38799c1SAaron Smith 
283b38799c1SAaron Smith   return true;
284aa816b8fSJim Ingham }
285aa816b8fSJim Ingham 
286b9c1b51eSKate Stone bool CPlusPlusLanguage::ExtractContextAndIdentifier(
287b9c1b51eSKate Stone     const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
288c1e530eeSAleksandr Urakov   if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))
289c1e530eeSAleksandr Urakov     return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,
290c1e530eeSAleksandr Urakov                                                                   identifier);
291c1e530eeSAleksandr Urakov 
292a633ee6eSEugene Zemtsov   CPlusPlusNameParser parser(name);
293a633ee6eSEugene Zemtsov   if (auto full_name = parser.ParseAsFullName()) {
294a633ee6eSEugene Zemtsov     identifier = full_name.getValue().basename;
295a633ee6eSEugene Zemtsov     context = full_name.getValue().context;
296aa816b8fSJim Ingham     return true;
297aa816b8fSJim Ingham   }
298aa816b8fSJim Ingham   return false;
299aa816b8fSJim Ingham }
300aa816b8fSJim Ingham 
301e0d2733bSPavel Labath namespace {
302e0d2733bSPavel Labath class NodeAllocator {
303e0d2733bSPavel Labath   llvm::BumpPtrAllocator Alloc;
304f5bb1d6cSLuke Drummond 
3055e6bd2f8SStefan Granitz public:
306e0d2733bSPavel Labath   void reset() { Alloc.Reset(); }
307f5bb1d6cSLuke Drummond 
308e0d2733bSPavel Labath   template <typename T, typename... Args> T *makeNode(Args &&... args) {
309e0d2733bSPavel Labath     return new (Alloc.Allocate(sizeof(T), alignof(T)))
310e0d2733bSPavel Labath         T(std::forward<Args>(args)...);
3115e6bd2f8SStefan Granitz   }
312f5bb1d6cSLuke Drummond 
313e0d2733bSPavel Labath   void *allocateNodeArray(size_t sz) {
314e0d2733bSPavel Labath     return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,
315e0d2733bSPavel Labath                           alignof(llvm::itanium_demangle::Node *));
316f5bb1d6cSLuke Drummond   }
317f5bb1d6cSLuke Drummond };
318f5bb1d6cSLuke Drummond 
319c16f0b18SPavel Labath template <typename Derived>
320c16f0b18SPavel Labath class ManglingSubstitutor
321c16f0b18SPavel Labath     : public llvm::itanium_demangle::AbstractManglingParser<Derived,
322e0d2733bSPavel Labath                                                             NodeAllocator> {
323c16f0b18SPavel Labath   using Base =
324c16f0b18SPavel Labath       llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
325f5bb1d6cSLuke Drummond 
326c16f0b18SPavel Labath public:
327c16f0b18SPavel Labath   ManglingSubstitutor() : Base(nullptr, nullptr) {}
328e0d2733bSPavel Labath 
329c16f0b18SPavel Labath   template <typename... Ts>
330c16f0b18SPavel Labath   ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) {
331c16f0b18SPavel Labath     this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...);
332c16f0b18SPavel Labath     return substituteImpl(Mangled);
333c16f0b18SPavel Labath   }
334e0d2733bSPavel Labath 
335c16f0b18SPavel Labath protected:
336c16f0b18SPavel Labath   void reset(llvm::StringRef Mangled) {
337c16f0b18SPavel Labath     Base::reset(Mangled.begin(), Mangled.end());
338e0d2733bSPavel Labath     Written = Mangled.begin();
339e0d2733bSPavel Labath     Result.clear();
340e0d2733bSPavel Labath     Substituted = false;
3415e6bd2f8SStefan Granitz   }
342f5bb1d6cSLuke Drummond 
343c16f0b18SPavel Labath   ConstString substituteImpl(llvm::StringRef Mangled) {
344e0d2733bSPavel Labath     Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
345c16f0b18SPavel Labath     if (this->parse() == nullptr) {
346e0d2733bSPavel Labath       LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled);
347e0d2733bSPavel Labath       return ConstString();
348e0d2733bSPavel Labath     }
349e0d2733bSPavel Labath     if (!Substituted)
350e0d2733bSPavel Labath       return ConstString();
351e0d2733bSPavel Labath 
352e0d2733bSPavel Labath     // Append any trailing unmodified input.
353e0d2733bSPavel Labath     appendUnchangedInput();
354e0d2733bSPavel Labath     LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
355e0d2733bSPavel Labath     return ConstString(Result);
356e0d2733bSPavel Labath   }
357e0d2733bSPavel Labath 
358c16f0b18SPavel Labath   void trySubstitute(llvm::StringRef From, llvm::StringRef To) {
359c16f0b18SPavel Labath     if (!llvm::StringRef(currentParserPos(), this->numLeft()).startswith(From))
360c16f0b18SPavel Labath       return;
361c16f0b18SPavel Labath 
362e0d2733bSPavel Labath     // We found a match. Append unmodified input up to this point.
363e0d2733bSPavel Labath     appendUnchangedInput();
364e0d2733bSPavel Labath 
365e0d2733bSPavel Labath     // And then perform the replacement.
366c16f0b18SPavel Labath     Result += To;
367c16f0b18SPavel Labath     Written += From.size();
368e0d2733bSPavel Labath     Substituted = true;
369e0d2733bSPavel Labath   }
370c16f0b18SPavel Labath 
371c16f0b18SPavel Labath private:
372c16f0b18SPavel Labath   /// Input character until which we have constructed the respective output
373c16f0b18SPavel Labath   /// already.
374c16f0b18SPavel Labath   const char *Written;
375c16f0b18SPavel Labath 
376c16f0b18SPavel Labath   llvm::SmallString<128> Result;
377c16f0b18SPavel Labath 
378c16f0b18SPavel Labath   /// Whether we have performed any substitutions.
379c16f0b18SPavel Labath   bool Substituted;
380c16f0b18SPavel Labath 
381c16f0b18SPavel Labath   const char *currentParserPos() const { return this->First; }
382c16f0b18SPavel Labath 
383c16f0b18SPavel Labath   void appendUnchangedInput() {
384c16f0b18SPavel Labath     Result +=
385c16f0b18SPavel Labath         llvm::StringRef(Written, std::distance(Written, currentParserPos()));
386c16f0b18SPavel Labath     Written = currentParserPos();
387c16f0b18SPavel Labath   }
388c16f0b18SPavel Labath };
389c16f0b18SPavel Labath 
390c16f0b18SPavel Labath /// Given a mangled function `Mangled`, replace all the primitive function type
391c16f0b18SPavel Labath /// arguments of `Search` with type `Replace`.
392c16f0b18SPavel Labath class TypeSubstitutor : public ManglingSubstitutor<TypeSubstitutor> {
393c16f0b18SPavel Labath   llvm::StringRef Search;
394c16f0b18SPavel Labath   llvm::StringRef Replace;
395c16f0b18SPavel Labath 
396c16f0b18SPavel Labath public:
397c16f0b18SPavel Labath   void reset(llvm::StringRef Mangled, llvm::StringRef Search,
398c16f0b18SPavel Labath              llvm::StringRef Replace) {
399c16f0b18SPavel Labath     ManglingSubstitutor::reset(Mangled);
400c16f0b18SPavel Labath     this->Search = Search;
401c16f0b18SPavel Labath     this->Replace = Replace;
402c16f0b18SPavel Labath   }
403c16f0b18SPavel Labath 
404c16f0b18SPavel Labath   llvm::itanium_demangle::Node *parseType() {
405c16f0b18SPavel Labath     trySubstitute(Search, Replace);
406c16f0b18SPavel Labath     return ManglingSubstitutor::parseType();
407e0d2733bSPavel Labath   }
408e0d2733bSPavel Labath };
409c16f0b18SPavel Labath 
410c16f0b18SPavel Labath class CtorDtorSubstitutor : public ManglingSubstitutor<CtorDtorSubstitutor> {
411c16f0b18SPavel Labath public:
412c16f0b18SPavel Labath   llvm::itanium_demangle::Node *
413c16f0b18SPavel Labath   parseCtorDtorName(llvm::itanium_demangle::Node *&SoFar, NameState *State) {
414c16f0b18SPavel Labath     trySubstitute("C1", "C2");
415c16f0b18SPavel Labath     trySubstitute("D1", "D2");
416c16f0b18SPavel Labath     return ManglingSubstitutor::parseCtorDtorName(SoFar, State);
417f5bb1d6cSLuke Drummond   }
418c16f0b18SPavel Labath };
419c16f0b18SPavel Labath } // namespace
420f5bb1d6cSLuke Drummond 
421a65f6aafSAlex Langford std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(
422a65f6aafSAlex Langford     const ConstString mangled_name) const {
423a65f6aafSAlex Langford   std::vector<ConstString> alternates;
424a65f6aafSAlex Langford 
425f5bb1d6cSLuke Drummond   /// Get a basic set of alternative manglings for the given symbol `name`, by
426f5bb1d6cSLuke Drummond   /// making a few basic possible substitutions on basic types, storage duration
427f5bb1d6cSLuke Drummond   /// and `const`ness for the given symbol. The output parameter `alternates`
428f5bb1d6cSLuke Drummond   /// is filled with a best-guess, non-exhaustive set of different manglings
429f5bb1d6cSLuke Drummond   /// for the given name.
430f5bb1d6cSLuke Drummond 
431f5bb1d6cSLuke Drummond   // Maybe we're looking for a const symbol but the debug info told us it was
432f5bb1d6cSLuke Drummond   // non-const...
433f5bb1d6cSLuke Drummond   if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
434f5bb1d6cSLuke Drummond       strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
435f5bb1d6cSLuke Drummond     std::string fixed_scratch("_ZNK");
436f5bb1d6cSLuke Drummond     fixed_scratch.append(mangled_name.GetCString() + 3);
437a65f6aafSAlex Langford     alternates.push_back(ConstString(fixed_scratch));
438f5bb1d6cSLuke Drummond   }
439f5bb1d6cSLuke Drummond 
440f5bb1d6cSLuke Drummond   // Maybe we're looking for a static symbol but we thought it was global...
441f5bb1d6cSLuke Drummond   if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
442f5bb1d6cSLuke Drummond       strncmp(mangled_name.GetCString(), "_ZL", 3)) {
443f5bb1d6cSLuke Drummond     std::string fixed_scratch("_ZL");
444f5bb1d6cSLuke Drummond     fixed_scratch.append(mangled_name.GetCString() + 2);
445a65f6aafSAlex Langford     alternates.push_back(ConstString(fixed_scratch));
446f5bb1d6cSLuke Drummond   }
447f5bb1d6cSLuke Drummond 
448e0d2733bSPavel Labath   TypeSubstitutor TS;
449f5bb1d6cSLuke Drummond   // `char` is implementation defined as either `signed` or `unsigned`.  As a
450f5bb1d6cSLuke Drummond   // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
451f5bb1d6cSLuke Drummond   // char, 'h'-unsigned char.  If we're looking for symbols with a signed char
452f5bb1d6cSLuke Drummond   // parameter, try finding matches which have the general case 'c'.
453f5bb1d6cSLuke Drummond   if (ConstString char_fixup =
454e0d2733bSPavel Labath           TS.substitute(mangled_name.GetStringRef(), "a", "c"))
455a65f6aafSAlex Langford     alternates.push_back(char_fixup);
456f5bb1d6cSLuke Drummond 
457f5bb1d6cSLuke Drummond   // long long parameter mangling 'x', may actually just be a long 'l' argument
458f5bb1d6cSLuke Drummond   if (ConstString long_fixup =
459e0d2733bSPavel Labath           TS.substitute(mangled_name.GetStringRef(), "x", "l"))
460a65f6aafSAlex Langford     alternates.push_back(long_fixup);
461f5bb1d6cSLuke Drummond 
462f5bb1d6cSLuke Drummond   // unsigned long long parameter mangling 'y', may actually just be unsigned
463f5bb1d6cSLuke Drummond   // long 'm' argument
464f5bb1d6cSLuke Drummond   if (ConstString ulong_fixup =
465e0d2733bSPavel Labath           TS.substitute(mangled_name.GetStringRef(), "y", "m"))
466a65f6aafSAlex Langford     alternates.push_back(ulong_fixup);
467f5bb1d6cSLuke Drummond 
468c16f0b18SPavel Labath   if (ConstString ctor_fixup =
469c16f0b18SPavel Labath           CtorDtorSubstitutor().substitute(mangled_name.GetStringRef()))
470a65f6aafSAlex Langford     alternates.push_back(ctor_fixup);
471c16f0b18SPavel Labath 
472a65f6aafSAlex Langford   return alternates;
473f5bb1d6cSLuke Drummond }
474f5bb1d6cSLuke Drummond 
475385b2189SAlex Langford ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName(
476385b2189SAlex Langford     const Mangled mangled, const SymbolContext &sym_ctx) const {
477385b2189SAlex Langford   ConstString demangled = mangled.GetDemangledName();
478385b2189SAlex Langford   if (!demangled)
479385b2189SAlex Langford     return ConstString();
480385b2189SAlex Langford 
481385b2189SAlex Langford   CPlusPlusLanguage::MethodName cpp_name(demangled);
482385b2189SAlex Langford   std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
483385b2189SAlex Langford 
484385b2189SAlex Langford   if (!scope_qualified_name.size())
485385b2189SAlex Langford     return ConstString();
486385b2189SAlex Langford 
487385b2189SAlex Langford   if (!sym_ctx.module_sp)
488385b2189SAlex Langford     return ConstString();
489385b2189SAlex Langford 
490385b2189SAlex Langford   lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile();
491385b2189SAlex Langford   if (!sym_file)
492385b2189SAlex Langford     return ConstString();
493385b2189SAlex Langford 
494385b2189SAlex Langford   std::vector<ConstString> alternates;
495385b2189SAlex Langford   sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
496385b2189SAlex Langford 
497385b2189SAlex Langford   std::vector<ConstString> param_and_qual_matches;
498385b2189SAlex Langford   std::vector<ConstString> param_matches;
499385b2189SAlex Langford   for (size_t i = 0; i < alternates.size(); i++) {
500385b2189SAlex Langford     ConstString alternate_mangled_name = alternates[i];
501385b2189SAlex Langford     Mangled mangled(alternate_mangled_name);
502385b2189SAlex Langford     ConstString demangled = mangled.GetDemangledName();
503385b2189SAlex Langford 
504385b2189SAlex Langford     CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
505385b2189SAlex Langford     if (!cpp_name.IsValid())
506385b2189SAlex Langford       continue;
507385b2189SAlex Langford 
508385b2189SAlex Langford     if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) {
509385b2189SAlex Langford       if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
510385b2189SAlex Langford         param_and_qual_matches.push_back(alternate_mangled_name);
511385b2189SAlex Langford       else
512385b2189SAlex Langford         param_matches.push_back(alternate_mangled_name);
513385b2189SAlex Langford     }
514385b2189SAlex Langford   }
515385b2189SAlex Langford 
516385b2189SAlex Langford   if (param_and_qual_matches.size())
517385b2189SAlex Langford     return param_and_qual_matches[0]; // It is assumed that there will be only
518385b2189SAlex Langford                                       // one!
519385b2189SAlex Langford   else if (param_matches.size())
520385b2189SAlex Langford     return param_matches[0]; // Return one of them as a best match
521385b2189SAlex Langford   else
522385b2189SAlex Langford     return ConstString();
523385b2189SAlex Langford }
524385b2189SAlex Langford 
525b9c1b51eSKate Stone static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
52633e97e63SEnrico Granata   if (!cpp_category_sp)
52733e97e63SEnrico Granata     return;
52833e97e63SEnrico Granata 
52933e97e63SEnrico Granata   TypeSummaryImpl::Flags stl_summary_flags;
53033e97e63SEnrico Granata   stl_summary_flags.SetCascades(true)
53133e97e63SEnrico Granata       .SetSkipPointers(false)
53233e97e63SEnrico Granata       .SetSkipReferences(false)
53333e97e63SEnrico Granata       .SetDontShowChildren(true)
53433e97e63SEnrico Granata       .SetDontShowValue(true)
53533e97e63SEnrico Granata       .SetShowMembersOneLiner(false)
53633e97e63SEnrico Granata       .SetHideItemNames(false);
53733e97e63SEnrico Granata 
5387ba2d3e8SThomas Anderson   AddCXXSummary(cpp_category_sp,
539693fbf5cSShafik Yaghmour                 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
5407ba2d3e8SThomas Anderson                 "std::string summary provider",
5411115d1d0SRaphael Isemann                 ConstString("^std::__[[:alnum:]]+::string$"), stl_summary_flags,
5427ba2d3e8SThomas Anderson                 true);
5437ba2d3e8SThomas Anderson   AddCXXSummary(cpp_category_sp,
5447ba2d3e8SThomas Anderson                 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
5457ba2d3e8SThomas Anderson                 "std::string summary provider",
5461115d1d0SRaphael Isemann                 ConstString("^std::__[[:alnum:]]+::basic_string<char, "
5471115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::char_traits<char>, "
5481115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::allocator<char> >$"),
5497ba2d3e8SThomas Anderson                 stl_summary_flags, true);
550506144daSJordan Rupprecht   AddCXXSummary(cpp_category_sp,
551506144daSJordan Rupprecht                 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
552506144daSJordan Rupprecht                 "std::string summary provider",
5531115d1d0SRaphael Isemann                 ConstString("^std::__[[:alnum:]]+::basic_string<unsigned char, "
5541115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::char_traits<unsigned char>, "
5551115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::allocator<unsigned char> >$"),
556506144daSJordan Rupprecht                 stl_summary_flags, true);
5577ba2d3e8SThomas Anderson 
5587ba2d3e8SThomas Anderson   AddCXXSummary(cpp_category_sp,
559693fbf5cSShafik Yaghmour                 lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
5607ba2d3e8SThomas Anderson                 "std::u16string summary provider",
56146fb5d5dSRaphael Isemann                 ConstString("^std::__[[:alnum:]]+::basic_string<char16_t, "
5621115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::char_traits<char16_t>, "
5631115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::allocator<char16_t> >$"),
5647ba2d3e8SThomas Anderson                 stl_summary_flags, true);
5657ba2d3e8SThomas Anderson 
5667ba2d3e8SThomas Anderson   AddCXXSummary(cpp_category_sp,
567693fbf5cSShafik Yaghmour                 lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
5687ba2d3e8SThomas Anderson                 "std::u32string summary provider",
56946fb5d5dSRaphael Isemann                 ConstString("^std::__[[:alnum:]]+::basic_string<char32_t, "
5701115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::char_traits<char32_t>, "
5711115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::allocator<char32_t> >$"),
5727ba2d3e8SThomas Anderson                 stl_summary_flags, true);
57333e97e63SEnrico Granata 
57446fb5d5dSRaphael Isemann   AddCXXSummary(
57546fb5d5dSRaphael Isemann       cpp_category_sp, lldb_private::formatters::LibcxxWStringSummaryProvider,
5767ba2d3e8SThomas Anderson       "std::wstring summary provider",
57746fb5d5dSRaphael Isemann       ConstString("^std::__[[:alnum:]]+::wstring$"), stl_summary_flags, true);
5787ba2d3e8SThomas Anderson   AddCXXSummary(cpp_category_sp,
5797ba2d3e8SThomas Anderson                 lldb_private::formatters::LibcxxWStringSummaryProvider,
5807ba2d3e8SThomas Anderson                 "std::wstring summary provider",
5811115d1d0SRaphael Isemann                 ConstString("^std::__[[:alnum:]]+::basic_string<wchar_t, "
5821115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::char_traits<wchar_t>, "
5831115d1d0SRaphael Isemann                             "std::__[[:alnum:]]+::allocator<wchar_t> >$"),
5847ba2d3e8SThomas Anderson                 stl_summary_flags, true);
58533e97e63SEnrico Granata 
58633e97e63SEnrico Granata   SyntheticChildren::Flags stl_synth_flags;
587b9c1b51eSKate Stone   stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
588b9c1b51eSKate Stone       false);
589393fe62eSJim Ingham   SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
590393fe62eSJim Ingham   stl_deref_flags.SetFrontEndWantsDereference();
59133e97e63SEnrico Granata 
592b9c1b51eSKate Stone   AddCXXSynthetic(
593b9c1b51eSKate Stone       cpp_category_sp,
5945269875eSPavel Labath       lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
5955269875eSPavel Labath       "libc++ std::bitset synthetic children",
5967ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"), stl_deref_flags,
5975269875eSPavel Labath       true);
5985269875eSPavel Labath   AddCXXSynthetic(
5995269875eSPavel Labath       cpp_category_sp,
600b9c1b51eSKate Stone       lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
601b9c1b51eSKate Stone       "libc++ std::vector synthetic children",
6027ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"), stl_deref_flags,
603b9c1b51eSKate Stone       true);
604b9c1b51eSKate Stone   AddCXXSynthetic(
605b9c1b51eSKate Stone       cpp_category_sp,
60689ac0c7dSPavel Labath       lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
60789ac0c7dSPavel Labath       "libc++ std::forward_list synthetic children",
6087ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
60989ac0c7dSPavel Labath       stl_synth_flags, true);
61089ac0c7dSPavel Labath   AddCXXSynthetic(
61189ac0c7dSPavel Labath       cpp_category_sp,
612b9c1b51eSKate Stone       lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
613b9c1b51eSKate Stone       "libc++ std::list synthetic children",
614b17d6c52SJan Kratochvil       // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
615b17d6c52SJan Kratochvil       // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
616b17d6c52SJan Kratochvil       ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
617b17d6c52SJan Kratochvil                   "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
618b17d6c52SJan Kratochvil       stl_deref_flags, true);
619b9c1b51eSKate Stone   AddCXXSynthetic(
620b9c1b51eSKate Stone       cpp_category_sp,
621b9c1b51eSKate Stone       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
622b9c1b51eSKate Stone       "libc++ std::map synthetic children",
6237ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::map<.+> >(( )?&)?$"), stl_synth_flags,
624b9c1b51eSKate Stone       true);
625b9c1b51eSKate Stone   AddCXXSynthetic(
626b9c1b51eSKate Stone       cpp_category_sp,
627b9c1b51eSKate Stone       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
628b9c1b51eSKate Stone       "libc++ std::set synthetic children",
6297ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::set<.+> >(( )?&)?$"), stl_deref_flags,
630b9c1b51eSKate Stone       true);
631b9c1b51eSKate Stone   AddCXXSynthetic(
632b9c1b51eSKate Stone       cpp_category_sp,
633b9c1b51eSKate Stone       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
634b9c1b51eSKate Stone       "libc++ std::multiset synthetic children",
6357ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::multiset<.+> >(( )?&)?$"),
6367ba2d3e8SThomas Anderson       stl_deref_flags, true);
637b9c1b51eSKate Stone   AddCXXSynthetic(
638b9c1b51eSKate Stone       cpp_category_sp,
639b9c1b51eSKate Stone       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
640b9c1b51eSKate Stone       "libc++ std::multimap synthetic children",
6417ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::multimap<.+> >(( )?&)?$"),
6427ba2d3e8SThomas Anderson       stl_synth_flags, true);
643b9c1b51eSKate Stone   AddCXXSynthetic(
644b9c1b51eSKate Stone       cpp_category_sp,
645b9c1b51eSKate Stone       lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,
646b9c1b51eSKate Stone       "libc++ std::unordered containers synthetic children",
6477ba2d3e8SThomas Anderson       ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
648b9c1b51eSKate Stone       stl_synth_flags, true);
649b9c1b51eSKate Stone   AddCXXSynthetic(
650b9c1b51eSKate Stone       cpp_category_sp,
651b9c1b51eSKate Stone       lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator,
652b9c1b51eSKate Stone       "libc++ std::initializer_list synthetic children",
653b9c1b51eSKate Stone       ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
654b9c1b51eSKate Stone       true);
655e0d51846SPavel Labath   AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
656e0d51846SPavel Labath                   "libc++ std::queue synthetic children",
6577ba2d3e8SThomas Anderson                   ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
658e0d51846SPavel Labath                   stl_synth_flags, true);
659333739d0SPavel Labath   AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
660333739d0SPavel Labath                   "libc++ std::tuple synthetic children",
6617ba2d3e8SThomas Anderson                   ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
6627ba2d3e8SThomas Anderson                   stl_synth_flags, true);
663c53d3684SAdrian Prantl   AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator,
664c53d3684SAdrian Prantl                   "libc++ std::optional synthetic children",
6657ba2d3e8SThomas Anderson                   ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
666c53d3684SAdrian Prantl                   stl_synth_flags, true);
6678306f76eSShafik Yaghmour   AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
6688306f76eSShafik Yaghmour                   "libc++ std::variant synthetic children",
6697ba2d3e8SThomas Anderson                   ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
6708306f76eSShafik Yaghmour                   stl_synth_flags, true);
671b9c1b51eSKate Stone   AddCXXSynthetic(
672b9c1b51eSKate Stone       cpp_category_sp,
673b9c1b51eSKate Stone       lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
674b9c1b51eSKate Stone       "libc++ std::atomic synthetic children",
6757ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
67633e97e63SEnrico Granata 
677b9c1b51eSKate Stone   cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
678fd50e7c0SRaphael Isemann       RegularExpression("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"),
679b9c1b51eSKate Stone       SyntheticChildrenSP(new ScriptedSyntheticChildren(
680b9c1b51eSKate Stone           stl_synth_flags,
68133e97e63SEnrico Granata           "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
68233e97e63SEnrico Granata 
683b9c1b51eSKate Stone   AddCXXSynthetic(
684b9c1b51eSKate Stone       cpp_category_sp,
685b9c1b51eSKate Stone       lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
686b9c1b51eSKate Stone       "shared_ptr synthetic children",
6877ba2d3e8SThomas Anderson       ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
688b9c1b51eSKate Stone       stl_synth_flags, true);
689a567d680Sshafik 
690a567d680Sshafik   ConstString libcxx_std_unique_ptr_regex(
691a567d680Sshafik       "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$");
692a567d680Sshafik   AddCXXSynthetic(
693a567d680Sshafik       cpp_category_sp,
694a567d680Sshafik       lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,
695a567d680Sshafik       "unique_ptr synthetic children", libcxx_std_unique_ptr_regex,
696a567d680Sshafik       stl_synth_flags, true);
697a567d680Sshafik 
698b9c1b51eSKate Stone   AddCXXSynthetic(
699b9c1b51eSKate Stone       cpp_category_sp,
700b9c1b51eSKate Stone       lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
701b9c1b51eSKate Stone       "weak_ptr synthetic children",
7027ba2d3e8SThomas Anderson       ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"),
7037ba2d3e8SThomas Anderson       stl_synth_flags, true);
70491e94a70Sshafik   AddCXXSummary(cpp_category_sp,
70591e94a70Sshafik                 lldb_private::formatters::LibcxxFunctionSummaryProvider,
70691e94a70Sshafik                 "libc++ std::function summary provider",
70791e94a70Sshafik                 ConstString("^std::__[[:alnum:]]+::function<.+>$"),
70891e94a70Sshafik                 stl_summary_flags, true);
70933e97e63SEnrico Granata 
710b9c1b51eSKate Stone   stl_summary_flags.SetDontShowChildren(false);
711b9c1b51eSKate Stone   stl_summary_flags.SetSkipPointers(false);
712b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
713b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxContainerSummaryProvider,
7145269875eSPavel Labath                 "libc++ std::bitset summary provider",
7157ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"),
7165269875eSPavel Labath                 stl_summary_flags, true);
7175269875eSPavel Labath   AddCXXSummary(cpp_category_sp,
7185269875eSPavel Labath                 lldb_private::formatters::LibcxxContainerSummaryProvider,
719b9c1b51eSKate Stone                 "libc++ std::vector summary provider",
7207ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"),
721b9c1b51eSKate Stone                 stl_summary_flags, true);
722b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
723b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxContainerSummaryProvider,
724b9c1b51eSKate Stone                 "libc++ std::list summary provider",
7257ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
72689ac0c7dSPavel Labath                 stl_summary_flags, true);
727b17d6c52SJan Kratochvil   AddCXXSummary(
728b17d6c52SJan Kratochvil       cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
72989ac0c7dSPavel Labath       "libc++ std::list summary provider",
730b17d6c52SJan Kratochvil       // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
731b17d6c52SJan Kratochvil       // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
732b17d6c52SJan Kratochvil       ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
733b17d6c52SJan Kratochvil                   "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
734b9c1b51eSKate Stone       stl_summary_flags, true);
735b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
736b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxContainerSummaryProvider,
737b9c1b51eSKate Stone                 "libc++ std::map summary provider",
7387ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::map<.+>(( )?&)?$"),
739b9c1b51eSKate Stone                 stl_summary_flags, true);
740b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
741b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxContainerSummaryProvider,
742b9c1b51eSKate Stone                 "libc++ std::deque summary provider",
7437ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::deque<.+>(( )?&)?$"),
744b9c1b51eSKate Stone                 stl_summary_flags, true);
745b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
746b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxContainerSummaryProvider,
747e0d51846SPavel Labath                 "libc++ std::queue summary provider",
7487ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
749e0d51846SPavel Labath                 stl_summary_flags, true);
750e0d51846SPavel Labath   AddCXXSummary(cpp_category_sp,
751e0d51846SPavel Labath                 lldb_private::formatters::LibcxxContainerSummaryProvider,
752b9c1b51eSKate Stone                 "libc++ std::set summary provider",
7537ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::set<.+>(( )?&)?$"),
754b9c1b51eSKate Stone                 stl_summary_flags, true);
755b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
756b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxContainerSummaryProvider,
757b9c1b51eSKate Stone                 "libc++ std::multiset summary provider",
7587ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::multiset<.+>(( )?&)?$"),
759b9c1b51eSKate Stone                 stl_summary_flags, true);
760b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
761b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxContainerSummaryProvider,
762b9c1b51eSKate Stone                 "libc++ std::multimap summary provider",
7637ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::multimap<.+>(( )?&)?$"),
764b9c1b51eSKate Stone                 stl_summary_flags, true);
765b9c1b51eSKate Stone   AddCXXSummary(
766b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
767b9c1b51eSKate Stone       "libc++ std::unordered containers summary provider",
7687ba2d3e8SThomas Anderson       ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
769b9c1b51eSKate Stone       stl_summary_flags, true);
770333739d0SPavel Labath   AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider,
771333739d0SPavel Labath                 "libc++ std::tuple summary provider",
7727ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
7737ba2d3e8SThomas Anderson                 stl_summary_flags, true);
77446fb5d5dSRaphael Isemann   AddCXXSummary(cpp_category_sp,
77546fb5d5dSRaphael Isemann                 lldb_private::formatters::LibCxxAtomicSummaryProvider,
776b9c1b51eSKate Stone                 "libc++ std::atomic summary provider",
77746fb5d5dSRaphael Isemann                 ConstString("^std::__[[:alnum:]]+::atomic<.+>$"),
77846fb5d5dSRaphael Isemann                 stl_summary_flags, true);
779c53d3684SAdrian Prantl   AddCXXSummary(cpp_category_sp,
780c53d3684SAdrian Prantl                 lldb_private::formatters::LibcxxOptionalSummaryProvider,
781c53d3684SAdrian Prantl                 "libc++ std::optional summary provider",
7827ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
783c53d3684SAdrian Prantl                 stl_summary_flags, true);
7848306f76eSShafik Yaghmour   AddCXXSummary(cpp_category_sp,
7858306f76eSShafik Yaghmour                 lldb_private::formatters::LibcxxVariantSummaryProvider,
7868306f76eSShafik Yaghmour                 "libc++ std::variant summary provider",
7877ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
7888306f76eSShafik Yaghmour                 stl_summary_flags, true);
78933e97e63SEnrico Granata 
79033e97e63SEnrico Granata   stl_summary_flags.SetSkipPointers(true);
79133e97e63SEnrico Granata 
792b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
793b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
794b9c1b51eSKate Stone                 "libc++ std::shared_ptr summary provider",
7957ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$"),
796b9c1b51eSKate Stone                 stl_summary_flags, true);
797b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
798b9c1b51eSKate Stone                 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
799b9c1b51eSKate Stone                 "libc++ std::weak_ptr summary provider",
8007ba2d3e8SThomas Anderson                 ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
801b9c1b51eSKate Stone                 stl_summary_flags, true);
802a567d680Sshafik   AddCXXSummary(cpp_category_sp,
803a567d680Sshafik                 lldb_private::formatters::LibcxxUniquePointerSummaryProvider,
804a567d680Sshafik                 "libc++ std::unique_ptr summary provider",
805a567d680Sshafik                 libcxx_std_unique_ptr_regex, stl_summary_flags, true);
80633e97e63SEnrico Granata 
807b9c1b51eSKate Stone   AddCXXSynthetic(
808b9c1b51eSKate Stone       cpp_category_sp,
809b9c1b51eSKate Stone       lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,
810b9c1b51eSKate Stone       "std::vector iterator synthetic children",
8117ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::__wrap_iter<.+>$"), stl_synth_flags,
8127ba2d3e8SThomas Anderson       true);
81333e97e63SEnrico Granata 
814b9c1b51eSKate Stone   AddCXXSynthetic(
815b9c1b51eSKate Stone       cpp_category_sp,
816b9c1b51eSKate Stone       lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,
817b9c1b51eSKate Stone       "std::map iterator synthetic children",
8187ba2d3e8SThomas Anderson       ConstString("^std::__[[:alnum:]]+::__map_iterator<.+>$"), stl_synth_flags,
819b9c1b51eSKate Stone       true);
82033e97e63SEnrico Granata }
82133e97e63SEnrico Granata 
822b9c1b51eSKate Stone static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
82333e97e63SEnrico Granata   if (!cpp_category_sp)
82433e97e63SEnrico Granata     return;
82533e97e63SEnrico Granata 
82633e97e63SEnrico Granata   TypeSummaryImpl::Flags stl_summary_flags;
82733e97e63SEnrico Granata   stl_summary_flags.SetCascades(true)
82833e97e63SEnrico Granata       .SetSkipPointers(false)
82933e97e63SEnrico Granata       .SetSkipReferences(false)
83033e97e63SEnrico Granata       .SetDontShowChildren(true)
83133e97e63SEnrico Granata       .SetDontShowValue(true)
83233e97e63SEnrico Granata       .SetShowMembersOneLiner(false)
83333e97e63SEnrico Granata       .SetHideItemNames(false);
83433e97e63SEnrico Granata 
835b9c1b51eSKate Stone   lldb::TypeSummaryImplSP std_string_summary_sp(
836b9c1b51eSKate Stone       new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}"));
83733e97e63SEnrico Granata 
838b9c1b51eSKate Stone   lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(
839b9c1b51eSKate Stone       stl_summary_flags, LibStdcppStringSummaryProvider,
84082ffb8e9STodd Fiala       "libstdc++ c++11 std::string summary provider"));
841b9c1b51eSKate Stone   lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(
842b9c1b51eSKate Stone       stl_summary_flags, LibStdcppWStringSummaryProvider,
84382ffb8e9STodd Fiala       "libstdc++ c++11 std::wstring summary provider"));
84482ffb8e9STodd Fiala 
84533e97e63SEnrico Granata   cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
84633e97e63SEnrico Granata                                                     std_string_summary_sp);
847b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
848b9c1b51eSKate Stone       ConstString("std::basic_string<char>"), std_string_summary_sp);
849b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
850b9c1b51eSKate Stone       ConstString("std::basic_string<char,std::char_traits<char>,std::"
851b9c1b51eSKate Stone                   "allocator<char> >"),
85233e97e63SEnrico Granata       std_string_summary_sp);
853b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
854b9c1b51eSKate Stone       ConstString("std::basic_string<char, std::char_traits<char>, "
855b9c1b51eSKate Stone                   "std::allocator<char> >"),
85633e97e63SEnrico Granata       std_string_summary_sp);
85733e97e63SEnrico Granata 
858b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
859b9c1b51eSKate Stone       ConstString("std::__cxx11::string"), cxx11_string_summary_sp);
860b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
861b9c1b51eSKate Stone       ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, "
862b9c1b51eSKate Stone                   "std::allocator<char> >"),
86382ffb8e9STodd Fiala       cxx11_string_summary_sp);
864506144daSJordan Rupprecht   cpp_category_sp->GetTypeSummariesContainer()->Add(
86546fb5d5dSRaphael Isemann       ConstString("std::__cxx11::basic_string<unsigned char, "
86646fb5d5dSRaphael Isemann                   "std::char_traits<unsigned char>, "
867506144daSJordan Rupprecht                   "std::allocator<unsigned char> >"),
868506144daSJordan Rupprecht       cxx11_string_summary_sp);
86982ffb8e9STodd Fiala 
870b9c1b51eSKate Stone   // making sure we force-pick the summary for printing wstring (_M_p is a
871b9c1b51eSKate Stone   // wchar_t*)
872b9c1b51eSKate Stone   lldb::TypeSummaryImplSP std_wstring_summary_sp(
873b9c1b51eSKate Stone       new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
87433e97e63SEnrico Granata 
87533e97e63SEnrico Granata   cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"),
87633e97e63SEnrico Granata                                                     std_wstring_summary_sp);
877b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
878b9c1b51eSKate Stone       ConstString("std::basic_string<wchar_t>"), std_wstring_summary_sp);
879b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
880b9c1b51eSKate Stone       ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::"
881b9c1b51eSKate Stone                   "allocator<wchar_t> >"),
88233e97e63SEnrico Granata       std_wstring_summary_sp);
883b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
884b9c1b51eSKate Stone       ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, "
885b9c1b51eSKate Stone                   "std::allocator<wchar_t> >"),
88633e97e63SEnrico Granata       std_wstring_summary_sp);
88733e97e63SEnrico Granata 
888b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
889b9c1b51eSKate Stone       ConstString("std::__cxx11::wstring"), cxx11_wstring_summary_sp);
890b9c1b51eSKate Stone   cpp_category_sp->GetTypeSummariesContainer()->Add(
891b9c1b51eSKate Stone       ConstString("std::__cxx11::basic_string<wchar_t, "
892b9c1b51eSKate Stone                   "std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
89382ffb8e9STodd Fiala       cxx11_wstring_summary_sp);
89433e97e63SEnrico Granata 
89533e97e63SEnrico Granata   SyntheticChildren::Flags stl_synth_flags;
896b9c1b51eSKate Stone   stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
897b9c1b51eSKate Stone       false);
898*566bfbb7SDanil Stefaniuc   SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
899*566bfbb7SDanil Stefaniuc   stl_deref_flags.SetFrontEndWantsDereference();
90033e97e63SEnrico Granata 
901b9c1b51eSKate Stone   cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
902fd50e7c0SRaphael Isemann       RegularExpression("^std::vector<.+>(( )?&)?$"),
903b9c1b51eSKate Stone       SyntheticChildrenSP(new ScriptedSyntheticChildren(
904b9c1b51eSKate Stone           stl_synth_flags,
90533e97e63SEnrico Granata           "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
906b9c1b51eSKate Stone   cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
907fd50e7c0SRaphael Isemann       RegularExpression("^std::map<.+> >(( )?&)?$"),
908b9c1b51eSKate Stone       SyntheticChildrenSP(new ScriptedSyntheticChildren(
909b9c1b51eSKate Stone           stl_synth_flags,
91033e97e63SEnrico Granata           "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
911b9c1b51eSKate Stone   cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
912fd50e7c0SRaphael Isemann       RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
913b9c1b51eSKate Stone       SyntheticChildrenSP(new ScriptedSyntheticChildren(
914b9c1b51eSKate Stone           stl_synth_flags,
91533e97e63SEnrico Granata           "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
916b9c1b51eSKate Stone   stl_summary_flags.SetDontShowChildren(false);
917b9c1b51eSKate Stone   stl_summary_flags.SetSkipPointers(true);
918b9c1b51eSKate Stone   cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
919*566bfbb7SDanil Stefaniuc       RegularExpression("^std::bitset<.+>(( )?&)?$"),
920*566bfbb7SDanil Stefaniuc       TypeSummaryImplSP(
921*566bfbb7SDanil Stefaniuc           new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
922*566bfbb7SDanil Stefaniuc   cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
923fd50e7c0SRaphael Isemann       RegularExpression("^std::vector<.+>(( )?&)?$"),
924b9c1b51eSKate Stone       TypeSummaryImplSP(
925b9c1b51eSKate Stone           new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
926b9c1b51eSKate Stone   cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
927fd50e7c0SRaphael Isemann       RegularExpression("^std::map<.+> >(( )?&)?$"),
92895eae423SZachary Turner       TypeSummaryImplSP(
92995eae423SZachary Turner           new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
93095eae423SZachary Turner   cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
931fd50e7c0SRaphael Isemann       RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
932b9c1b51eSKate Stone       TypeSummaryImplSP(
933b9c1b51eSKate Stone           new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
93433e97e63SEnrico Granata 
935b9c1b51eSKate Stone   AddCXXSynthetic(
936b9c1b51eSKate Stone       cpp_category_sp,
937b9c1b51eSKate Stone       lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,
938b9c1b51eSKate Stone       "std::vector iterator synthetic children",
939b9c1b51eSKate Stone       ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
94033e97e63SEnrico Granata 
941b9c1b51eSKate Stone   AddCXXSynthetic(
942b9c1b51eSKate Stone       cpp_category_sp,
943b9c1b51eSKate Stone       lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,
944b9c1b51eSKate Stone       "std::map iterator synthetic children",
945b9c1b51eSKate Stone       ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
9469c6c8e99STamas Berghammer 
947b9c1b51eSKate Stone   AddCXXSynthetic(
948b9c1b51eSKate Stone       cpp_category_sp,
949d161b214STamas Berghammer       lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
950d161b214STamas Berghammer       "std::unique_ptr synthetic children",
951d161b214STamas Berghammer       ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
952d161b214STamas Berghammer   AddCXXSynthetic(
953d161b214STamas Berghammer       cpp_category_sp,
954b9c1b51eSKate Stone       lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
955b9c1b51eSKate Stone       "std::shared_ptr synthetic children",
956b9c1b51eSKate Stone       ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
957b9c1b51eSKate Stone   AddCXXSynthetic(
958b9c1b51eSKate Stone       cpp_category_sp,
959b9c1b51eSKate Stone       lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
960b9c1b51eSKate Stone       "std::weak_ptr synthetic children",
961b9c1b51eSKate Stone       ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
9627f15dba1STamas Berghammer   AddCXXSynthetic(
9637f15dba1STamas Berghammer       cpp_category_sp,
9647f15dba1STamas Berghammer       lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator,
9657f15dba1STamas Berghammer       "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"),
9667f15dba1STamas Berghammer       stl_synth_flags, true);
967b9c1b51eSKate Stone 
968*566bfbb7SDanil Stefaniuc   AddCXXSynthetic(
969*566bfbb7SDanil Stefaniuc       cpp_category_sp,
970*566bfbb7SDanil Stefaniuc       lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,
971*566bfbb7SDanil Stefaniuc       "std::bitset synthetic child", ConstString("^std::bitset<.+>(( )?&)?$"),
972*566bfbb7SDanil Stefaniuc       stl_deref_flags, true);
973*566bfbb7SDanil Stefaniuc 
974b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
975d161b214STamas Berghammer                 lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
976d161b214STamas Berghammer                 "libstdc++ std::unique_ptr summary provider",
977d161b214STamas Berghammer                 ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags,
978d161b214STamas Berghammer                 true);
979d161b214STamas Berghammer   AddCXXSummary(cpp_category_sp,
980b9c1b51eSKate Stone                 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
981b9c1b51eSKate Stone                 "libstdc++ std::shared_ptr summary provider",
982b9c1b51eSKate Stone                 ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags,
9839c6c8e99STamas Berghammer                 true);
984b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
985b9c1b51eSKate Stone                 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
986b9c1b51eSKate Stone                 "libstdc++ std::weak_ptr summary provider",
987b9c1b51eSKate Stone                 ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
9889c6c8e99STamas Berghammer                 true);
98933e97e63SEnrico Granata }
99033e97e63SEnrico Granata 
991b9c1b51eSKate Stone static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
99233e97e63SEnrico Granata   if (!cpp_category_sp)
99333e97e63SEnrico Granata     return;
99433e97e63SEnrico Granata 
99533e97e63SEnrico Granata   TypeSummaryImpl::Flags string_flags;
99633e97e63SEnrico Granata   string_flags.SetCascades(true)
99733e97e63SEnrico Granata       .SetSkipPointers(true)
99833e97e63SEnrico Granata       .SetSkipReferences(false)
99933e97e63SEnrico Granata       .SetDontShowChildren(true)
100033e97e63SEnrico Granata       .SetDontShowValue(false)
100133e97e63SEnrico Granata       .SetShowMembersOneLiner(false)
100233e97e63SEnrico Granata       .SetHideItemNames(false);
100333e97e63SEnrico Granata 
100433e97e63SEnrico Granata   TypeSummaryImpl::Flags string_array_flags;
100533e97e63SEnrico Granata   string_array_flags.SetCascades(true)
100633e97e63SEnrico Granata       .SetSkipPointers(true)
100733e97e63SEnrico Granata       .SetSkipReferences(false)
100833e97e63SEnrico Granata       .SetDontShowChildren(true)
100933e97e63SEnrico Granata       .SetDontShowValue(true)
101033e97e63SEnrico Granata       .SetShowMembersOneLiner(false)
101133e97e63SEnrico Granata       .SetHideItemNames(false);
101233e97e63SEnrico Granata 
1013b9c1b51eSKate Stone   // FIXME because of a bug in the FormattersContainer we need to add a summary
1014b9c1b51eSKate Stone   // for both X* and const X* (<rdar://problem/12717717>)
1015b9c1b51eSKate Stone   AddCXXSummary(
1016c46d39b9SJonas Devlieghere       cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider,
1017c46d39b9SJonas Devlieghere       "char8_t * summary provider", ConstString("char8_t *"), string_flags);
1018c46d39b9SJonas Devlieghere   AddCXXSummary(cpp_category_sp,
1019c46d39b9SJonas Devlieghere                 lldb_private::formatters::Char8StringSummaryProvider,
1020c46d39b9SJonas Devlieghere                 "char8_t [] summary provider",
1021aee49255SDavid Blaikie                 ConstString("char8_t ?\\[[0-9]+\\]"), string_array_flags, true);
1022c46d39b9SJonas Devlieghere 
1023c46d39b9SJonas Devlieghere   AddCXXSummary(
1024b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
1025b9c1b51eSKate Stone       "char16_t * summary provider", ConstString("char16_t *"), string_flags);
1026045c8292SDawn Perchik   AddCXXSummary(cpp_category_sp,
1027045c8292SDawn Perchik                 lldb_private::formatters::Char16StringSummaryProvider,
1028045c8292SDawn Perchik                 "char16_t [] summary provider",
1029aee49255SDavid Blaikie                 ConstString("char16_t ?\\[[0-9]+\\]"), string_array_flags, true);
103033e97e63SEnrico Granata 
1031b9c1b51eSKate Stone   AddCXXSummary(
1032b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider,
1033b9c1b51eSKate Stone       "char32_t * summary provider", ConstString("char32_t *"), string_flags);
1034045c8292SDawn Perchik   AddCXXSummary(cpp_category_sp,
1035045c8292SDawn Perchik                 lldb_private::formatters::Char32StringSummaryProvider,
1036045c8292SDawn Perchik                 "char32_t [] summary provider",
1037aee49255SDavid Blaikie                 ConstString("char32_t ?\\[[0-9]+\\]"), string_array_flags, true);
103833e97e63SEnrico Granata 
1039b9c1b51eSKate Stone   AddCXXSummary(
1040b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider,
1041b9c1b51eSKate Stone       "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
1042b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp,
1043b9c1b51eSKate Stone                 lldb_private::formatters::WCharStringSummaryProvider,
1044b9c1b51eSKate Stone                 "wchar_t * summary provider",
1045aee49255SDavid Blaikie                 ConstString("wchar_t ?\\[[0-9]+\\]"), string_array_flags, true);
104633e97e63SEnrico Granata 
1047b9c1b51eSKate Stone   AddCXXSummary(
1048b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
1049b9c1b51eSKate Stone       "unichar * summary provider", ConstString("unichar *"), string_flags);
105033e97e63SEnrico Granata 
105133e97e63SEnrico Granata   TypeSummaryImpl::Flags widechar_flags;
105233e97e63SEnrico Granata   widechar_flags.SetDontShowValue(true)
105333e97e63SEnrico Granata       .SetSkipPointers(true)
105433e97e63SEnrico Granata       .SetSkipReferences(false)
105533e97e63SEnrico Granata       .SetCascades(true)
105633e97e63SEnrico Granata       .SetDontShowChildren(true)
105733e97e63SEnrico Granata       .SetHideItemNames(true)
105833e97e63SEnrico Granata       .SetShowMembersOneLiner(false);
105933e97e63SEnrico Granata 
1060c46d39b9SJonas Devlieghere   AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
1061c46d39b9SJonas Devlieghere                 "char8_t summary provider", ConstString("char8_t"),
1062c46d39b9SJonas Devlieghere                 widechar_flags);
1063b9c1b51eSKate Stone   AddCXXSummary(
1064b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
1065b9c1b51eSKate Stone       "char16_t summary provider", ConstString("char16_t"), widechar_flags);
1066b9c1b51eSKate Stone   AddCXXSummary(
1067b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::Char32SummaryProvider,
1068b9c1b51eSKate Stone       "char32_t summary provider", ConstString("char32_t"), widechar_flags);
1069b9c1b51eSKate Stone   AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,
1070b9c1b51eSKate Stone                 "wchar_t summary provider", ConstString("wchar_t"),
1071b9c1b51eSKate Stone                 widechar_flags);
107233e97e63SEnrico Granata 
1073b9c1b51eSKate Stone   AddCXXSummary(
1074b9c1b51eSKate Stone       cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
1075b9c1b51eSKate Stone       "unichar summary provider", ConstString("unichar"), widechar_flags);
107633e97e63SEnrico Granata }
107733e97e63SEnrico Granata 
1078c046497bSEnrico Granata std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
107963db2395SEnrico Granata   class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
1080c046497bSEnrico Granata   public:
10811756630dSRaphael Isemann     CompilerType AdjustForInclusion(CompilerType &candidate) override {
108263db2395SEnrico Granata       LanguageType lang_type(candidate.GetMinimumLanguage());
108363db2395SEnrico Granata       if (!Language::LanguageIsC(lang_type) &&
108463db2395SEnrico Granata           !Language::LanguageIsCPlusPlus(lang_type))
108563db2395SEnrico Granata         return CompilerType();
108663db2395SEnrico Granata       if (candidate.IsTypedefType())
108763db2395SEnrico Granata         return candidate.GetTypedefedType();
108863db2395SEnrico Granata       return candidate;
1089c046497bSEnrico Granata     }
1090c046497bSEnrico Granata   };
1091c046497bSEnrico Granata 
1092c046497bSEnrico Granata   return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
1093c046497bSEnrico Granata }
1094c046497bSEnrico Granata 
1095b9c1b51eSKate Stone lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
1096c5f28e2aSKamil Rytarowski   static llvm::once_flag g_initialize;
109733e97e63SEnrico Granata   static TypeCategoryImplSP g_category;
109833e97e63SEnrico Granata 
1099c5f28e2aSKamil Rytarowski   llvm::call_once(g_initialize, [this]() -> void {
1100a3939e15SPavel Labath     DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),
1101a3939e15SPavel Labath                                                g_category);
1102b9c1b51eSKate Stone     if (g_category) {
110333e97e63SEnrico Granata       LoadLibStdcppFormatters(g_category);
11047ba2d3e8SThomas Anderson       LoadLibCxxFormatters(g_category);
110533e97e63SEnrico Granata       LoadSystemFormatters(g_category);
110633e97e63SEnrico Granata     }
110733e97e63SEnrico Granata   });
110833e97e63SEnrico Granata   return g_category;
110933e97e63SEnrico Granata }
111033e97e63SEnrico Granata 
11117cb59e1aSEnrico Granata HardcodedFormatters::HardcodedSummaryFinder
1112b9c1b51eSKate Stone CPlusPlusLanguage::GetHardcodedSummaries() {
1113c5f28e2aSKamil Rytarowski   static llvm::once_flag g_initialize;
11147cb59e1aSEnrico Granata   static ConstString g_vectortypes("VectorTypes");
11157cb59e1aSEnrico Granata   static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
11167cb59e1aSEnrico Granata 
1117c5f28e2aSKamil Rytarowski   llvm::call_once(g_initialize, []() -> void {
11187cb59e1aSEnrico Granata     g_formatters.push_back(
1119b9c1b51eSKate Stone         [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
11207cb59e1aSEnrico Granata            FormatManager &) -> TypeSummaryImpl::SharedPointer {
1121b9c1b51eSKate Stone           static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1122b9c1b51eSKate Stone               new CXXFunctionSummaryFormat(
1123b9c1b51eSKate Stone                   TypeSummaryImpl::Flags(),
1124b9c1b51eSKate Stone                   lldb_private::formatters::CXXFunctionPointerSummaryProvider,
1125b9c1b51eSKate Stone                   "Function pointer summary provider"));
1126b9c1b51eSKate Stone           if (valobj.GetCompilerType().IsFunctionPointerType()) {
11277cb59e1aSEnrico Granata             return formatter_sp;
11287cb59e1aSEnrico Granata           }
11297cb59e1aSEnrico Granata           return nullptr;
11307cb59e1aSEnrico Granata         });
11317cb59e1aSEnrico Granata     g_formatters.push_back(
1132b9c1b51eSKate Stone         [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
11337cb59e1aSEnrico Granata            FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1134b9c1b51eSKate Stone           static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1135b9c1b51eSKate Stone               new CXXFunctionSummaryFormat(
1136b9c1b51eSKate Stone                   TypeSummaryImpl::Flags()
11377cb59e1aSEnrico Granata                       .SetCascades(true)
11387cb59e1aSEnrico Granata                       .SetDontShowChildren(true)
11397cb59e1aSEnrico Granata                       .SetHideItemNames(true)
11407cb59e1aSEnrico Granata                       .SetShowMembersOneLiner(true)
11417cb59e1aSEnrico Granata                       .SetSkipPointers(true)
11427cb59e1aSEnrico Granata                       .SetSkipReferences(false),
11437cb59e1aSEnrico Granata                   lldb_private::formatters::VectorTypeSummaryProvider,
11447cb59e1aSEnrico Granata                   "vector_type pointer summary provider"));
114503310c1eSRaphael Isemann           if (valobj.GetCompilerType().IsVectorType()) {
11467cb59e1aSEnrico Granata             if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
11477cb59e1aSEnrico Granata               return formatter_sp;
11487cb59e1aSEnrico Granata           }
11497cb59e1aSEnrico Granata           return nullptr;
11507cb59e1aSEnrico Granata         });
1151c530ba98SSean Callanan     g_formatters.push_back(
1152b9c1b51eSKate Stone         [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1153c530ba98SSean Callanan            FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1154b9c1b51eSKate Stone           static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1155b9c1b51eSKate Stone               new CXXFunctionSummaryFormat(
1156b9c1b51eSKate Stone                   TypeSummaryImpl::Flags()
1157c530ba98SSean Callanan                       .SetCascades(true)
1158c530ba98SSean Callanan                       .SetDontShowChildren(true)
1159c530ba98SSean Callanan                       .SetHideItemNames(true)
1160c530ba98SSean Callanan                       .SetShowMembersOneLiner(true)
1161c530ba98SSean Callanan                       .SetSkipPointers(true)
1162c530ba98SSean Callanan                       .SetSkipReferences(false),
1163c530ba98SSean Callanan                   lldb_private::formatters::BlockPointerSummaryProvider,
1164c530ba98SSean Callanan                   "block pointer summary provider"));
116503310c1eSRaphael Isemann           if (valobj.GetCompilerType().IsBlockPointerType()) {
1166c530ba98SSean Callanan             return formatter_sp;
1167c530ba98SSean Callanan           }
1168c530ba98SSean Callanan           return nullptr;
1169c530ba98SSean Callanan         });
11707cb59e1aSEnrico Granata   });
11717cb59e1aSEnrico Granata 
11727cb59e1aSEnrico Granata   return g_formatters;
11737cb59e1aSEnrico Granata }
11747cb59e1aSEnrico Granata 
11757cb59e1aSEnrico Granata HardcodedFormatters::HardcodedSyntheticFinder
1176b9c1b51eSKate Stone CPlusPlusLanguage::GetHardcodedSynthetics() {
1177c5f28e2aSKamil Rytarowski   static llvm::once_flag g_initialize;
11787cb59e1aSEnrico Granata   static ConstString g_vectortypes("VectorTypes");
11797cb59e1aSEnrico Granata   static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
11807cb59e1aSEnrico Granata 
1181c5f28e2aSKamil Rytarowski   llvm::call_once(g_initialize, []() -> void {
1182b9c1b51eSKate Stone     g_formatters.push_back([](lldb_private::ValueObject &valobj,
118346fb5d5dSRaphael Isemann                               lldb::DynamicValueType, FormatManager &fmt_mgr)
118446fb5d5dSRaphael Isemann                                -> SyntheticChildren::SharedPointer {
1185b9c1b51eSKate Stone       static CXXSyntheticChildren::SharedPointer formatter_sp(
1186b9c1b51eSKate Stone           new CXXSyntheticChildren(
1187b9c1b51eSKate Stone               SyntheticChildren::Flags()
1188b9c1b51eSKate Stone                   .SetCascades(true)
1189b9c1b51eSKate Stone                   .SetSkipPointers(true)
1190b9c1b51eSKate Stone                   .SetSkipReferences(true)
1191b9c1b51eSKate Stone                   .SetNonCacheable(true),
11927cb59e1aSEnrico Granata               "vector_type synthetic children",
11937cb59e1aSEnrico Granata               lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
119403310c1eSRaphael Isemann       if (valobj.GetCompilerType().IsVectorType()) {
11957cb59e1aSEnrico Granata         if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
11967cb59e1aSEnrico Granata           return formatter_sp;
11977cb59e1aSEnrico Granata       }
11987cb59e1aSEnrico Granata       return nullptr;
11997cb59e1aSEnrico Granata     });
1200b9c1b51eSKate Stone     g_formatters.push_back([](lldb_private::ValueObject &valobj,
120146fb5d5dSRaphael Isemann                               lldb::DynamicValueType, FormatManager &fmt_mgr)
120246fb5d5dSRaphael Isemann                                -> SyntheticChildren::SharedPointer {
1203b9c1b51eSKate Stone       static CXXSyntheticChildren::SharedPointer formatter_sp(
1204b9c1b51eSKate Stone           new CXXSyntheticChildren(
1205b9c1b51eSKate Stone               SyntheticChildren::Flags()
1206b9c1b51eSKate Stone                   .SetCascades(true)
1207b9c1b51eSKate Stone                   .SetSkipPointers(true)
1208b9c1b51eSKate Stone                   .SetSkipReferences(true)
1209b9c1b51eSKate Stone                   .SetNonCacheable(true),
1210c530ba98SSean Callanan               "block pointer synthetic children",
1211c530ba98SSean Callanan               lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
121203310c1eSRaphael Isemann       if (valobj.GetCompilerType().IsBlockPointerType()) {
1213c530ba98SSean Callanan         return formatter_sp;
1214c530ba98SSean Callanan       }
1215c530ba98SSean Callanan       return nullptr;
1216c530ba98SSean Callanan     });
12177cb59e1aSEnrico Granata   });
12187cb59e1aSEnrico Granata 
12197cb59e1aSEnrico Granata   return g_formatters;
12207cb59e1aSEnrico Granata }
1221566afa0aSRaphael Isemann 
1222406ad187SJonas Devlieghere bool CPlusPlusLanguage::IsNilReference(ValueObject &valobj) {
1223406ad187SJonas Devlieghere   if (!Language::LanguageIsCPlusPlus(valobj.GetObjectRuntimeLanguage()) ||
1224406ad187SJonas Devlieghere       !valobj.IsPointerType())
1225406ad187SJonas Devlieghere     return false;
1226406ad187SJonas Devlieghere   bool canReadValue = true;
1227406ad187SJonas Devlieghere   bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
1228406ad187SJonas Devlieghere   return canReadValue && isZero;
1229406ad187SJonas Devlieghere }
1230406ad187SJonas Devlieghere 
1231566afa0aSRaphael Isemann bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
1232566afa0aSRaphael Isemann   const auto suffixes = {".cpp", ".cxx", ".c++", ".cc",  ".c",
1233566afa0aSRaphael Isemann                          ".h",   ".hh",  ".hpp", ".hxx", ".h++"};
1234566afa0aSRaphael Isemann   for (auto suffix : suffixes) {
1235e50f9c41SMartin Storsjö     if (file_path.endswith_insensitive(suffix))
1236566afa0aSRaphael Isemann       return true;
1237566afa0aSRaphael Isemann   }
1238566afa0aSRaphael Isemann 
1239566afa0aSRaphael Isemann   // Check if we're in a STL path (where the files usually have no extension
1240566afa0aSRaphael Isemann   // that we could check for.
1241566afa0aSRaphael Isemann   return file_path.contains("/usr/include/c++/");
1242566afa0aSRaphael Isemann }
1243