Loading...
Searching...
No Matches
attributes.h
Go to the documentation of this file.
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
32
33#include "pxr/pxr.h"
35
36PXR_NAMESPACE_OPEN_SCOPE
37
38#if defined(doxygen)
39
51# define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
52
65# define ARCH_SCANF_FUNCTION(_fmt, _firstArg)
66
75# define ARCH_NOINLINE
76
89# define ARCH_UNUSED_ARG
90
104# define ARCH_UNUSED_FUNCTION
105
124# define ARCH_USED_FUNCTION
125
143# define ARCH_CONSTRUCTOR(_name, _priority, ...)
144
162# define ARCH_DESTRUCTOR(_name, _priority, ...)
163
170# define ARCH_EMPTY_BASES
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_UNUSED_ARG __attribute__ ((unused))
180# define ARCH_UNUSED_FUNCTION __attribute__((unused))
181# define ARCH_USED_FUNCTION __attribute__((used))
182# define ARCH_EMPTY_BASES
183
184#elif defined(ARCH_COMPILER_MSVC)
185
186# define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
187# define ARCH_SCANF_FUNCTION(_fmt, _firstArg)
188# define ARCH_NOINLINE // __declspec(noinline)
189# define ARCH_UNUSED_ARG
190# define ARCH_UNUSED_FUNCTION
191# define ARCH_USED_FUNCTION
192# define ARCH_EMPTY_BASES __declspec(empty_bases)
193
194#else
195
196// Leave macros undefined so we'll fail to build on a new system/compiler
197// rather than fail mysteriously at runtime.
198
199#endif
200
201// Helper to do on-demand static initialziation. We need to insert per-library
202// static initializers if the ARCH_CONSTRUCTOR macros are used, etc, but we
203// don't want that to happen otherwise. This mechanism makes that possible. It
204// works by creating a class template (Arch_PerLibInit) that has hidden
205// visibility and a static member of its template parameter (StaticInit). In
206// its constructor, it "uses" its static member 'init', in order to ensure it
207// gets instantiated. Since it's a static member, it gets initialized only if
208// it's instantiated. This lets us have macros like ARCH_CONSTRUCTOR() that
209// require a static initializer, but to only emit that static initializer in
210// translation units that actually invoke the macro. Clients typically do this
211// by way of the _ARCH_ENSURE_PER_LIB_INIT macro. This is tested on all current
212// supported compilers (clang, gcc, msvc). The hidden visibility is required to
213// ensure that each library gets its own initialization. Without it, on Linux,
214// there would be exactly *one* initialization no matter how many libraries are
215// loaded.
216template <class StaticInit>
217struct ARCH_HIDDEN Arch_PerLibInit {
218 Arch_PerLibInit() { /* "use" of init here forces instantiation */
219 (void)init; }
220private:
221 static StaticInit init;
222};
223template <class StaticInit>
224StaticInit Arch_PerLibInit<StaticInit>::init;
225
226#define _ARCH_CAT_NOEXPAND(a, b) a ## b
227#define _ARCH_CAT(a, b) _ARCH_CAT_NOEXPAND(a, b)
228#define _ARCH_ENSURE_PER_LIB_INIT(T, prefix) \
229 static Arch_PerLibInit<T> _ARCH_CAT(prefix, __COUNTER__)
230
231#if defined(doxygen)
232
233// The macros are already defined above in doxygen.
234
235#elif defined(ARCH_OS_DARWIN)
236
237// Entry for a constructor/destructor in the custom section.
238struct Arch_ConstructorEntry {
239 typedef void (*Type)(void);
240 Type function;
241 unsigned int version:24; // USD version
242 unsigned int priority:8; // Priority of function
243};
244
245// Emit a Arch_ConstructorEntry in the __Data,pxrctor section.
246# define ARCH_CONSTRUCTOR(_name, _priority, ...) \
247 static void _name(__VA_ARGS__); \
248 static const Arch_ConstructorEntry _ARCH_CAT_NOEXPAND(arch_ctor_, _name) \
249 __attribute__((used, section("__DATA,pxrctor"))) = { \
250 reinterpret_cast<Arch_ConstructorEntry::Type>(&_name), \
251 static_cast<unsigned>(PXR_VERSION), \
252 _priority \
253 }; \
254 static void _name(__VA_ARGS__)
255
256// Emit a Arch_ConstructorEntry in the __Data,pxrdtor section.
257# define ARCH_DESTRUCTOR(_name, _priority, ...) \
258 static void _name(__VA_ARGS__); \
259 static const Arch_ConstructorEntry _ARCH_CAT_NOEXPAND(arch_dtor_, _name) \
260 __attribute__((used, section("__DATA,pxrdtor"))) = { \
261 reinterpret_cast<Arch_ConstructorEntry::Type>(&_name), \
262 static_cast<unsigned>(PXR_VERSION), \
263 _priority \
264 }; \
265 static void _name(__VA_ARGS__)
266
267#elif defined(ARCH_COMPILER_GCC) || defined(ARCH_COMPILER_CLANG)
268
269// The used attribute is required to prevent these apparently unused functions
270// from being removed by the linker.
271# define ARCH_CONSTRUCTOR(_name, _priority, ...) \
272 __attribute__((used, section(".pxrctor"), constructor((_priority) + 100))) \
273 static void _name(__VA_ARGS__)
274# define ARCH_DESTRUCTOR(_name, _priority, ...) \
275 __attribute__((used, section(".pxrdtor"), destructor((_priority) + 100))) \
276 static void _name(__VA_ARGS__)
277
278#elif defined(ARCH_OS_WINDOWS)
279
280# include "pxr/base/arch/api.h"
281
282// Entry for a constructor/destructor in the custom section.
283 __declspec(align(16))
284 struct Arch_ConstructorEntry {
285 typedef void (__cdecl *Type)(void);
286 Type function;
287 unsigned int version:24; // USD version
288 unsigned int priority:8; // Priority of function
289 };
290
291// Declare the special sections.
292# pragma section(".pxrctor", read)
293# pragma section(".pxrdtor", read)
294
295// Objects of this type run the ARCH_CONSTRUCTOR and ARCH_DESTRUCTOR functions
296// for the library containing the object in the c'tor and d'tor, respectively.
297// Each HMODULE is handled at most once.
298struct Arch_ConstructorInit {
299 ARCH_API Arch_ConstructorInit();
300 ARCH_API ~Arch_ConstructorInit();
301};
302
303// Emit a Arch_ConstructorEntry in the .pxrctor section. The namespace and
304// extern are to convince the compiler and linker to leave the object in the
305// final library/executable instead of stripping it out. In clang/gcc we use
306// __attribute__((used)) to do that.
307# define ARCH_CONSTRUCTOR(_name, _priority, ...) \
308 static void _name(__VA_ARGS__); \
309 namespace { \
310 __declspec(allocate(".pxrctor")) \
311 extern const Arch_ConstructorEntry \
312 _ARCH_CAT_NOEXPAND(arch_ctor_, _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 // Emit a Arch_ConstructorEntry in the .pxrdtor section.
322# define ARCH_DESTRUCTOR(_name, _priority, ...) \
323 static void _name(__VA_ARGS__); \
324 namespace { \
325 __declspec(allocate(".pxrdtor")) \
326 extern const Arch_ConstructorEntry \
327 _ARCH_CAT_NOEXPAND(arch_dtor_, _name) = { \
328 reinterpret_cast<Arch_ConstructorEntry::Type>(&_name), \
329 static_cast<unsigned>(PXR_VERSION), \
330 _priority \
331 }; \
332 } \
333 _ARCH_ENSURE_PER_LIB_INIT(Arch_ConstructorInit, _archCtorInit); \
334 static void _name(__VA_ARGS__)
335
336#else
337
338// Leave macros undefined so we'll fail to build on a new system/compiler
339// rather than fail mysteriously at runtime.
340
341#endif
342
343PXR_NAMESPACE_CLOSE_SCOPE
344
345#endif // PXR_BASE_ARCH_ATTRIBUTES_H
Defines symbol visibility macros.