1 // Copyright (c) 2016 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(HPX_TRAITS_GET_FUNCTION_ADDRESS_FEB_19_2016_0801PM) 7 #define HPX_TRAITS_GET_FUNCTION_ADDRESS_FEB_19_2016_0801PM 8 9 #include <hpx/config.hpp> 10 11 #include <cstddef> 12 #include <memory> 13 14 namespace hpx { namespace traits 15 { 16 // By default we return the address of the object which is used to invoke 17 // the trait. 18 template <typename F, typename Enable = void> 19 struct get_function_address 20 { callhpx::traits::get_function_address21 static std::size_t call(F const& f) noexcept 22 { 23 return reinterpret_cast<std::size_t>(std::addressof(f)); 24 } 25 }; 26 27 // For global (and static) functions we return the function address itself 28 template <typename R, typename ... Ts> 29 struct get_function_address<R (*)(Ts...)> 30 { callhpx::traits::get_function_address31 static std::size_t call(R (*f)(Ts...)) noexcept 32 { 33 return reinterpret_cast<std::size_t>(f); 34 } 35 }; 36 37 // For member functions we return the first sizeof(void*) bytes of the 38 // storage the member function pointer occupies. 39 // 40 // BADBAD: This invokes undefined behavior. What it does is to 41 // access the first sizeof(void*) bytes of the member 42 // function pointer. In our case this is not a problem as 43 // the value will be used to resolve a (debug) symbol only. 44 // 45 // The value is never dereferenced or used in any other 46 // way. So the worst what can happen is that no matching 47 // symbol is found. 48 // 49 // On some systems and for certain types of member function 50 // pointers this might even give the correct value 51 // representing the symbol corresponding to the function. 52 // 53 template <typename R, typename Obj, typename ... Ts> 54 struct get_function_address<R (Obj::*)(Ts...)> 55 { callhpx::traits::get_function_address56 static std::size_t call(R (Obj::*f)(Ts...)) noexcept 57 { 58 #if defined(__clang__) 59 # pragma clang diagnostic push 60 # pragma clang diagnostic ignored "-Wstrict-aliasing" 61 #endif 62 63 #if defined(__GNUG__) && !defined(__INTEL_COMPILER) && \ 64 (!defined(__NVCC__) || (__CUDACC_VER_MAJOR__ >= 8)) 65 # if defined(HPX_GCC_DIAGNOSTIC_PRAGMA_CONTEXTS) 66 # pragma GCC diagnostic push 67 # endif 68 # pragma GCC diagnostic ignored "-Wstrict-aliasing" 69 #endif 70 71 return reinterpret_cast<std::size_t>(*reinterpret_cast<void**>(&f)); 72 73 #if defined(__GNUG__) && !defined(__INTEL_COMPILER) && \ 74 (!defined(__NVCC__) || (__CUDACC_VER_MAJOR__ >= 8)) 75 #if defined(HPX_GCC_DIAGNOSTIC_PRAGMA_CONTEXTS) 76 #pragma GCC diagnostic pop 77 #endif 78 #endif 79 80 #if defined(__clang__) 81 # pragma clang diagnostic pop 82 #endif 83 } 84 }; 85 86 template <typename R, typename Obj, typename ... Ts> 87 struct get_function_address<R (Obj::*)(Ts...) const> 88 { callhpx::traits::get_function_address89 static std::size_t call(R (Obj::*f)(Ts...) const) noexcept 90 { 91 #if defined(__clang__) 92 # pragma clang diagnostic push 93 # pragma clang diagnostic ignored "-Wstrict-aliasing" 94 #endif 95 96 #if defined(__GNUG__) && !defined(__INTEL_COMPILER) && \ 97 (!defined(__NVCC__) || (__CUDACC_VER_MAJOR__ >= 8)) 98 # if defined(HPX_GCC_DIAGNOSTIC_PRAGMA_CONTEXTS) 99 # pragma GCC diagnostic push 100 # endif 101 # pragma GCC diagnostic ignored "-Wstrict-aliasing" 102 #endif 103 104 return reinterpret_cast<std::size_t>(*reinterpret_cast<void**>(&f)); 105 106 #if defined(__GNUG__) && !defined(__INTEL_COMPILER) && \ 107 (!defined(__NVCC__) || (__CUDACC_VER_MAJOR__ >= 8)) 108 #if defined(HPX_GCC_DIAGNOSTIC_PRAGMA_CONTEXTS) 109 #pragma GCC diagnostic pop 110 #endif 111 #endif 112 113 #if defined(__clang__) 114 # pragma clang diagnostic pop 115 #endif 116 } 117 }; 118 }} 119 120 #endif 121