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); + // TODO: not static? + 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,119 @@ +//===-- 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 + +using namespace lldb; +using namespace lldb_private; + +// 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(); +} + +// TODO:MOVE +struct SharedLib { + void *handle; + const char *libraryFile; + int flagDefault = RTLD_LOCAL | RTLD_LAZY; + SharedLib() {} + + ~SharedLib() { release(); } + + // Return true if `dlopen` succeeded + bool open(const char *libraryFile, int flag) { + release(); + this->libraryFile = libraryFile; + handle = dlopen(libraryFile, flag); + if (handle) + return true; + return false; + } + + void release() { + // if(handle) seems needed: + // https://stackoverflow.com/questions/11412943is-it-safe-to-call-dlclosenull + if (handle) + dlclose(handle); + } + + template Fun *getFun(const char *symbol) { + assert(handle); + return reinterpret_cast(dlsym(handle, symbol)); + } +}; + +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(); + // IMPROVE + static auto fun = []() -> decltype(lldbd_demangle) * { + auto lib2 = new SharedLib(); + // TODO: so vs dylib + auto file = "liblldbdplugin.dylib"; + if (!lib2->open(file, lib2->flagDefault)) { + return nullptr; + } + + auto fun0 = lib2->getFun("d_initialize"); + (*fun0)(); + + auto fun = lib2->getFun("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'); +}