mfbt/Attributes.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mfbt/Attributes.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,492 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/* Implementations of various class and method modifier attributes. */
    1.11 +
    1.12 +#ifndef mozilla_Attributes_h
    1.13 +#define mozilla_Attributes_h
    1.14 +
    1.15 +#include "mozilla/Compiler.h"
    1.16 +
    1.17 +/*
    1.18 + * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the
    1.19 + * method decorated with it must be inlined, even if the compiler thinks
    1.20 + * otherwise.  This is only a (much) stronger version of the inline hint:
    1.21 + * compilers are not guaranteed to respect it (although they're much more likely
    1.22 + * to do so).
    1.23 + *
    1.24 + * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the
    1.25 + * compiler to inline even in DEBUG builds. It should be used very rarely.
    1.26 + */
    1.27 +#if defined(_MSC_VER)
    1.28 +#  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     __forceinline
    1.29 +#elif defined(__GNUC__)
    1.30 +#  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     __attribute__((always_inline)) inline
    1.31 +#else
    1.32 +#  define MOZ_ALWAYS_INLINE_EVEN_DEBUG     inline
    1.33 +#endif
    1.34 +
    1.35 +#if !defined(DEBUG)
    1.36 +#  define MOZ_ALWAYS_INLINE     MOZ_ALWAYS_INLINE_EVEN_DEBUG
    1.37 +#elif defined(_MSC_VER) && !defined(__cplusplus)
    1.38 +#  define MOZ_ALWAYS_INLINE     __inline
    1.39 +#else
    1.40 +#  define MOZ_ALWAYS_INLINE     inline
    1.41 +#endif
    1.42 +
    1.43 +/*
    1.44 + * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
    1.45 + * without warnings (functionality used by the macros below).  These modes are
    1.46 + * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
    1.47 + * standardly, by checking whether __cplusplus has a C++11 or greater value.
    1.48 + * Current versions of g++ do not correctly set __cplusplus, so we check both
    1.49 + * for forward compatibility.
    1.50 + */
    1.51 +#if defined(__clang__)
    1.52 +   /*
    1.53 +    * Per Clang documentation, "Note that marketing version numbers should not
    1.54 +    * be used to check for language features, as different vendors use different
    1.55 +    * numbering schemes. Instead, use the feature checking macros."
    1.56 +    */
    1.57 +#  ifndef __has_extension
    1.58 +#    define __has_extension __has_feature /* compatibility, for older versions of clang */
    1.59 +#  endif
    1.60 +#  if __has_extension(cxx_constexpr)
    1.61 +#    define MOZ_HAVE_CXX11_CONSTEXPR
    1.62 +#  endif
    1.63 +#  if __has_extension(cxx_explicit_conversions)
    1.64 +#    define MOZ_HAVE_EXPLICIT_CONVERSION
    1.65 +#  endif
    1.66 +#  if __has_extension(cxx_deleted_functions)
    1.67 +#    define MOZ_HAVE_CXX11_DELETE
    1.68 +#  endif
    1.69 +#  if __has_extension(cxx_override_control)
    1.70 +#    define MOZ_HAVE_CXX11_OVERRIDE
    1.71 +#    define MOZ_HAVE_CXX11_FINAL         final
    1.72 +#  endif
    1.73 +#  if __has_attribute(noinline)
    1.74 +#    define MOZ_HAVE_NEVER_INLINE        __attribute__((noinline))
    1.75 +#  endif
    1.76 +#  if __has_attribute(noreturn)
    1.77 +#    define MOZ_HAVE_NORETURN            __attribute__((noreturn))
    1.78 +#  endif
    1.79 +#elif defined(__GNUC__)
    1.80 +#  if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
    1.81 +#    if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
    1.82 +#      define MOZ_HAVE_CXX11_OVERRIDE
    1.83 +#      define MOZ_HAVE_CXX11_FINAL       final
    1.84 +#    endif
    1.85 +#    if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0)
    1.86 +#      define MOZ_HAVE_CXX11_CONSTEXPR
    1.87 +#    endif
    1.88 +#    if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0)
    1.89 +#      define MOZ_HAVE_EXPLICIT_CONVERSION
    1.90 +#    endif
    1.91 +#    define MOZ_HAVE_CXX11_DELETE
    1.92 +#  else
    1.93 +     /* __final is a non-C++11 GCC synonym for 'final', per GCC r176655. */
    1.94 +#    if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
    1.95 +#      define MOZ_HAVE_CXX11_FINAL       __final
    1.96 +#    endif
    1.97 +#  endif
    1.98 +#  define MOZ_HAVE_NEVER_INLINE          __attribute__((noinline))
    1.99 +#  define MOZ_HAVE_NORETURN              __attribute__((noreturn))
   1.100 +#elif defined(_MSC_VER)
   1.101 +#  if _MSC_VER >= 1800
   1.102 +#    define MOZ_HAVE_CXX11_DELETE
   1.103 +#  endif
   1.104 +#  if _MSC_VER >= 1700
   1.105 +#    define MOZ_HAVE_CXX11_FINAL         final
   1.106 +#  else
   1.107 +     /* MSVC <= 10 used to spell "final" as "sealed". */
   1.108 +#    define MOZ_HAVE_CXX11_FINAL         sealed
   1.109 +#  endif
   1.110 +#  define MOZ_HAVE_CXX11_OVERRIDE
   1.111 +#  define MOZ_HAVE_NEVER_INLINE          __declspec(noinline)
   1.112 +#  define MOZ_HAVE_NORETURN              __declspec(noreturn)
   1.113 +// Staying away from explicit conversion operators in MSVC for now, see
   1.114 +// http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
   1.115 +#endif
   1.116 +
   1.117 +/*
   1.118 + * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a
   1.119 + * function at compile time. A constexpr function cannot examine any values
   1.120 + * except its arguments and can have no side effects except its return value.
   1.121 + * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's
   1.122 + * value may be computed at compile time.  It should be prefered to just
   1.123 + * marking variables as MOZ_CONSTEXPR because if the compiler does not support
   1.124 + * constexpr it will fall back to making the variable const, and some compilers
   1.125 + * do not accept variables being marked both const and constexpr.
   1.126 + */
   1.127 +#ifdef MOZ_HAVE_CXX11_CONSTEXPR
   1.128 +#  define MOZ_CONSTEXPR         constexpr
   1.129 +#  define MOZ_CONSTEXPR_VAR     constexpr
   1.130 +#else
   1.131 +#  define MOZ_CONSTEXPR         /* no support */
   1.132 +#  define MOZ_CONSTEXPR_VAR     const
   1.133 +#endif
   1.134 +
   1.135 +/*
   1.136 + * MOZ_EXPLICIT_CONVERSION is a specifier on a type conversion
   1.137 + * overloaded operator that declares that a C++11 compiler should restrict
   1.138 + * this operator to allow only explicit type conversions, disallowing
   1.139 + * implicit conversions.
   1.140 + *
   1.141 + * Example:
   1.142 + *
   1.143 + *   template<typename T>
   1.144 + *   class Ptr
   1.145 + *   {
   1.146 + *      T* ptr;
   1.147 + *      MOZ_EXPLICIT_CONVERSION operator bool() const {
   1.148 + *        return ptr != nullptr;
   1.149 + *      }
   1.150 + *   };
   1.151 + *
   1.152 + */
   1.153 +#ifdef MOZ_HAVE_EXPLICIT_CONVERSION
   1.154 +#  define MOZ_EXPLICIT_CONVERSION explicit
   1.155 +#else
   1.156 +#  define MOZ_EXPLICIT_CONVERSION /* no support */
   1.157 +#endif
   1.158 +
   1.159 +/*
   1.160 + * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
   1.161 + * method decorated with it must never be inlined, even if the compiler would
   1.162 + * otherwise choose to inline the method.  Compilers aren't absolutely
   1.163 + * guaranteed to support this, but most do.
   1.164 + */
   1.165 +#if defined(MOZ_HAVE_NEVER_INLINE)
   1.166 +#  define MOZ_NEVER_INLINE      MOZ_HAVE_NEVER_INLINE
   1.167 +#else
   1.168 +#  define MOZ_NEVER_INLINE      /* no support */
   1.169 +#endif
   1.170 +
   1.171 +/*
   1.172 + * MOZ_NORETURN, specified at the start of a function declaration, indicates
   1.173 + * that the given function does not return.  (The function definition does not
   1.174 + * need to be annotated.)
   1.175 + *
   1.176 + *   MOZ_NORETURN void abort(const char* msg);
   1.177 + *
   1.178 + * This modifier permits the compiler to optimize code assuming a call to such a
   1.179 + * function will never return.  It also enables the compiler to avoid spurious
   1.180 + * warnings about not initializing variables, or about any other seemingly-dodgy
   1.181 + * operations performed after the function returns.
   1.182 + *
   1.183 + * This modifier does not affect the corresponding function's linking behavior.
   1.184 + */
   1.185 +#if defined(MOZ_HAVE_NORETURN)
   1.186 +#  define MOZ_NORETURN          MOZ_HAVE_NORETURN
   1.187 +#else
   1.188 +#  define MOZ_NORETURN          /* no support */
   1.189 +#endif
   1.190 +
   1.191 +/*
   1.192 + * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
   1.193 + * instrumentation shipped with Clang and GCC) to not instrument the annotated
   1.194 + * function. Furthermore, it will prevent the compiler from inlining the
   1.195 + * function because inlining currently breaks the blacklisting mechanism of
   1.196 + * AddressSanitizer.
   1.197 + */
   1.198 +#if defined(__has_feature)
   1.199 +#  if __has_feature(address_sanitizer)
   1.200 +#    define MOZ_HAVE_ASAN_BLACKLIST
   1.201 +#  endif
   1.202 +#elif defined(__GNUC__)
   1.203 +#  if defined(__SANITIZE_ADDRESS__)
   1.204 +#    define MOZ_HAVE_ASAN_BLACKLIST
   1.205 +#  endif
   1.206 +#endif
   1.207 +
   1.208 +#if defined(MOZ_HAVE_ASAN_BLACKLIST)
   1.209 +#  define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address))
   1.210 +#else
   1.211 +#  define MOZ_ASAN_BLACKLIST /* nothing */
   1.212 +#endif
   1.213 +
   1.214 +/*
   1.215 + * MOZ_TSAN_BLACKLIST is a macro to tell ThreadSanitizer (a compile-time
   1.216 + * instrumentation shipped with Clang) to not instrument the annotated function.
   1.217 + * Furthermore, it will prevent the compiler from inlining the function because
   1.218 + * inlining currently breaks the blacklisting mechanism of ThreadSanitizer.
   1.219 + */
   1.220 +#if defined(__has_feature)
   1.221 +#  if __has_feature(thread_sanitizer)
   1.222 +#    define MOZ_TSAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread))
   1.223 +#  else
   1.224 +#    define MOZ_TSAN_BLACKLIST /* nothing */
   1.225 +#  endif
   1.226 +#else
   1.227 +#  define MOZ_TSAN_BLACKLIST /* nothing */
   1.228 +#endif
   1.229 +
   1.230 +#ifdef __cplusplus
   1.231 +
   1.232 +/*
   1.233 + * MOZ_DELETE, specified immediately prior to the ';' terminating an undefined-
   1.234 + * method declaration, attempts to delete that method from the corresponding
   1.235 + * class.  An attempt to use the method will always produce an error *at compile
   1.236 + * time* (instead of sometimes as late as link time) when this macro can be
   1.237 + * implemented.  For example, you can use MOZ_DELETE to produce classes with no
   1.238 + * implicit copy constructor or assignment operator:
   1.239 + *
   1.240 + *   struct NonCopyable
   1.241 + *   {
   1.242 + *     private:
   1.243 + *       NonCopyable(const NonCopyable& other) MOZ_DELETE;
   1.244 + *       void operator=(const NonCopyable& other) MOZ_DELETE;
   1.245 + *   };
   1.246 + *
   1.247 + * If MOZ_DELETE can't be implemented for the current compiler, use of the
   1.248 + * annotated method will still cause an error, but the error might occur at link
   1.249 + * time in some cases rather than at compile time.
   1.250 + *
   1.251 + * MOZ_DELETE relies on C++11 functionality not universally implemented.  As a
   1.252 + * backstop, method declarations using MOZ_DELETE should be private.
   1.253 + */
   1.254 +#if defined(MOZ_HAVE_CXX11_DELETE)
   1.255 +#  define MOZ_DELETE            = delete
   1.256 +#else
   1.257 +#  define MOZ_DELETE            /* no support */
   1.258 +#endif
   1.259 +
   1.260 +/*
   1.261 + * MOZ_OVERRIDE explicitly indicates that a virtual member function in a class
   1.262 + * overrides a member function of a base class, rather than potentially being a
   1.263 + * new member function.  MOZ_OVERRIDE should be placed immediately before the
   1.264 + * ';' terminating the member function's declaration, or before '= 0;' if the
   1.265 + * member function is pure.  If the member function is defined in the class
   1.266 + * definition, it should appear before the opening brace of the function body.
   1.267 + *
   1.268 + *   class Base
   1.269 + *   {
   1.270 + *     public:
   1.271 + *       virtual void f() = 0;
   1.272 + *   };
   1.273 + *   class Derived1 : public Base
   1.274 + *   {
   1.275 + *     public:
   1.276 + *       virtual void f() MOZ_OVERRIDE;
   1.277 + *   };
   1.278 + *   class Derived2 : public Base
   1.279 + *   {
   1.280 + *     public:
   1.281 + *       virtual void f() MOZ_OVERRIDE = 0;
   1.282 + *   };
   1.283 + *   class Derived3 : public Base
   1.284 + *   {
   1.285 + *     public:
   1.286 + *       virtual void f() MOZ_OVERRIDE { }
   1.287 + *   };
   1.288 + *
   1.289 + * In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that
   1.290 + * the function marked with it override a member function of a base class: it
   1.291 + * is a compile error if it does not.  Otherwise MOZ_OVERRIDE does not affect
   1.292 + * semantics and merely documents the override relationship to the reader (but
   1.293 + * of course must still be used correctly to not break C++11 compilers).
   1.294 + */
   1.295 +#if defined(MOZ_HAVE_CXX11_OVERRIDE)
   1.296 +#  define MOZ_OVERRIDE          override
   1.297 +#else
   1.298 +#  define MOZ_OVERRIDE          /* no support */
   1.299 +#endif
   1.300 +
   1.301 +/*
   1.302 + * MOZ_FINAL indicates that some functionality cannot be overridden through
   1.303 + * inheritance.  It can be used to annotate either classes/structs or virtual
   1.304 + * member functions.
   1.305 + *
   1.306 + * To annotate a class/struct with MOZ_FINAL, place MOZ_FINAL immediately after
   1.307 + * the name of the class, before the list of classes from which it derives (if
   1.308 + * any) and before its opening brace.  MOZ_FINAL must not be used to annotate
   1.309 + * unnamed classes or structs.  (With some compilers, and with C++11 proper, the
   1.310 + * underlying expansion is ambiguous with specifying a class name.)
   1.311 + *
   1.312 + *   class Base MOZ_FINAL
   1.313 + *   {
   1.314 + *     public:
   1.315 + *       Base();
   1.316 + *       ~Base();
   1.317 + *       virtual void f() { }
   1.318 + *   };
   1.319 + *   // This will be an error in some compilers:
   1.320 + *   class Derived : public Base
   1.321 + *   {
   1.322 + *     public:
   1.323 + *       ~Derived() { }
   1.324 + *   };
   1.325 + *
   1.326 + * One particularly common reason to specify MOZ_FINAL upon a class is to tell
   1.327 + * the compiler that it's not dangerous for it to have a non-virtual destructor
   1.328 + * yet have one or more virtual functions, silencing the warning it might emit
   1.329 + * in this case.  Suppose Base above weren't annotated with MOZ_FINAL.  Because
   1.330 + * ~Base() is non-virtual, an attempt to delete a Derived* through a Base*
   1.331 + * wouldn't call ~Derived(), so any cleanup ~Derived() might do wouldn't happen.
   1.332 + * (Formally C++ says behavior is undefined, but compilers will likely just call
   1.333 + * ~Base() and not ~Derived().)  Specifying MOZ_FINAL tells the compiler that
   1.334 + * it's safe for the destructor to be non-virtual.
   1.335 + *
   1.336 + * In compilers implementing final controls, it is an error to inherit from a
   1.337 + * class annotated with MOZ_FINAL.  In other compilers it serves only as
   1.338 + * documentation.
   1.339 + *
   1.340 + * To annotate a virtual member function with MOZ_FINAL, place MOZ_FINAL
   1.341 + * immediately before the ';' terminating the member function's declaration, or
   1.342 + * before '= 0;' if the member function is pure.  If the member function is
   1.343 + * defined in the class definition, it should appear before the opening brace of
   1.344 + * the function body.  (This placement is identical to that for MOZ_OVERRIDE.
   1.345 + * If both are used, they should appear in the order 'MOZ_FINAL MOZ_OVERRIDE'
   1.346 + * for consistency.)
   1.347 + *
   1.348 + *   class Base
   1.349 + *   {
   1.350 + *     public:
   1.351 + *       virtual void f() MOZ_FINAL;
   1.352 + *   };
   1.353 + *   class Derived
   1.354 + *   {
   1.355 + *     public:
   1.356 + *       // This will be an error in some compilers:
   1.357 + *       virtual void f();
   1.358 + *   };
   1.359 + *
   1.360 + * In compilers implementing final controls, it is an error for a derived class
   1.361 + * to override a method annotated with MOZ_FINAL.  In other compilers it serves
   1.362 + * only as documentation.
   1.363 + */
   1.364 +#if defined(MOZ_HAVE_CXX11_FINAL)
   1.365 +#  define MOZ_FINAL             MOZ_HAVE_CXX11_FINAL
   1.366 +#else
   1.367 +#  define MOZ_FINAL             /* no support */
   1.368 +#endif
   1.369 +
   1.370 +/**
   1.371 + * MOZ_WARN_UNUSED_RESULT tells the compiler to emit a warning if a function's
   1.372 + * return value is not used by the caller.
   1.373 + *
   1.374 + * Place this attribute at the very beginning of a function definition. For
   1.375 + * example, write
   1.376 + *
   1.377 + *   MOZ_WARN_UNUSED_RESULT int foo();
   1.378 + *
   1.379 + * or
   1.380 + *
   1.381 + *   MOZ_WARN_UNUSED_RESULT int foo() { return 42; }
   1.382 + */
   1.383 +#if defined(__GNUC__) || defined(__clang__)
   1.384 +#  define MOZ_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
   1.385 +#else
   1.386 +#  define MOZ_WARN_UNUSED_RESULT
   1.387 +#endif
   1.388 +
   1.389 +/*
   1.390 + * The following macros are attributes that support the static analysis plugin
   1.391 + * included with Mozilla, and will be implemented (when such support is enabled)
   1.392 + * as C++11 attributes. Since such attributes are legal pretty much everywhere
   1.393 + * and have subtly different semantics depending on their placement, the
   1.394 + * following is a guide on where to place the attributes.
   1.395 + *
   1.396 + * Attributes that apply to a struct or class precede the name of the class:
   1.397 + * (Note that this is different from the placement of MOZ_FINAL for classes!)
   1.398 + *
   1.399 + *   class MOZ_CLASS_ATTRIBUTE SomeClass {};
   1.400 + *
   1.401 + * Attributes that apply to functions follow the parentheses and const
   1.402 + * qualifiers but precede MOZ_FINAL, MOZ_OVERRIDE and the function body:
   1.403 + *
   1.404 + *   void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE;
   1.405 + *   void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {}
   1.406 + *   void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0;
   1.407 + *   void OverriddenFunction() MOZ_FUNCTION_ATTIRBUTE MOZ_OVERRIDE;
   1.408 + *
   1.409 + * Attributes that apply to variables or parameters follow the variable's name:
   1.410 + *
   1.411 + *   int variable MOZ_VARIABLE_ATTRIBUTE;
   1.412 + *
   1.413 + * Attributes that apply to types follow the type name:
   1.414 + *
   1.415 + *   typedef int MOZ_TYPE_ATTRIBUTE MagicInt;
   1.416 + *   int MOZ_TYPE_ATTRIBUTE someVariable;
   1.417 + *   int * MOZ_TYPE_ATTRIBUTE magicPtrInt;
   1.418 + *   int MOZ_TYPE_ATTRIBUTE * ptrToMagicInt;
   1.419 + *
   1.420 + * Attributes that apply to statements precede the statement:
   1.421 + *
   1.422 + *   MOZ_IF_ATTRIBUTE if (x == 0)
   1.423 + *   MOZ_DO_ATTRIBUTE do { } while(0);
   1.424 + *
   1.425 + * Attributes that apply to labels precede the label:
   1.426 + *
   1.427 + *   MOZ_LABEL_ATTRIBUTE target:
   1.428 + *     goto target;
   1.429 + *   MOZ_CASE_ATTRIBUTE case 5:
   1.430 + *   MOZ_DEFAULT_ATTRIBUTE default:
   1.431 + *
   1.432 + * The static analyses that are performed by the plugin are as follows:
   1.433 + *
   1.434 + * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate
   1.435 + *   subclasses must provide an exact override of this method; if a subclass
   1.436 + *   does not override this method, the compiler will emit an error. This
   1.437 + *   attribute is not limited to virtual methods, so if it is applied to a
   1.438 + *   nonvirtual method and the subclass does not provide an equivalent
   1.439 + *   definition, the compiler will emit an error.
   1.440 + * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is
   1.441 + *   expected to live on the stack, so it is a compile-time error to use it, or
   1.442 + *   an array of such objects, as a global or static variable, or as the type of
   1.443 + *   a new expression (unless placement new is being used). If a member of
   1.444 + *   another class uses this class, or if another class inherits from this
   1.445 + *   class, then it is considered to be a stack class as well, although this
   1.446 + *   attribute need not be provided in such cases.
   1.447 + * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is
   1.448 + *   expected to live on the stack or in static storage, so it is a compile-time
   1.449 + *   error to use it, or an array of such objects, as the type of a new
   1.450 + *   expression (unless placement new is being used). If a member of another
   1.451 + *   class uses this class, or if another class inherits from this class, then
   1.452 + *   it is considered to be a non-heap class as well, although this attribute
   1.453 + *   need not be provided in such cases.
   1.454 + * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return
   1.455 + *   value is allocated on the heap, and will as a result check such allocations
   1.456 + *   during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking.
   1.457 + */
   1.458 +#ifdef MOZ_CLANG_PLUGIN
   1.459 +#  define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override")))
   1.460 +#  define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
   1.461 +#  define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class")))
   1.462 +/*
   1.463 + * It turns out that clang doesn't like void func() __attribute__ {} without a
   1.464 + * warning, so use pragmas to disable the warning. This code won't work on GCC
   1.465 + * anyways, so the warning is safe to ignore.
   1.466 + */
   1.467 +#  define MOZ_HEAP_ALLOCATOR \
   1.468 +    _Pragma("clang diagnostic push") \
   1.469 +    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
   1.470 +    __attribute__((annotate("moz_heap_allocator"))) \
   1.471 +    _Pragma("clang diagnostic pop")
   1.472 +#else
   1.473 +#  define MOZ_MUST_OVERRIDE /* nothing */
   1.474 +#  define MOZ_STACK_CLASS /* nothing */
   1.475 +#  define MOZ_NONHEAP_CLASS /* nothing */
   1.476 +#  define MOZ_HEAP_ALLOCATOR /* nothing */
   1.477 +#endif /* MOZ_CLANG_PLUGIN */
   1.478 +
   1.479 +/*
   1.480 + * MOZ_THIS_IN_INITIALIZER_LIST is used to avoid a warning when we know that
   1.481 + * it's safe to use 'this' in an initializer list.
   1.482 + */
   1.483 +#ifdef _MSC_VER
   1.484 +#  define MOZ_THIS_IN_INITIALIZER_LIST() \
   1.485 +     __pragma(warning(push)) \
   1.486 +     __pragma(warning(disable:4355)) \
   1.487 +     this \
   1.488 +     __pragma(warning(pop))
   1.489 +#else
   1.490 +#  define MOZ_THIS_IN_INITIALIZER_LIST() this
   1.491 +#endif
   1.492 +
   1.493 +#endif /* __cplusplus */
   1.494 +
   1.495 +#endif /* mozilla_Attributes_h */

mercurial