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