• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
RichManglingContext()27   RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) {
28     m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size));
29     m_ipd_buf[0] = '\0';
30   }
31 
~RichManglingContext()32   ~RichManglingContext() { std::free(m_ipd_buf); }
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   /// If this symbol describes a function.
46   bool IsFunction() const;
47 
48   /// Get the base name of a function. This doesn't include trailing template
49   /// arguments, ie "a::b<int>" gives "b". The result will overwrite the
50   /// internal buffer. It can be obtained via GetBufferRef().
51   void ParseFunctionBaseName();
52 
53   /// Get the context name for a function. For "a::b::c", this function returns
54   /// "a::b". The result will overwrite the internal buffer. It can be obtained
55   /// via GetBufferRef().
56   void ParseFunctionDeclContextName();
57 
58   /// Get the entire demangled name. The result will overwrite the internal
59   /// buffer. It can be obtained via GetBufferRef().
60   void ParseFullName();
61 
62   /// Obtain a StringRef to the internal buffer that holds the result of the
63   /// most recent ParseXy() operation. The next ParseXy() call invalidates it.
GetBufferRef()64   llvm::StringRef GetBufferRef() const {
65     assert(m_provider != None && "Initialize a provider first");
66     return m_buffer;
67   }
68 
69 private:
70   enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage };
71 
72   /// Selects the rich mangling info provider.
73   InfoProvider m_provider;
74 
75   /// Reference to the buffer used for results of ParseXy() operations.
76   llvm::StringRef m_buffer;
77 
78   /// Members for ItaniumPartialDemangler
79   llvm::ItaniumPartialDemangler m_ipd;
80   char *m_ipd_buf;
81   size_t m_ipd_buf_size;
82 
83   /// Members for PluginCxxLanguage
84   /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
85   /// respective header is in Plugins and including it from here causes cyclic
86   /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp.
87   llvm::Any m_cxx_method_parser;
88 
89   /// Clean up memory and set a new info provider for this instance.
90   void ResetProvider(InfoProvider new_provider);
91 
92   /// Uniform handling of string buffers for ItaniumPartialDemangler.
93   void processIPDStrResult(char *ipd_res, size_t res_len);
94 
95   /// Cast the given parser to the given type. Ideally we would have a type
96   /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
97   /// can't access CPlusPlusLanguage::MethodName from within the header.
get(llvm::Any parser)98   template <class ParserT> static ParserT *get(llvm::Any parser) {
99     assert(parser.hasValue());
100     assert(llvm::any_isa<ParserT *>(parser));
101     return llvm::any_cast<ParserT *>(parser);
102   }
103 };
104 
105 } // namespace lldb_private
106 
107 #endif
108