aboutsummaryrefslogtreecommitdiffstats
path: root/util/system/type_name.cpp
blob: 0377da42128ef04edf041e6ab7227e544cb0864b (plain) (blame)
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
#include "platform.h"
#include "demangle_impl.h"

#ifdef __GNUC__
    #include <stdexcept>
    #include <cxxabi.h>
#endif

#include "type_name.h"

namespace {

#if defined(_LIBCPP_VERSION)
    // libc++ is nested under std::__y1
    constexpr std::string_view STD_ABI_PREFIX = "std::__y1::";
#elif defined(_linux_)
    // libstdc++ is nested under std::__cxx11
    // FIXME: is there any way to test if we are building against libstdc++?
    constexpr std::string_view STD_ABI_PREFIX = "std::__cxx11::";
#else
    // There is no need to cutoff ABI prefix on Windows
#endif
    constexpr std::string_view STD_PREFIX = "std::";

} // anonymous namespace

const char* NPrivate::TCppDemangler::Demangle(const char* name) {
#ifndef __GNUC__
    return name;
#else
    int status;
    TmpBuf_.Reset(__cxxabiv1::__cxa_demangle(name, nullptr, nullptr, &status));

    if (!TmpBuf_) {
        return name;
    }

    return TmpBuf_.Get();
#endif
}

TString CppDemangle(const TString& name) {
    return NPrivate::TCppDemangler().Demangle(name.data());
}

TString TypeName(const std::type_info& typeInfo) {
    TString demangled = CppDemangle(typeInfo.name()); // NOLINT(arcadia-typeid-name-restriction)
#if defined(_linux_) || defined(_darwin_)
    SubstGlobal(demangled, STD_ABI_PREFIX, STD_PREFIX);
#endif
    return demangled;
}

TString TypeName(const std::type_index& typeIndex) {
    TString demangled = CppDemangle(typeIndex.name());
#if defined(_linux_) || defined(_darwin_)
    SubstGlobal(demangled, STD_ABI_PREFIX, STD_PREFIX);
#endif
    return demangled;
}