Back to index

enigmail  1.4.3
Attributes.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim: set ts=8 sw=4 et tw=99 ft=cpp:
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at:
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is Mozilla Code.
00018  *
00019  * The Initial Developer of the Original Code is
00020  *   The Mozilla Foundation
00021  * Portions created by the Initial Developer are Copyright (C) 2011
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Jeff Walden <jwalden+code@mit.edu> (original author)
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 /* Implementations of various class and method modifier attributes. */
00042 
00043 #ifndef mozilla_Attributes_h_
00044 #define mozilla_Attributes_h_
00045 
00046 /*
00047  * This header does not include any other headers so that it can be included by
00048  * code that is (only currently) mfbt-incompatible.
00049  */
00050 
00051 /*
00052  * MOZ_INLINE is a macro which expands to tell the compiler that the method
00053  * decorated with it should be inlined.  This macro is usable from C and C++
00054  * code, even though C89 does not support the |inline| keyword.  The compiler
00055  * may ignore this directive if it chooses.
00056  */
00057 #if defined(__cplusplus)
00058 #  define MOZ_INLINE            inline
00059 #elif defined(_MSC_VER)
00060 #  define MOZ_INLINE            __inline
00061 #elif defined(__GNUC__)
00062 #  define MOZ_INLINE            __inline__
00063 #else
00064 #  define MOZ_INLINE            inline
00065 #endif
00066 
00067 /*
00068  * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the
00069  * method decorated with it must be inlined, even if the compiler thinks
00070  * otherwise.  This is only a (much) stronger version of the MOZ_INLINE hint:
00071  * compilers are not guaranteed to respect it (although they're much more likely
00072  * to do so).
00073  */
00074 #if defined(DEBUG)
00075 #  define MOZ_ALWAYS_INLINE     MOZ_INLINE
00076 #elif defined(_MSC_VER)
00077 #  define MOZ_ALWAYS_INLINE     __forceinline
00078 #elif defined(__GNUC__)
00079 #  define MOZ_ALWAYS_INLINE     __attribute__((always_inline)) MOZ_INLINE
00080 #else
00081 #  define MOZ_ALWAYS_INLINE     MOZ_INLINE
00082 #endif
00083 
00084 /*
00085  * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
00086  * without warnings (functionality used by the macros below).  These modes are
00087  * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
00088  * standardly, by checking whether __cplusplus has a C++11 or greater value.
00089  * Current versions of g++ do not correctly set __cplusplus, so we check both
00090  * for forward compatibility.
00091  */
00092 #if defined(__clang__)
00093    /*
00094     * Per Clang documentation, "Note that marketing version numbers should not
00095     * be used to check for language features, as different vendors use different
00096     * numbering schemes. Instead, use the feature checking macros."
00097     */
00098 #  ifndef __has_extension
00099 #    define __has_extension __has_feature /* compatibility, for older versions of clang */
00100 #  endif
00101 #  if __has_extension(cxx_deleted_functions)
00102 #    define MOZ_HAVE_CXX11_DELETE
00103 #  endif
00104 #  if __has_extension(cxx_override_control)
00105 #    define MOZ_HAVE_CXX11_OVERRIDE
00106 #    define MOZ_HAVE_CXX11_FINAL         final
00107 #  endif
00108 #  if __has_attribute(noinline)
00109 #    define MOZ_HAVE_NEVER_INLINE        __attribute__((noinline))
00110 #  endif
00111 #  if __has_attribute(noreturn)
00112 #    define MOZ_HAVE_NORETURN            __attribute__((noreturn))
00113 #  endif
00114 #elif defined(__GNUC__)
00115 #  if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
00116 #    if __GNUC__ > 4
00117 #      define MOZ_HAVE_CXX11_DELETE
00118 #      define MOZ_HAVE_CXX11_OVERRIDE
00119 #      define MOZ_HAVE_CXX11_FINAL       final
00120 #    elif __GNUC__ == 4
00121 #      if __GNUC_MINOR__ >= 7
00122 #        define MOZ_HAVE_CXX11_OVERRIDE
00123 #        define MOZ_HAVE_CXX11_FINAL     final
00124 #      endif
00125 #      if __GNUC_MINOR__ >= 4
00126 #        define MOZ_HAVE_CXX11_DELETE
00127 #      endif
00128 #    endif
00129 #  else
00130      /* __final is a non-C++11 GCC synonym for 'final', per GCC r176655. */
00131 #    if __GNUC__ > 4
00132 #      define MOZ_HAVE_CXX11_FINAL       __final
00133 #    elif __GNUC__ == 4
00134 #      if __GNUC_MINOR__ >= 7
00135 #        define MOZ_HAVE_CXX11_FINAL     __final
00136 #      endif
00137 #    endif
00138 #  endif
00139 #  define MOZ_HAVE_NEVER_INLINE          __attribute__((noinline))
00140 #  define MOZ_HAVE_NORETURN              __attribute__((noreturn))
00141 #elif defined(_MSC_VER)
00142 #  if _MSC_VER >= 1400
00143 #    define MOZ_HAVE_CXX11_OVERRIDE
00144      /* MSVC currently spells "final" as "sealed". */
00145 #    define MOZ_HAVE_CXX11_FINAL         sealed
00146 #  endif
00147 #  define MOZ_HAVE_NEVER_INLINE          __declspec(noinline)
00148 #  define MOZ_HAVE_NORETURN              __declspec(noreturn)
00149 #endif
00150 
00151 /*
00152  * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
00153  * method decorated with it must never be inlined, even if the compiler would
00154  * otherwise choose to inline the method.  Compilers aren't absolutely
00155  * guaranteed to support this, but most do.
00156  */
00157 #if defined(MOZ_HAVE_NEVER_INLINE)
00158 #  define MOZ_NEVER_INLINE      MOZ_HAVE_NEVER_INLINE
00159 #else
00160 #  define MOZ_NEVER_INLINE      /* no support */
00161 #endif
00162 
00163 /*
00164  * MOZ_NORETURN, specified at the start of a function declaration, indicates
00165  * that the given function does not return.  (The function definition does not
00166  * need to be annotated.)
00167  *
00168  *   MOZ_NORETURN void abort(const char* msg);
00169  *
00170  * This modifier permits the compiler to optimize code assuming a call to such a
00171  * function will never return.  It also enables the compiler to avoid spurious
00172  * warnings about not initializing variables, or about any other seemingly-dodgy
00173  * operations performed after the function returns.
00174  *
00175  * This modifier does not affect the corresponding function's linking behavior.
00176  */
00177 #if defined(MOZ_HAVE_NORETURN)
00178 #  define MOZ_NORETURN          MOZ_HAVE_NORETURN
00179 #else
00180 #  define MOZ_NORETURN          /* no support */
00181 #endif
00182 
00183 #ifdef __cplusplus
00184 
00185 /*
00186  * MOZ_DELETE, specified immediately prior to the ';' terminating an undefined-
00187  * method declaration, attempts to delete that method from the corresponding
00188  * class.  An attempt to use the method will always produce an error *at compile
00189  * time* (instead of sometimes as late as link time) when this macro can be
00190  * implemented.  For example, you can use MOZ_DELETE to produce classes with no
00191  * implicit copy constructor or assignment operator:
00192  *
00193  *   struct NonCopyable
00194  *   {
00195  *     private:
00196  *       NonCopyable(const NonCopyable& other) MOZ_DELETE;
00197  *       void operator=(const NonCopyable& other) MOZ_DELETE;
00198  *   };
00199  *
00200  * If MOZ_DELETE can't be implemented for the current compiler, use of the
00201  * annotated method will still cause an error, but the error might occur at link
00202  * time in some cases rather than at compile time.
00203  *
00204  * MOZ_DELETE relies on C++11 functionality not universally implemented.  As a
00205  * backstop, method declarations using MOZ_DELETE should be private.
00206  */
00207 #if defined(MOZ_HAVE_CXX11_DELETE)
00208 #  define MOZ_DELETE            = delete
00209 #else
00210 #  define MOZ_DELETE            /* no support */
00211 #endif
00212 
00213 /*
00214  * MOZ_OVERRIDE explicitly indicates that a virtual member function in a class
00215  * overrides a member function of a base class, rather than potentially being a
00216  * new member function.  MOZ_OVERRIDE should be placed immediately before the
00217  * ';' terminating the member function's declaration, or before '= 0;' if the
00218  * member function is pure.  If the member function is defined in the class
00219  * definition, it should appear before the opening brace of the function body.
00220  *
00221  *   class Base
00222  *   {
00223  *     public:
00224  *       virtual void f() = 0;
00225  *   };
00226  *   class Derived1 : public Base
00227  *   {
00228  *     public:
00229  *       virtual void f() MOZ_OVERRIDE;
00230  *   };
00231  *   class Derived2 : public Base
00232  *   {
00233  *     public:
00234  *       virtual void f() MOZ_OVERRIDE = 0;
00235  *   };
00236  *   class Derived3 : public Base
00237  *   {
00238  *     public:
00239  *       virtual void f() MOZ_OVERRIDE { }
00240  *   };
00241  *
00242  * In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that
00243  * the function marked with it override a member function of a base class: it
00244  * is a compile error if it does not.  Otherwise MOZ_OVERRIDE does not affect
00245  * semantics and merely documents the override relationship to the reader (but
00246  * of course must still be used correctly to not break C++11 compilers).
00247  */
00248 #if defined(MOZ_HAVE_CXX11_OVERRIDE)
00249 #  define MOZ_OVERRIDE          override
00250 #else
00251 #  define MOZ_OVERRIDE          /* no support */
00252 #endif
00253 
00254 /*
00255  * MOZ_FINAL indicates that some functionality cannot be overridden through
00256  * inheritance.  It can be used to annotate either classes/structs or virtual
00257  * member functions.
00258  *
00259  * To annotate a class/struct with MOZ_FINAL, place MOZ_FINAL immediately after
00260  * the name of the class, before the list of classes from which it derives (if
00261  * any) and before its opening brace.  MOZ_FINAL must not be used to annotate
00262  * unnamed classes or structs.  (With some compilers, and with C++11 proper, the
00263  * underlying expansion is ambiguous with specifying a class name.)
00264  *
00265  *   class Base MOZ_FINAL
00266  *   {
00267  *     public:
00268  *       Base();
00269  *       ~Base();
00270  *       virtual void f() { }
00271  *   };
00272  *   // This will be an error in some compilers:
00273  *   class Derived : public Base
00274  *   {
00275  *     public:
00276  *       ~Derived() { }
00277  *   };
00278  *
00279  * One particularly common reason to specify MOZ_FINAL upon a class is to tell
00280  * the compiler that it's not dangerous for it to have a non-virtual destructor
00281  * yet have one or more virtual functions, silencing the warning it might emit
00282  * in this case.  Suppose Base above weren't annotated with MOZ_FINAL.  Because
00283  * ~Base() is non-virtual, an attempt to delete a Derived* through a Base*
00284  * wouldn't call ~Derived(), so any cleanup ~Derived() might do wouldn't happen.
00285  * (Formally C++ says behavior is undefined, but compilers will likely just call
00286  * ~Base() and not ~Derived().)  Specifying MOZ_FINAL tells the compiler that
00287  * it's safe for the destructor to be non-virtual.
00288  *
00289  * In compilers implementing final controls, it is an error to inherit from a
00290  * class annotated with MOZ_FINAL.  In other compilers it serves only as
00291  * documentation.
00292  *
00293  * To annotate a virtual member function with MOZ_FINAL, place MOZ_FINAL
00294  * immediately before the ';' terminating the member function's declaration, or
00295  * before '= 0;' if the member function is pure.  If the member function is
00296  * defined in the class definition, it should appear before the opening brace of
00297  * the function body.  (This placement is identical to that for MOZ_OVERRIDE.
00298  * If both are used, they should appear in the order 'MOZ_FINAL MOZ_OVERRIDE'
00299  * for consistency.)
00300  *
00301  *   class Base
00302  *   {
00303  *     public:
00304  *       virtual void f() MOZ_FINAL;
00305  *   };
00306  *   class Derived
00307  *   {
00308  *     public:
00309  *       // This will be an error in some compilers:
00310  *       virtual void f();
00311  *   };
00312  *
00313  * In compilers implementing final controls, it is an error for a derived class
00314  * to override a method annotated with MOZ_FINAL.  In other compilers it serves
00315  * only as documentation.
00316  */
00317 #if defined(MOZ_HAVE_CXX11_FINAL)
00318 #  define MOZ_FINAL             MOZ_HAVE_CXX11_FINAL
00319 #else
00320 #  define MOZ_FINAL             /* no support */
00321 #endif
00322 
00336 #if defined(__GNUC__) || defined(__clang__)
00337 #  define MOZ_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
00338 #else
00339 #  define MOZ_WARN_UNUSED_RESULT
00340 #endif
00341 
00342 #endif /* __cplusplus */
00343 
00344 #endif  /* mozilla_Attributes_h_ */