demangle.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "crucible/core/demangle.inl" #include <cstdlib> #include "crucible/core/platform.hpp" #ifdef CRUCIBLE_PLATFORM_IS_POSIX_LIKE #include <cxxabi.h> #endif // CRUCIBLE_PLATFORM_IS_POSIX_LIKE namespace crucible::core { #ifdef CRUCIBLE_PLATFORM_IS_POSIX_LIKE namespace { struct Demangler { char *data { nullptr }; std::size_t size { 0 }; int status { 0 }; explicit Demangler(Immutable_View<char> const &mangled); ~Demangler(); }; Demangler::Demangler(Immutable_View<char> const &mangled) { data = abi::__cxa_demangle(mangled.data(), nullptr, &size, &status); } Demangler::~Demangler() { if (data != nullptr) { std::free(data); } data = nullptr; size = 0; status = 0; } } #endif // CRUCIBLE_PLATFORM_IS_POSIX_LIKE auto Insufficient_Demangle_Memory::describe() const -> String { return String { "Failed to allocate memory for symbol demangling" }; } auto Invalid_Demangle_Arguments::describe() const -> String { return String { "Demangler called with invalid arguments" }; } auto Unknown_Demangle_Error::describe() const -> String { return String { "Unknown demangler error" }; } auto demangle(Immutable_View<char> const mangled) -> Demangle_Result<String> { #ifdef CRUCIBLE_PLATFORM_IS_POSIX_LIKE Demangler const demangler { mangled }; if (demangler.status == 0) { return make_success<String>(demangler.data, demangler.size); } if (demangler.status == -1) { return make_failure<Demangle_Error>(Insufficient_Demangle_Memory {}); } if (demangler.status == -2) { return make_success<String>(mangled.data(), mangled.size()); } if (demangler.status == -3) { return make_failure<Demangle_Error>(Invalid_Demangle_Arguments {}); } return make_failure<Demangle_Error>(Unknown_Demangle_Error {}); #endif // CRUCIBLE_PLATFORM_IS_POSIX_LIKE #ifdef CRUCIBLE_PLATFORM_IS_WINDOWS_LIKE // MSVC already gives us unmangled symbols from everywhere that matters return make_success(make_string(mangled)); #endif // CRUCIBLE_PLATFORM_IS_WINDOWS_LIKE } }