timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
demangle.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25#pragma once
26
32
33#include <cstdio>
34#include <cstring>
35#include <string>
36#include <typeinfo>
37
38#if defined(TIMEMORY_UNIX)
39# include <cxxabi.h>
40#endif
41
42namespace tim
43{
44//--------------------------------------------------------------------------------------//
45
46inline std::string
47demangle(const char* _mangled_name, int* _status = nullptr)
48{
49#if defined(TIMEMORY_ENABLE_DEMANGLE)
50 // return the mangled since there is no buffer
51 if(!_mangled_name)
52 return std::string{};
53
54 int _ret = 0;
55 std::string _demangled_name{ _mangled_name };
56 if(!_status)
57 _status = &_ret;
58
59 // PARAMETERS to __cxa_demangle
60 // mangled_name:
61 // A NULL-terminated character string containing the name to be demangled.
62 // buffer:
63 // A region of memory, allocated with malloc, of *length bytes, into which the
64 // demangled name is stored. If output_buffer is not long enough, it is expanded
65 // using realloc. output_buffer may instead be NULL; in that case, the demangled
66 // name is placed in a region of memory allocated with malloc.
67 // _buflen:
68 // If length is non-NULL, the length of the buffer containing the demangled name
69 // is placed in *length.
70 // status:
71 // *status is set to one of the following values
72 char* _demang = abi::__cxa_demangle(_mangled_name, nullptr, nullptr, _status);
73 switch(*_status)
74 {
75 // 0 : The demangling operation succeeded.
76 // -1 : A memory allocation failiure occurred.
77 // -2 : mangled_name is not a valid name under the C++ ABI mangling rules.
78 // -3 : One of the arguments is invalid.
79 case 0:
80 {
81 if(_demang)
82 _demangled_name = std::string{ _demang };
83 break;
84 }
85 case -1:
86 {
87 char _msg[1024];
88 ::memset(_msg, '\0', 1024 * sizeof(char));
89 ::snprintf(_msg, 1024, "memory allocation failure occurred demangling %s",
90 _mangled_name);
91 ::perror(_msg);
92 break;
93 }
94 case -2: break;
95 case -3:
96 {
97 char _msg[1024];
98 ::memset(_msg, '\0', 1024 * sizeof(char));
99 ::snprintf(_msg, 1024, "Invalid argument in: (\"%s\", nullptr, nullptr, %p)",
100 _mangled_name, (void*) _status);
101 ::perror(_msg);
102 break;
103 }
104 default: break;
105 };
106
107 // free allocated buffer
108 ::free(_demang);
109 return _demangled_name;
110#else
111 (void) _status;
112 return _mangled_name;
113#endif
114}
115
116//--------------------------------------------------------------------------------------//
117
118inline std::string
119demangle(const std::string& _str, int* _status = nullptr)
120{
121 return demangle(_str.c_str(), _status);
122}
123
124//--------------------------------------------------------------------------------------//
125
126template <typename Tp>
127inline auto
129{
130 // static because a type demangle will always be the same
131 static auto _val = []() {
132 // wrap the type in type_list and then extract ... from tim::type_list<...>
133 auto _tmp = ::tim::demangle(typeid(type_list<Tp>).name());
134 auto _key = std::string{ "type_list" };
135 auto _idx = _tmp.find(_key);
136 _idx = _tmp.find('<', _idx);
137 _tmp = _tmp.substr(_idx + 1);
138 _idx = _tmp.find_last_of('>');
139 _tmp = _tmp.substr(0, _idx);
140 // strip trailing whitespaces
141 while((_idx = _tmp.find_last_of(' ')) == _tmp.length() - 1)
142 _tmp = _tmp.substr(0, _idx);
143 return _tmp;
144 }();
145 return _val;
146}
147
148//--------------------------------------------------------------------------------------//
149
150template <typename Tp>
151inline auto
153{
154 // static because a type demangle will always be the same
155 static auto _val = demangle(typeid(Tp).name());
156 return _val;
157}
158
159//--------------------------------------------------------------------------------------//
160
161} // namespace tim
162
163#if defined(TIMEMORY_UTILITY_HEADER_MODE)
165#endif
const hash_alias_ptr_t hash_value_t std::string *& _ret
Definition: definition.hpp:300
Definition: kokkosp.cpp:39
auto try_demangle()
Definition: demangle.hpp:128
std::string demangle(const char *_mangled_name, int *_status=nullptr)
Definition: demangle.hpp:47
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
auto demangle()
Definition: demangle.hpp:152
lightweight tuple-alternative for meta-programming logic
Definition: types.hpp:233