Index: include/lldb/Core/Mangled.h =================================================================== --- include/lldb/Core/Mangled.h +++ include/lldb/Core/Mangled.h @@ -49,7 +49,8 @@ enum ManglingScheme { eManglingSchemeNone = 0, eManglingSchemeMSVC, - eManglingSchemeItanium + eManglingSchemeItanium, + eManglingSchemeD }; //---------------------------------------------------------------------- Index: source/Core/CMakeLists.txt =================================================================== --- source/Core/CMakeLists.txt +++ source/Core/CMakeLists.txt @@ -69,6 +69,7 @@ lldbPluginProcessUtility lldbPluginCPlusPlusLanguage lldbPluginObjCLanguage + lldbPluginDLanguage lldbPluginObjectFileJIT ${LLDB_CURSES_LIBS} Index: source/Core/Mangled.cpp =================================================================== --- source/Core/Mangled.cpp +++ source/Core/Mangled.cpp @@ -36,6 +36,7 @@ #include "lldb/lldb-enumerations.h" // for LanguageType #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/D/DLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "llvm/ADT/StringRef.h" // for StringRef @@ -74,6 +75,8 @@ return Mangled::eManglingSchemeMSVC; if (s[0] == '_' && s[1] == 'Z') return Mangled::eManglingSchemeItanium; + if (DLanguage::IsDMangledName(s)) + return Mangled::eManglingSchemeD; } return Mangled::eManglingSchemeNone; } @@ -322,6 +325,10 @@ } break; } + case eManglingSchemeD: { + demangled_name = DLanguage::demangle(m_mangled); + break; + } case eManglingSchemeNone: break; } @@ -431,6 +438,8 @@ return lldb::eLanguageTypeC_plus_plus; else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name)) return lldb::eLanguageTypeObjC; + else if (DLanguage::IsDMangledName(mangled_name)) + return lldb::eLanguageTypeD; } } else { // ObjC names aren't really mangled, so they won't necessarily be in the Index: source/Plugins/Language/CMakeLists.txt =================================================================== --- source/Plugins/Language/CMakeLists.txt +++ source/Plugins/Language/CMakeLists.txt @@ -4,3 +4,4 @@ add_subdirectory(ObjC) add_subdirectory(ObjCPlusPlus) add_subdirectory(OCaml) +add_subdirectory(D) Index: source/Plugins/Language/D/CMakeLists.txt =================================================================== --- /dev/null +++ source/Plugins/Language/D/CMakeLists.txt @@ -0,0 +1,7 @@ +add_lldb_library(lldbPluginDLanguage PLUGIN + DLanguage.cpp + + LINK_LIBS + lldbCore + lldbTarget +) Index: source/Plugins/Language/D/DLanguage.h =================================================================== --- /dev/null +++ source/Plugins/Language/D/DLanguage.h @@ -0,0 +1,57 @@ +//===-- DLanguage.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_DLanguage_h_ +#define liblldb_DLanguage_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/Language.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class DLanguage : public Language { +public: + DLanguage() = default; + + ~DLanguage() override = default; + + lldb::LanguageType GetLanguageType() const override { + return lldb::eLanguageTypeD; + } + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + + static void Terminate(); + + static lldb_private::Language *CreateInstance(lldb::LanguageType language); + + static lldb_private::ConstString GetPluginNameStatic(); + + static bool IsDMangledName(const char *name); + // Consider using non-static methods + static char *demangle(const ConstString &mangled); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; +}; + +} // namespace lldb_private + +#endif // liblldb_DLanguage_h_ Index: source/Plugins/Language/D/DLanguage.cpp =================================================================== --- /dev/null +++ source/Plugins/Language/D/DLanguage.cpp @@ -0,0 +1,99 @@ +//===-- DLanguage.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DLanguage.h" + +#include "lldb/Core/PluginManager.h" +#include "lldb/Utility/ConstString.h" +#include "llvm/Support/DynamicLibrary.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +using llvm::sys::DynamicLibrary; + +template +Fun *getTypedSymbol(DynamicLibrary &lib, const char *symbol) { + return reinterpret_cast(lib.getAddressOfSymbol(symbol)); +} + +// D Plugin will define these symbols. They're declared to use with decltype. +extern "C" { +char *lldbd_demangle(size_t length, const char *mangled); +void d_initialize(); +} + +void DLanguage::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), "D Language", + CreateInstance); +} + +void DLanguage::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } + +lldb_private::ConstString DLanguage::GetPluginNameStatic() { + static ConstString g_name("D"); + return g_name; +} + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ +lldb_private::ConstString DLanguage::GetPluginName() { + return GetPluginNameStatic(); +} + +uint32_t DLanguage::GetPluginVersion() { return 1; } + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ +Language *DLanguage::CreateInstance(lldb::LanguageType language) { + switch (language) { + case lldb::eLanguageTypeD: + return new DLanguage(); + default: + return nullptr; + } +} + +char *DLanguage::demangle(const ConstString &mangled) { + auto len = mangled.GetLength(); + auto s = mangled.GetCString(); + static auto fun = []() -> decltype(lldbd_demangle) * { + // TODO: so vs dylib + auto file = "liblldbdplugin.dylib"; + std::string errMsg; + auto lib2 = DynamicLibrary::getPermanentLibrary(file, &errMsg); + + if (!lib2.isValid()) { + // Not dumping `errMsg` because would result in noise if user did not + // intend to call dlopen. + return nullptr; + } + + auto fun0 = getTypedSymbol(lib2, "d_initialize"); + assert(fun0); + (*fun0)(); + + auto fun = getTypedSymbol(lib2, "lldbd_demangle"); + assert(fun); + return fun; + }(); + if (!fun) + return nullptr; + return (*fun)(len, s); +} + +bool DLanguage::IsDMangledName(const char *name) { + if (name == nullptr) + return false; + return (name[0] != '\0' && name[0] == '_' && name[1] == 'D'); +}