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