stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
// Copyright 2015 Klemens Morgenstern
|
||||
//
|
||||
// This file provides a demangling for function names, i.e. entry points of a dll.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_DLL_DEMANGLE_SYMBOL_HPP_
|
||||
#define BOOST_DLL_DEMANGLE_SYMBOL_HPP_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(BOOST_MSVC) || defined(BOOST_MSVC_FULL_VER)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace dll
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef void * (__cdecl * allocation_function)(std::size_t);
|
||||
typedef void (__cdecl * free_function)(void *);
|
||||
|
||||
extern "C" char* __unDName( char* outputString,
|
||||
const char* name,
|
||||
int maxStringLength, // Note, COMMA is leading following optional arguments
|
||||
allocation_function pAlloc,
|
||||
free_function pFree,
|
||||
unsigned short disableFlags
|
||||
);
|
||||
|
||||
|
||||
inline std::string demangle_symbol(const char *mangled_name)
|
||||
{
|
||||
|
||||
allocation_function alloc = [](std::size_t size){return static_cast<void*>(new char[size]);};
|
||||
free_function free_f = [](void* p){delete [] static_cast<char*>(p);};
|
||||
|
||||
|
||||
|
||||
std::unique_ptr<char> name { __unDName(
|
||||
nullptr,
|
||||
mangled_name,
|
||||
0,
|
||||
alloc,
|
||||
free_f,
|
||||
static_cast<unsigned short>(0))};
|
||||
|
||||
return std::string(name.get());
|
||||
}
|
||||
inline std::string demangle_symbol(const std::string& mangled_name)
|
||||
{
|
||||
return demangle_symbol(mangled_name.c_str());
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
#else
|
||||
|
||||
#include <boost/core/demangle.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace dll
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline std::string demangle_symbol(const char *mangled_name)
|
||||
{
|
||||
|
||||
if (*mangled_name == '_')
|
||||
{
|
||||
//because it start's with an underline _
|
||||
auto dm = boost::core::demangle(mangled_name);
|
||||
if (!dm.empty())
|
||||
return dm;
|
||||
else
|
||||
return (mangled_name);
|
||||
}
|
||||
|
||||
//could not demangled
|
||||
return "";
|
||||
|
||||
|
||||
}
|
||||
|
||||
//for my personal convinience
|
||||
inline std::string demangle_symbol(const std::string& mangled_name)
|
||||
{
|
||||
return demangle_symbol(mangled_name.c_str());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
namespace experimental
|
||||
{
|
||||
using ::boost::dll::detail::demangle_symbol;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* BOOST_DEMANGLE_HPP_ */
|
||||
@@ -0,0 +1,326 @@
|
||||
// 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_ */
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
// 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_MANGLE_STORAGE_BASE_HPP_
|
||||
#define BOOST_DLL_DETAIL_MANGLE_STORAGE_BASE_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <boost/dll/detail/demangling/demangle_symbol.hpp>
|
||||
#include <boost/dll/library_info.hpp>
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
namespace boost { namespace dll { namespace detail {
|
||||
|
||||
///stores the mangled names with the demangled name.
|
||||
struct mangled_storage_base
|
||||
{
|
||||
struct entry
|
||||
{
|
||||
std::string mangled;
|
||||
std::string demangled;
|
||||
entry() = default;
|
||||
entry(const std::string & m, const std::string &d) : mangled(m), demangled(d) {}
|
||||
entry(const entry&) = default;
|
||||
entry(entry&&) = default;
|
||||
entry &operator= (const entry&) = default;
|
||||
entry &operator= (entry&&) = default;
|
||||
};
|
||||
protected:
|
||||
std::vector<entry> storage_;
|
||||
///if a unknown class is imported it can be overloaded by this type
|
||||
std::map<boost::typeindex::ctti_type_index, std::string> aliases_;
|
||||
public:
|
||||
void assign(const mangled_storage_base & storage)
|
||||
{
|
||||
aliases_ = storage.aliases_;
|
||||
storage_ = storage.storage_;
|
||||
}
|
||||
void swap( mangled_storage_base & storage)
|
||||
{
|
||||
aliases_.swap(storage.aliases_);
|
||||
storage_.swap(storage.storage_);
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
storage_.clear();
|
||||
aliases_.clear();
|
||||
}
|
||||
std::vector<entry> & get_storage() {return storage_;};
|
||||
template<typename T>
|
||||
std::string get_name() const
|
||||
{
|
||||
using boost::typeindex::ctti_type_index;
|
||||
auto tx = ctti_type_index::type_id<T>();
|
||||
auto val = (aliases_.count(tx) > 0) ? aliases_.at(tx) : tx.pretty_name();
|
||||
return val;
|
||||
}
|
||||
|
||||
mangled_storage_base() = default;
|
||||
mangled_storage_base(mangled_storage_base&&) = default;
|
||||
mangled_storage_base(const mangled_storage_base&) = default;
|
||||
|
||||
mangled_storage_base(const std::vector<std::string> & symbols) { add_symbols(symbols);}
|
||||
|
||||
explicit mangled_storage_base(library_info & li) : mangled_storage_base(li.symbols()) {}
|
||||
|
||||
explicit mangled_storage_base(
|
||||
const boost::filesystem::path& library_path,
|
||||
bool throw_if_not_native_format = true)
|
||||
: mangled_storage_base(library_info(library_path, throw_if_not_native_format).symbols())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void load(library_info & li) { storage_.clear(); add_symbols(li.symbols()); };
|
||||
void load(const boost::filesystem::path& library_path,
|
||||
bool throw_if_not_native_format = true)
|
||||
{
|
||||
storage_.clear();
|
||||
add_symbols(library_info(library_path, throw_if_not_native_format).symbols());
|
||||
};
|
||||
|
||||
/*! Allows do add a class as alias, if the class imported is not known
|
||||
* in this binary.
|
||||
* @tparam Alias The Alias type
|
||||
* @param The name to create the alias for.
|
||||
*
|
||||
* @note There can be multiple aliases, this is on purpose.
|
||||
*/
|
||||
template<typename Alias> void add_alias(const std::string& name)
|
||||
{
|
||||
aliases_.emplace(
|
||||
boost::typeindex::ctti_type_index::type_id<Alias>(),
|
||||
name
|
||||
);
|
||||
}
|
||||
void add_symbols(const std::vector<std::string> & symbols)
|
||||
{
|
||||
for (auto & sym : symbols)
|
||||
{
|
||||
auto dm = demangle_symbol(sym);
|
||||
if (!dm.empty())
|
||||
storage_.emplace_back(sym, dm);
|
||||
else
|
||||
storage_.emplace_back(sym, sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* BOOST_DLL_DETAIL_MANGLE_STORAGE_HPP_ */
|
||||
@@ -0,0 +1,439 @@
|
||||
// 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_MSVC_HPP_
|
||||
#define BOOST_DLL_DETAIL_DEMANGLING_MSVC_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_lvalue_reference.hpp>
|
||||
#include <boost/type_traits/is_rvalue_reference.hpp>
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#include <boost/spirit/home/x3.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>();
|
||||
}
|
||||
//function to remove preceeding 'class ' or 'struct ' if the are given in this format.
|
||||
|
||||
inline static void trim_typename(std::string & val);
|
||||
public:
|
||||
using ctor_sym = std::string;
|
||||
using dtor_sym = std::string;
|
||||
|
||||
using mangled_storage_base::mangled_storage_base;
|
||||
|
||||
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> //overload, does not need to virtual.
|
||||
std::string get_name() const
|
||||
{
|
||||
auto nm = mangled_storage_base::get_name<T>();
|
||||
trim_typename(nm);
|
||||
return nm;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string get_vtable() const;
|
||||
|
||||
template<typename T>
|
||||
std::vector<std::string> get_related() const;
|
||||
|
||||
};
|
||||
|
||||
void mangled_storage_impl::trim_typename(std::string & val)
|
||||
{
|
||||
//remove preceeding class or struct, because you might want to use a struct as class, et vice versa
|
||||
if (val.size() >= 6)
|
||||
{
|
||||
using namespace std;
|
||||
static constexpr char class_ [7] = "class ";
|
||||
static constexpr char struct_[8] = "struct ";
|
||||
|
||||
if (equal(begin(class_), end(class_)-1, val.begin())) //aklright, starts with 'class '
|
||||
val.erase(0, 6);
|
||||
else if (val.size() >= 7)
|
||||
if (equal(begin(struct_), end(struct_)-1, val.begin()))
|
||||
val.erase(0, 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace parser
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
|
||||
auto ptr_rule_impl(std::integral_constant<std::size_t, 32>)
|
||||
{
|
||||
return -((-x3::space) >> "__ptr32");
|
||||
}
|
||||
auto ptr_rule_impl(std::integral_constant<std::size_t, 64>)
|
||||
{
|
||||
return -((-x3::space) >> "__ptr64");
|
||||
}
|
||||
|
||||
auto ptr_rule() { return ptr_rule_impl(std::integral_constant<std::size_t, sizeof(std::size_t)*8>());}
|
||||
|
||||
auto const visibility = ("public:" | x3::lit("protected:") | "private:");
|
||||
auto const virtual_ = x3::space >> "virtual";
|
||||
auto const static_ = x3::space >> x3::lit("static") ;
|
||||
|
||||
auto const_rule_impl(true_type ) {return x3::space >> "const";};
|
||||
auto const_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
|
||||
|
||||
auto volatile_rule_impl(true_type ) {return x3::space >> "volatile";};
|
||||
auto volatile_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
|
||||
|
||||
|
||||
auto inv_const_rule_impl(true_type ) {return "const" >> x3::space ;};
|
||||
auto inv_const_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto inv_const_rule() {using t = is_const<typename remove_reference<T>::type>; return inv_const_rule_impl(t());}
|
||||
|
||||
auto inv_volatile_rule_impl(true_type ) {return "volatile" >> x3::space;};
|
||||
auto inv_volatile_rule_impl(false_type) {return x3::eps;};
|
||||
template<typename T>
|
||||
auto inv_volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return inv_volatile_rule_impl(t());}
|
||||
|
||||
|
||||
auto reference_rule_impl(false_type, false_type) {return x3::eps;}
|
||||
auto reference_rule_impl(true_type, false_type) {return x3::space >>"&" ;}
|
||||
auto reference_rule_impl(false_type, true_type ) {return x3::space >>"&&" ;}
|
||||
|
||||
|
||||
template<typename T>
|
||||
auto reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
|
||||
|
||||
auto const class_ = ("class" | x3::lit("struct"));
|
||||
|
||||
//it takes a string, because it may be overloaded.
|
||||
template<typename T>
|
||||
auto type_rule(const std::string & type_name)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
return -(class_ >> x3::space)>> x3::string(type_name) >>
|
||||
const_rule<T>() >>
|
||||
volatile_rule<T>() >>
|
||||
reference_rule<T>() >>
|
||||
ptr_rule();
|
||||
}
|
||||
template<>
|
||||
auto type_rule<void>(const std::string &) { return x3::string("void"); };
|
||||
|
||||
auto const cdecl_ = "__cdecl" >> x3::space;
|
||||
auto const stdcall = "__stdcall" >> x3::space;
|
||||
#if defined(_WIN64)//seems to be necessary by msvc 14-x64
|
||||
auto const thiscall = "__cdecl" >> x3::space;
|
||||
#else
|
||||
auto const thiscall = "__thiscall" >> x3::space;
|
||||
#endif
|
||||
|
||||
template<typename Return, typename Arg>
|
||||
auto arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
return type_rule<Arg>(ms.get_name<Arg>());
|
||||
}
|
||||
|
||||
template<typename Return, typename First, typename Second, typename ...Args>
|
||||
auto arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
|
||||
{
|
||||
|
||||
using next_type = Return (*)(Second, Args...);
|
||||
return type_rule<First>(ms.get_name<First>()) >> x3::char_(',') >> arg_list(ms, next_type());
|
||||
}
|
||||
|
||||
template<typename Return>
|
||||
auto arg_list(const mangled_storage_impl& /*ms*/, Return (*)())
|
||||
{
|
||||
return x3::string("void");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T> std::string mangled_storage_impl::get_variable(const std::string &name) const
|
||||
{
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
|
||||
auto type_name = get_name<T>();
|
||||
|
||||
auto matcher =
|
||||
-(visibility >> static_ >> x3::space) >> //it may be a static class-member
|
||||
parser::type_rule<T>(type_name) >> x3::space >>
|
||||
name;
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
if (e.demangled == name)//maybe not mangled,
|
||||
return true;
|
||||
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
|
||||
if (found != storage_.end())
|
||||
return found->mangled;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
template<typename Func> std::string mangled_storage_impl::get_function(const std::string &name) const
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
using func_type = Func*;
|
||||
using return_type = typename function_traits<Func>::result_type;
|
||||
std::string return_type_name = get_name<return_type>();
|
||||
|
||||
|
||||
auto matcher =
|
||||
-(visibility >> static_ >> x3::space) >> //it may be a static class-member, which does however not have the static attribute.
|
||||
parser::type_rule<return_type>(return_type_name) >> x3::space >>
|
||||
cdecl_ >> //cdecl declaration for methods. stdcall cannot be
|
||||
name >> x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >> parser::ptr_rule();
|
||||
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
if (e.demangled == name)//maybe not mangled,
|
||||
return true;
|
||||
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
|
||||
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
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
using func_type = Func*;
|
||||
using return_type = typename function_traits<Func>::result_type;
|
||||
auto return_type_name = get_name<return_type>();
|
||||
|
||||
|
||||
auto cname = get_name<Class>();
|
||||
|
||||
auto matcher =
|
||||
visibility >> -virtual_ >> x3::space >>
|
||||
parser::type_rule<return_type>(return_type_name) >> x3::space >>
|
||||
thiscall >> //cdecl declaration for methods. stdcall cannot be
|
||||
cname >> "::" >> name >>
|
||||
x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >>
|
||||
inv_const_rule<Class>() >> inv_volatile_rule<Class>() >> parser::ptr_rule();
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
|
||||
if (found != storage_.end())
|
||||
return found->mangled;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
template<typename Signature>
|
||||
auto mangled_storage_impl::get_constructor() const -> ctor_sym
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
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 =
|
||||
visibility >> x3::space >>
|
||||
thiscall >> //cdecl declaration for methods. stdcall cannot be
|
||||
ctor_name >>
|
||||
x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >> parser::ptr_rule();
|
||||
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto f = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
|
||||
if (f != storage_.end())
|
||||
return f->mangled;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
template<typename Class>
|
||||
auto mangled_storage_impl::get_destructor() const -> dtor_sym
|
||||
{
|
||||
namespace x3 = spirit::x3;
|
||||
using namespace parser;
|
||||
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 + "(void)";
|
||||
unscoped_cname = class_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
unscoped_cname = class_name.substr(pos+2) ;
|
||||
dtor_name = class_name+ "::~" + unscoped_cname + "(void)";
|
||||
}
|
||||
}
|
||||
|
||||
auto matcher =
|
||||
visibility >> -virtual_ >> x3::space >>
|
||||
thiscall >> //cdecl declaration for methods. stdcall cannot be
|
||||
dtor_name >> parser::ptr_rule();
|
||||
|
||||
|
||||
auto predicate = [&](const mangled_storage_base::entry & e)
|
||||
{
|
||||
auto itr = e.demangled.begin();
|
||||
auto end = e.demangled.end();
|
||||
auto res = x3::parse(itr, end, matcher);
|
||||
|
||||
return res && (itr == end);
|
||||
};
|
||||
|
||||
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
|
||||
|
||||
|
||||
if (found != storage_.end())
|
||||
return found->mangled;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string mangled_storage_impl::get_vtable() const
|
||||
{
|
||||
std::string id = "const " + get_name<T>() + "::`vftable'";
|
||||
|
||||
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_MSVC_HPP_ */
|
||||
Reference in New Issue
Block a user