123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- // Copyright 2016 Klemens Morgenstern
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt
- // or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
- #define BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
- #include <boost/dll/detail/demangling/mangled_storage_base.hpp>
- #include <iterator>
- #include <algorithm>
- #include <boost/type_traits/is_const.hpp>
- #include <boost/type_traits/is_volatile.hpp>
- #include <boost/type_traits/is_rvalue_reference.hpp>
- #include <boost/type_traits/is_lvalue_reference.hpp>
- #include <boost/type_traits/function_traits.hpp>
- namespace boost { namespace dll { namespace detail {
- class mangled_storage_impl : public mangled_storage_base
- {
- template<typename T>
- struct dummy {};
- template<typename Return, typename ...Args>
- std::vector<std::string> get_func_params(dummy<Return(Args...)>) const
- {
- return {get_name<Args>()...};
- }
- template<typename Return, typename ...Args>
- std::string get_return_type(dummy<Return(Args...)>) const
- {
- return get_name<Return>();
- }
- public:
- using mangled_storage_base::mangled_storage_base;
- struct ctor_sym
- {
- std::string C1;
- std::string C2;
- std::string C3;
- bool empty() const
- {
- return C1.empty() && C2.empty() && C3.empty();
- }
- };
- struct dtor_sym
- {
- std::string D0;
- std::string D1;
- std::string D2;
- bool empty() const
- {
- return D0.empty() && D1.empty() && D2.empty();
- }
- };
- template<typename T>
- std::string get_variable(const std::string &name) const;
- template<typename Func>
- std::string get_function(const std::string &name) const;
- template<typename Class, typename Func>
- std::string get_mem_fn(const std::string &name) const;
- template<typename Signature>
- ctor_sym get_constructor() const;
- template<typename Class>
- dtor_sym get_destructor() const;
- template<typename T>
- std::string get_type_info() const;
- template<typename T>
- std::vector<std::string> get_related() const;
- };
- namespace parser
- {
- inline std::string const_rule_impl(true_type ) {return " const";}
- inline std::string const_rule_impl(false_type) {return "";}
- template<typename T>
- std::string const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
- inline std::string volatile_rule_impl(true_type ) {return " volatile";}
- inline std::string volatile_rule_impl(false_type) {return "";}
- template<typename T>
- std::string volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
- inline std::string reference_rule_impl(false_type, false_type) {return "";}
- inline std::string reference_rule_impl(true_type, false_type) {return "&" ;}
- inline std::string reference_rule_impl(false_type, true_type ) {return "&&";}
- template<typename T>
- 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());}
- //it takes a string, because it may be overloaded.
- template<typename T>
- std::string type_rule(const std::string & type_name)
- {
- using namespace std;
- return type_name +
- const_rule<T>() +
- volatile_rule<T>() +
- reference_rule<T>();
- }
- template<typename Return, typename Arg>
- std::string arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
- {
- using namespace std;
- auto str = ms.get_name<Arg>();
- return type_rule<Arg>(str);
- }
- template<typename Return, typename First, typename Second, typename ...Args>
- std::string arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
- {
- auto st = ms.get_name<First>();
- using next_type = Return (*)(Second, Args...);
- return type_rule<First>(st) + ", " + arg_list(ms, next_type());
- }
- template<typename Return>
- std::string arg_list(const mangled_storage_impl &, Return (*)())
- {
- return "";
- }
- }
- template<typename T> std::string mangled_storage_impl::get_variable(const std::string &name) const
- {
- auto found = std::find_if(storage_.begin(), storage_.end(),
- [&](const entry& e) {return e.demangled == name;});
- if (found != storage_.end())
- return found->mangled;
- else
- return "";
- }
- template<typename Func> std::string mangled_storage_impl::get_function(const std::string &name) const
- {
- using func_type = Func*;
- auto matcher = name + '(' + parser::arg_list(*this, func_type()) + ')';
- auto found = std::find_if(storage_.begin(), storage_.end(), [&](const entry& e) {return e.demangled == matcher;});
- if (found != storage_.end())
- return found->mangled;
- else
- return "";
- }
- template<typename Class, typename Func>
- std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
- {
- using namespace parser;
- using func_type = Func*;
- std::string cname = get_name<Class>();
- auto matcher = cname + "::" + name +
- '(' + parser::arg_list(*this, func_type()) + ')'
- + const_rule<Class>() + volatile_rule<Class>();
- auto found = std::find_if(storage_.begin(), storage_.end(), [&](const entry& e) {return e.demangled == matcher;});
- if (found != storage_.end())
- return found->mangled;
- else
- return "";
- }
- template<typename Signature>
- auto mangled_storage_impl::get_constructor() const -> ctor_sym
- {
- using namespace parser;
- using func_type = Signature*;
- std::string ctor_name; // = class_name + "::" + name;
- std::string unscoped_cname; //the unscoped class-name
- {
- auto class_name = get_return_type(dummy<Signature>());
- auto pos = class_name.rfind("::");
- if (pos == std::string::npos)
- {
- ctor_name = class_name+ "::" +class_name ;
- unscoped_cname = class_name;
- }
- else
- {
- unscoped_cname = class_name.substr(pos+2) ;
- ctor_name = class_name+ "::" + unscoped_cname;
- }
- }
- auto matcher =
- ctor_name + '(' + parser::arg_list(*this, func_type()) + ')';
- std::vector<entry> findings;
- std::copy_if(storage_.begin(), storage_.end(),
- std::back_inserter(findings), [&](const entry& e) {return e.demangled == matcher;});
- ctor_sym ct;
- for (auto & e : findings)
- {
- if (e.mangled.find(unscoped_cname +"C1E") != std::string::npos)
- ct.C1 = e.mangled;
- else if (e.mangled.find(unscoped_cname +"C2E") != std::string::npos)
- ct.C2 = e.mangled;
- else if (e.mangled.find(unscoped_cname +"C3E") != std::string::npos)
- ct.C3 = e.mangled;
- }
- return ct;
- }
- template<typename Class>
- auto mangled_storage_impl::get_destructor() const -> dtor_sym
- {
- std::string dtor_name; // = class_name + "::" + name;
- std::string unscoped_cname; //the unscoped class-name
- {
- auto class_name = get_name<Class>();
- auto pos = class_name.rfind("::");
- if (pos == std::string::npos)
- {
- dtor_name = class_name+ "::~" + class_name + "()";
- unscoped_cname = class_name;
- }
- else
- {
- unscoped_cname = class_name.substr(pos+2) ;
- dtor_name = class_name+ "::~" + unscoped_cname + "()";
- }
- }
- auto d0 = unscoped_cname + "D0Ev";
- auto d1 = unscoped_cname + "D1Ev";
- auto d2 = unscoped_cname + "D2Ev";
- dtor_sym dt;
- //this is so simple, i don#t need a predicate
- for (auto & s : storage_)
- {
- //alright, name fits
- if (s.demangled == dtor_name)
- {
- if (s.mangled.find(d0) != std::string::npos)
- dt.D0 = s.mangled;
- else if (s.mangled.find(d1) != std::string::npos)
- dt.D1 = s.mangled;
- else if (s.mangled.find(d2) != std::string::npos)
- dt.D2 = s.mangled;
- }
- }
- return dt;
- }
- template<typename T>
- std::string mangled_storage_impl::get_type_info() const
- {
- std::string id = "typeinfo for " + get_name<T>();
- auto predicate = [&](const mangled_storage_base::entry & e)
- {
- return e.demangled == id;
- };
- auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
- if (found != storage_.end())
- return found->mangled;
- else
- return "";
- }
- template<typename T>
- std::vector<std::string> mangled_storage_impl::get_related() const
- {
- std::vector<std::string> ret;
- auto name = get_name<T>();
- for (auto & c : storage_)
- {
- if (c.demangled.find(name) != std::string::npos)
- ret.push_back(c.demangled);
- }
- return ret;
- }
- }}}
- #endif /* BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_ */
|