• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_BASE_COMPILER_SPECIFIC_H_
6 #define V8_BASE_COMPILER_SPECIFIC_H_
7 
8 #include "include/v8config.h"
9 
10 // Annotation to silence compiler warnings about unused
11 // types/functions/variables. Use like:
12 //
13 //   using V8_ALLOW_UNUSED Bar = Foo;
14 //   V8_ALLOW_UNUSED void foo() {}
15 #if V8_HAS_ATTRIBUTE_UNUSED
16 #define V8_ALLOW_UNUSED __attribute__((unused))
17 #else
18 #define V8_ALLOW_UNUSED
19 #endif
20 
21 // Tell the compiler a function is using a printf-style format string.
22 // |format_param| is the one-based index of the format string parameter;
23 // |dots_param| is the one-based index of the "..." parameter.
24 // For v*printf functions (which take a va_list), pass 0 for dots_param.
25 // (This is undocumented but matches what the system C headers do.)
26 #if defined(__GNUC__)
27 #define PRINTF_FORMAT(format_param, dots_param) \
28   __attribute__((format(printf, format_param, dots_param)))
29 #else
30 #define PRINTF_FORMAT(format_param, dots_param)
31 #endif
32 
33 // The C++ standard requires that static const members have an out-of-class
34 // definition (in a single compilation unit), but MSVC chokes on this (when
35 // language extensions, which are required, are enabled). (You're only likely to
36 // notice the need for a definition if you take the address of the member or,
37 // more commonly, pass it to a function that takes it as a reference argument --
38 // probably an STL function.) This macro makes MSVC do the right thing. See
39 // http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx for more
40 // information. Use like:
41 //
42 // In .h file:
43 //   struct Foo {
44 //     static const int kBar = 5;
45 //   };
46 //
47 // In .cc file:
48 //   STATIC_CONST_MEMBER_DEFINITION const int Foo::kBar;
49 #if V8_HAS_DECLSPEC_SELECTANY
50 #define STATIC_CONST_MEMBER_DEFINITION __declspec(selectany)
51 #else
52 #define STATIC_CONST_MEMBER_DEFINITION
53 #endif
54 
55 #if V8_CC_MSVC
56 
57 #include <sal.h>
58 
59 // Macros for suppressing and disabling warnings on MSVC.
60 //
61 // Warning numbers are enumerated at:
62 // http://msdn.microsoft.com/en-us/library/8x5x43k7(VS.80).aspx
63 //
64 // The warning pragma:
65 // http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx
66 //
67 // Using __pragma instead of #pragma inside macros:
68 // http://msdn.microsoft.com/en-us/library/d9x1s805.aspx
69 
70 // MSVC_SUPPRESS_WARNING disables warning |n| for the remainder of the line and
71 // for the next line of the source file.
72 #define MSVC_SUPPRESS_WARNING(n) __pragma(warning(suppress : n))
73 
74 // Allows exporting a class that inherits from a non-exported base class.
75 // This uses suppress instead of push/pop because the delimiter after the
76 // declaration (either "," or "{") has to be placed before the pop macro.
77 //
78 // Example usage:
79 // class EXPORT_API Foo : NON_EXPORTED_BASE(public Bar) {
80 //
81 // MSVC Compiler warning C4275:
82 // non dll-interface class 'Bar' used as base for dll-interface class 'Foo'.
83 // Note that this is intended to be used only when no access to the base class'
84 // static data is done through derived classes or inline methods. For more info,
85 // see http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx
86 #define NON_EXPORTED_BASE(code) \
87   MSVC_SUPPRESS_WARNING(4275)   \
88   code
89 
90 #else  // Not MSVC
91 
92 #define MSVC_SUPPRESS_WARNING(n)
93 #define NON_EXPORTED_BASE(code) code
94 
95 #endif  // V8_CC_MSVC
96 
97 // Allowing the use of noexcept by removing the keyword on older compilers that
98 // do not support adding noexcept to default members.
99 // Disabled on MSVC because constructors of standard containers are not noexcept
100 // there.
101 #if ((!defined(V8_CC_GNU) && !defined(V8_CC_MSVC) &&                      \
102       !defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64) && \
103       !defined(V8_TARGET_ARCH_PPC) && !defined(V8_TARGET_ARCH_PPC64) &&   \
104       !defined(V8_TARGET_ARCH_RISCV64)) ||                                \
105      (defined(__clang__) && __cplusplus > 201300L))
106 #define V8_NOEXCEPT noexcept
107 #else
108 #define V8_NOEXCEPT
109 #endif
110 
111 // Specify memory alignment for structs, classes, etc.
112 // Use like:
113 //   class ALIGNAS(16) MyClass { ... }
114 //   ALIGNAS(16) int array[4];
115 //
116 // In most places you can use the C++11 keyword "alignas", which is preferred.
117 //
118 // But compilers have trouble mixing __attribute__((...)) syntax with
119 // alignas(...) syntax.
120 //
121 // Doesn't work in clang or gcc:
122 //   struct alignas(16) __attribute__((packed)) S { char c; };
123 // Works in clang but not gcc:
124 //   struct __attribute__((packed)) alignas(16) S2 { char c; };
125 // Works in clang and gcc:
126 //   struct alignas(16) S3 { char c; } __attribute__((packed));
127 //
128 // There are also some attributes that must be specified *before* a class
129 // definition: visibility (used for exporting functions/classes) is one of
130 // these attributes. This means that it is not possible to use alignas() with a
131 // class that is marked as exported.
132 #if defined(V8_CC_MSVC)
133 #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
134 #else
135 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
136 #endif
137 
138 #endif  // V8_BASE_COMPILER_SPECIFIC_H_
139