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