]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/dll/detail/demangling/itanium.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / dll / detail / demangling / itanium.hpp
CommitLineData
7c673cae
FG
1// Copyright 2016 Klemens Morgenstern
2//
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt
5// or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
8#define BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
9
10#include <boost/dll/detail/demangling/mangled_storage_base.hpp>
11#include <iterator>
12#include <algorithm>
13#include <boost/type_traits/is_const.hpp>
14#include <boost/type_traits/is_volatile.hpp>
15#include <boost/type_traits/is_rvalue_reference.hpp>
16#include <boost/type_traits/is_lvalue_reference.hpp>
17#include <boost/type_traits/function_traits.hpp>
18
19
20namespace boost { namespace dll { namespace detail {
21
22
23
24class mangled_storage_impl : public mangled_storage_base
25{
26 template<typename T>
27 struct dummy {};
28
29 template<typename Return, typename ...Args>
30 std::vector<std::string> get_func_params(dummy<Return(Args...)>) const
31 {
32 return {get_name<Args>()...};
33 }
34 template<typename Return, typename ...Args>
35 std::string get_return_type(dummy<Return(Args...)>) const
36 {
37 return get_name<Return>();
38 }
39public:
40 using mangled_storage_base::mangled_storage_base;
41 struct ctor_sym
42 {
43 std::string C1;
44 std::string C2;
45 std::string C3;
46
47 bool empty() const
48 {
49 return C1.empty() && C2.empty() && C3.empty();
50 }
51 };
52
53 struct dtor_sym
54 {
55 std::string D0;
56 std::string D1;
57 std::string D2;
58 bool empty() const
59 {
60 return D0.empty() && D1.empty() && D2.empty();
61 }
62 };
63
64 template<typename T>
65 std::string get_variable(const std::string &name) const;
66
67 template<typename Func>
68 std::string get_function(const std::string &name) const;
69
70 template<typename Class, typename Func>
71 std::string get_mem_fn(const std::string &name) const;
72
73 template<typename Signature>
74 ctor_sym get_constructor() const;
75
76 template<typename Class>
77 dtor_sym get_destructor() const;
78
79 template<typename T>
80 std::string get_type_info() const;
81
82 template<typename T>
83 std::vector<std::string> get_related() const;
84
85};
86
87
88
89namespace parser
90{
20effc67
TL
91 //! declare
92 template <typename... T>
93 struct dummy;
94
95 template <typename T>
96 std::string parse_type_helper(const mangled_storage_impl & ms, dummy<T>*);
97
98 template <typename... T, template <typename...> class Tn>
99 std::string parse_type_helper(const mangled_storage_impl & ms, dummy<Tn<T...>>*);
100
101 template <typename... T, template <typename...> class Tn>
102 std::string parse_type(const mangled_storage_impl & ms, dummy<Tn<T...>>*);
103
104 template <typename T>
105 std::string parse_type(const mangled_storage_impl & ms, dummy<T>*);
106
107 template <typename T1, typename T2, typename... T3>
108 std::string parse_type(const mangled_storage_impl & ms, dummy<T1, T2, T3...>*);
109
110 template <typename R, typename... Args>
111 std::string parse_type(const mangled_storage_impl & ms, dummy<R(Args...)>*);
112
113 std::string parse_type(const mangled_storage_impl & ms, dummy<>*);
114
115 template<typename T>
116 std::string
117 type_name(const mangled_storage_impl &);
118
119
120 //The purpose of this class template is to separate the pure type from the rule name from the target type
121 template<typename T>
122 struct pure_type
123 {
124 typedef T type;
125 inline static std::string type_rule() { return ""; }
126 };
127
128 template<typename T>
129 struct pure_type<T*>
130 {
131 typedef typename pure_type<T>::type type;
132 inline static std::string type_rule()
133 {
134 return pure_type<T>::type_rule() + "*";
135 }
136 };
137
138 template<typename T>
139 struct pure_type<T const>
140 {
141 typedef typename pure_type<T>::type type;
142 inline static std::string type_rule()
143 {
144 return pure_type<T>::type_rule() + " const";
145 }
146 };
147
148 template<typename T>
149 struct pure_type<T volatile>
150 {
151 typedef typename pure_type<T>::type type;
152 inline static std::string type_rule()
153 {
154 return pure_type<T>::type_rule() + " volatile";
155 }
156 };
157
158 template<typename T>
159 struct pure_type<T const volatile>
160 {
161 typedef typename pure_type<T>::type type;
162 inline static std::string type_rule()
163 {
164 return pure_type<T>::type_rule() + " const volatile";
165 }
166 };
167
168 template<typename T>
169 struct pure_type<T&>
170 {
171 typedef typename pure_type<T>::type type;
172 inline static std::string type_rule()
173 {
174 return pure_type<T>::type_rule() + "&";
175 }
176 };
177
178 template<typename T>
179 struct pure_type<T&&>
180 {
181 typedef typename pure_type<T>::type type;
182 inline static std::string type_rule()
183 {
184 return pure_type<T>::type_rule() + "&&";
185 }
186 };
7c673cae
FG
187
188 inline std::string const_rule_impl(true_type ) {return " const";}
189 inline std::string const_rule_impl(false_type) {return "";}
190 template<typename T>
191 std::string const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
192
193 inline std::string volatile_rule_impl(true_type ) {return " volatile";}
194 inline std::string volatile_rule_impl(false_type) {return "";}
195 template<typename T>
196 std::string volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
197
198 inline std::string reference_rule_impl(false_type, false_type) {return "";}
199 inline std::string reference_rule_impl(true_type, false_type) {return "&" ;}
200 inline std::string reference_rule_impl(false_type, true_type ) {return "&&";}
201
7c673cae
FG
202 template<typename T>
203 std::string reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
204
205 //it takes a string, because it may be overloaded.
7c673cae
FG
206 template<typename Return, typename Arg>
207 std::string arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
208 {
209 using namespace std;
20effc67 210 return type_name<Arg>(ms);
7c673cae
FG
211 }
212
213 template<typename Return, typename First, typename Second, typename ...Args>
214 std::string arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
215 {
7c673cae 216 using next_type = Return (*)(Second, Args...);
20effc67 217 return type_name<First>(ms) + ", " + arg_list(ms, next_type());
7c673cae
FG
218 }
219
220 template<typename Return>
221 std::string arg_list(const mangled_storage_impl &, Return (*)())
222 {
223 return "";
224 }
20effc67
TL
225
226 //! implement
227 template <typename T>
228 inline std::string parse_type_helper(const mangled_storage_impl & ms, dummy<T>*) {
229 return ms.get_name<T>();
230 }
231
232 template <typename... T, template <typename...> class Tn>
233 inline std::string parse_type_helper(const mangled_storage_impl & ms, dummy<Tn<T...>>*) {
234 using type = dummy<Tn<T...>>*;
235 return parse_type(ms, type());
236 }
237
238 template <typename R, typename... Args>
239 inline std::string parse_type(const mangled_storage_impl & ms, dummy<R(*)(Args...)>*) {
240 using args_type = dummy<Args...>*;
241 using return_type = dummy<R>*;
242 return parse_type(ms, return_type()) + " (*)(" + parse_type(ms, args_type()) + ")";
243 }
244
245 template <typename R, typename... Args>
246 inline std::string parse_type(const mangled_storage_impl & ms, dummy<R(Args...)>*) {
247 using args_type = dummy<Args...>*;
248 using return_type = dummy<R>*;
249 return parse_type(ms, return_type()) + " (" + parse_type(ms, args_type()) + ")";
250 }
251
252 template <typename T>
253 inline std::string parse_type(const mangled_storage_impl & ms, dummy<T>*) {
254 using type = dummy<typename pure_type<T>::type>*;
255 auto str = parse_type_helper(ms, type());
256 return str + pure_type<T>::type_rule();
257 }
258
259 template <typename T1, typename T2, typename... T3>
260 inline std::string parse_type(const mangled_storage_impl & ms, dummy<T1, T2, T3...>*) {
261 using first_type = dummy<T1>*;
262 using next_type = dummy<T2, T3...>*;
263 return parse_type(ms, first_type()) + ", " + parse_type(ms, next_type());
264 }
265
266 template <typename... T, template <typename...> class Tn>
267 inline std::string parse_type(const mangled_storage_impl & ms, dummy<Tn<T...>>*) {
268 using next_type = dummy<T...>*;
269 std::string str = ms.get_name<Tn<T...>>();
270 auto frist = str.find_first_of("<");
271 std::string template_name = str.substr(0, frist);
272 std::string args_name = parse_type(ms, next_type());
273 char last_ch = args_name[args_name.size() - 1];
274 return template_name + "<" + args_name + (last_ch == '>' ? " >" : ">");
275 }
276
277 inline std::string parse_type(const mangled_storage_impl &, dummy<>*) {
278 return "";
279 }
280
281 template<typename T>
282 inline std::string
283 type_name(const mangled_storage_impl &ms)
284 {
285 using namespace parser;
286 using type = dummy<T>*;
287 return parse_type(ms, type());
288 }
7c673cae
FG
289}
290
291
292
293template<typename T> std::string mangled_storage_impl::get_variable(const std::string &name) const
294{
295 auto found = std::find_if(storage_.begin(), storage_.end(),
296 [&](const entry& e) {return e.demangled == name;});
297
298 if (found != storage_.end())
299 return found->mangled;
300 else
301 return "";
302}
303
304template<typename Func> std::string mangled_storage_impl::get_function(const std::string &name) const
305{
306 using func_type = Func*;
307
308 auto matcher = name + '(' + parser::arg_list(*this, func_type()) + ')';
309
310 auto found = std::find_if(storage_.begin(), storage_.end(), [&](const entry& e) {return e.demangled == matcher;});
311 if (found != storage_.end())
312 return found->mangled;
313 else
314 return "";
315
316}
317
318template<typename Class, typename Func>
319std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
320{
321 using namespace parser;
322
323 using func_type = Func*;
324
325 std::string cname = get_name<Class>();
326
f67539c2 327 const auto matcher = cname + "::" + name +
7c673cae
FG
328 '(' + parser::arg_list(*this, func_type()) + ')'
329 + const_rule<Class>() + volatile_rule<Class>();
330
f67539c2
TL
331 // Linux export table contains int MyClass::Func<float>(), but expected in import_mangled MyClass::Func<float>() without returned type.
332 auto found = std::find_if(storage_.begin(), storage_.end(), [&matcher](const entry& e) {
333 if (e.demangled == matcher) {
334 return true;
335 }
336
337 const auto pos = e.demangled.rfind(matcher);
338 if (pos == std::string::npos) {
339 // Not found.
340 return false;
341 }
342
343 if (pos + matcher.size() != e.demangled.size()) {
344 // There are some characters after the `matcher` string.
345 return false;
346 }
347
348 // Double checking that we matched a full function name
349 return e.demangled[pos - 1] == ' '; // `if (e.demangled == matcher)` makes sure that `pos > 0`
350 });
7c673cae
FG
351
352 if (found != storage_.end())
353 return found->mangled;
354 else
355 return "";
356
357}
358
359
360template<typename Signature>
361auto mangled_storage_impl::get_constructor() const -> ctor_sym
362{
363 using namespace parser;
364
365 using func_type = Signature*;
366
367 std::string ctor_name; // = class_name + "::" + name;
368 std::string unscoped_cname; //the unscoped class-name
369 {
370 auto class_name = get_return_type(dummy<Signature>());
371 auto pos = class_name.rfind("::");
372 if (pos == std::string::npos)
373 {
374 ctor_name = class_name+ "::" +class_name ;
375 unscoped_cname = class_name;
376 }
377 else
378 {
379 unscoped_cname = class_name.substr(pos+2) ;
380 ctor_name = class_name+ "::" + unscoped_cname;
381 }
382 }
383
384 auto matcher =
385 ctor_name + '(' + parser::arg_list(*this, func_type()) + ')';
386
387
388 std::vector<entry> findings;
389 std::copy_if(storage_.begin(), storage_.end(),
390 std::back_inserter(findings), [&](const entry& e) {return e.demangled == matcher;});
391
392 ctor_sym ct;
393
394 for (auto & e : findings)
395 {
396
397 if (e.mangled.find(unscoped_cname +"C1E") != std::string::npos)
398 ct.C1 = e.mangled;
399 else if (e.mangled.find(unscoped_cname +"C2E") != std::string::npos)
400 ct.C2 = e.mangled;
401 else if (e.mangled.find(unscoped_cname +"C3E") != std::string::npos)
402 ct.C3 = e.mangled;
403 }
404 return ct;
405}
406
407template<typename Class>
408auto mangled_storage_impl::get_destructor() const -> dtor_sym
409{
410 std::string dtor_name; // = class_name + "::" + name;
411 std::string unscoped_cname; //the unscoped class-name
412 {
413 auto class_name = get_name<Class>();
414 auto pos = class_name.rfind("::");
415 if (pos == std::string::npos)
416 {
417 dtor_name = class_name+ "::~" + class_name + "()";
418 unscoped_cname = class_name;
419 }
420 else
421 {
422 unscoped_cname = class_name.substr(pos+2) ;
423 dtor_name = class_name+ "::~" + unscoped_cname + "()";
424 }
425 }
426
427 auto d0 = unscoped_cname + "D0Ev";
428 auto d1 = unscoped_cname + "D1Ev";
429 auto d2 = unscoped_cname + "D2Ev";
430
431 dtor_sym dt;
432 //this is so simple, i don#t need a predicate
433 for (auto & s : storage_)
434 {
435 //alright, name fits
436 if (s.demangled == dtor_name)
437 {
438 if (s.mangled.find(d0) != std::string::npos)
439 dt.D0 = s.mangled;
440 else if (s.mangled.find(d1) != std::string::npos)
441 dt.D1 = s.mangled;
442 else if (s.mangled.find(d2) != std::string::npos)
443 dt.D2 = s.mangled;
444
445 }
446 }
447 return dt;
448
449}
450
451template<typename T>
452std::string mangled_storage_impl::get_type_info() const
453{
454 std::string id = "typeinfo for " + get_name<T>();
455
456
457 auto predicate = [&](const mangled_storage_base::entry & e)
458 {
459 return e.demangled == id;
460 };
461
462 auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
463
464
465 if (found != storage_.end())
466 return found->mangled;
467 else
468 return "";
469}
470
471template<typename T>
472std::vector<std::string> mangled_storage_impl::get_related() const
473{
474 std::vector<std::string> ret;
475 auto name = get_name<T>();
476
477 for (auto & c : storage_)
478 {
479 if (c.demangled.find(name) != std::string::npos)
480 ret.push_back(c.demangled);
481 }
482
483 return ret;
484}
485
486}}}
487
488
489#endif /* BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_ */