Skip to content

Commit 1fb0c8b

Browse files
committed
Implement cuda::demangle
1 parent b7697c6 commit 1fb0c8b

File tree

4 files changed

+178
-2
lines changed

4 files changed

+178
-2
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of libcu++, the C++ Standard Library for your entire system,
4+
// under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#ifndef _CUDA___BINUTILS_DEMANGLE_H
12+
#define _CUDA___BINUTILS_DEMANGLE_H
13+
14+
#include <cuda/std/detail/__config>
15+
16+
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
17+
# pragma GCC system_header
18+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
19+
# pragma clang system_header
20+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
21+
# pragma system_header
22+
#endif // no system header
23+
24+
#if _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
25+
26+
# include <cuda/std/__cstddef/types.h>
27+
# include <cuda/std/__exception/cuda_error.h>
28+
# include <cuda/std/cstdlib>
29+
# include <cuda/std/string_view>
30+
31+
# include <string>
32+
33+
# include <nv_decode.h>
34+
35+
# include <cuda/std/__cccl/prologue.h>
36+
37+
_LIBCUDACXX_BEGIN_NAMESPACE_CUDA
38+
39+
//! @brief Demangles a CUDA C++ mangled name.
40+
//!
41+
//! @param __name The mangled name to demangle.
42+
//!
43+
//! @return A `std::string` containing the demangled name.
44+
//!
45+
//! @throws cuda::cuda_error if memory allocation fails, or if the input name is invalid.
46+
[[nodiscard]] ::std::string demangle(_CUDA_VSTD::string_view __name)
47+
{
48+
// input must be zero-terminated, so we convert string_view to std::string
49+
::std::string __name_in{__name.begin(), __name.end()};
50+
51+
int __status{};
52+
char* __dname_ptr = ::__cu_demangle(__name_in.c_str(), nullptr, nullptr, &__status);
53+
54+
_CCCL_TRY
55+
{
56+
switch (__status)
57+
{
58+
case 0: {
59+
::std::string __ret{__dname_ptr};
60+
_CUDA_VSTD::free(__dname_ptr);
61+
return __ret;
62+
}
63+
case -1:
64+
::cuda::__throw_cuda_error(::cudaErrorMemoryAllocation, "failed to allocate memory for demangled name");
65+
case -2:
66+
::cuda::__throw_cuda_error(::cudaErrorInvalidSymbol, "invalid mangled name passed to demangle function");
67+
case -3:
68+
::cuda::__throw_cuda_error(::cudaErrorInvalidValue, "invalid value passed to demangle function");
69+
default:
70+
// Should not happen, but if it does, we throw an unknown error
71+
::cuda::__throw_cuda_error(::cudaErrorUnknown, "unknown error during demangling occurred");
72+
}
73+
}
74+
_CCCL_CATCH_ALL
75+
{
76+
// If an exception is thrown, free the allocated memory and rethrow the exception
77+
_CUDA_VSTD::free(__dname_ptr);
78+
throw;
79+
}
80+
}
81+
82+
_LIBCUDACXX_END_NAMESPACE_CUDA
83+
84+
# include <cuda/std/__cccl/epilogue.h>
85+
86+
#endif // _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC)
87+
88+
#endif // _CUDA___BINUTILS_DEMANGLE_H
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of libcu++, the C++ Standard Library for your entire system,
4+
// under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#ifndef _CUDA_BINUTILS
12+
#define _CUDA_BINUTILS
13+
14+
#include <cuda/std/detail/__config>
15+
16+
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
17+
# pragma GCC system_header
18+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
19+
# pragma clang system_header
20+
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
21+
# pragma system_header
22+
#endif // no system header
23+
24+
#include <cuda/__binutils/demangle.h>
25+
26+
#endif // _CUDA_BINUTILS

libcudacxx/test/libcudacxx/CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,21 @@ if (${CMAKE_CUDA_COMPILER_ID} STREQUAL "Clang")
7777
" ${CMAKE_CUDA_FLAGS}"
7878
" -L${CUDAToolkit_LIBRARY_DIR}"
7979
" -lcuda"
80-
" -lcudart")
80+
" -lcudart"
81+
" -lcufilt")
8182
elseif (${CMAKE_CUDA_COMPILER_ID} STREQUAL "NVIDIA")
8283
string(APPEND LIBCUDACXX_TEST_COMPILER_FLAGS
8384
" ${LIBCUDACXX_FORCE_INCLUDE}"
8485
" ${LIBCUDACXX_WARNING_LEVEL}"
8586
" -Wno-deprecated-gpu-targets")
87+
string(APPEND LIBCUDACXX_TEST_LINKER_FLAGS
88+
" -lcufilt")
8689
elseif (${CMAKE_CUDA_COMPILER_ID} STREQUAL "NVHPC")
8790
string(APPEND LIBCUDACXX_TEST_COMPILER_FLAGS
8891
" -stdpar")
8992
string(APPEND LIBCUDACXX_TEST_LINKER_FLAGS
90-
" -stdpar")
93+
" -stdpar"
94+
" -lcufilt")
9195
endif()
9296

9397
set(LIBCUDACXX_COMPUTE_ARCHS_STRING "${CMAKE_CUDA_ARCHITECTURES}")
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of CUDA Experimental in CUDA C++ Core Libraries,
4+
// under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
// UNSUPPORTED: nvrtc
12+
13+
#include <cuda/__binutils_>
14+
#include <cuda/std/cassert>
15+
#include <cuda/std/string_view>
16+
#include <cuda/std/type_traits>
17+
18+
#include <string>
19+
20+
void test()
21+
{
22+
// 1. test signature of
23+
static_assert(cuda::std::is_same_v<decltype(cuda::demangle(cuda::std::string_view{})), std::string>);
24+
static_assert(!noexcept(cuda::demangle(cuda::std::string_view{})));
25+
26+
// 2. test positive case
27+
{
28+
constexpr auto real_mangled_name = "_ZN8clstmp01I5cls01E13clstmp01_mf01Ev";
29+
const auto demangled = cuda::demangle(real_mangled_name);
30+
assert(demangled == "clstmp01<cls01>::clstmp01_mf01()");
31+
}
32+
33+
// 3. test error case
34+
#if _CCCL_HAS_EXCEPTIONS()
35+
{
36+
constexpr auto fake_mangled_name = "B@d_iDentiFier";
37+
try
38+
{
39+
auto demangled = cuda::demangle(fake_mangled_name);
40+
assert(false);
41+
}
42+
catch (const cuda::cuda_error& e)
43+
{
44+
assert(e.status() == cudaErrorInvalidSymbol);
45+
}
46+
catch (...)
47+
{
48+
assert(false);
49+
}
50+
}
51+
#endif // _CCCL_HAS_EXCEPTIONS()
52+
}
53+
54+
int main(int, char**)
55+
{
56+
NV_IF_TARGET(NV_IS_HOST, (test();))
57+
return 0;
58+
}

0 commit comments

Comments
 (0)