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