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 
19 #include <memory>
20 
22 
23 #if defined(doxygen)
24 
25 /// Macro used to indicate a function takes a printf-like specification.
26 ///
27 /// This attribute is used as follows:
28 /// \code
29 /// void PrintFunc(T1 arg1, T2 arg2, const char* fmt, ...)
30 /// ARCH_PRINTF_FUNCTION(3, 4)
31 /// \endcode
32 /// This indicates that the third argument is the format string, and that the
33 /// fourth argument is where the var-args corresponding to the format string begin.
34 ///
35 /// \hideinitializer
36 # define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
37 
38 /// Macro used to indicate a function takes a scanf-like specification.
39 ///
40 /// This attribute is used as follows:
41 /// \code
42 /// void ScanFunc(T1 arg1, T2 arg2, const char* fmt, ...)
43 /// ARCH_PRINTF_FUNCTION(3, 4)
44 /// \endcode
45 /// This indicates that the third argument is the format string, and
46 /// that the fourth argument is where the var-args corresponding to the
47 /// format string begin.
48 ///
49 /// \hideinitializer
50 # define ARCH_SCANF_FUNCTION(_fmt, _firstArg)
51 
52 /// Macro used to indicate that a function should never be inlined.
53 ///
54 /// This attribute is used as follows:
55 /// \code
56 /// void Func(T1 arg1, T2 arg2) ARCH_NOINLINE;
57 /// \endcode
58 ///
59 /// \hideinitializer
60 # define ARCH_NOINLINE
61 
62 /// Macro used to indicate a function parameter may be unused.
63 ///
64 /// In general, avoid this attribute if possible. Mostly this attribute
65 /// should be used when the set of arguments to a function is described
66 /// as part of a macro. The usage is:
67 /// \code
68 /// void Func(T1 arg1, ARCH_UNUSED_ARG T2 arg2, ARCH_UNUSED_ARG T3 arg3, T4 arg4) {
69 /// ...
70 /// }
71 /// \endcode
72 ///
73 /// \hideinitializer
74 # define ARCH_UNUSED_ARG
75 
76 /// Macro used to indicate a function may be unused.
77 ///
78 /// In general, avoid this attribute if possible. Mostly this attribute
79 /// should be used when you need to keep a function around (for some
80 /// good reason), but it is not used in the rest of the code. The usage
81 /// is:
82 /// \code
83 /// ARCH_UNUSED_FUNCTION void Func() {
84 /// ...
85 /// }
86 /// \endcode
87 ///
88 /// \hideinitializer
89 # define ARCH_UNUSED_FUNCTION
90 
91 /// Macro used to indicate that a function's code must always be emitted even
92 /// if not required.
93 ///
94 /// This attribute is especially useful with templated registration functions,
95 /// which might not be present in the linked binary if they are not used (or
96 /// the compiler optimizes away their use.)
97 ///
98 /// The usage is:
99 /// \code
100 /// template <typename T>
101 /// struct TraitsClass {
102 /// static void RegistryFunction() ARCH_USED_FUNCTION {
103 /// ...
104 /// }
105 /// };
106 /// \endcode
107 ///
108 /// \hideinitializer
109 # define ARCH_USED_FUNCTION
110 
111 /// Macro to begin the definition of a function that should be executed by
112 /// the dynamic loader when the dynamic object (library or program) is
113 /// loaded.
114 ///
115 /// \p _priority is used to order the execution of constructors. Valid
116 /// values are integers in the range [0,255]. Constructors with lower
117 /// numbers are run first. It is unspecified if these functions are run
118 /// before or after dynamic initialization of non-local variables.
119 ///
120 /// \p _name is the name of the function and must be unique across all
121 /// invocations of ARCH_CONSTRUCTOR in the same translation unit.
122 ///
123 /// \hideinitializer
124 # define ARCH_CONSTRUCTOR(_name, _priority)
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 /// unloaded.
129 ///
130 /// \p _priority is used to order the execution of destructors. Valid
131 /// values are integers in the range [0,255]. Destructors with higher
132 /// numbers are run first. It is unspecified if these functions are run
133 /// before or after dynamically initialized 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 ///
138 /// \hideinitializer
139 # define ARCH_DESTRUCTOR(_name, _priority)
140 
141 /// Macro to begin the definition of a class that is using private inheritance
142 /// to take advantage of the empty base optimization. Some compilers require
143 /// an explicit tag.
144 ///
145 /// In C++20, usage of private inheritance may be able to be retired with the
146 /// [[no_unique_address]] tag.
147 # define ARCH_EMPTY_BASES
148 
149 /// Macro used to indicate that a function should not be instrumented
150 /// with address santizers.
151 ///
152 /// In general, this attribute should be used sparingly. Its purpose
153 /// is mostly for tests that when built with address sanitizer will trigger
154 /// a false-positive, meaning the test is checking something that address
155 /// sanitizer is trying to catch.
156 ///
157 /// Its important to understand that this attribute will only disable
158 /// address sanitizer instrumentation for the function it's applied to.
159 /// Any sanitized functions called from the target function
160 /// will still be instrumented.
161 ///
162 /// This attribute is used as follows:
163 /// \code
164 /// ARCH_NO_SANITIZE_ADDRESS_FUNCTION void Func() {
165 /// ...
166 /// }
167 /// \endcode
168 ///
169 /// \hideinitializer
170 # define ARCH_NO_SANITIZE_ADDRESS_FUNCTION
171 
172 #elif defined(ARCH_COMPILER_GCC) || defined(ARCH_COMPILER_CLANG)
173 
174 # define ARCH_PRINTF_FUNCTION(_fmt, _firstArg) \
175  __attribute__((format(printf, _fmt, _firstArg)))
176 # define ARCH_SCANF_FUNCTION(_fmt, _firstArg) \
177  __attribute__((format(scanf, _fmt, _firstArg)))
178 # define ARCH_NOINLINE __attribute__((noinline))
179 # define ARCH_ALWAYS_INLINE __attribute__((always_inline))
180 # define ARCH_UNUSED_ARG __attribute__ ((unused))
181 # define ARCH_UNUSED_FUNCTION __attribute__((unused))
182 # define ARCH_USED_FUNCTION __attribute__((used))
183 # define ARCH_EMPTY_BASES
184 
185 #if defined(ARCH_SANITIZE_ADDRESS)
186 # define ARCH_NO_SANITIZE_ADDRESS_FUNCTION \
187  __attribute__((no_sanitize_address))
188 #else
189 # define ARCH_NO_SANITIZE_ADDRESS_FUNCTION
190 #endif
191 
192 // Function attributes for other sanitizers (thread, undefined behavior, etc.)
193 // intentionally omitted until support is added
194 
195 #elif defined(ARCH_COMPILER_MSVC)
196 
197 # define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
198 # define ARCH_SCANF_FUNCTION(_fmt, _firstArg)
199 # define ARCH_NOINLINE // __declspec(noinline)
200 # define ARCH_ALWAYS_INLINE
201 # define ARCH_UNUSED_ARG
202 # define ARCH_UNUSED_FUNCTION
203 # define ARCH_USED_FUNCTION
204 # define ARCH_EMPTY_BASES __declspec(empty_bases)
205 
206 #if defined(ARCH_SANITIZE_ADDRESS)
207 # define ARCH_NO_SANITIZE_ADDRESS_FUNCTION \
208  __declspec(no_sanitize_address)
209 #else
210 # define ARCH_NO_SANITIZE_ADDRESS_FUNCTION
211 #endif
212 
213 // Function attributes for other sanitizers (thread, undefined behavior, etc.)
214 // intentionally omitted until support is added
215 
216 #else
217 
218 // Leave macros undefined so we'll fail to build on a new system/compiler
219 // rather than fail mysteriously at runtime.
220 
221 #endif
222 
223 // Helper to do on-demand static initialization. We need to insert per-library
224 // static initializers if the ARCH_CONSTRUCTOR macros are used, etc, but we
225 // don't want that to happen otherwise. This mechanism makes that possible. It
226 // works by creating a class template (Arch_PerLibInit) that has hidden
227 // visibility and a static member of its template parameter (StaticInit). In
228 // its constructor, it "uses" its static member 'init', in order to ensure it
229 // gets instantiated. Since it's a static member, it gets initialized only if
230 // it's instantiated. This lets us have macros like ARCH_CONSTRUCTOR() that
231 // require a static initializer, but to only emit that static initializer in
232 // translation units that actually invoke the macro. Clients typically do this
233 // by way of the _ARCH_ENSURE_PER_LIB_INIT macro. This is tested on all current
234 // supported compilers (clang, gcc, msvc). The hidden visibility is required to
235 // ensure that each library gets its own initialization. Without it, on Linux,
236 // there would be exactly *one* initialization no matter how many libraries are
237 // loaded.
238 template <class StaticInit>
240  Arch_PerLibInit() { /* "use" of init here forces instantiation */
241  (void)init; }
242 private:
243  static StaticInit init;
244 };
245 template <class StaticInit>
247 
248 #define _ARCH_CAT_NOEXPAND(a, b) a ## b
249 #define _ARCH_CAT(a, b) _ARCH_CAT_NOEXPAND(a, b)
250 #define _ARCH_ENSURE_PER_LIB_INIT(T, prefix) \
251  static Arch_PerLibInit<T> _ARCH_CAT(prefix, __COUNTER__)
252 
253 #if defined(doxygen)
254 
255 // The macros are already defined above in doxygen.
256 
257 #elif defined(ARCH_OS_DARWIN)
258 
259 // Entry for a constructor/destructor in the custom section.
260 struct Arch_ConstructorEntry {
261  typedef void (*Type)(void);
262  Type function;
263  unsigned int version:24; // USD version
264  unsigned int priority:8; // Priority of function
265 };
266 
267 // Emit a Arch_ConstructorEntry in the __Data,pxrctor section.
268 # define ARCH_CONSTRUCTOR(_name, _priority) \
269  static void _name(); \
270  static const Arch_ConstructorEntry _ARCH_CAT_NOEXPAND(arch_ctor_, _name) \
271  __attribute__((used, section("__DATA,pxrctor"))) = { \
272  reinterpret_cast<Arch_ConstructorEntry::Type>(&_name), \
273  static_cast<unsigned>(PXR_VERSION), \
274  _priority \
275  }; \
276  static void _name()
277 
278 // Emit a Arch_ConstructorEntry in the __Data,pxrdtor section.
279 # define ARCH_DESTRUCTOR(_name, _priority) \
280  static void _name(); \
281  static const Arch_ConstructorEntry _ARCH_CAT_NOEXPAND(arch_dtor_, _name) \
282  __attribute__((used, section("__DATA,pxrdtor"))) = { \
283  reinterpret_cast<Arch_ConstructorEntry::Type>(&_name), \
284  static_cast<unsigned>(PXR_VERSION), \
285  _priority \
286  }; \
287  static void _name()
288 
289 #elif defined(ARCH_COMPILER_GCC) || defined(ARCH_COMPILER_CLANG)
290 
291 // The used attribute is required to prevent these apparently unused functions
292 // from being removed by the linker.
293 # define ARCH_CONSTRUCTOR(_name, _priority) \
294  __attribute__((used, section(".pxrctor"), constructor((_priority) + 100))) \
295  static void _name()
296 # define ARCH_DESTRUCTOR(_name, _priority) \
297  __attribute__((used, section(".pxrdtor"), destructor((_priority) + 100))) \
298  static void _name()
299 
300 #elif defined(ARCH_OS_WINDOWS)
301 
302 # include "pxr/base/arch/api.h"
303 
304 // Entry for a constructor/destructor in the custom section.
305  __declspec(align(16))
306  struct Arch_ConstructorEntry {
307  typedef void (__cdecl *Type)(void);
308  Type function;
309  unsigned int version:24; // USD version
310  unsigned int priority:8; // Priority of function
311  };
312 
313 // Declare the special sections.
314 # pragma section(".pxrctor", read)
315 # pragma section(".pxrdtor", read)
316 
317 // Objects of this type run the ARCH_CONSTRUCTOR and ARCH_DESTRUCTOR functions
318 // for the library containing the object in the c'tor and d'tor, respectively.
319 // Each HMODULE is handled at most once.
320 struct Arch_ConstructorInit {
321  ARCH_API Arch_ConstructorInit();
322  ARCH_API ~Arch_ConstructorInit();
323 };
324 
325 // Emit an Arch_ConstructorEntry in the .pxrctor section. The
326 // arch_{c,d}tor_unused assignment is a workaround to ensure arch_{c,d}tor
327 // isn't removed when /Zc:inline is enabled. In clang/gcc we use
328 // __attribute__((used)) to do that.
329 # define ARCH_CONSTRUCTOR(_name, _priority) \
330  static void _name(); \
331  namespace { \
332  __declspec(allocate(".pxrctor")) \
333  static const Arch_ConstructorEntry \
334  _ARCH_CAT_NOEXPAND(arch_ctor_, _name) = { \
335  reinterpret_cast<Arch_ConstructorEntry::Type>(&_name), \
336  static_cast<unsigned>(PXR_VERSION), \
337  _priority \
338  }; \
339  void _ARCH_CAT_NOEXPAND(arch_ctor_unused, _name)() { \
340  static const auto unused = \
341  std::addressof(_ARCH_CAT_NOEXPAND(arch_ctor_, _name)); \
342  } \
343  } \
344  _ARCH_ENSURE_PER_LIB_INIT(Arch_ConstructorInit, _archCtorInit); \
345  static void _name()
346 
347  // Emit a Arch_ConstructorEntry in the .pxrdtor section.
348 # define ARCH_DESTRUCTOR(_name, _priority) \
349  static void _name(); \
350  namespace { \
351  __declspec(allocate(".pxrdtor")) \
352  static const Arch_ConstructorEntry \
353  _ARCH_CAT_NOEXPAND(arch_dtor_, _name) = { \
354  reinterpret_cast<Arch_ConstructorEntry::Type>(&_name), \
355  static_cast<unsigned>(PXR_VERSION), \
356  _priority \
357  }; \
358  void _ARCH_CAT_NOEXPAND(arch_dtor_unused, _name)() { \
359  static const auto unused = \
360  std::addressof(_ARCH_CAT_NOEXPAND(arch_dtor_, _name)); \
361  } \
362  } \
363  _ARCH_ENSURE_PER_LIB_INIT(Arch_ConstructorInit, _archCtorInit); \
364  static void _name()
365 
366 #else
367 
368 // Leave macros undefined so we'll fail to build on a new system/compiler
369 // rather than fail mysteriously at runtime.
370 
371 #endif
372 
374 
375 #endif // PXR_BASE_ARCH_ATTRIBUTES_H
#define ARCH_HIDDEN
Definition: export.h:166
void
Definition: png.h:1083
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
GT_API const UT_StringHolder version
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
#define ARCH_API
Definition: api.h:23