mfbt/Attributes.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /* Implementations of various class and method modifier attributes. */
michael@0 8
michael@0 9 #ifndef mozilla_Attributes_h
michael@0 10 #define mozilla_Attributes_h
michael@0 11
michael@0 12 #include "mozilla/Compiler.h"
michael@0 13
michael@0 14 /*
michael@0 15 * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the
michael@0 16 * method decorated with it must be inlined, even if the compiler thinks
michael@0 17 * otherwise. This is only a (much) stronger version of the inline hint:
michael@0 18 * compilers are not guaranteed to respect it (although they're much more likely
michael@0 19 * to do so).
michael@0 20 *
michael@0 21 * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the
michael@0 22 * compiler to inline even in DEBUG builds. It should be used very rarely.
michael@0 23 */
michael@0 24 #if defined(_MSC_VER)
michael@0 25 # define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline
michael@0 26 #elif defined(__GNUC__)
michael@0 27 # define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline
michael@0 28 #else
michael@0 29 # define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline
michael@0 30 #endif
michael@0 31
michael@0 32 #if !defined(DEBUG)
michael@0 33 # define MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG
michael@0 34 #elif defined(_MSC_VER) && !defined(__cplusplus)
michael@0 35 # define MOZ_ALWAYS_INLINE __inline
michael@0 36 #else
michael@0 37 # define MOZ_ALWAYS_INLINE inline
michael@0 38 #endif
michael@0 39
michael@0 40 /*
michael@0 41 * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
michael@0 42 * without warnings (functionality used by the macros below). These modes are
michael@0 43 * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
michael@0 44 * standardly, by checking whether __cplusplus has a C++11 or greater value.
michael@0 45 * Current versions of g++ do not correctly set __cplusplus, so we check both
michael@0 46 * for forward compatibility.
michael@0 47 */
michael@0 48 #if defined(__clang__)
michael@0 49 /*
michael@0 50 * Per Clang documentation, "Note that marketing version numbers should not
michael@0 51 * be used to check for language features, as different vendors use different
michael@0 52 * numbering schemes. Instead, use the feature checking macros."
michael@0 53 */
michael@0 54 # ifndef __has_extension
michael@0 55 # define __has_extension __has_feature /* compatibility, for older versions of clang */
michael@0 56 # endif
michael@0 57 # if __has_extension(cxx_constexpr)
michael@0 58 # define MOZ_HAVE_CXX11_CONSTEXPR
michael@0 59 # endif
michael@0 60 # if __has_extension(cxx_explicit_conversions)
michael@0 61 # define MOZ_HAVE_EXPLICIT_CONVERSION
michael@0 62 # endif
michael@0 63 # if __has_extension(cxx_deleted_functions)
michael@0 64 # define MOZ_HAVE_CXX11_DELETE
michael@0 65 # endif
michael@0 66 # if __has_extension(cxx_override_control)
michael@0 67 # define MOZ_HAVE_CXX11_OVERRIDE
michael@0 68 # define MOZ_HAVE_CXX11_FINAL final
michael@0 69 # endif
michael@0 70 # if __has_attribute(noinline)
michael@0 71 # define MOZ_HAVE_NEVER_INLINE __attribute__((noinline))
michael@0 72 # endif
michael@0 73 # if __has_attribute(noreturn)
michael@0 74 # define MOZ_HAVE_NORETURN __attribute__((noreturn))
michael@0 75 # endif
michael@0 76 #elif defined(__GNUC__)
michael@0 77 # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
michael@0 78 # if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
michael@0 79 # define MOZ_HAVE_CXX11_OVERRIDE
michael@0 80 # define MOZ_HAVE_CXX11_FINAL final
michael@0 81 # endif
michael@0 82 # if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0)
michael@0 83 # define MOZ_HAVE_CXX11_CONSTEXPR
michael@0 84 # endif
michael@0 85 # if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0)
michael@0 86 # define MOZ_HAVE_EXPLICIT_CONVERSION
michael@0 87 # endif
michael@0 88 # define MOZ_HAVE_CXX11_DELETE
michael@0 89 # else
michael@0 90 /* __final is a non-C++11 GCC synonym for 'final', per GCC r176655. */
michael@0 91 # if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
michael@0 92 # define MOZ_HAVE_CXX11_FINAL __final
michael@0 93 # endif
michael@0 94 # endif
michael@0 95 # define MOZ_HAVE_NEVER_INLINE __attribute__((noinline))
michael@0 96 # define MOZ_HAVE_NORETURN __attribute__((noreturn))
michael@0 97 #elif defined(_MSC_VER)
michael@0 98 # if _MSC_VER >= 1800
michael@0 99 # define MOZ_HAVE_CXX11_DELETE
michael@0 100 # endif
michael@0 101 # if _MSC_VER >= 1700
michael@0 102 # define MOZ_HAVE_CXX11_FINAL final
michael@0 103 # else
michael@0 104 /* MSVC <= 10 used to spell "final" as "sealed". */
michael@0 105 # define MOZ_HAVE_CXX11_FINAL sealed
michael@0 106 # endif
michael@0 107 # define MOZ_HAVE_CXX11_OVERRIDE
michael@0 108 # define MOZ_HAVE_NEVER_INLINE __declspec(noinline)
michael@0 109 # define MOZ_HAVE_NORETURN __declspec(noreturn)
michael@0 110 // Staying away from explicit conversion operators in MSVC for now, see
michael@0 111 // http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
michael@0 112 #endif
michael@0 113
michael@0 114 /*
michael@0 115 * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a
michael@0 116 * function at compile time. A constexpr function cannot examine any values
michael@0 117 * except its arguments and can have no side effects except its return value.
michael@0 118 * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's
michael@0 119 * value may be computed at compile time. It should be prefered to just
michael@0 120 * marking variables as MOZ_CONSTEXPR because if the compiler does not support
michael@0 121 * constexpr it will fall back to making the variable const, and some compilers
michael@0 122 * do not accept variables being marked both const and constexpr.
michael@0 123 */
michael@0 124 #ifdef MOZ_HAVE_CXX11_CONSTEXPR
michael@0 125 # define MOZ_CONSTEXPR constexpr
michael@0 126 # define MOZ_CONSTEXPR_VAR constexpr
michael@0 127 #else
michael@0 128 # define MOZ_CONSTEXPR /* no support */
michael@0 129 # define MOZ_CONSTEXPR_VAR const
michael@0 130 #endif
michael@0 131
michael@0 132 /*
michael@0 133 * MOZ_EXPLICIT_CONVERSION is a specifier on a type conversion
michael@0 134 * overloaded operator that declares that a C++11 compiler should restrict
michael@0 135 * this operator to allow only explicit type conversions, disallowing
michael@0 136 * implicit conversions.
michael@0 137 *
michael@0 138 * Example:
michael@0 139 *
michael@0 140 * template<typename T>
michael@0 141 * class Ptr
michael@0 142 * {
michael@0 143 * T* ptr;
michael@0 144 * MOZ_EXPLICIT_CONVERSION operator bool() const {
michael@0 145 * return ptr != nullptr;
michael@0 146 * }
michael@0 147 * };
michael@0 148 *
michael@0 149 */
michael@0 150 #ifdef MOZ_HAVE_EXPLICIT_CONVERSION
michael@0 151 # define MOZ_EXPLICIT_CONVERSION explicit
michael@0 152 #else
michael@0 153 # define MOZ_EXPLICIT_CONVERSION /* no support */
michael@0 154 #endif
michael@0 155
michael@0 156 /*
michael@0 157 * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
michael@0 158 * method decorated with it must never be inlined, even if the compiler would
michael@0 159 * otherwise choose to inline the method. Compilers aren't absolutely
michael@0 160 * guaranteed to support this, but most do.
michael@0 161 */
michael@0 162 #if defined(MOZ_HAVE_NEVER_INLINE)
michael@0 163 # define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE
michael@0 164 #else
michael@0 165 # define MOZ_NEVER_INLINE /* no support */
michael@0 166 #endif
michael@0 167
michael@0 168 /*
michael@0 169 * MOZ_NORETURN, specified at the start of a function declaration, indicates
michael@0 170 * that the given function does not return. (The function definition does not
michael@0 171 * need to be annotated.)
michael@0 172 *
michael@0 173 * MOZ_NORETURN void abort(const char* msg);
michael@0 174 *
michael@0 175 * This modifier permits the compiler to optimize code assuming a call to such a
michael@0 176 * function will never return. It also enables the compiler to avoid spurious
michael@0 177 * warnings about not initializing variables, or about any other seemingly-dodgy
michael@0 178 * operations performed after the function returns.
michael@0 179 *
michael@0 180 * This modifier does not affect the corresponding function's linking behavior.
michael@0 181 */
michael@0 182 #if defined(MOZ_HAVE_NORETURN)
michael@0 183 # define MOZ_NORETURN MOZ_HAVE_NORETURN
michael@0 184 #else
michael@0 185 # define MOZ_NORETURN /* no support */
michael@0 186 #endif
michael@0 187
michael@0 188 /*
michael@0 189 * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
michael@0 190 * instrumentation shipped with Clang and GCC) to not instrument the annotated
michael@0 191 * function. Furthermore, it will prevent the compiler from inlining the
michael@0 192 * function because inlining currently breaks the blacklisting mechanism of
michael@0 193 * AddressSanitizer.
michael@0 194 */
michael@0 195 #if defined(__has_feature)
michael@0 196 # if __has_feature(address_sanitizer)
michael@0 197 # define MOZ_HAVE_ASAN_BLACKLIST
michael@0 198 # endif
michael@0 199 #elif defined(__GNUC__)
michael@0 200 # if defined(__SANITIZE_ADDRESS__)
michael@0 201 # define MOZ_HAVE_ASAN_BLACKLIST
michael@0 202 # endif
michael@0 203 #endif
michael@0 204
michael@0 205 #if defined(MOZ_HAVE_ASAN_BLACKLIST)
michael@0 206 # define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address))
michael@0 207 #else
michael@0 208 # define MOZ_ASAN_BLACKLIST /* nothing */
michael@0 209 #endif
michael@0 210
michael@0 211 /*
michael@0 212 * MOZ_TSAN_BLACKLIST is a macro to tell ThreadSanitizer (a compile-time
michael@0 213 * instrumentation shipped with Clang) to not instrument the annotated function.
michael@0 214 * Furthermore, it will prevent the compiler from inlining the function because
michael@0 215 * inlining currently breaks the blacklisting mechanism of ThreadSanitizer.
michael@0 216 */
michael@0 217 #if defined(__has_feature)
michael@0 218 # if __has_feature(thread_sanitizer)
michael@0 219 # define MOZ_TSAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread))
michael@0 220 # else
michael@0 221 # define MOZ_TSAN_BLACKLIST /* nothing */
michael@0 222 # endif
michael@0 223 #else
michael@0 224 # define MOZ_TSAN_BLACKLIST /* nothing */
michael@0 225 #endif
michael@0 226
michael@0 227 #ifdef __cplusplus
michael@0 228
michael@0 229 /*
michael@0 230 * MOZ_DELETE, specified immediately prior to the ';' terminating an undefined-
michael@0 231 * method declaration, attempts to delete that method from the corresponding
michael@0 232 * class. An attempt to use the method will always produce an error *at compile
michael@0 233 * time* (instead of sometimes as late as link time) when this macro can be
michael@0 234 * implemented. For example, you can use MOZ_DELETE to produce classes with no
michael@0 235 * implicit copy constructor or assignment operator:
michael@0 236 *
michael@0 237 * struct NonCopyable
michael@0 238 * {
michael@0 239 * private:
michael@0 240 * NonCopyable(const NonCopyable& other) MOZ_DELETE;
michael@0 241 * void operator=(const NonCopyable& other) MOZ_DELETE;
michael@0 242 * };
michael@0 243 *
michael@0 244 * If MOZ_DELETE can't be implemented for the current compiler, use of the
michael@0 245 * annotated method will still cause an error, but the error might occur at link
michael@0 246 * time in some cases rather than at compile time.
michael@0 247 *
michael@0 248 * MOZ_DELETE relies on C++11 functionality not universally implemented. As a
michael@0 249 * backstop, method declarations using MOZ_DELETE should be private.
michael@0 250 */
michael@0 251 #if defined(MOZ_HAVE_CXX11_DELETE)
michael@0 252 # define MOZ_DELETE = delete
michael@0 253 #else
michael@0 254 # define MOZ_DELETE /* no support */
michael@0 255 #endif
michael@0 256
michael@0 257 /*
michael@0 258 * MOZ_OVERRIDE explicitly indicates that a virtual member function in a class
michael@0 259 * overrides a member function of a base class, rather than potentially being a
michael@0 260 * new member function. MOZ_OVERRIDE should be placed immediately before the
michael@0 261 * ';' terminating the member function's declaration, or before '= 0;' if the
michael@0 262 * member function is pure. If the member function is defined in the class
michael@0 263 * definition, it should appear before the opening brace of the function body.
michael@0 264 *
michael@0 265 * class Base
michael@0 266 * {
michael@0 267 * public:
michael@0 268 * virtual void f() = 0;
michael@0 269 * };
michael@0 270 * class Derived1 : public Base
michael@0 271 * {
michael@0 272 * public:
michael@0 273 * virtual void f() MOZ_OVERRIDE;
michael@0 274 * };
michael@0 275 * class Derived2 : public Base
michael@0 276 * {
michael@0 277 * public:
michael@0 278 * virtual void f() MOZ_OVERRIDE = 0;
michael@0 279 * };
michael@0 280 * class Derived3 : public Base
michael@0 281 * {
michael@0 282 * public:
michael@0 283 * virtual void f() MOZ_OVERRIDE { }
michael@0 284 * };
michael@0 285 *
michael@0 286 * In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that
michael@0 287 * the function marked with it override a member function of a base class: it
michael@0 288 * is a compile error if it does not. Otherwise MOZ_OVERRIDE does not affect
michael@0 289 * semantics and merely documents the override relationship to the reader (but
michael@0 290 * of course must still be used correctly to not break C++11 compilers).
michael@0 291 */
michael@0 292 #if defined(MOZ_HAVE_CXX11_OVERRIDE)
michael@0 293 # define MOZ_OVERRIDE override
michael@0 294 #else
michael@0 295 # define MOZ_OVERRIDE /* no support */
michael@0 296 #endif
michael@0 297
michael@0 298 /*
michael@0 299 * MOZ_FINAL indicates that some functionality cannot be overridden through
michael@0 300 * inheritance. It can be used to annotate either classes/structs or virtual
michael@0 301 * member functions.
michael@0 302 *
michael@0 303 * To annotate a class/struct with MOZ_FINAL, place MOZ_FINAL immediately after
michael@0 304 * the name of the class, before the list of classes from which it derives (if
michael@0 305 * any) and before its opening brace. MOZ_FINAL must not be used to annotate
michael@0 306 * unnamed classes or structs. (With some compilers, and with C++11 proper, the
michael@0 307 * underlying expansion is ambiguous with specifying a class name.)
michael@0 308 *
michael@0 309 * class Base MOZ_FINAL
michael@0 310 * {
michael@0 311 * public:
michael@0 312 * Base();
michael@0 313 * ~Base();
michael@0 314 * virtual void f() { }
michael@0 315 * };
michael@0 316 * // This will be an error in some compilers:
michael@0 317 * class Derived : public Base
michael@0 318 * {
michael@0 319 * public:
michael@0 320 * ~Derived() { }
michael@0 321 * };
michael@0 322 *
michael@0 323 * One particularly common reason to specify MOZ_FINAL upon a class is to tell
michael@0 324 * the compiler that it's not dangerous for it to have a non-virtual destructor
michael@0 325 * yet have one or more virtual functions, silencing the warning it might emit
michael@0 326 * in this case. Suppose Base above weren't annotated with MOZ_FINAL. Because
michael@0 327 * ~Base() is non-virtual, an attempt to delete a Derived* through a Base*
michael@0 328 * wouldn't call ~Derived(), so any cleanup ~Derived() might do wouldn't happen.
michael@0 329 * (Formally C++ says behavior is undefined, but compilers will likely just call
michael@0 330 * ~Base() and not ~Derived().) Specifying MOZ_FINAL tells the compiler that
michael@0 331 * it's safe for the destructor to be non-virtual.
michael@0 332 *
michael@0 333 * In compilers implementing final controls, it is an error to inherit from a
michael@0 334 * class annotated with MOZ_FINAL. In other compilers it serves only as
michael@0 335 * documentation.
michael@0 336 *
michael@0 337 * To annotate a virtual member function with MOZ_FINAL, place MOZ_FINAL
michael@0 338 * immediately before the ';' terminating the member function's declaration, or
michael@0 339 * before '= 0;' if the member function is pure. If the member function is
michael@0 340 * defined in the class definition, it should appear before the opening brace of
michael@0 341 * the function body. (This placement is identical to that for MOZ_OVERRIDE.
michael@0 342 * If both are used, they should appear in the order 'MOZ_FINAL MOZ_OVERRIDE'
michael@0 343 * for consistency.)
michael@0 344 *
michael@0 345 * class Base
michael@0 346 * {
michael@0 347 * public:
michael@0 348 * virtual void f() MOZ_FINAL;
michael@0 349 * };
michael@0 350 * class Derived
michael@0 351 * {
michael@0 352 * public:
michael@0 353 * // This will be an error in some compilers:
michael@0 354 * virtual void f();
michael@0 355 * };
michael@0 356 *
michael@0 357 * In compilers implementing final controls, it is an error for a derived class
michael@0 358 * to override a method annotated with MOZ_FINAL. In other compilers it serves
michael@0 359 * only as documentation.
michael@0 360 */
michael@0 361 #if defined(MOZ_HAVE_CXX11_FINAL)
michael@0 362 # define MOZ_FINAL MOZ_HAVE_CXX11_FINAL
michael@0 363 #else
michael@0 364 # define MOZ_FINAL /* no support */
michael@0 365 #endif
michael@0 366
michael@0 367 /**
michael@0 368 * MOZ_WARN_UNUSED_RESULT tells the compiler to emit a warning if a function's
michael@0 369 * return value is not used by the caller.
michael@0 370 *
michael@0 371 * Place this attribute at the very beginning of a function definition. For
michael@0 372 * example, write
michael@0 373 *
michael@0 374 * MOZ_WARN_UNUSED_RESULT int foo();
michael@0 375 *
michael@0 376 * or
michael@0 377 *
michael@0 378 * MOZ_WARN_UNUSED_RESULT int foo() { return 42; }
michael@0 379 */
michael@0 380 #if defined(__GNUC__) || defined(__clang__)
michael@0 381 # define MOZ_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
michael@0 382 #else
michael@0 383 # define MOZ_WARN_UNUSED_RESULT
michael@0 384 #endif
michael@0 385
michael@0 386 /*
michael@0 387 * The following macros are attributes that support the static analysis plugin
michael@0 388 * included with Mozilla, and will be implemented (when such support is enabled)
michael@0 389 * as C++11 attributes. Since such attributes are legal pretty much everywhere
michael@0 390 * and have subtly different semantics depending on their placement, the
michael@0 391 * following is a guide on where to place the attributes.
michael@0 392 *
michael@0 393 * Attributes that apply to a struct or class precede the name of the class:
michael@0 394 * (Note that this is different from the placement of MOZ_FINAL for classes!)
michael@0 395 *
michael@0 396 * class MOZ_CLASS_ATTRIBUTE SomeClass {};
michael@0 397 *
michael@0 398 * Attributes that apply to functions follow the parentheses and const
michael@0 399 * qualifiers but precede MOZ_FINAL, MOZ_OVERRIDE and the function body:
michael@0 400 *
michael@0 401 * void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE;
michael@0 402 * void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {}
michael@0 403 * void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0;
michael@0 404 * void OverriddenFunction() MOZ_FUNCTION_ATTIRBUTE MOZ_OVERRIDE;
michael@0 405 *
michael@0 406 * Attributes that apply to variables or parameters follow the variable's name:
michael@0 407 *
michael@0 408 * int variable MOZ_VARIABLE_ATTRIBUTE;
michael@0 409 *
michael@0 410 * Attributes that apply to types follow the type name:
michael@0 411 *
michael@0 412 * typedef int MOZ_TYPE_ATTRIBUTE MagicInt;
michael@0 413 * int MOZ_TYPE_ATTRIBUTE someVariable;
michael@0 414 * int * MOZ_TYPE_ATTRIBUTE magicPtrInt;
michael@0 415 * int MOZ_TYPE_ATTRIBUTE * ptrToMagicInt;
michael@0 416 *
michael@0 417 * Attributes that apply to statements precede the statement:
michael@0 418 *
michael@0 419 * MOZ_IF_ATTRIBUTE if (x == 0)
michael@0 420 * MOZ_DO_ATTRIBUTE do { } while(0);
michael@0 421 *
michael@0 422 * Attributes that apply to labels precede the label:
michael@0 423 *
michael@0 424 * MOZ_LABEL_ATTRIBUTE target:
michael@0 425 * goto target;
michael@0 426 * MOZ_CASE_ATTRIBUTE case 5:
michael@0 427 * MOZ_DEFAULT_ATTRIBUTE default:
michael@0 428 *
michael@0 429 * The static analyses that are performed by the plugin are as follows:
michael@0 430 *
michael@0 431 * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate
michael@0 432 * subclasses must provide an exact override of this method; if a subclass
michael@0 433 * does not override this method, the compiler will emit an error. This
michael@0 434 * attribute is not limited to virtual methods, so if it is applied to a
michael@0 435 * nonvirtual method and the subclass does not provide an equivalent
michael@0 436 * definition, the compiler will emit an error.
michael@0 437 * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is
michael@0 438 * expected to live on the stack, so it is a compile-time error to use it, or
michael@0 439 * an array of such objects, as a global or static variable, or as the type of
michael@0 440 * a new expression (unless placement new is being used). If a member of
michael@0 441 * another class uses this class, or if another class inherits from this
michael@0 442 * class, then it is considered to be a stack class as well, although this
michael@0 443 * attribute need not be provided in such cases.
michael@0 444 * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is
michael@0 445 * expected to live on the stack or in static storage, so it is a compile-time
michael@0 446 * error to use it, or an array of such objects, as the type of a new
michael@0 447 * expression (unless placement new is being used). If a member of another
michael@0 448 * class uses this class, or if another class inherits from this class, then
michael@0 449 * it is considered to be a non-heap class as well, although this attribute
michael@0 450 * need not be provided in such cases.
michael@0 451 * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return
michael@0 452 * value is allocated on the heap, and will as a result check such allocations
michael@0 453 * during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking.
michael@0 454 */
michael@0 455 #ifdef MOZ_CLANG_PLUGIN
michael@0 456 # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override")))
michael@0 457 # define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
michael@0 458 # define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class")))
michael@0 459 /*
michael@0 460 * It turns out that clang doesn't like void func() __attribute__ {} without a
michael@0 461 * warning, so use pragmas to disable the warning. This code won't work on GCC
michael@0 462 * anyways, so the warning is safe to ignore.
michael@0 463 */
michael@0 464 # define MOZ_HEAP_ALLOCATOR \
michael@0 465 _Pragma("clang diagnostic push") \
michael@0 466 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
michael@0 467 __attribute__((annotate("moz_heap_allocator"))) \
michael@0 468 _Pragma("clang diagnostic pop")
michael@0 469 #else
michael@0 470 # define MOZ_MUST_OVERRIDE /* nothing */
michael@0 471 # define MOZ_STACK_CLASS /* nothing */
michael@0 472 # define MOZ_NONHEAP_CLASS /* nothing */
michael@0 473 # define MOZ_HEAP_ALLOCATOR /* nothing */
michael@0 474 #endif /* MOZ_CLANG_PLUGIN */
michael@0 475
michael@0 476 /*
michael@0 477 * MOZ_THIS_IN_INITIALIZER_LIST is used to avoid a warning when we know that
michael@0 478 * it's safe to use 'this' in an initializer list.
michael@0 479 */
michael@0 480 #ifdef _MSC_VER
michael@0 481 # define MOZ_THIS_IN_INITIALIZER_LIST() \
michael@0 482 __pragma(warning(push)) \
michael@0 483 __pragma(warning(disable:4355)) \
michael@0 484 this \
michael@0 485 __pragma(warning(pop))
michael@0 486 #else
michael@0 487 # define MOZ_THIS_IN_INITIALIZER_LIST() this
michael@0 488 #endif
michael@0 489
michael@0 490 #endif /* __cplusplus */
michael@0 491
michael@0 492 #endif /* mozilla_Attributes_h */

mercurial