Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 The Chromium 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 BASE_COMPILER_SPECIFIC_H_
      6 #define BASE_COMPILER_SPECIFIC_H_
      7 
      8 #include "build/build_config.h"
      9 
     10 #if defined(ANDROID)
     11 // Prefer Android's libbase definitions to our own.
     12 #include <android-base/macros.h>
     13 #endif  // defined(ANDROID)
     14 
     15 #if defined(COMPILER_MSVC)
     16 
     17 // For _Printf_format_string_.
     18 #include <sal.h>
     19 
     20 // Macros for suppressing and disabling warnings on MSVC.
     21 //
     22 // Warning numbers are enumerated at:
     23 // http://msdn.microsoft.com/en-us/library/8x5x43k7(VS.80).aspx
     24 //
     25 // The warning pragma:
     26 // http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx
     27 //
     28 // Using __pragma instead of #pragma inside macros:
     29 // http://msdn.microsoft.com/en-us/library/d9x1s805.aspx
     30 
     31 // MSVC_SUPPRESS_WARNING disables warning |n| for the remainder of the line and
     32 // for the next line of the source file.
     33 #define MSVC_SUPPRESS_WARNING(n) __pragma(warning(suppress:n))
     34 
     35 // MSVC_PUSH_DISABLE_WARNING pushes |n| onto a stack of warnings to be disabled.
     36 // The warning remains disabled until popped by MSVC_POP_WARNING.
     37 #define MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \
     38                                      __pragma(warning(disable:n))
     39 
     40 // MSVC_PUSH_WARNING_LEVEL pushes |n| as the global warning level.  The level
     41 // remains in effect until popped by MSVC_POP_WARNING().  Use 0 to disable all
     42 // warnings.
     43 #define MSVC_PUSH_WARNING_LEVEL(n) __pragma(warning(push, n))
     44 
     45 // Pop effects of innermost MSVC_PUSH_* macro.
     46 #define MSVC_POP_WARNING() __pragma(warning(pop))
     47 
     48 #define MSVC_DISABLE_OPTIMIZE() __pragma(optimize("", off))
     49 #define MSVC_ENABLE_OPTIMIZE() __pragma(optimize("", on))
     50 
     51 // Allows exporting a class that inherits from a non-exported base class.
     52 // This uses suppress instead of push/pop because the delimiter after the
     53 // declaration (either "," or "{") has to be placed before the pop macro.
     54 //
     55 // Example usage:
     56 // class EXPORT_API Foo : NON_EXPORTED_BASE(public Bar) {
     57 //
     58 // MSVC Compiler warning C4275:
     59 // non dll-interface class 'Bar' used as base for dll-interface class 'Foo'.
     60 // Note that this is intended to be used only when no access to the base class'
     61 // static data is done through derived classes or inline methods. For more info,
     62 // see http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx
     63 #define NON_EXPORTED_BASE(code) MSVC_SUPPRESS_WARNING(4275) \
     64                                 code
     65 
     66 #else  // Not MSVC
     67 
     68 #define _Printf_format_string_
     69 #define MSVC_SUPPRESS_WARNING(n)
     70 #define MSVC_PUSH_DISABLE_WARNING(n)
     71 #define MSVC_PUSH_WARNING_LEVEL(n)
     72 #define MSVC_POP_WARNING()
     73 #define MSVC_DISABLE_OPTIMIZE()
     74 #define MSVC_ENABLE_OPTIMIZE()
     75 #define NON_EXPORTED_BASE(code) code
     76 
     77 #endif  // COMPILER_MSVC
     78 
     79 
     80 // Annotate a variable indicating it's ok if the variable is not used.
     81 // (Typically used to silence a compiler warning when the assignment
     82 // is important for some other reason.)
     83 // Use like:
     84 //   int x = ...;
     85 //   ALLOW_UNUSED_LOCAL(x);
     86 #define ALLOW_UNUSED_LOCAL(x) false ? (void)x : (void)0
     87 
     88 // Annotate a typedef or function indicating it's ok if it's not used.
     89 // Use like:
     90 //   typedef Foo Bar ALLOW_UNUSED_TYPE;
     91 #if defined(COMPILER_GCC) || defined(__clang__)
     92 #define ALLOW_UNUSED_TYPE __attribute__((unused))
     93 #else
     94 #define ALLOW_UNUSED_TYPE
     95 #endif
     96 
     97 // Annotate a function indicating it should not be inlined.
     98 // Use like:
     99 //   NOINLINE void DoStuff() { ... }
    100 #if defined(COMPILER_GCC)
    101 #define NOINLINE __attribute__((noinline))
    102 #elif defined(COMPILER_MSVC)
    103 #define NOINLINE __declspec(noinline)
    104 #else
    105 #define NOINLINE
    106 #endif
    107 
    108 #if COMPILER_GCC && defined(NDEBUG)
    109 #define ALWAYS_INLINE inline __attribute__((__always_inline__))
    110 #elif COMPILER_MSVC && defined(NDEBUG)
    111 #define ALWAYS_INLINE __forceinline
    112 #else
    113 #define ALWAYS_INLINE inline
    114 #endif
    115 
    116 // Specify memory alignment for structs, classes, etc.
    117 // Use like:
    118 //   class ALIGNAS(16) MyClass { ... }
    119 //   ALIGNAS(16) int array[4];
    120 #if defined(COMPILER_MSVC)
    121 #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
    122 #elif defined(COMPILER_GCC)
    123 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
    124 #endif
    125 
    126 // Return the byte alignment of the given type (available at compile time).
    127 // Use like:
    128 //   ALIGNOF(int32_t)  // this would be 4
    129 #if defined(COMPILER_MSVC)
    130 #define ALIGNOF(type) __alignof(type)
    131 #elif defined(COMPILER_GCC)
    132 #define ALIGNOF(type) __alignof__(type)
    133 #endif
    134 
    135 // Annotate a function indicating the caller must examine the return value.
    136 // Use like:
    137 //   int foo() WARN_UNUSED_RESULT;
    138 // To explicitly ignore a result, see |ignore_result()| in base/macros.h.
    139 #undef WARN_UNUSED_RESULT
    140 #if defined(COMPILER_GCC) || defined(__clang__)
    141 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
    142 #else
    143 #define WARN_UNUSED_RESULT
    144 #endif
    145 
    146 // Tell the compiler a function is using a printf-style format string.
    147 // |format_param| is the one-based index of the format string parameter;
    148 // |dots_param| is the one-based index of the "..." parameter.
    149 // For v*printf functions (which take a va_list), pass 0 for dots_param.
    150 // (This is undocumented but matches what the system C headers do.)
    151 #if defined(COMPILER_GCC)
    152 #define PRINTF_FORMAT(format_param, dots_param) \
    153     __attribute__((format(printf, format_param, dots_param)))
    154 #else
    155 #define PRINTF_FORMAT(format_param, dots_param)
    156 #endif
    157 
    158 // WPRINTF_FORMAT is the same, but for wide format strings.
    159 // This doesn't appear to yet be implemented in any compiler.
    160 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 .
    161 #define WPRINTF_FORMAT(format_param, dots_param)
    162 // If available, it would look like:
    163 //   __attribute__((format(wprintf, format_param, dots_param)))
    164 
    165 // Sanitizers annotations.
    166 #if defined(__has_attribute)
    167 #if __has_attribute(no_sanitize)
    168 #define NO_SANITIZE(what) __attribute__((no_sanitize(what)))
    169 #endif
    170 #endif
    171 #if !defined(NO_SANITIZE)
    172 #define NO_SANITIZE(what)
    173 #endif
    174 
    175 // MemorySanitizer annotations.
    176 #if defined(MEMORY_SANITIZER) && !defined(OS_NACL)
    177 #include <sanitizer/msan_interface.h>
    178 
    179 // Mark a memory region fully initialized.
    180 // Use this to annotate code that deliberately reads uninitialized data, for
    181 // example a GC scavenging root set pointers from the stack.
    182 #define MSAN_UNPOISON(p, size)  __msan_unpoison(p, size)
    183 
    184 // Check a memory region for initializedness, as if it was being used here.
    185 // If any bits are uninitialized, crash with an MSan report.
    186 // Use this to sanitize data which MSan won't be able to track, e.g. before
    187 // passing data to another process via shared memory.
    188 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \
    189     __msan_check_mem_is_initialized(p, size)
    190 #else  // MEMORY_SANITIZER
    191 #define MSAN_UNPOISON(p, size)
    192 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size)
    193 #endif  // MEMORY_SANITIZER
    194 
    195 // DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons.
    196 #if !defined(DISABLE_CFI_PERF)
    197 #if defined(__clang__) && defined(OFFICIAL_BUILD)
    198 #define DISABLE_CFI_PERF __attribute__((no_sanitize("cfi")))
    199 #else
    200 #define DISABLE_CFI_PERF
    201 #endif
    202 #endif
    203 
    204 // Macro useful for writing cross-platform function pointers.
    205 #if !defined(CDECL)
    206 #if defined(OS_WIN)
    207 #define CDECL __cdecl
    208 #else  // defined(OS_WIN)
    209 #define CDECL
    210 #endif  // defined(OS_WIN)
    211 #endif  // !defined(CDECL)
    212 
    213 // Macro for hinting that an expression is likely to be false.
    214 #if !defined(UNLIKELY)
    215 #if defined(COMPILER_GCC)
    216 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
    217 #else
    218 #define UNLIKELY(x) (x)
    219 #endif  // defined(COMPILER_GCC)
    220 #endif  // !defined(UNLIKELY)
    221 
    222 #if !defined(LIKELY)
    223 #if defined(COMPILER_GCC)
    224 #define LIKELY(x) __builtin_expect(!!(x), 1)
    225 #else
    226 #define LIKELY(x) (x)
    227 #endif  // defined(COMPILER_GCC)
    228 #endif  // !defined(LIKELY)
    229 
    230 // Compiler feature-detection.
    231 // clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension
    232 #if defined(__has_feature)
    233 #define HAS_FEATURE(FEATURE) __has_feature(FEATURE)
    234 #else
    235 #define HAS_FEATURE(FEATURE) 0
    236 #endif
    237 
    238 #endif  // BASE_COMPILER_SPECIFIC_H_
    239