[llvm] 22a1aa5 - [Demangle] Add minimal support for D programming language
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 9 09:29:21 PST 2021
Author: Luís Ferreira
Date: 2021-11-09T09:29:13-08:00
New Revision: 22a1aa5a43cbdaf9dde014ba1f120e0f7ca1788b
URL: https://github.com/llvm/llvm-project/commit/22a1aa5a43cbdaf9dde014ba1f120e0f7ca1788b
DIFF: https://github.com/llvm/llvm-project/commit/22a1aa5a43cbdaf9dde014ba1f120e0f7ca1788b.diff
LOG: [Demangle] Add minimal support for D programming language
This patch adds minimal support for D programming language demangling on LLVM
core based on the D name mangling spec. This will allow easier integration on a
future LLDB plugin for D either in the upstream tree or outside of it.
Minimal support includes recognizing D demangling encoding and at least one
mangling name, which in this case is `_Dmain` mangle.
Reviewed By: jhenderson, lattner
Differential Revision: https://reviews.llvm.org/D111414
Added:
llvm/lib/Demangle/DLangDemangle.cpp
llvm/test/Demangle/dlang.test
llvm/unittests/Demangle/DLangDemangleTest.cpp
Modified:
llvm/include/llvm/Demangle/Demangle.h
llvm/lib/Demangle/CMakeLists.txt
llvm/lib/Demangle/Demangle.cpp
llvm/unittests/Demangle/CMakeLists.txt
llvm/unittests/Demangle/DemangleTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h
index 521795f7a1f81..3150e049320bf 100644
--- a/llvm/include/llvm/Demangle/Demangle.h
+++ b/llvm/include/llvm/Demangle/Demangle.h
@@ -60,6 +60,9 @@ char *microsoftDemangle(const char *mangled_name, size_t *n_read, char *buf,
// Demangles a Rust v0 mangled symbol. The API follows that of __cxa_demangle.
char *rustDemangle(const char *MangledName, char *Buf, size_t *N, int *Status);
+// Demangles a D mangled symbol.
+char *dlangDemangle(const char *MangledName);
+
/// Attempt to demangle a string using
diff erent demangling schemes.
/// The function uses heuristics to determine which demangling scheme to use.
/// \param MangledName - reference to string to demangle.
diff --git a/llvm/lib/Demangle/CMakeLists.txt b/llvm/lib/Demangle/CMakeLists.txt
index 86e2d49dddf2b..eb7d212a02449 100644
--- a/llvm/lib/Demangle/CMakeLists.txt
+++ b/llvm/lib/Demangle/CMakeLists.txt
@@ -4,6 +4,7 @@ add_llvm_component_library(LLVMDemangle
MicrosoftDemangle.cpp
MicrosoftDemangleNodes.cpp
RustDemangle.cpp
+ DLangDemangle.cpp
ADDITIONAL_HEADER_DIRS
"${LLVM_MAIN_INCLUDE_DIR}/llvm/Demangle"
diff --git a/llvm/lib/Demangle/DLangDemangle.cpp b/llvm/lib/Demangle/DLangDemangle.cpp
new file mode 100644
index 0000000000000..d6e8fe97982be
--- /dev/null
+++ b/llvm/lib/Demangle/DLangDemangle.cpp
@@ -0,0 +1,44 @@
+//===--- DLangDemangle.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines a demangler for the D programming language as specified
+/// in the ABI specification, available at:
+/// https://dlang.org/spec/abi.html#name_mangling
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Demangle/Demangle.h"
+#include "llvm/Demangle/Utility.h"
+
+#include <cstring>
+
+using namespace llvm;
+using llvm::itanium_demangle::OutputBuffer;
+
+char *llvm::dlangDemangle(const char *MangledName) {
+ if (MangledName == nullptr || strncmp(MangledName, "_D", 2) != 0)
+ return nullptr;
+
+ OutputBuffer Demangled;
+ if (!initializeOutputBuffer(nullptr, nullptr, Demangled, 1024))
+ return nullptr;
+
+ if (strcmp(MangledName, "_Dmain") == 0)
+ Demangled << "D main";
+
+ // OutputBuffer's internal buffer is not null terminated and therefore we need
+ // to add it to comply with C null terminated strings.
+ if (Demangled.getCurrentPosition() > 0) {
+ Demangled << '\0';
+ Demangled.setCurrentPosition(Demangled.getCurrentPosition() - 1);
+ return Demangled.getBuffer();
+ }
+
+ return nullptr;
+}
diff --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp
index 8a1c59a4b2e54..13aa2864c183d 100644
--- a/llvm/lib/Demangle/Demangle.cpp
+++ b/llvm/lib/Demangle/Demangle.cpp
@@ -21,6 +21,11 @@ static bool isItaniumEncoding(const char *S) {
static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; }
+static bool isDLangEncoding(const std::string &MangledName) {
+ return MangledName.size() >= 2 && MangledName[0] == '_' &&
+ MangledName[1] == 'D';
+}
+
std::string llvm::demangle(const std::string &MangledName) {
std::string Result;
const char *S = MangledName.c_str();
@@ -47,6 +52,8 @@ bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) {
Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr);
else if (isRustEncoding(MangledName))
Demangled = rustDemangle(MangledName, nullptr, nullptr, nullptr);
+ else if (isDLangEncoding(MangledName))
+ Demangled = dlangDemangle(MangledName);
if (!Demangled)
return false;
diff --git a/llvm/test/Demangle/dlang.test b/llvm/test/Demangle/dlang.test
new file mode 100644
index 0000000000000..831aa5e9a4d6e
--- /dev/null
+++ b/llvm/test/Demangle/dlang.test
@@ -0,0 +1,10 @@
+RUN: llvm-cxxfilt -n < %s | FileCheck --match-full-lines %s
+
+; Full test suite for dlang demangling at
+; llvm/unittests/Demangle/DLangDemangleTest.cpp
+
+CHECK: D main
+ _Dmain
+
+CHECK: _DDD
+ _DDD
diff --git a/llvm/unittests/Demangle/CMakeLists.txt b/llvm/unittests/Demangle/CMakeLists.txt
index 5ee315790215e..d6071bc36bda8 100644
--- a/llvm/unittests/Demangle/CMakeLists.txt
+++ b/llvm/unittests/Demangle/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
add_llvm_unittest(DemangleTests
DemangleTest.cpp
+ DLangDemangleTest.cpp
ItaniumDemangleTest.cpp
OutputBufferTest.cpp
PartialDemangleTest.cpp
diff --git a/llvm/unittests/Demangle/DLangDemangleTest.cpp b/llvm/unittests/Demangle/DLangDemangleTest.cpp
new file mode 100644
index 0000000000000..8a324ecd23219
--- /dev/null
+++ b/llvm/unittests/Demangle/DLangDemangleTest.cpp
@@ -0,0 +1,33 @@
+//===------------------ DLangDemangleTest.cpp -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Demangle/Demangle.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include <cstdlib>
+#include <utility>
+
+struct DLangDemangleTestFixture
+ : public testing::TestWithParam<std::pair<const char *, const char *>> {
+ char *Demangled;
+
+ void SetUp() override { Demangled = llvm::dlangDemangle(GetParam().first); }
+
+ void TearDown() override { std::free(Demangled); }
+};
+
+TEST_P(DLangDemangleTestFixture, DLangDemangleTest) {
+ EXPECT_STREQ(Demangled, GetParam().second);
+}
+
+INSTANTIATE_TEST_SUITE_P(DLangDemangleTest, DLangDemangleTestFixture,
+ testing::Values(std::make_pair("_Dmain", "D main"),
+ std::make_pair(nullptr, nullptr),
+ std::make_pair("_Z", nullptr),
+ std::make_pair("_DDD", nullptr)));
diff --git a/llvm/unittests/Demangle/DemangleTest.cpp b/llvm/unittests/Demangle/DemangleTest.cpp
index 22266752d1853..e60a75ecd76da 100644
--- a/llvm/unittests/Demangle/DemangleTest.cpp
+++ b/llvm/unittests/Demangle/DemangleTest.cpp
@@ -23,6 +23,7 @@ TEST(Demangle, demangleTest) {
EXPECT_EQ(demangle("foo"), "foo");
EXPECT_EQ(demangle("_RNvC3foo3bar"), "foo::bar");
EXPECT_EQ(demangle("__RNvC3foo3bar"), "foo::bar");
+ EXPECT_EQ(demangle("_Dmain"), "D main");
// Regression test for demangling of optional template-args for vendor
// extended type qualifier (https://bugs.llvm.org/show_bug.cgi?id=48009)
More information about the llvm-commits
mailing list