Bug 321958 - Remove dead code nsIPluginTagInfo.getTagText, r=josh
[gecko.git] / mfbt / Attributes.h
blobd112619e68a213ba30f066135861dfc75eacdd19
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* Implementations of various class and method modifier attributes. */
8 #ifndef mozilla_Attributes_h_
9 #define mozilla_Attributes_h_
12 * This header does not include any other headers so that it can be included by
13 * code that is (only currently) mfbt-incompatible.
17 * MOZ_INLINE is a macro which expands to tell the compiler that the method
18 * decorated with it should be inlined. This macro is usable from C and C++
19 * code, even though C89 does not support the |inline| keyword. The compiler
20 * may ignore this directive if it chooses.
22 #if defined(__cplusplus)
23 # define MOZ_INLINE inline
24 #elif defined(_MSC_VER)
25 # define MOZ_INLINE __inline
26 #elif defined(__GNUC__)
27 # define MOZ_INLINE __inline__
28 #else
29 # define MOZ_INLINE inline
30 #endif
33 * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the
34 * method decorated with it must be inlined, even if the compiler thinks
35 * otherwise. This is only a (much) stronger version of the MOZ_INLINE hint:
36 * compilers are not guaranteed to respect it (although they're much more likely
37 * to do so).
39 #if defined(DEBUG)
40 # define MOZ_ALWAYS_INLINE MOZ_INLINE
41 #elif defined(_MSC_VER)
42 # define MOZ_ALWAYS_INLINE __forceinline
43 #elif defined(__GNUC__)
44 # define MOZ_ALWAYS_INLINE __attribute__((always_inline)) MOZ_INLINE
45 #else
46 # define MOZ_ALWAYS_INLINE MOZ_INLINE
47 #endif
50 * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
51 * without warnings (functionality used by the macros below). These modes are
52 * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
53 * standardly, by checking whether __cplusplus has a C++11 or greater value.
54 * Current versions of g++ do not correctly set __cplusplus, so we check both
55 * for forward compatibility.
57 #if defined(__clang__)
59 * Per Clang documentation, "Note that marketing version numbers should not
60 * be used to check for language features, as different vendors use different
61 * numbering schemes. Instead, use the feature checking macros."
63 # ifndef __has_extension
64 # define __has_extension __has_feature /* compatibility, for older versions of clang */
65 # endif
66 # if __has_extension(cxx_constexpr)
67 # define MOZ_HAVE_CXX11_CONSTEXPR
68 # endif
69 # if __cplusplus >= 201103L
70 # if __has_extension(cxx_deleted_functions)
71 # define MOZ_HAVE_CXX11_DELETE
72 # endif
73 # if __has_extension(cxx_override_control)
74 # define MOZ_HAVE_CXX11_OVERRIDE
75 # define MOZ_HAVE_CXX11_FINAL final
76 # endif
77 # endif
78 # if __has_extension(cxx_strong_enums)
79 # define MOZ_HAVE_CXX11_ENUM_TYPE
80 # define MOZ_HAVE_CXX11_STRONG_ENUMS
81 # endif
82 # if __has_attribute(noinline)
83 # define MOZ_HAVE_NEVER_INLINE __attribute__((noinline))
84 # endif
85 # if __has_attribute(noreturn)
86 # define MOZ_HAVE_NORETURN __attribute__((noreturn))
87 # endif
88 #elif defined(__GNUC__)
89 # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
90 # if __GNUC__ > 4
91 # define MOZ_HAVE_CXX11_DELETE
92 # define MOZ_HAVE_CXX11_OVERRIDE
93 # define MOZ_HAVE_CXX11_FINAL final
94 # elif __GNUC__ == 4
95 # if __GNUC_MINOR__ >= 7
96 # define MOZ_HAVE_CXX11_OVERRIDE
97 # define MOZ_HAVE_CXX11_FINAL final
98 # endif
99 # if __GNUC_MINOR__ >= 6
100 # define MOZ_HAVE_CXX11_CONSTEXPR
101 # endif
102 # define MOZ_HAVE_CXX11_DELETE
103 # if __GNUC_MINOR__ >= 5
104 # define MOZ_HAVE_CXX11_ENUM_TYPE
105 # define MOZ_HAVE_CXX11_STRONG_ENUMS
106 # endif
107 # endif
108 # else
109 /* __final is a non-C++11 GCC synonym for 'final', per GCC r176655. */
110 # if __GNUC__ > 4
111 # define MOZ_HAVE_CXX11_FINAL __final
112 # elif __GNUC__ == 4
113 # if __GNUC_MINOR__ >= 7
114 # define MOZ_HAVE_CXX11_FINAL __final
115 # endif
116 # endif
117 # endif
118 # define MOZ_HAVE_NEVER_INLINE __attribute__((noinline))
119 # define MOZ_HAVE_NORETURN __attribute__((noreturn))
120 #elif defined(_MSC_VER)
121 # if _MSC_VER >= 1700
122 # define MOZ_HAVE_CXX11_FINAL final
123 # define MOZ_HAVE_CXX11_STRONG_ENUMS
124 # else
125 /* MSVC <= 10 used to spell "final" as "sealed". */
126 # define MOZ_HAVE_CXX11_FINAL sealed
127 # endif
128 # define MOZ_HAVE_CXX11_OVERRIDE
129 # define MOZ_HAVE_CXX11_ENUM_TYPE
130 # define MOZ_HAVE_NEVER_INLINE __declspec(noinline)
131 # define MOZ_HAVE_NORETURN __declspec(noreturn)
132 #endif
135 * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a
136 * function at compile time. A constexpr function cannot examine any values
137 * except its arguments and can have no side effects except its return value.
139 #ifdef MOZ_HAVE_CXX11_CONSTEXPR
140 # define MOZ_CONSTEXPR constexpr
141 #else
142 # define MOZ_CONSTEXPR /* no support */
143 #endif
146 * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
147 * method decorated with it must never be inlined, even if the compiler would
148 * otherwise choose to inline the method. Compilers aren't absolutely
149 * guaranteed to support this, but most do.
151 #if defined(MOZ_HAVE_NEVER_INLINE)
152 # define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE
153 #else
154 # define MOZ_NEVER_INLINE /* no support */
155 #endif
158 * MOZ_NORETURN, specified at the start of a function declaration, indicates
159 * that the given function does not return. (The function definition does not
160 * need to be annotated.)
162 * MOZ_NORETURN void abort(const char* msg);
164 * This modifier permits the compiler to optimize code assuming a call to such a
165 * function will never return. It also enables the compiler to avoid spurious
166 * warnings about not initializing variables, or about any other seemingly-dodgy
167 * operations performed after the function returns.
169 * This modifier does not affect the corresponding function's linking behavior.
171 #if defined(MOZ_HAVE_NORETURN)
172 # define MOZ_NORETURN MOZ_HAVE_NORETURN
173 #else
174 # define MOZ_NORETURN /* no support */
175 #endif
178 * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
179 * instrumentation shipped with Clang) to not instrument the annotated function.
180 * Furthermore, it will prevent the compiler from inlining the function because
181 * inlining currently breaks the blacklisting mechanism of AddressSanitizer.
183 #if defined(MOZ_ASAN)
184 # define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_address_safety_analysis))
185 # else
186 # define MOZ_ASAN_BLACKLIST
187 #endif
190 #ifdef __cplusplus
193 * MOZ_DELETE, specified immediately prior to the ';' terminating an undefined-
194 * method declaration, attempts to delete that method from the corresponding
195 * class. An attempt to use the method will always produce an error *at compile
196 * time* (instead of sometimes as late as link time) when this macro can be
197 * implemented. For example, you can use MOZ_DELETE to produce classes with no
198 * implicit copy constructor or assignment operator:
200 * struct NonCopyable
202 * private:
203 * NonCopyable(const NonCopyable& other) MOZ_DELETE;
204 * void operator=(const NonCopyable& other) MOZ_DELETE;
205 * };
207 * If MOZ_DELETE can't be implemented for the current compiler, use of the
208 * annotated method will still cause an error, but the error might occur at link
209 * time in some cases rather than at compile time.
211 * MOZ_DELETE relies on C++11 functionality not universally implemented. As a
212 * backstop, method declarations using MOZ_DELETE should be private.
214 #if defined(MOZ_HAVE_CXX11_DELETE)
215 # define MOZ_DELETE = delete
216 #else
217 # define MOZ_DELETE /* no support */
218 #endif
221 * MOZ_OVERRIDE explicitly indicates that a virtual member function in a class
222 * overrides a member function of a base class, rather than potentially being a
223 * new member function. MOZ_OVERRIDE should be placed immediately before the
224 * ';' terminating the member function's declaration, or before '= 0;' if the
225 * member function is pure. If the member function is defined in the class
226 * definition, it should appear before the opening brace of the function body.
228 * class Base
230 * public:
231 * virtual void f() = 0;
232 * };
233 * class Derived1 : public Base
235 * public:
236 * virtual void f() MOZ_OVERRIDE;
237 * };
238 * class Derived2 : public Base
240 * public:
241 * virtual void f() MOZ_OVERRIDE = 0;
242 * };
243 * class Derived3 : public Base
245 * public:
246 * virtual void f() MOZ_OVERRIDE { }
247 * };
249 * In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that
250 * the function marked with it override a member function of a base class: it
251 * is a compile error if it does not. Otherwise MOZ_OVERRIDE does not affect
252 * semantics and merely documents the override relationship to the reader (but
253 * of course must still be used correctly to not break C++11 compilers).
255 #if defined(MOZ_HAVE_CXX11_OVERRIDE)
256 # define MOZ_OVERRIDE override
257 #else
258 # define MOZ_OVERRIDE /* no support */
259 #endif
262 * MOZ_FINAL indicates that some functionality cannot be overridden through
263 * inheritance. It can be used to annotate either classes/structs or virtual
264 * member functions.
266 * To annotate a class/struct with MOZ_FINAL, place MOZ_FINAL immediately after
267 * the name of the class, before the list of classes from which it derives (if
268 * any) and before its opening brace. MOZ_FINAL must not be used to annotate
269 * unnamed classes or structs. (With some compilers, and with C++11 proper, the
270 * underlying expansion is ambiguous with specifying a class name.)
272 * class Base MOZ_FINAL
274 * public:
275 * Base();
276 * ~Base();
277 * virtual void f() { }
278 * };
279 * // This will be an error in some compilers:
280 * class Derived : public Base
282 * public:
283 * ~Derived() { }
284 * };
286 * One particularly common reason to specify MOZ_FINAL upon a class is to tell
287 * the compiler that it's not dangerous for it to have a non-virtual destructor
288 * yet have one or more virtual functions, silencing the warning it might emit
289 * in this case. Suppose Base above weren't annotated with MOZ_FINAL. Because
290 * ~Base() is non-virtual, an attempt to delete a Derived* through a Base*
291 * wouldn't call ~Derived(), so any cleanup ~Derived() might do wouldn't happen.
292 * (Formally C++ says behavior is undefined, but compilers will likely just call
293 * ~Base() and not ~Derived().) Specifying MOZ_FINAL tells the compiler that
294 * it's safe for the destructor to be non-virtual.
296 * In compilers implementing final controls, it is an error to inherit from a
297 * class annotated with MOZ_FINAL. In other compilers it serves only as
298 * documentation.
300 * To annotate a virtual member function with MOZ_FINAL, place MOZ_FINAL
301 * immediately before the ';' terminating the member function's declaration, or
302 * before '= 0;' if the member function is pure. If the member function is
303 * defined in the class definition, it should appear before the opening brace of
304 * the function body. (This placement is identical to that for MOZ_OVERRIDE.
305 * If both are used, they should appear in the order 'MOZ_FINAL MOZ_OVERRIDE'
306 * for consistency.)
308 * class Base
310 * public:
311 * virtual void f() MOZ_FINAL;
312 * };
313 * class Derived
315 * public:
316 * // This will be an error in some compilers:
317 * virtual void f();
318 * };
320 * In compilers implementing final controls, it is an error for a derived class
321 * to override a method annotated with MOZ_FINAL. In other compilers it serves
322 * only as documentation.
324 #if defined(MOZ_HAVE_CXX11_FINAL)
325 # define MOZ_FINAL MOZ_HAVE_CXX11_FINAL
326 #else
327 # define MOZ_FINAL /* no support */
328 #endif
331 * MOZ_ENUM_TYPE specifies the underlying numeric type for an enum. It's
332 * specified by placing MOZ_ENUM_TYPE(type) immediately after the enum name in
333 * its declaration, and before the opening curly brace, like
335 * enum MyEnum MOZ_ENUM_TYPE(uint16_t)
337 * A,
338 * B = 7,
340 * };
342 * In supporting compilers, the macro will expand to ": uint16_t". The
343 * compiler will allocate exactly two bytes for MyEnum, and will require all
344 * enumerators to have values between 0 and 65535. (Thus specifying "B =
345 * 100000" instead of "B = 7" would fail to compile.) In old compilers, the
346 * macro expands to the empty string, and the underlying type is generally
347 * undefined.
349 #ifdef MOZ_HAVE_CXX11_ENUM_TYPE
350 # define MOZ_ENUM_TYPE(type) : type
351 #else
352 # define MOZ_ENUM_TYPE(type) /* no support */
353 #endif
356 * MOZ_BEGIN_ENUM_CLASS and MOZ_END_ENUM_CLASS provide access to the
357 * strongly-typed enumeration feature of C++11 ("enum class"). If supported
358 * by the compiler, an enum defined using these macros will not be implicitly
359 * converted to any other type, and its enumerators will be scoped using the
360 * enumeration name. Place MOZ_BEGIN_ENUM_CLASS(EnumName, type) in place of
361 * "enum EnumName {", and MOZ_END_ENUM_CLASS(EnumName) in place of the closing
362 * "};". For example,
364 * MOZ_BEGIN_ENUM_CLASS(Enum, int32_t)
365 * A, B = 6
366 * MOZ_END_ENUM_CLASS(Enum)
368 * This will make "Enum::A" and "Enum::B" appear in the global scope, but "A"
369 * and "B" will not. In compilers that support C++11 strongly-typed
370 * enumerations, implicit conversions of Enum values to numeric types will
371 * fail. In other compilers, Enum itself will actually be defined as a class,
372 * and some implicit conversions will fail while others will succeed.
374 * The type argument specifies the underlying type for the enum where
375 * supported, as with MOZ_ENUM_TYPE(). For simplicity, it is currently
376 * mandatory. As with MOZ_ENUM_TYPE(), it will do nothing on compilers that do
377 * not support it.
379 * Note that the workaround implemented here is not compatible with enums
380 * nested inside a class.
382 #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS)
383 /* All compilers that support strong enums also support an explicit
384 * underlying type, so no extra check is needed */
385 # define MOZ_BEGIN_ENUM_CLASS(Name, type) enum class Name : type {
386 # define MOZ_END_ENUM_CLASS(Name) };
387 #else
389 * We need Name to both name a type, and scope the provided enumerator
390 * names. Namespaces and classes both provide scoping, but namespaces
391 * aren't types, so we need to use a class that wraps the enum values. We
392 * have an implicit conversion from the inner enum type to the class, so
393 * statements like
395 * Enum x = Enum::A;
397 * will still work. We need to define an implicit conversion from the class
398 * to the inner enum as well, so that (for instance) switch statements will
399 * work. This means that the class can be implicitly converted to a numeric
400 * value as well via the enum type, since C++ allows an implicit
401 * user-defined conversion followed by a standard conversion to still be
402 * implicit.
404 * We have an explicit constructor from int defined, so that casts like
405 * (Enum)7 will still work. We also have a zero-argument constructor with
406 * no arguments, so declaration without initialization (like "Enum foo;")
407 * will work.
409 * Additionally, we'll delete as many operators as possible for the inner
410 * enum type, so statements like this will still fail:
412 * f(5 + Enum::B); // deleted operator+
414 * But we can't prevent things like this, because C++ doesn't allow
415 * overriding conversions or assignment operators for enums:
417 * int x = Enum::A;
418 * int f()
420 * return Enum::A;
423 # define MOZ_BEGIN_ENUM_CLASS(Name, type) \
424 class Name \
426 public: \
427 enum Enum MOZ_ENUM_TYPE(type) \
429 # define MOZ_END_ENUM_CLASS(Name) \
430 }; \
431 Name() {} \
432 Name(Enum aEnum) : mEnum(aEnum) {} \
433 explicit Name(int num) : mEnum((Enum)num) {} \
434 operator Enum() const { return mEnum; } \
435 private: \
436 Enum mEnum; \
437 }; \
438 inline int operator+(const int&, const Name::Enum&) MOZ_DELETE; \
439 inline int operator+(const Name::Enum&, const int&) MOZ_DELETE; \
440 inline int operator-(const int&, const Name::Enum&) MOZ_DELETE; \
441 inline int operator-(const Name::Enum&, const int&) MOZ_DELETE; \
442 inline int operator*(const int&, const Name::Enum&) MOZ_DELETE; \
443 inline int operator*(const Name::Enum&, const int&) MOZ_DELETE; \
444 inline int operator/(const int&, const Name::Enum&) MOZ_DELETE; \
445 inline int operator/(const Name::Enum&, const int&) MOZ_DELETE; \
446 inline int operator%(const int&, const Name::Enum&) MOZ_DELETE; \
447 inline int operator%(const Name::Enum&, const int&) MOZ_DELETE; \
448 inline int operator+(const Name::Enum&) MOZ_DELETE; \
449 inline int operator-(const Name::Enum&) MOZ_DELETE; \
450 inline int& operator++(Name::Enum&) MOZ_DELETE; \
451 inline int operator++(Name::Enum&, int) MOZ_DELETE; \
452 inline int& operator--(Name::Enum&) MOZ_DELETE; \
453 inline int operator--(Name::Enum&, int) MOZ_DELETE; \
454 inline bool operator==(const int&, const Name::Enum&) MOZ_DELETE; \
455 inline bool operator==(const Name::Enum&, const int&) MOZ_DELETE; \
456 inline bool operator!=(const int&, const Name::Enum&) MOZ_DELETE; \
457 inline bool operator!=(const Name::Enum&, const int&) MOZ_DELETE; \
458 inline bool operator>(const int&, const Name::Enum&) MOZ_DELETE; \
459 inline bool operator>(const Name::Enum&, const int&) MOZ_DELETE; \
460 inline bool operator<(const int&, const Name::Enum&) MOZ_DELETE; \
461 inline bool operator<(const Name::Enum&, const int&) MOZ_DELETE; \
462 inline bool operator>=(const int&, const Name::Enum&) MOZ_DELETE; \
463 inline bool operator>=(const Name::Enum&, const int&) MOZ_DELETE; \
464 inline bool operator<=(const int&, const Name::Enum&) MOZ_DELETE; \
465 inline bool operator<=(const Name::Enum&, const int&) MOZ_DELETE; \
466 inline bool operator!(const Name::Enum&) MOZ_DELETE; \
467 inline bool operator&&(const bool&, const Name::Enum&) MOZ_DELETE; \
468 inline bool operator&&(const Name::Enum&, const bool&) MOZ_DELETE; \
469 inline bool operator||(const bool&, const Name::Enum&) MOZ_DELETE; \
470 inline bool operator||(const Name::Enum&, const bool&) MOZ_DELETE; \
471 inline int operator~(const Name::Enum&) MOZ_DELETE; \
472 inline int operator&(const int&, const Name::Enum&) MOZ_DELETE; \
473 inline int operator&(const Name::Enum&, const int&) MOZ_DELETE; \
474 inline int operator|(const int&, const Name::Enum&) MOZ_DELETE; \
475 inline int operator|(const Name::Enum&, const int&) MOZ_DELETE; \
476 inline int operator^(const int&, const Name::Enum&) MOZ_DELETE; \
477 inline int operator^(const Name::Enum&, const int&) MOZ_DELETE; \
478 inline int operator<<(const int&, const Name::Enum&) MOZ_DELETE; \
479 inline int operator<<(const Name::Enum&, const int&) MOZ_DELETE; \
480 inline int operator>>(const int&, const Name::Enum&) MOZ_DELETE; \
481 inline int operator>>(const Name::Enum&, const int&) MOZ_DELETE; \
482 inline int& operator+=(int&, const Name::Enum&) MOZ_DELETE; \
483 inline int& operator-=(int&, const Name::Enum&) MOZ_DELETE; \
484 inline int& operator*=(int&, const Name::Enum&) MOZ_DELETE; \
485 inline int& operator/=(int&, const Name::Enum&) MOZ_DELETE; \
486 inline int& operator%=(int&, const Name::Enum&) MOZ_DELETE; \
487 inline int& operator&=(int&, const Name::Enum&) MOZ_DELETE; \
488 inline int& operator|=(int&, const Name::Enum&) MOZ_DELETE; \
489 inline int& operator^=(int&, const Name::Enum&) MOZ_DELETE; \
490 inline int& operator<<=(int&, const Name::Enum&) MOZ_DELETE; \
491 inline int& operator>>=(int&, const Name::Enum&) MOZ_DELETE;
492 #endif
495 * MOZ_WARN_UNUSED_RESULT tells the compiler to emit a warning if a function's
496 * return value is not used by the caller.
498 * Place this attribute at the very beginning of a function definition. For
499 * example, write
501 * MOZ_WARN_UNUSED_RESULT int foo();
503 * or
505 * MOZ_WARN_UNUSED_RESULT int foo() { return 42; }
507 #if defined(__GNUC__) || defined(__clang__)
508 # define MOZ_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
509 #else
510 # define MOZ_WARN_UNUSED_RESULT
511 #endif
513 #endif /* __cplusplus */
515 #endif /* mozilla_Attributes_h_ */