Index: include/lldb/Core/RichManglingInfo.h =================================================================== --- /dev/null +++ include/lldb/Core/RichManglingInfo.h @@ -0,0 +1,101 @@ +//===-- RichManglingInfo.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RichManglingInfo_h_ +#define liblldb_RichManglingInfo_h_ + +#include "lldb/lldb-private.h" +#include "llvm/Demangle/Demangle.h" + +namespace lldb_private { + +/// Uniform wrapper for access to rich mangling information from different +/// providers. See Mangled::DemangleWithRichManglingInfo() +class RichManglingInfo { +public: + /// If this symbol describes a constructor or destructor. + bool isCtorOrDtor() const; + + /// If this symbol describes a function. + bool isFunction() const; + + /// Get the base name of a function. This doesn't include trailing template + /// arguments, ie for "a::b" this function returns "b". + const char *getFunctionBaseName() const; + + /// Get the context name for a function. For "a::b::c", this function returns + /// "a::b". + const char *getFunctionDeclContextName() const; + +private: + enum InfoProvider { ItaniumPartialDemangler, PluginCxxLanguage }; + + /// Selects the rich mangling info provider. Initially undefined, but + /// initialized in RichManglingSpec::CreateX (instance not accessible before). + InfoProvider m_provider; + + /// Members for ItaniumPartialDemangler + llvm::ItaniumPartialDemangler *m_IPD = nullptr; + mutable size_t m_IPD_size = 0; + mutable char *m_IPD_buf = nullptr; + + /// Members for PluginCxxLanguage + /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The + /// respective header is in Plugins and including it from here causes cyclic + /// dependency. Keep a void* here instead and cast it on-demand on the cpp. + void *m_legacy_parser = nullptr; + + /// Obtain the legacy parser casted to the given type. Ideally we had a type + /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we + /// can't access CPlusPlusLanguage::MethodName from within the header. + template ParserT *get() const { + assert(m_legacy_parser); + return reinterpret_cast(m_legacy_parser); + } + + /// Reset the provider and clean up memory before reassigning/destroying. + void ResetProvider(); + + // Default construction in undefined state from RichManglingSpec. + RichManglingInfo() = default; + + // Destruction from RichManglingSpec. + ~RichManglingInfo(); + + // No copy + RichManglingInfo(const RichManglingInfo &) = delete; + RichManglingInfo &operator=(const RichManglingInfo &) = delete; + + // No move + RichManglingInfo(RichManglingInfo &&) = delete; + RichManglingInfo &operator=(RichManglingInfo &&) = delete; + + // Declare RichManglingSpec as friend so it can access the default ctor and + // assign to members in its CreateX methods. + friend class RichManglingSpec; +}; + +//---------------------------------------------------------------------- + +/// Unique owner of RichManglingInfo. Handles configuration and lifetime. +class RichManglingSpec { +public: + RichManglingInfo *CreateItaniumInfo(); + RichManglingInfo *CreateLegacyCxxParserInfo(const ConstString &mangled); + + llvm::ItaniumPartialDemangler &GetIPD() { return m_IPD; } + +private: + RichManglingInfo m_info; + llvm::ItaniumPartialDemangler m_IPD; +}; + +} // namespace lldb_private + +#endif Index: include/lldb/Symbol/Symtab.h =================================================================== --- include/lldb/Symbol/Symtab.h +++ include/lldb/Symbol/Symtab.h @@ -17,93 +17,9 @@ #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/Symbol.h" #include "lldb/lldb-private.h" -#include "llvm/Demangle/Demangle.h" namespace lldb_private { -/// Uniform wrapper for access to rich mangling information from different -/// providers. See Mangled::DemangleWithRichManglingInfo() -class RichManglingInfo { -public: - /// If this symbol describes a constructor or destructor. - bool isCtorOrDtor() const; - - /// If this symbol describes a function. - bool isFunction() const; - - /// Get the base name of a function. This doesn't include trailing template - /// arguments, ie for "a::b" this function returns "b". - const char *getFunctionBaseName() const; - - /// Get the context name for a function. For "a::b::c", this function returns - /// "a::b". - const char *getFunctionDeclContextName() const; - -private: - enum InfoProvider { ItaniumPartialDemangler, PluginCxxLanguage }; - - /// Selects the rich mangling info provider. Initially undefined, but - /// initialized in RichManglingSpec::CreateX (instance not accessible before). - InfoProvider m_provider; - - /// Members for ItaniumPartialDemangler - llvm::ItaniumPartialDemangler *m_IPD = nullptr; - mutable size_t m_IPD_size = 0; - mutable char *m_IPD_buf = nullptr; - - /// Members for PluginCxxLanguage - /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The - /// respective header is in Plugins and including it from here causes cyclic - /// dependency. Keep a void* here instead and cast it on-demand on the cpp. - void *m_legacy_parser = nullptr; - - /// Obtain the legacy parser casted to the given type. Ideally we had a type - /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we - /// can't access CPlusPlusLanguage::MethodName from within the header. - template ParserT *get() const { - assert(m_legacy_parser); - return reinterpret_cast(m_legacy_parser); - } - - /// Reset the provider and clean up memory before reassigning/destroying. - void ResetProvider(); - - // Default construction in undefined state from RichManglingSpec. - RichManglingInfo() = default; - - // Destruction from RichManglingSpec. - ~RichManglingInfo(); - - // No copy - RichManglingInfo(const RichManglingInfo &) = delete; - RichManglingInfo &operator=(const RichManglingInfo &) = delete; - - // No move - RichManglingInfo(RichManglingInfo &&) = delete; - RichManglingInfo &operator=(RichManglingInfo &&) = delete; - - // Declare RichManglingSpec as friend so it can access the default ctor and - // assign to members in its CreateX methods. - friend class RichManglingSpec; -}; - -//---------------------------------------------------------------------- - -/// Unique owner of RichManglingInfo. Handles initialization and lifetime. -class RichManglingSpec { -public: - RichManglingInfo *CreateItaniumInfo(); - RichManglingInfo *CreateLegacyCxxParserInfo(const ConstString &mangled); - - llvm::ItaniumPartialDemangler &GetIPD() { return m_IPD; } - -private: - RichManglingInfo m_info; - llvm::ItaniumPartialDemangler m_IPD; -}; - -//---------------------------------------------------------------------- - class Symtab { public: typedef std::vector IndexCollection; Index: source/Core/CMakeLists.txt =================================================================== --- source/Core/CMakeLists.txt +++ source/Core/CMakeLists.txt @@ -34,6 +34,7 @@ Opcode.cpp PluginManager.cpp RegisterValue.cpp + RichManglingInfo.cpp Scalar.cpp SearchFilter.cpp Section.cpp Index: source/Core/Mangled.cpp =================================================================== --- source/Core/Mangled.cpp +++ source/Core/Mangled.cpp @@ -16,6 +16,7 @@ #pragma comment(lib, "dbghelp.lib") #endif +#include "lldb/Core/RichManglingInfo.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" Index: source/Core/RichManglingInfo.cpp =================================================================== --- /dev/null +++ source/Core/RichManglingInfo.cpp @@ -0,0 +1,87 @@ +//===-- RichManglingInfo.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/RichManglingInfo.h" +#include "lldb/Utility/ConstString.h" + +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" + +using namespace lldb; +using namespace lldb_private; + +void RichManglingInfo::ResetProvider() { + // If we want to support parsers for other languages some day, we need a + // switch here to delete the correct parser type. + if (m_legacy_parser) { + assert(m_provider == RichManglingInfo::PluginCxxLanguage); + delete get(); + m_legacy_parser = nullptr; + } +} + +RichManglingInfo *RichManglingSpec::CreateItaniumInfo() { + m_info.ResetProvider(); + m_info.m_provider = RichManglingInfo::ItaniumPartialDemangler; + m_info.m_IPD = &m_IPD; + return &m_info; +} + +RichManglingInfo * +RichManglingSpec::CreateLegacyCxxParserInfo(const ConstString &mangled) { + m_info.ResetProvider(); + m_info.m_provider = RichManglingInfo::PluginCxxLanguage; + m_info.m_legacy_parser = new CPlusPlusLanguage::MethodName(mangled); + return &m_info; +} + +RichManglingInfo::~RichManglingInfo() { + ResetProvider(); + delete m_IPD_buf; +} + +bool RichManglingInfo::isCtorOrDtor() const { + switch (m_provider) { + case ItaniumPartialDemangler: + return m_IPD->isCtorOrDtor(); + case PluginCxxLanguage: { + // We can only check for destructors here. + auto base_name = get()->GetBasename(); + return base_name.front() == '~'; + } + } +} + +bool RichManglingInfo::isFunction() const { + switch (m_provider) { + case ItaniumPartialDemangler: + return m_IPD->isFunction(); + case PluginCxxLanguage: + return get()->IsValid(); + } +} + +const char *RichManglingInfo::getFunctionBaseName() const { + switch (m_provider) { + case ItaniumPartialDemangler: + m_IPD_buf = m_IPD->getFunctionBaseName(m_IPD_buf, &m_IPD_size); + return m_IPD_buf; + case PluginCxxLanguage: + return get()->GetBasename().data(); + } +} + +const char *RichManglingInfo::getFunctionDeclContextName() const { + switch (m_provider) { + case ItaniumPartialDemangler: + m_IPD_buf = m_IPD->getFunctionDeclContextName(m_IPD_buf, &m_IPD_size); + return m_IPD_buf; + case PluginCxxLanguage: + return get()->GetContext().data(); + } +} Index: source/Symbol/Symtab.cpp =================================================================== --- source/Symbol/Symtab.cpp +++ source/Symbol/Symtab.cpp @@ -10,9 +10,10 @@ #include #include -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" + #include "lldb/Core/Module.h" +#include "lldb/Core/RichManglingInfo.h" #include "lldb/Core/STLUtils.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" @@ -22,7 +23,6 @@ #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" -#include "llvm/Demangle/Demangle.h" using namespace lldb; using namespace lldb_private; @@ -213,81 +213,6 @@ return nullptr; } -//---------------------------------------------------------------------- -// RichManglingInfo -//---------------------------------------------------------------------- - -void RichManglingInfo::ResetProvider() { - // If we want to support parsers for other languages some day, we need a - // switch here to delete the correct parser type. - if (m_legacy_parser) { - assert(m_provider == RichManglingInfo::PluginCxxLanguage); - delete get(); - m_legacy_parser = nullptr; - } -} - -RichManglingInfo *RichManglingSpec::CreateItaniumInfo() { - m_info.ResetProvider(); - m_info.m_provider = RichManglingInfo::ItaniumPartialDemangler; - m_info.m_IPD = &m_IPD; - return &m_info; -} - -RichManglingInfo * -RichManglingSpec::CreateLegacyCxxParserInfo(const ConstString &mangled) { - m_info.ResetProvider(); - m_info.m_provider = RichManglingInfo::PluginCxxLanguage; - m_info.m_legacy_parser = new CPlusPlusLanguage::MethodName(mangled); - return &m_info; -} - -RichManglingInfo::~RichManglingInfo() { - ResetProvider(); - delete m_IPD_buf; -} - -bool RichManglingInfo::isCtorOrDtor() const { - switch (m_provider) { - case ItaniumPartialDemangler: - return m_IPD->isCtorOrDtor(); - case PluginCxxLanguage: { - // We can only check for destructors here. - auto base_name = get()->GetBasename(); - return base_name.front() == '~'; - } - } -} - -bool RichManglingInfo::isFunction() const { - switch (m_provider) { - case ItaniumPartialDemangler: - return m_IPD->isFunction(); - case PluginCxxLanguage: - return get()->IsValid(); - } -} - -const char *RichManglingInfo::getFunctionBaseName() const { - switch (m_provider) { - case ItaniumPartialDemangler: - m_IPD_buf = m_IPD->getFunctionBaseName(m_IPD_buf, &m_IPD_size); - return m_IPD_buf; - case PluginCxxLanguage: - return get()->GetBasename().data(); - } -} - -const char *RichManglingInfo::getFunctionDeclContextName() const { - switch (m_provider) { - case ItaniumPartialDemangler: - m_IPD_buf = m_IPD->getFunctionDeclContextName(m_IPD_buf, &m_IPD_size); - return m_IPD_buf; - case PluginCxxLanguage: - return get()->GetContext().data(); - } -} - //---------------------------------------------------------------------- // InitNameIndexes //----------------------------------------------------------------------