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