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 /// 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. 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 = None; 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 /// Note: m_ipd_buf is a raw pointer due to being resized by realloc via 81 /// ItaniumPartialDemangler. It should be managed with malloc/free, not 82 /// new/delete. 83 char *m_ipd_buf; 84 size_t m_ipd_buf_size = 2048; 85 86 /// Members for PluginCxxLanguage 87 /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The 88 /// respective header is in Plugins and including it from here causes cyclic 89 /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp. 90 llvm::Any m_cxx_method_parser; 91 92 /// Clean up memory when using PluginCxxLanguage 93 void ResetCxxMethodParser(); 94 95 /// Clean up memory and set a new info provider for this instance. 96 void ResetProvider(InfoProvider new_provider); 97 98 /// Uniform handling of string buffers for ItaniumPartialDemangler. 99 void processIPDStrResult(char *ipd_res, size_t res_len); 100 101 /// Cast the given parser to the given type. Ideally we would have a type 102 /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we 103 /// can't access CPlusPlusLanguage::MethodName from within the header. 104 template <class ParserT> static ParserT *get(llvm::Any parser) { 105 assert(parser.hasValue()); 106 assert(llvm::any_isa<ParserT *>(parser)); 107 return llvm::any_cast<ParserT *>(parser); 108 } 109 }; 110 111 } // namespace lldb_private 112 113 #endif 114