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