LSSTApplications
20.0.0
LSSTDataManagementBasePackage
stack
1a1d771
Linux64
utils
20.0.0
src
Demangle.cc
Go to the documentation of this file.
1
/*
2
* LSST Data Management System
3
* Copyright 2008, 2009, 2010 LSST Corporation.
4
*
5
* This product includes software developed by the
6
* LSST Project (http://www.lsst.org/).
7
*
8
* This program is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation, either version 3 of the License, or
11
* (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
*
18
* You should have received a copy of the LSST License Statement and
19
* the GNU General Public License along with this program. If not,
20
* see <http://www.lsstcorp.org/LegalNotices/>.
21
*/
22
23
#include "
lsst/utils/Demangle.h
"
24
25
#include <iostream>
26
#include <string>
27
#include <stack>
28
#include <boost/format.hpp>
29
#include <boost/multi_index_container.hpp>
30
#include <boost/multi_index/sequenced_index.hpp>
31
#include <boost/multi_index/ordered_index.hpp>
32
#include <boost/multi_index/member.hpp>
33
34
namespace
lsst
{
35
namespace
utils {
36
/*
37
* Provide a symbol table for "substitutions" while mangling
38
*/
39
using
boost::multi_index_container;
40
using namespace
boost::multi_index;
41
42
class
Symbol
{
43
public
:
44
int
n
;
// index of substitution
45
std::string
key
;
// key to saved string
46
47
Symbol
(
std::string
key
) :
n
(n_next++),
key
(
key
) { }
48
~Symbol
() {}
49
50
static
void
reset
() { n_next = 0; }
// reset counter
51
52
void
print
()
const
{
53
std::cout
<<
'\t'
<<
n
<<
" "
<<
key
<<
'\n'
;
54
}
55
private
:
56
static
int
n_next;
// the next value of n
57
};
58
59
/*
60
* Tags for indices
61
*/
62
struct
n
{};
// lookup by n
63
struct
key
{};
// lookup by key
64
65
int
Symbol::n_next = 0;
// unique ID for each symbol
66
84
static
bool
interpret_typeletter(
const
char
c,
std::string
&
type
) {
85
switch
(c) {
86
case
'v'
:
type
=
"void"
;
return
true
;
87
case
'w'
:
type
=
"wchar_t"
;
return
true
;
88
case
'b'
:
type
=
"bool"
;
return
true
;
89
case
'c'
:
type
=
"char"
;
return
true
;
90
case
'a'
:
type
=
"schar"
;
return
true
;
91
case
'h'
:
type
=
"uchar"
;
return
true
;
92
case
's'
:
type
=
"short"
;
return
true
;
93
case
't'
:
type
=
"ushort"
;
return
true
;
94
case
'i'
:
type
=
"int"
;
return
true
;
95
case
'j'
:
type
=
"uint"
;
return
true
;
96
case
'l'
:
type
=
"long"
;
return
true
;
97
case
'm'
:
type
=
"ulong"
;
return
true
;
98
case
'x'
:
type
=
"long long"
;
return
true
;
99
case
'y'
:
type
=
"ulong long"
;
return
true
;
100
case
'n'
:
type
=
"__int128"
;
return
true
;
101
case
'o'
:
type
=
"__uint128"
;
return
true
;
102
case
'f'
:
type
=
"float"
;
return
true
;
103
case
'd'
:
type
=
"double"
;
return
true
;
104
case
'e'
:
type
=
"long double"
;
return
true
;
105
case
'g'
:
type
=
"__float128"
;
return
true
;
106
case
'z'
:
type
=
"..."
;
return
true
;
107
case
'u'
:
type
=
"vendor extended type"
;
return
true
;
108
default
:
return
false
;
109
}
110
}
111
112
113
std::string
demangleType
(
std::string
const
_typeName) {
114
#if 1
115
typedef
multi_index_container<
116
Symbol
,
117
indexed_by<
118
ordered_unique<tag<n>,
119
member<Symbol, int, &Symbol::n> >,
120
ordered_unique<tag<key>,
121
member<Symbol, std::string, &Symbol::key> >
122
>
123
> SymbolTable;
124
typedef
SymbolTable::index<n>::type::iterator nIterator;
125
typedef
SymbolTable::index<key>::type::iterator keyIterator;
126
Symbol::reset
();
127
128
// Here's my symbol table and its indices
129
SymbolTable st;
130
131
SymbolTable::index<n>::type
&nIndex = st.get<
n
>();
132
SymbolTable::index<key>::type
&keyIndex = st.get<
key
>();
133
//
134
// Start mangling
135
//
136
std::string
typeName(
""
);
137
const
char
*
ptr
= _typeName.
c_str
();
138
139
if
(*
ptr
==
'r'
|| *
ptr
==
'V'
|| *
ptr
==
'K'
) {
140
ptr
++;
// (restrict/volatile/const)
141
}
142
143
if
(*
ptr
==
'P'
)
ptr
++;
// We passed "this" which is (type *)
144
145
std::string
currentSymbol =
""
;
// Current symbol
146
std::stack<char>
typeStack;
// Did we last see an N or an I?
147
148
int
lastTokenWasType = 0;
// When > 0, the last token was a type such as int or float
149
while
(*
ptr
!=
'\0'
) {
150
lastTokenWasType--;
151
switch
(*
ptr
) {
152
case
'E'
:
153
ptr
++;
154
currentSymbol =
""
;
155
156
if
(typeStack.
empty
()) {
157
typeStack.
push
(
'\a'
);
// at least don't crash
158
}
159
160
if
(typeStack.
top
() ==
'I'
) {
161
typeName +=
'>'
;
162
}
else
if
(typeStack.
top
() ==
'L'
) {
163
;
164
}
else
if
(typeStack.
top
() ==
'N'
) {
165
;
166
}
167
typeStack.
pop
();
168
169
if
(!typeStack.
empty
() && typeStack.
top
() ==
'I'
) {
170
if
(*
ptr
!=
'E'
&& typeName[typeName.size() - 1] !=
'<'
) {
171
typeName +=
','
;
172
}
173
}
174
175
break
;
176
case
'I'
:
177
typeStack.
push
(*
ptr
++);
178
currentSymbol =
""
;
179
180
typeName +=
'<'
;
181
break
;
182
case
'L'
:
183
typeStack.
push
(*
ptr
++);
184
currentSymbol =
""
;
185
{
186
std::string
type
;
187
if
(interpret_typeletter(*
ptr
,
type
)) {
188
typeName +=
"("
+
type
+
')'
;
189
}
else
{
190
typeName +=
'c'
;
191
}
192
ptr
++;
193
}
194
if
(*
ptr
==
'n'
) {
195
typeName +=
'-'
;
ptr
++;
196
}
197
while
(*
ptr
!=
'\0'
&& *
ptr
!=
'E'
) {
198
typeName += *
ptr
++;
199
}
200
break
;
201
case
'N'
:
202
typeStack.
push
(*
ptr
++);
203
currentSymbol =
""
;
204
break
;
205
case
'S'
:
206
++
ptr
;
207
switch
(*
ptr
) {
208
case
't'
: typeName +=
"::std::"
;
break
;
209
case
'a'
: typeName +=
"::std::allocator"
;
break
;
210
case
'b'
: typeName +=
"::std::basic_string"
;
break
;
211
case
's'
: typeName +=
"::std::basic_string<char,::std::char_traits<char>,::std::allocator<char>>"
;
break
;
212
case
'i'
: typeName +=
"::std::basic_istream<char, std::char_traits<char> >"
;
break
;
213
case
'o'
: typeName +=
"::std::basic_ostream<char,std::char_traits<char>>"
;
break
;
214
case
'd'
: typeName +=
"::std::basic_iostream<char,std::char_traits<char>>"
;
break
;
215
default
:
216
{
217
int
subst = 0;
// number of substitution
218
219
if
(*
ptr
==
'_'
) {
220
;
// S_ => 0
221
}
else
if
(isdigit(*
ptr
) || isupper(*
ptr
)) {
222
while
(isdigit(*
ptr
) || isupper(*
ptr
)) {
223
if
(isdigit(*
ptr
)) {
224
subst = 36*subst + (*
ptr
-
'0'
);
225
}
else
{
226
subst = 36*subst + 10 + (*
ptr
-
'A'
);
227
}
228
ptr
++;
229
}
230
subst++;
// S_ == 0; S1_ == 1
231
assert (*
ptr
==
'_'
);
232
ptr
++;
233
}
234
235
nIterator sym = nIndex.find(subst);
236
if
(sym == nIndex.end()) {
// not found
237
typeName += (
boost::format
(
"[S%d]"
) % subst).str();
238
}
else
{
239
typeName += sym->key;
240
}
241
242
}
243
break
;
244
}
245
currentSymbol =
""
;
246
break
;
247
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
248
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
249
{
250
const
int
len = atoi(
ptr
++);
251
while
(isdigit(*
ptr
))
ptr
++;
252
253
std::string
name
=
""
;
254
for
(
int
i = 0; *
ptr
!=
'\0'
&& i < len; i++) {
255
name
+= *
ptr
++;
256
}
257
258
if
(currentSymbol !=
""
) {
259
currentSymbol +=
"::"
;
260
typeName +=
"::"
;
261
}
262
263
currentSymbol +=
name
;
264
typeName +=
name
;
265
266
if
(keyIndex.find(currentSymbol) == keyIndex.end()) {
267
st.insert(currentSymbol);
268
}
269
}
270
break
;
271
default
:
272
{
273
std::string
type
;
274
if
(interpret_typeletter(*
ptr
,
type
)) {
275
if
(lastTokenWasType > 0) {
276
typeName +=
","
;
277
}
278
typeName +=
type
;
279
lastTokenWasType = 2;
// it'll be decremented on every char in the name
280
}
else
{
281
typeName += *
ptr
;
282
}
283
ptr
++;
284
}
285
}
286
}
287
288
static
volatile
bool
dumpSymbolTable =
false
;
// can be set from gdb
289
if
(dumpSymbolTable) {
290
// The test on the iterator is paranoid, but they _could_
291
// have deleted elements. In this case, they didn't.
292
for
(
unsigned
int
i = 0; i < st.size(); i++) {
293
nIterator el = nIndex.find(2);
294
if
(el != nIndex.end()) {
// did we find it?
295
el->print();
296
}
297
}
298
}
299
300
return
typeName;
301
#else
302
return
_typeName;
303
#endif
304
}
305
306
}}
// namespace lsst::utils
lsst::utils::n
Definition:
Demangle.cc:62
std::string
STL class.
lsst::utils::Symbol::~Symbol
~Symbol()
Definition:
Demangle.cc:48
Demangle.h
std::stack
STL class.
pex.config.history.format
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition:
history.py:174
lsst::utils::Symbol::key
std::string key
Definition:
Demangle.cc:45
lsst::utils::Symbol::reset
static void reset()
Definition:
Demangle.cc:50
lsst::afw::geom.transform.transformContinued.name
string name
Definition:
transformContinued.py:32
lsst::utils::key
Definition:
Demangle.cc:63
lsst::utils::Symbol::print
void print() const
Definition:
Demangle.cc:52
std::cout
lsst::utils::Symbol
Definition:
Demangle.cc:42
std::string::c_str
T c_str(T... args)
std::stack::pop
T pop(T... args)
std::stack::top
T top(T... args)
ptr
uint64_t * ptr
Definition:
RangeSet.cc:88
lsst
A base class for image defects.
Definition:
imageAlgorithm.dox:1
type
table::Key< int > type
Definition:
Detector.cc:163
lsst::utils::Symbol::Symbol
Symbol(std::string key)
Definition:
Demangle.cc:47
std::stack::empty
T empty(T... args)
std::stack::push
T push(T... args)
lsst::utils::Symbol::n
int n
Definition:
Demangle.cc:44
lsst::utils::demangleType
std::string demangleType(std::string const _typeName)
Definition:
Demangle.cc:113
Generated on Wed Jun 24 2020 18:10:12 for LSSTApplications by
1.8.18