1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_ARCH_ATTRIBUTES_H
25 #define PXR_BASE_ARCH_ATTRIBUTES_H
26 
27 /// \file arch/attributes.h
28 /// Define function attributes.
29 ///
30 /// This file allows you to define architecture-specific or compiler-specific
31 /// options to be used outside lib/arch.
32 
33 #include "pxr/pxr.h"
34 #include "pxr/base/arch/export.h"
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 #if defined(doxygen)
39 
40 /// Macro used to indicate a function takes a printf-like specification.
41 ///
42 /// This attribute is used as follows:
43 /// \code
44 ///    void PrintFunc(T1 arg1, T2 arg2, const char* fmt, ...)
45 ///        ARCH_PRINTF_FUNCTION(3, 4)
46 /// \endcode
47 /// This indicates that the third argument is the format string, and that the
48 /// fourth argument is where the var-args corresponding to the format string begin.
49 ///
50 /// \hideinitializer
51 #   define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
52 
53 /// Macro used to indicate a function takes a scanf-like specification.
54 ///
55 /// This attribute is used as follows:
56 /// \code
57 ///    void ScanFunc(T1 arg1, T2 arg2, const char* fmt, ...)
58 ///        ARCH_PRINTF_FUNCTION(3, 4)
59 /// \endcode
60 /// This indicates that the third argument is the format string, and
61 /// that the fourth argument is where the var-args corresponding to the
62 /// format string begin.
63 ///
64 /// \hideinitializer
65 #   define ARCH_SCANF_FUNCTION(_fmt, _firstArg)
66 
67 /// Macro used to indicate that a function should never be inlined.
68 ///
69 /// This attribute is used as follows:
70 /// \code
71 ///    void Func(T1 arg1, T2 arg2) ARCH_NOINLINE;
72 /// \endcode
73 ///
74 /// \hideinitializer
75 #   define ARCH_NOINLINE
76 
77 /// Macro used to indicate a function parameter may be unused.
78 ///
79 /// In general, avoid this attribute if possible.  Mostly this attribute
80 /// should be used when the set of arguments to a function is described
81 /// as part of a macro.  The usage is:
82 /// \code
83 ///    void Func(T1 arg1, ARCH_UNUSED_ARG T2 arg2, ARCH_UNUSED_ARG T3 arg3, T4 arg4) {
84 ///        ...
85 ///    }
86 /// \endcode
87 ///
88 /// \hideinitializer
89 #   define ARCH_UNUSED_ARG
90 
91 /// Macro used to indicate a function may be unused.
92 ///
93 /// In general, avoid this attribute if possible.  Mostly this attribute
94 /// should be used when you need to keep a function around (for some
95 /// good reason), but it is not used in the rest of the code. The usage
96 /// is:
97 /// \code
98 ///    ARCH_UNUSED_FUNCTION void Func() {
99 ///        ...
100 ///    }
101 /// \endcode
102 ///
103 /// \hideinitializer
104 #   define ARCH_UNUSED_FUNCTION
105 
106 /// Macro used to indicate that a function's code must always be emitted even
107 /// if not required.
108 ///
109 /// This attribute is especially useful with templated registration functions,
110 /// which might not be present in the linked binary if they are not used (or
111 /// the compiler optimizes away their use.)
112 ///
113 /// The usage is:
114 /// \code
115 /// template <typename T>
116 /// struct TraitsClass {
117 ///    static void RegistryFunction() ARCH_USED_FUNCTION {
118 ///        ...
119 ///    }
120 /// };
121 /// \endcode
122 ///
123 /// \hideinitializer
124 #   define ARCH_USED_FUNCTION
125 
126 /// Macro to begin the definition of a function that should be executed by
127 /// the dynamic loader when the dynamic object (library or program) is
128 /// loaded.
129 ///
130 /// \p _priority is used to order the execution of constructors.  Valid
131 /// values are integers in the range [0,255].  Constructors with lower
132 /// numbers are run first.  It is unspecified if these functions are run
133 /// before or after dynamic initialization of non-local variables.
134 ///
135 /// \p _name is the name of the function and must be unique across all
136 /// invocations of ARCH_CONSTRUCTOR in the same translation unit.
137 /// The remaining arguments should be types for the signature of the
138 /// function.  The types are only to make the name unique (when mangled);
139 /// the function will be called with no arguments so the arguments must
140 /// not be used.  If you don't need any arguments you must use void.
141 ///
142 /// \hideinitializer
143 #   define ARCH_CONSTRUCTOR(_name, _priority, ...)
144 
145 /// Macro to begin the definition of a function that should be executed by
146 /// the dynamic loader when the dynamic object (library or program) is
147 /// unloaded.
148 ///
149 /// \p _priority is used to order the execution of destructors.  Valid
150 /// values are integers in the range [0,255].  Destructors with higher
151 /// numbers are run first.  It is unspecified if these functions are run
152 /// before or after dynamically initialized non-local variables.
153 ///
154 /// \p _name is the name of the function and must be unique across all
155 /// invocations of ARCH_CONSTRUCTOR in the same translation unit.
156 /// The remaining arguments should be types for the signature of the
157 /// function.  The types are only to make the name unique (when mangled);
158 /// the function will be called with no arguments so the arguments must
159 /// not be used.  If you don't need any arguments you must use void.
160 ///
161 /// \hideinitializer
162 #   define ARCH_DESTRUCTOR(_name, _priority, ...)
163 
164 #elif defined(ARCH_COMPILER_GCC) || defined(ARCH_COMPILER_CLANG)
165 
166 #   define ARCH_PRINTF_FUNCTION(_fmt, _firstArg) \
167         __attribute__((format(printf, _fmt, _firstArg)))
168 #   define ARCH_SCANF_FUNCTION(_fmt, _firstArg)	\
169         __attribute__((format(scanf, _fmt, _firstArg)))
170 #   define ARCH_NOINLINE __attribute__((noinline))
171 #   define ARCH_UNUSED_ARG   __attribute__ ((unused))
172 #   define ARCH_UNUSED_FUNCTION __attribute__((unused))
173 #   define ARCH_USED_FUNCTION __attribute__((used))
174 
175 #elif defined(ARCH_COMPILER_MSVC)
176 
177 #   define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
178 #   define ARCH_SCANF_FUNCTION(_fmt, _firstArg)
179 #   define ARCH_NOINLINE // __declspec(noinline)
180 #   define ARCH_UNUSED_ARG
181 #   define ARCH_UNUSED_FUNCTION
182 #   define ARCH_USED_FUNCTION
183 
184 #else
185 
186 // Leave macros undefined so we'll fail to build on a new system/compiler
187 // rather than fail mysteriously at runtime.
188 
189 #endif
190 
191 // Helper to do on-demand static initialziation.  We need to insert per-library
192 // static initializers if the ARCH_CONSTRUCTOR macros are used, etc, but we
193 // don't want that to happen otherwise.  This mechanism makes that possible.  It
194 // works by creating a class template (Arch_PerLibInit) that has hidden
195 // visibility and a static member of its template parameter (StaticInit).  In
196 // its constructor, it "uses" its static member 'init', in order to ensure it
197 // gets instantiated.  Since it's a static member, it gets initialized only if
198 // it's instantiated.  This lets us have macros like ARCH_CONSTRUCTOR() that
199 // require a static initializer, but to only emit that static initializer in
200 // translation units that actually invoke the macro.  Clients typically do this
201 // by way of the _ARCH_ENSURE_PER_LIB_INIT macro.  This is tested on all current
202 // supported compilers (clang, gcc, msvc).  The hidden visibility is required to
203 // ensure that each library gets its own initialization.  Without it, on Linux,
204 // there would be exactly *one* initialization no matter how many libraries are
205 // loaded.
206 template <class StaticInit>
207 struct ARCH_HIDDEN Arch_PerLibInit {
Arch_PerLibInitArch_PerLibInit208     Arch_PerLibInit() { /* "use" of init here forces instantiation */
209         (void)init; }
210 private:
211     static StaticInit init;
212 };
213 template <class StaticInit>
214 StaticInit Arch_PerLibInit<StaticInit>::init;
215 
216 #define _ARCH_CAT_NOEXPAND(a, b) a ## b
217 #define _ARCH_CAT(a, b) _ARCH_CAT_NOEXPAND(a, b)
218 #define _ARCH_ENSURE_PER_LIB_INIT(T, prefix) \
219     static Arch_PerLibInit<T> _ARCH_CAT(prefix, __COUNTER__)
220 
221 #if defined(doxygen)
222 
223 // The macros are already defined above in doxygen.
224 
225 #elif defined(ARCH_OS_DARWIN)
226 
227 // Entry for a constructor/destructor in the custom section.
228 struct Arch_ConstructorEntry {
229     typedef void (*Type)(void);
230     Type function;
231     unsigned int version:24;    // USD version
232     unsigned int priority:8;    // Priority of function
233 };
234 
235 // Emit a Arch_ConstructorEntry in the __Data,pxrctor section.
236 #   define ARCH_CONSTRUCTOR(_name, _priority, ...)                             \
237     static void _name(__VA_ARGS__);                                            \
238     static const Arch_ConstructorEntry _ARCH_CAT_NOEXPAND(arch_ctor_, _name)   \
239         __attribute__((used, section("__DATA,pxrctor"))) = {                   \
240         reinterpret_cast<Arch_ConstructorEntry::Type>(&_name),                 \
241         0u,                                                                    \
242         _priority                                                              \
243     };                                                                         \
244     static void _name(__VA_ARGS__)
245 
246 // Emit a Arch_ConstructorEntry in the __Data,pxrdtor section.
247 #   define ARCH_DESTRUCTOR(_name, _priority, ...)                              \
248     static void _name(__VA_ARGS__);                                            \
249     static const Arch_ConstructorEntry _ARCH_CAT_NOEXPAND(arch_dtor_, _name)   \
250         __attribute__((used, section("__DATA,pxrdtor"))) = {                   \
251         reinterpret_cast<Arch_ConstructorEntry::Type>(&_name),                 \
252         0u,                                                                    \
253         _priority                                                              \
254     };                                                                         \
255     static void _name(__VA_ARGS__)
256 
257 #elif defined(ARCH_COMPILER_GCC) || defined(ARCH_COMPILER_CLANG)
258 
259 // The used attribute is required to prevent these apparently unused functions
260 // from being removed by the linker.
261 #   define ARCH_CONSTRUCTOR(_name, _priority, ...) \
262         __attribute__((used, section(".pxrctor"), constructor((_priority) + 100))) \
263         static void _name(__VA_ARGS__)
264 #   define ARCH_DESTRUCTOR(_name, _priority, ...) \
265         __attribute__((used, section(".pxrdtor"), destructor((_priority) + 100))) \
266         static void _name(__VA_ARGS__)
267 
268 #elif defined(ARCH_OS_WINDOWS)
269 
270 #    include "pxr/base/arch/api.h"
271 
272 // Entry for a constructor/destructor in the custom section.
273     __declspec(align(16))
274     struct Arch_ConstructorEntry {
275         typedef void (__cdecl *Type)(void);
276         Type function;
277         unsigned int version:24;    // USD version
278         unsigned int priority:8;    // Priority of function
279     };
280 
281 // Declare the special sections.
282 #   pragma section(".pxrctor", read)
283 #   pragma section(".pxrdtor", read)
284 
285 // Objects of this type run the ARCH_CONSTRUCTOR and ARCH_DESTRUCTOR functions
286 // for the library containing the object in the c'tor and d'tor, respectively.
287 // Each HMODULE is handled at most once.
288 struct Arch_ConstructorInit {
289     ARCH_API Arch_ConstructorInit();
290     ARCH_API ~Arch_ConstructorInit();
291 };
292 
293 // Emit a Arch_ConstructorEntry in the .pxrctor section.  The namespace and
294 // extern are to convince the compiler and linker to leave the object in the
295 // final library/executable instead of stripping it out.  In clang/gcc we use
296 // __attribute__((used)) to do that.
297 #   define ARCH_CONSTRUCTOR(_name, _priority, ...)                             \
298     static void _name(__VA_ARGS__);                                            \
299     namespace {                                                                \
300     __declspec(allocate(".pxrctor"))                                           \
301     extern const Arch_ConstructorEntry                                         \
302     _ARCH_CAT_NOEXPAND(arch_ctor_, _name) = {                                  \
303         reinterpret_cast<Arch_ConstructorEntry::Type>(&_name),                 \
304         0u,                                                                    \
305         _priority                                                              \
306     };                                                                         \
307     }                                                                          \
308     _ARCH_ENSURE_PER_LIB_INIT(Arch_ConstructorInit, _archCtorInit);            \
309     static void _name(__VA_ARGS__)
310 
311     // Emit a Arch_ConstructorEntry in the .pxrdtor section.
312 #   define ARCH_DESTRUCTOR(_name, _priority, ...)                              \
313     static void _name(__VA_ARGS__);                                            \
314     namespace {                                                                \
315     __declspec(allocate(".pxrdtor"))                                           \
316     extern const Arch_ConstructorEntry                                         \
317     _ARCH_CAT_NOEXPAND(arch_dtor_, _name) = {                                  \
318         reinterpret_cast<Arch_ConstructorEntry::Type>(&_name),                 \
319         0u,                                                                    \
320         _priority                                                              \
321     };                                                                         \
322     }                                                                          \
323     _ARCH_ENSURE_PER_LIB_INIT(Arch_ConstructorInit, _archCtorInit);            \
324     static void _name(__VA_ARGS__)
325 
326 #else
327 
328 // Leave macros undefined so we'll fail to build on a new system/compiler
329 // rather than fail mysteriously at runtime.
330 
331 #endif
332 
333 PXR_NAMESPACE_CLOSE_SCOPE
334 
335 #endif // PXR_BASE_ARCH_ATTRIBUTES_H
336