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 // Specify memory alignment for structs, classes, etc.
    109 // Use like:
    110 //   class ALIGNAS(16) MyClass { ... }
    111 //   ALIGNAS(16) int array[4];
    112 #if defined(COMPILER_MSVC)
    113 #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
    114 #elif defined(COMPILER_GCC)
    115 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
    116 #endif
    117 
    118 // Return the byte alignment of the given type (available at compile time).
    119 // Use like:
    120 //   ALIGNOF(int32_t)  // this would be 4
    121 #if defined(COMPILER_MSVC)
    122 #define ALIGNOF(type) __alignof(type)
    123 #elif defined(COMPILER_GCC)
    124 #define ALIGNOF(type) __alignof__(type)
    125 #endif
    126 
    127 // Annotate a function indicating the caller must examine the return value.
    128 // Use like:
    129 //   int foo() WARN_UNUSED_RESULT;
    130 // To explicitly ignore a result, see |ignore_result()| in base/macros.h.
    131 #undef WARN_UNUSED_RESULT
    132 #if defined(COMPILER_GCC) || defined(__clang__)
    133 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
    134 #else
    135 #define WARN_UNUSED_RESULT
    136 #endif
    137 
    138 // Tell the compiler a function is using a printf-style format string.
    139 // |format_param| is the one-based index of the format string parameter;
    140 // |dots_param| is the one-based index of the "..." parameter.
    141 // For v*printf functions (which take a va_list), pass 0 for dots_param.
    142 // (This is undocumented but matches what the system C headers do.)
    143 #if defined(COMPILER_GCC)
    144 #define PRINTF_FORMAT(format_param, dots_param) \
    145     __attribute__((format(printf, format_param, dots_param)))
    146 #else
    147 #define PRINTF_FORMAT(format_param, dots_param)
    148 #endif
    149 
    150 // WPRINTF_FORMAT is the same, but for wide format strings.
    151 // This doesn't appear to yet be implemented in any compiler.
    152 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 .
    153 #define WPRINTF_FORMAT(format_param, dots_param)
    154 // If available, it would look like:
    155 //   __attribute__((format(wprintf, format_param, dots_param)))
    156 
    157 // MemorySanitizer annotations.
    158 #if defined(MEMORY_SANITIZER) && !defined(OS_NACL)
    159 #include <sanitizer/msan_interface.h>
    160 
    161 // Mark a memory region fully initialized.
    162 // Use this to annotate code that deliberately reads uninitialized data, for
    163 // example a GC scavenging root set pointers from the stack.
    164 #define MSAN_UNPOISON(p, size)  __msan_unpoison(p, size)
    165 
    166 // Check a memory region for initializedness, as if it was being used here.
    167 // If any bits are uninitialized, crash with an MSan report.
    168 // Use this to sanitize data which MSan won't be able to track, e.g. before
    169 // passing data to another process via shared memory.
    170 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \
    171     __msan_check_mem_is_initialized(p, size)
    172 #else  // MEMORY_SANITIZER
    173 #define MSAN_UNPOISON(p, size)
    174 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size)
    175 #endif  // MEMORY_SANITIZER
    176 
    177 // Macro useful for writing cross-platform function pointers.
    178 #if !defined(CDECL)
    179 #if defined(OS_WIN)
    180 #define CDECL __cdecl
    181 #else  // defined(OS_WIN)
    182 #define CDECL
    183 #endif  // defined(OS_WIN)
    184 #endif  // !defined(CDECL)
    185 
    186 // Macro for hinting that an expression is likely to be false.
    187 #if !defined(UNLIKELY)
    188 #if defined(COMPILER_GCC)
    189 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
    190 #else
    191 #define UNLIKELY(x) (x)
    192 #endif  // defined(COMPILER_GCC)
    193 #endif  // !defined(UNLIKELY)
    194 
    195 // Compiler feature-detection.
    196 // clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension
    197 #if defined(__has_feature)
    198 #define HAS_FEATURE(FEATURE) __has_feature(FEATURE)
    199 #else
    200 #define HAS_FEATURE(FEATURE) 0
    201 #endif
    202 
    203 #endif  // BASE_COMPILER_SPECIFIC_H_
    204