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