1 //===-- RichManglingContext.h -----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_RichManglingContext_h_ 11 #define liblldb_RichManglingContext_h_ 12 13 #include "lldb/lldb-forward.h" 14 #include "lldb/lldb-private.h" 15 16 #include "lldb/Utility/ConstString.h" 17 18 #include "llvm/ADT/Any.h" 19 #include "llvm/ADT/SmallString.h" 20 #include "llvm/Demangle/Demangle.h" 21 22 namespace lldb_private { 23 24 /// Uniform wrapper for access to rich mangling information from different 25 /// providers. See Mangled::DemangleWithRichManglingInfo() 26 class RichManglingContext { 27 public: RichManglingContext()28 RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) { 29 m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size)); 30 m_ipd_buf[0] = '\0'; 31 } 32 ~RichManglingContext()33 ~RichManglingContext() { std::free(m_ipd_buf); } 34 35 /// Use the ItaniumPartialDemangler to obtain rich mangling information from 36 /// the given mangled name. 37 bool FromItaniumName(const ConstString &mangled); 38 39 /// Use the legacy language parser implementation to obtain rich mangling 40 /// information from the given demangled name. 41 bool FromCxxMethodName(const ConstString &demangled); 42 43 /// If this symbol describes a constructor or destructor. 44 bool IsCtorOrDtor() const; 45 46 /// If this symbol describes a function. 47 bool IsFunction() const; 48 49 /// Get the base name of a function. This doesn't include trailing template 50 /// arguments, ie "a::b<int>" gives "b". The result will overwrite the 51 /// internal buffer. It can be obtained via GetBufferRef(). 52 void ParseFunctionBaseName(); 53 54 /// Get the context name for a function. For "a::b::c", this function returns 55 /// "a::b". The result will overwrite the internal buffer. It can be obtained 56 /// via GetBufferRef(). 57 void ParseFunctionDeclContextName(); 58 59 /// Get the entire demangled name. The result will overwrite the internal 60 /// buffer. It can be obtained via GetBufferRef(). 61 void ParseFullName(); 62 63 /// Obtain a StringRef to the internal buffer that holds the result of the 64 /// most recent ParseXy() operation. The next ParseXy() call invalidates it. GetBufferRef()65 llvm::StringRef GetBufferRef() const { 66 assert(m_provider != None && "Initialize a provider first"); 67 return m_buffer; 68 } 69 70 private: 71 enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage }; 72 73 /// Selects the rich mangling info provider. 74 InfoProvider m_provider; 75 76 /// Reference to the buffer used for results of ParseXy() operations. 77 llvm::StringRef m_buffer; 78 79 /// Members for ItaniumPartialDemangler 80 llvm::ItaniumPartialDemangler m_ipd; 81 char *m_ipd_buf; 82 size_t m_ipd_buf_size; 83 84 /// Members for PluginCxxLanguage 85 /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The 86 /// respective header is in Plugins and including it from here causes cyclic 87 /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp. 88 llvm::Any m_cxx_method_parser; 89 90 /// Clean up memory and set a new info provider for this instance. 91 void ResetProvider(InfoProvider new_provider); 92 93 /// Uniform handling of string buffers for ItaniumPartialDemangler. 94 void processIPDStrResult(char *ipd_res, size_t res_len); 95 96 /// Cast the given parser to the given type. Ideally we would have a type 97 /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we 98 /// can't access CPlusPlusLanguage::MethodName from within the header. get(llvm::Any parser)99 template <class ParserT> static ParserT *get(llvm::Any parser) { 100 assert(parser.hasValue()); 101 assert(llvm::any_isa<ParserT *>(parser)); 102 return llvm::any_cast<ParserT *>(parser); 103 } 104 }; 105 106 } // namespace lldb_private 107 108 #endif 109