itanium.hpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. #ifndef BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
  7. #define BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
  8. #include <boost/dll/detail/demangling/mangled_storage_base.hpp>
  9. #include <iterator>
  10. #include <algorithm>
  11. #include <boost/type_traits/is_const.hpp>
  12. #include <boost/type_traits/is_volatile.hpp>
  13. #include <boost/type_traits/is_rvalue_reference.hpp>
  14. #include <boost/type_traits/is_lvalue_reference.hpp>
  15. #include <boost/type_traits/function_traits.hpp>
  16. namespace boost { namespace dll { namespace detail {
  17. class mangled_storage_impl : public mangled_storage_base
  18. {
  19. template<typename T>
  20. struct dummy {};
  21. template<typename Return, typename ...Args>
  22. std::vector<std::string> get_func_params(dummy<Return(Args...)>) const
  23. {
  24. return {get_name<Args>()...};
  25. }
  26. template<typename Return, typename ...Args>
  27. std::string get_return_type(dummy<Return(Args...)>) const
  28. {
  29. return get_name<Return>();
  30. }
  31. public:
  32. using mangled_storage_base::mangled_storage_base;
  33. struct ctor_sym
  34. {
  35. std::string C1;
  36. std::string C2;
  37. std::string C3;
  38. bool empty() const
  39. {
  40. return C1.empty() && C2.empty() && C3.empty();
  41. }
  42. };
  43. struct dtor_sym
  44. {
  45. std::string D0;
  46. std::string D1;
  47. std::string D2;
  48. bool empty() const
  49. {
  50. return D0.empty() && D1.empty() && D2.empty();
  51. }
  52. };
  53. template<typename T>
  54. std::string get_variable(const std::string &name) const;
  55. template<typename Func>
  56. std::string get_function(const std::string &name) const;
  57. template<typename Class, typename Func>
  58. std::string get_mem_fn(const std::string &name) const;
  59. template<typename Signature>
  60. ctor_sym get_constructor() const;
  61. template<typename Class>
  62. dtor_sym get_destructor() const;
  63. template<typename T>
  64. std::string get_type_info() const;
  65. template<typename T>
  66. std::vector<std::string> get_related() const;
  67. };
  68. namespace parser
  69. {
  70. inline std::string const_rule_impl(true_type ) {return " const";}
  71. inline std::string const_rule_impl(false_type) {return "";}
  72. template<typename T>
  73. std::string const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
  74. inline std::string volatile_rule_impl(true_type ) {return " volatile";}
  75. inline std::string volatile_rule_impl(false_type) {return "";}
  76. template<typename T>
  77. std::string volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
  78. inline std::string reference_rule_impl(false_type, false_type) {return "";}
  79. inline std::string reference_rule_impl(true_type, false_type) {return "&" ;}
  80. inline std::string reference_rule_impl(false_type, true_type ) {return "&&";}
  81. template<typename T>
  82. 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());}
  83. //it takes a string, because it may be overloaded.
  84. template<typename T>
  85. std::string type_rule(const std::string & type_name)
  86. {
  87. using namespace std;
  88. return type_name +
  89. const_rule<T>() +
  90. volatile_rule<T>() +
  91. reference_rule<T>();
  92. }
  93. template<typename Return, typename Arg>
  94. std::string arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
  95. {
  96. using namespace std;
  97. auto str = ms.get_name<Arg>();
  98. return type_rule<Arg>(str);
  99. }
  100. template<typename Return, typename First, typename Second, typename ...Args>
  101. std::string arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
  102. {
  103. auto st = ms.get_name<First>();
  104. using next_type = Return (*)(Second, Args...);
  105. return type_rule<First>(st) + ", " + arg_list(ms, next_type());
  106. }
  107. template<typename Return>
  108. std::string arg_list(const mangled_storage_impl &, Return (*)())
  109. {
  110. return "";
  111. }
  112. }
  113. template<typename T> std::string mangled_storage_impl::get_variable(const std::string &name) const
  114. {
  115. auto found = std::find_if(storage_.begin(), storage_.end(),
  116. [&](const entry& e) {return e.demangled == name;});
  117. if (found != storage_.end())
  118. return found->mangled;
  119. else
  120. return "";
  121. }
  122. template<typename Func> std::string mangled_storage_impl::get_function(const std::string &name) const
  123. {
  124. using func_type = Func*;
  125. auto matcher = name + '(' + parser::arg_list(*this, func_type()) + ')';
  126. auto found = std::find_if(storage_.begin(), storage_.end(), [&](const entry& e) {return e.demangled == matcher;});
  127. if (found != storage_.end())
  128. return found->mangled;
  129. else
  130. return "";
  131. }
  132. template<typename Class, typename Func>
  133. std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
  134. {
  135. using namespace parser;
  136. using func_type = Func*;
  137. std::string cname = get_name<Class>();
  138. auto matcher = cname + "::" + name +
  139. '(' + parser::arg_list(*this, func_type()) + ')'
  140. + const_rule<Class>() + volatile_rule<Class>();
  141. auto found = std::find_if(storage_.begin(), storage_.end(), [&](const entry& e) {return e.demangled == matcher;});
  142. if (found != storage_.end())
  143. return found->mangled;
  144. else
  145. return "";
  146. }
  147. template<typename Signature>
  148. auto mangled_storage_impl::get_constructor() const -> ctor_sym
  149. {
  150. using namespace parser;
  151. using func_type = Signature*;
  152. std::string ctor_name; // = class_name + "::" + name;
  153. std::string unscoped_cname; //the unscoped class-name
  154. {
  155. auto class_name = get_return_type(dummy<Signature>());
  156. auto pos = class_name.rfind("::");
  157. if (pos == std::string::npos)
  158. {
  159. ctor_name = class_name+ "::" +class_name ;
  160. unscoped_cname = class_name;
  161. }
  162. else
  163. {
  164. unscoped_cname = class_name.substr(pos+2) ;
  165. ctor_name = class_name+ "::" + unscoped_cname;
  166. }
  167. }
  168. auto matcher =
  169. ctor_name + '(' + parser::arg_list(*this, func_type()) + ')';
  170. std::vector<entry> findings;
  171. std::copy_if(storage_.begin(), storage_.end(),
  172. std::back_inserter(findings), [&](const entry& e) {return e.demangled == matcher;});
  173. ctor_sym ct;
  174. for (auto & e : findings)
  175. {
  176. if (e.mangled.find(unscoped_cname +"C1E") != std::string::npos)
  177. ct.C1 = e.mangled;
  178. else if (e.mangled.find(unscoped_cname +"C2E") != std::string::npos)
  179. ct.C2 = e.mangled;
  180. else if (e.mangled.find(unscoped_cname +"C3E") != std::string::npos)
  181. ct.C3 = e.mangled;
  182. }
  183. return ct;
  184. }
  185. template<typename Class>
  186. auto mangled_storage_impl::get_destructor() const -> dtor_sym
  187. {
  188. std::string dtor_name; // = class_name + "::" + name;
  189. std::string unscoped_cname; //the unscoped class-name
  190. {
  191. auto class_name = get_name<Class>();
  192. auto pos = class_name.rfind("::");
  193. if (pos == std::string::npos)
  194. {
  195. dtor_name = class_name+ "::~" + class_name + "()";
  196. unscoped_cname = class_name;
  197. }
  198. else
  199. {
  200. unscoped_cname = class_name.substr(pos+2) ;
  201. dtor_name = class_name+ "::~" + unscoped_cname + "()";
  202. }
  203. }
  204. auto d0 = unscoped_cname + "D0Ev";
  205. auto d1 = unscoped_cname + "D1Ev";
  206. auto d2 = unscoped_cname + "D2Ev";
  207. dtor_sym dt;
  208. //this is so simple, i don#t need a predicate
  209. for (auto & s : storage_)
  210. {
  211. //alright, name fits
  212. if (s.demangled == dtor_name)
  213. {
  214. if (s.mangled.find(d0) != std::string::npos)
  215. dt.D0 = s.mangled;
  216. else if (s.mangled.find(d1) != std::string::npos)
  217. dt.D1 = s.mangled;
  218. else if (s.mangled.find(d2) != std::string::npos)
  219. dt.D2 = s.mangled;
  220. }
  221. }
  222. return dt;
  223. }
  224. template<typename T>
  225. std::string mangled_storage_impl::get_type_info() const
  226. {
  227. std::string id = "typeinfo for " + get_name<T>();
  228. auto predicate = [&](const mangled_storage_base::entry & e)
  229. {
  230. return e.demangled == id;
  231. };
  232. auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
  233. if (found != storage_.end())
  234. return found->mangled;
  235. else
  236. return "";
  237. }
  238. template<typename T>
  239. std::vector<std::string> mangled_storage_impl::get_related() const
  240. {
  241. std::vector<std::string> ret;
  242. auto name = get_name<T>();
  243. for (auto & c : storage_)
  244. {
  245. if (c.demangled.find(name) != std::string::npos)
  246. ret.push_back(c.demangled);
  247. }
  248. return ret;
  249. }
  250. }}}
  251. #endif /* BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_ */