Skip to content

Commit fbafd60

Browse files
committed
[libc++] Add test to ensure that the mangling of types stays the same
1 parent 4fb81f1 commit fbafd60

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// We're using `std::from_chars` in this test
10+
// UNSUPPORTED: c++03, c++11, c++14
11+
12+
// Make sure that the mangling of our public types stays the same
13+
14+
#include <cassert>
15+
#include <charconv>
16+
#include <iostream>
17+
#include <map>
18+
#include <typeinfo>
19+
#include <string_view>
20+
21+
template <class>
22+
struct mangling {};
23+
24+
struct test_struct {};
25+
26+
_LIBCPP_BEGIN_NAMESPACE_STD
27+
struct ns_mangling {};
28+
_LIBCPP_END_NAMESPACE_STD
29+
30+
namespace std::__name {
31+
struct ns_mangling {};
32+
} // namespace std::__name
33+
34+
namespace std::__long_name_to_make_sure_multiple_digits_work {
35+
struct ns_mangling {};
36+
} // namespace std::__long_name_to_make_sure_multiple_digits_work
37+
38+
std::string get_std_inline_namespace_mangling(const std::type_info& info) {
39+
std::string name = info.name();
40+
assert(name.starts_with("NSt"));
41+
unsigned name_len;
42+
auto res = std::from_chars(name.data() + 3, name.data() + name.size(), name_len);
43+
assert(res.ec == std::errc{});
44+
return std::move(name).substr(0, (res.ptr + name_len) - name.data());
45+
}
46+
47+
void expect_mangling(const std::type_info& info, std::string expected_name) {
48+
if (expected_name != info.name())
49+
std::__libcpp_verbose_abort("Expected: '%s'\n Got: '%s'\n", expected_name.c_str(), info.name());
50+
}
51+
52+
#define EXPECT_MANGLING(expected_mangling, ...) expect_mangling(typeid(__VA_ARGS__), expected_mangling)
53+
54+
// Mangling names are really long, but splitting it up into multiple lines doesn't make it any more readable
55+
// clang-format off
56+
int main(int, char**) {
57+
// self-test inline namespace recovery
58+
assert(get_std_inline_namespace_mangling(typeid(std::__name::ns_mangling)) == "NSt6__name");
59+
assert(get_std_inline_namespace_mangling(typeid(std::__long_name_to_make_sure_multiple_digits_work::ns_mangling)) == "NSt45__long_name_to_make_sure_multiple_digits_work");
60+
61+
// selftest
62+
EXPECT_MANGLING("11test_struct", test_struct);
63+
64+
std::string ns_std = get_std_inline_namespace_mangling(typeid(std::ns_mangling));
65+
66+
// std::map
67+
EXPECT_MANGLING(ns_std + "3mapIiiNS_4lessIiEENS_9allocatorINS_4pairIKiiEEEEEE", std::map<int, int>);
68+
EXPECT_MANGLING(ns_std + "14__map_iteratorINS_15__tree_iteratorINS_12__value_typeIiiEEPNS_11__tree_nodeIS3_PvEElEEEE", std::map<int, int>::iterator);
69+
EXPECT_MANGLING(ns_std + "20__map_const_iteratorINS_21__tree_const_iteratorINS_12__value_typeIiiEEPNS_11__tree_nodeIS3_PvEElEEEE", std::map<int, int>::const_iterator);
70+
71+
return 0;
72+
}

0 commit comments

Comments
 (0)