File indexing completed on 2025-01-18 09:30:42
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
0008 #define BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
0009
0010 #include <boost/dll/detail/demangling/mangled_storage_base.hpp>
0011 #include <iterator>
0012 #include <algorithm>
0013 #include <boost/type_traits/is_const.hpp>
0014 #include <boost/type_traits/is_volatile.hpp>
0015 #include <boost/type_traits/is_rvalue_reference.hpp>
0016 #include <boost/type_traits/is_lvalue_reference.hpp>
0017 #include <boost/type_traits/function_traits.hpp>
0018
0019
0020 namespace boost { namespace dll { namespace detail {
0021
0022
0023
0024 class mangled_storage_impl : public mangled_storage_base
0025 {
0026 template<typename T>
0027 struct dummy {};
0028
0029 template<typename Return, typename ...Args>
0030 std::vector<std::string> get_func_params(dummy<Return(Args...)>) const
0031 {
0032 return {get_name<Args>()...};
0033 }
0034 template<typename Return, typename ...Args>
0035 std::string get_return_type(dummy<Return(Args...)>) const
0036 {
0037 return get_name<Return>();
0038 }
0039 public:
0040 using mangled_storage_base::mangled_storage_base;
0041 struct ctor_sym
0042 {
0043 std::string C1;
0044 std::string C2;
0045 std::string C3;
0046
0047 bool empty() const
0048 {
0049 return C1.empty() && C2.empty() && C3.empty();
0050 }
0051 };
0052
0053 struct dtor_sym
0054 {
0055 std::string D0;
0056 std::string D1;
0057 std::string D2;
0058 bool empty() const
0059 {
0060 return D0.empty() && D1.empty() && D2.empty();
0061 }
0062 };
0063
0064 template<typename T>
0065 std::string get_variable(const std::string &name) const;
0066
0067 template<typename Func>
0068 std::string get_function(const std::string &name) const;
0069
0070 template<typename Class, typename Func>
0071 std::string get_mem_fn(const std::string &name) const;
0072
0073 template<typename Signature>
0074 ctor_sym get_constructor() const;
0075
0076 template<typename Class>
0077 dtor_sym get_destructor() const;
0078
0079 template<typename T>
0080 std::string get_type_info() const;
0081
0082 template<typename T>
0083 std::vector<std::string> get_related() const;
0084
0085 };
0086
0087
0088
0089 namespace parser
0090 {
0091
0092 template <typename... T>
0093 struct dummy;
0094
0095 template <typename T>
0096 std::string parse_type_helper(const mangled_storage_impl & ms, dummy<T>*);
0097
0098 template <typename... T, template <typename...> class Tn>
0099 std::string parse_type_helper(const mangled_storage_impl & ms, dummy<Tn<T...>>*);
0100
0101 template <typename... T, template <typename...> class Tn>
0102 std::string parse_type(const mangled_storage_impl & ms, dummy<Tn<T...>>*);
0103
0104 template <typename T>
0105 std::string parse_type(const mangled_storage_impl & ms, dummy<T>*);
0106
0107 template <typename T1, typename T2, typename... T3>
0108 std::string parse_type(const mangled_storage_impl & ms, dummy<T1, T2, T3...>*);
0109
0110 template <typename R, typename... Args>
0111 std::string parse_type(const mangled_storage_impl & ms, dummy<R(Args...)>*);
0112
0113 std::string parse_type(const mangled_storage_impl & ms, dummy<>*);
0114
0115 template<typename T>
0116 std::string
0117 type_name(const mangled_storage_impl &);
0118
0119
0120
0121 template<typename T>
0122 struct pure_type
0123 {
0124 typedef T type;
0125 inline static std::string type_rule() { return ""; }
0126 };
0127
0128 template<typename T>
0129 struct pure_type<T*>
0130 {
0131 typedef typename pure_type<T>::type type;
0132 inline static std::string type_rule()
0133 {
0134 return pure_type<T>::type_rule() + "*";
0135 }
0136 };
0137
0138 template<typename T>
0139 struct pure_type<T const>
0140 {
0141 typedef typename pure_type<T>::type type;
0142 inline static std::string type_rule()
0143 {
0144 return pure_type<T>::type_rule() + " const";
0145 }
0146 };
0147
0148 template<typename T>
0149 struct pure_type<T volatile>
0150 {
0151 typedef typename pure_type<T>::type type;
0152 inline static std::string type_rule()
0153 {
0154 return pure_type<T>::type_rule() + " volatile";
0155 }
0156 };
0157
0158 template<typename T>
0159 struct pure_type<T const volatile>
0160 {
0161 typedef typename pure_type<T>::type type;
0162 inline static std::string type_rule()
0163 {
0164 return pure_type<T>::type_rule() + " const volatile";
0165 }
0166 };
0167
0168 template<typename T>
0169 struct pure_type<T&>
0170 {
0171 typedef typename pure_type<T>::type type;
0172 inline static std::string type_rule()
0173 {
0174 return pure_type<T>::type_rule() + "&";
0175 }
0176 };
0177
0178 template<typename T>
0179 struct pure_type<T&&>
0180 {
0181 typedef typename pure_type<T>::type type;
0182 inline static std::string type_rule()
0183 {
0184 return pure_type<T>::type_rule() + "&&";
0185 }
0186 };
0187
0188 inline std::string const_rule_impl(true_type ) {return " const";}
0189 inline std::string const_rule_impl(false_type) {return "";}
0190 template<typename T>
0191 std::string const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
0192
0193 inline std::string volatile_rule_impl(true_type ) {return " volatile";}
0194 inline std::string volatile_rule_impl(false_type) {return "";}
0195 template<typename T>
0196 std::string volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
0197
0198 inline std::string reference_rule_impl(false_type, false_type) {return "";}
0199 inline std::string reference_rule_impl(true_type, false_type) {return "&" ;}
0200 inline std::string reference_rule_impl(false_type, true_type ) {return "&&";}
0201
0202 template<typename T>
0203 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());}
0204
0205
0206 template<typename Return, typename Arg>
0207 std::string arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
0208 {
0209 using namespace std;
0210 return type_name<Arg>(ms);
0211 }
0212
0213 template<typename Return, typename First, typename Second, typename ...Args>
0214 std::string arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
0215 {
0216 using next_type = Return (*)(Second, Args...);
0217 return type_name<First>(ms) + ", " + arg_list(ms, next_type());
0218 }
0219
0220 template<typename Return>
0221 std::string arg_list(const mangled_storage_impl &, Return (*)())
0222 {
0223 return "";
0224 }
0225
0226
0227 template <typename T>
0228 inline std::string parse_type_helper(const mangled_storage_impl & ms, dummy<T>*) {
0229 return ms.get_name<T>();
0230 }
0231
0232 template <typename... T, template <typename...> class Tn>
0233 inline std::string parse_type_helper(const mangled_storage_impl & ms, dummy<Tn<T...>>*) {
0234 using type = dummy<Tn<T...>>*;
0235 return parse_type(ms, type());
0236 }
0237
0238 template <typename R, typename... Args>
0239 inline std::string parse_type(const mangled_storage_impl & ms, dummy<R(*)(Args...)>*) {
0240 using args_type = dummy<Args...>*;
0241 using return_type = dummy<R>*;
0242 return parse_type(ms, return_type()) + " (*)(" + parse_type(ms, args_type()) + ")";
0243 }
0244
0245 template <typename R, typename... Args>
0246 inline std::string parse_type(const mangled_storage_impl & ms, dummy<R(Args...)>*) {
0247 using args_type = dummy<Args...>*;
0248 using return_type = dummy<R>*;
0249 return parse_type(ms, return_type()) + " (" + parse_type(ms, args_type()) + ")";
0250 }
0251
0252 template <typename T>
0253 inline std::string parse_type(const mangled_storage_impl & ms, dummy<T>*) {
0254 using type = dummy<typename pure_type<T>::type>*;
0255 auto str = parse_type_helper(ms, type());
0256 return str + pure_type<T>::type_rule();
0257 }
0258
0259 template <typename T1, typename T2, typename... T3>
0260 inline std::string parse_type(const mangled_storage_impl & ms, dummy<T1, T2, T3...>*) {
0261 using first_type = dummy<T1>*;
0262 using next_type = dummy<T2, T3...>*;
0263 return parse_type(ms, first_type()) + ", " + parse_type(ms, next_type());
0264 }
0265
0266 template <typename... T, template <typename...> class Tn>
0267 inline std::string parse_type(const mangled_storage_impl & ms, dummy<Tn<T...>>*) {
0268 using next_type = dummy<T...>*;
0269 std::string str = ms.get_name<Tn<T...>>();
0270 auto frist = str.find_first_of("<");
0271 std::string template_name = str.substr(0, frist);
0272 std::string args_name = parse_type(ms, next_type());
0273 char last_ch = args_name[args_name.size() - 1];
0274 return template_name + "<" + args_name + (last_ch == '>' ? " >" : ">");
0275 }
0276
0277 inline std::string parse_type(const mangled_storage_impl &, dummy<>*) {
0278 return "";
0279 }
0280
0281 template<typename T>
0282 inline std::string
0283 type_name(const mangled_storage_impl &ms)
0284 {
0285 using namespace parser;
0286 using type = dummy<T>*;
0287 return parse_type(ms, type());
0288 }
0289 }
0290
0291
0292
0293 template<typename T> std::string mangled_storage_impl::get_variable(const std::string &name) const
0294 {
0295 auto found = std::find_if(storage_.begin(), storage_.end(),
0296 [&](const entry& e) {return e.demangled == name;});
0297
0298 if (found != storage_.end())
0299 return found->mangled;
0300 else
0301 return "";
0302 }
0303
0304 template<typename Func> std::string mangled_storage_impl::get_function(const std::string &name) const
0305 {
0306 using func_type = Func*;
0307
0308 auto matcher = name + '(' + parser::arg_list(*this, func_type()) + ')';
0309
0310 auto found = std::find_if(storage_.begin(), storage_.end(), [&](const entry& e) {return e.demangled == matcher;});
0311 if (found != storage_.end())
0312 return found->mangled;
0313 else
0314 return "";
0315
0316 }
0317
0318 template<typename Class, typename Func>
0319 std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
0320 {
0321 using namespace parser;
0322
0323 using func_type = Func*;
0324
0325 std::string cname = get_name<Class>();
0326
0327 const auto matcher = cname + "::" + name +
0328 '(' + parser::arg_list(*this, func_type()) + ')'
0329 + const_rule<Class>() + volatile_rule<Class>();
0330
0331
0332 auto found = std::find_if(storage_.begin(), storage_.end(), [&matcher](const entry& e) {
0333 if (e.demangled == matcher) {
0334 return true;
0335 }
0336
0337 const auto pos = e.demangled.rfind(matcher);
0338 if (pos == std::string::npos) {
0339
0340 return false;
0341 }
0342
0343 if (pos + matcher.size() != e.demangled.size()) {
0344
0345 return false;
0346 }
0347
0348
0349 return e.demangled[pos - 1] == ' ';
0350 });
0351
0352 if (found != storage_.end())
0353 return found->mangled;
0354 else
0355 return "";
0356
0357 }
0358
0359
0360 template<typename Signature>
0361 auto mangled_storage_impl::get_constructor() const -> ctor_sym
0362 {
0363 using namespace parser;
0364
0365 using func_type = Signature*;
0366
0367 std::string ctor_name;
0368 std::string unscoped_cname;
0369 {
0370 auto class_name = get_return_type(dummy<Signature>());
0371 auto pos = class_name.rfind("::");
0372 if (pos == std::string::npos)
0373 {
0374 ctor_name = class_name+ "::" +class_name ;
0375 unscoped_cname = class_name;
0376 }
0377 else
0378 {
0379 unscoped_cname = class_name.substr(pos+2) ;
0380 ctor_name = class_name+ "::" + unscoped_cname;
0381 }
0382 }
0383
0384 auto matcher =
0385 ctor_name + '(' + parser::arg_list(*this, func_type()) + ')';
0386
0387
0388 std::vector<entry> findings;
0389 std::copy_if(storage_.begin(), storage_.end(),
0390 std::back_inserter(findings), [&](const entry& e) {return e.demangled == matcher;});
0391
0392 ctor_sym ct;
0393
0394 for (auto & e : findings)
0395 {
0396
0397 if (e.mangled.find(unscoped_cname +"C1E") != std::string::npos)
0398 ct.C1 = e.mangled;
0399 else if (e.mangled.find(unscoped_cname +"C2E") != std::string::npos)
0400 ct.C2 = e.mangled;
0401 else if (e.mangled.find(unscoped_cname +"C3E") != std::string::npos)
0402 ct.C3 = e.mangled;
0403 }
0404 return ct;
0405 }
0406
0407 template<typename Class>
0408 auto mangled_storage_impl::get_destructor() const -> dtor_sym
0409 {
0410 std::string dtor_name;
0411 std::string unscoped_cname;
0412 {
0413 auto class_name = get_name<Class>();
0414 auto pos = class_name.rfind("::");
0415 if (pos == std::string::npos)
0416 {
0417 dtor_name = class_name+ "::~" + class_name + "()";
0418 unscoped_cname = class_name;
0419 }
0420 else
0421 {
0422 unscoped_cname = class_name.substr(pos+2) ;
0423 dtor_name = class_name+ "::~" + unscoped_cname + "()";
0424 }
0425 }
0426
0427 auto d0 = unscoped_cname + "D0Ev";
0428 auto d1 = unscoped_cname + "D1Ev";
0429 auto d2 = unscoped_cname + "D2Ev";
0430
0431 dtor_sym dt;
0432
0433 for (auto & s : storage_)
0434 {
0435
0436 if (s.demangled == dtor_name)
0437 {
0438 if (s.mangled.find(d0) != std::string::npos)
0439 dt.D0 = s.mangled;
0440 else if (s.mangled.find(d1) != std::string::npos)
0441 dt.D1 = s.mangled;
0442 else if (s.mangled.find(d2) != std::string::npos)
0443 dt.D2 = s.mangled;
0444
0445 }
0446 }
0447 return dt;
0448
0449 }
0450
0451 template<typename T>
0452 std::string mangled_storage_impl::get_type_info() const
0453 {
0454 std::string id = "typeinfo for " + get_name<T>();
0455
0456
0457 auto predicate = [&](const mangled_storage_base::entry & e)
0458 {
0459 return e.demangled == id;
0460 };
0461
0462 auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
0463
0464
0465 if (found != storage_.end())
0466 return found->mangled;
0467 else
0468 return "";
0469 }
0470
0471 template<typename T>
0472 std::vector<std::string> mangled_storage_impl::get_related() const
0473 {
0474 std::vector<std::string> ret;
0475 auto name = get_name<T>();
0476
0477 for (auto & c : storage_)
0478 {
0479 if (c.demangled.find(name) != std::string::npos)
0480 ret.push_back(c.demangled);
0481 }
0482
0483 return ret;
0484 }
0485
0486 }}}
0487
0488
0489 #endif