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 @@ -37,6 +37,7 @@ #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "Plugins/Language/D/DLanguage.h" #include "llvm/ADT/StringRef.h" // for StringRef #include "llvm/Support/Compiler.h" // for LLVM_PRETT... @@ -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,123 @@ +//===-- DLanguage.cpp +// +// 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; + +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 of `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'); +}