1 //===-- RichManglingContext.h -----------------------------------*- C++ -*-===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_CORE_RICHMANGLINGCONTEXT_H
10 #define LLDB_CORE_RICHMANGLINGCONTEXT_H
11 
12 #include "lldb/lldb-forward.h"
13 #include "lldb/lldb-private.h"
14 
15 #include "lldb/Utility/ConstString.h"
16 
17 #include "llvm/ADT/Any.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/Demangle/Demangle.h"
20 
21 namespace lldb_private {
22 
23 /// Uniform wrapper for access to rich mangling information from different
24 /// providers. See Mangled::DemangleWithRichManglingInfo()
25 class RichManglingContext {
26 public:
27   RichManglingContext() {
28     m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size));
29     m_ipd_buf[0] = '\0';
30   }
31 
32   ~RichManglingContext();
33 
34   /// Use the ItaniumPartialDemangler to obtain rich mangling information from
35   /// the given mangled name.
36   bool FromItaniumName(ConstString mangled);
37 
38   /// Use the legacy language parser implementation to obtain rich mangling
39   /// information from the given demangled name.
40   bool FromCxxMethodName(ConstString demangled);
41 
42   /// If this symbol describes a constructor or destructor.
43   bool IsCtorOrDtor() const;
44 
45   /// Get the base name of a function. This doesn't include trailing template
46   /// arguments, ie "a::b<int>" gives "b".
47   llvm::StringRef ParseFunctionBaseName();
48 
49   /// Get the context name for a function. For "a::b::c", this function returns
50   /// "a::b".
51   llvm::StringRef ParseFunctionDeclContextName();
52 
53   /// Get the entire demangled name.
54   llvm::StringRef ParseFullName();
55 
56 private:
57   enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage };
58 
59   /// Selects the rich mangling info provider.
60   InfoProvider m_provider = None;
61 
62   /// Members for ItaniumPartialDemangler
63   llvm::ItaniumPartialDemangler m_ipd;
64   /// Note: m_ipd_buf is a raw pointer due to being resized by realloc via
65   /// ItaniumPartialDemangler. It should be managed with malloc/free, not
66   /// new/delete.
67   char *m_ipd_buf;
68   size_t m_ipd_buf_size = 2048;
69 
70   /// Members for PluginCxxLanguage
71   /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
72   /// respective header is in Plugins and including it from here causes cyclic
73   /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp.
74   llvm::Any m_cxx_method_parser;
75 
76   /// Clean up memory when using PluginCxxLanguage
77   void ResetCxxMethodParser();
78 
79   /// Clean up memory and set a new info provider for this instance.
80   void ResetProvider(InfoProvider new_provider);
81 
82   /// Uniform handling of string buffers for ItaniumPartialDemangler.
83   llvm::StringRef processIPDStrResult(char *ipd_res, size_t res_len);
84 
85   /// Cast the given parser to the given type. Ideally we would have a type
86   /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
87   /// can't access CPlusPlusLanguage::MethodName from within the header.
88   template <class ParserT> static ParserT *get(llvm::Any parser) {
89     assert(parser.hasValue());
90     assert(llvm::any_isa<ParserT *>(parser));
91     return llvm::any_cast<ParserT *>(parser);
92   }
93 };
94 
95 } // namespace lldb_private
96 
97 #endif
98