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