Home | History | Annotate | Download | only in Support
      1 //===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines several macros, based on the current compiler.  This allows
     11 // use of compiler-specific features in a way that remains portable.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_SUPPORT_COMPILER_H
     16 #define LLVM_SUPPORT_COMPILER_H
     17 
     18 #ifndef __has_feature
     19 # define __has_feature(x) 0
     20 #endif
     21 
     22 /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
     23 /// into a shared library, then the class should be private to the library and
     24 /// not accessible from outside it.  Can also be used to mark variables and
     25 /// functions, making them private to any shared library they are linked into.
     26 #if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
     27 #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
     28 #else
     29 #define LLVM_LIBRARY_VISIBILITY
     30 #endif
     31 
     32 #if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
     33 #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
     34 #else
     35 #define LLVM_ATTRIBUTE_USED
     36 #endif
     37 
     38 // Some compilers warn about unused functions. When a function is sometimes
     39 // used or not depending on build settings (e.g. a function only called from
     40 // within "assert"), this attribute can be used to suppress such warnings.
     41 //
     42 // However, it shouldn't be used for unused *variables*, as those have a much
     43 // more portable solution:
     44 //   (void)unused_var_name;
     45 // Prefer cast-to-void wherever it is sufficient.
     46 #if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
     47 #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
     48 #else
     49 #define LLVM_ATTRIBUTE_UNUSED
     50 #endif
     51 
     52 #if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
     53 #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
     54 #else
     55 #define LLVM_ATTRIBUTE_WEAK
     56 #endif
     57 
     58 #ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions.
     59 #define LLVM_READNONE __attribute__((__const__))
     60 #else
     61 #define LLVM_READNONE
     62 #endif
     63 
     64 #ifdef __GNUC__  // aka 'PURE' but following LLVM Conventions.
     65 #define LLVM_READONLY __attribute__((__pure__))
     66 #else
     67 #define LLVM_READONLY
     68 #endif
     69 
     70 #if (__GNUC__ >= 4)
     71 #define BUILTIN_EXPECT(EXPR, VALUE) __builtin_expect((EXPR), (VALUE))
     72 #else
     73 #define BUILTIN_EXPECT(EXPR, VALUE) (EXPR)
     74 #endif
     75 
     76 
     77 // C++ doesn't support 'extern template' of template specializations.  GCC does,
     78 // but requires __extension__ before it.  In the header, use this:
     79 //   EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
     80 // in the .cpp file, use this:
     81 //   TEMPLATE_INSTANTIATION(class foo<bar>);
     82 #ifdef __GNUC__
     83 #define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
     84 #define TEMPLATE_INSTANTIATION(X) template X
     85 #else
     86 #define EXTERN_TEMPLATE_INSTANTIATION(X)
     87 #define TEMPLATE_INSTANTIATION(X)
     88 #endif
     89 
     90 // LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
     91 // mark a method "not for inlining".
     92 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
     93 #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
     94 #elif defined(_MSC_VER)
     95 #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
     96 #else
     97 #define LLVM_ATTRIBUTE_NOINLINE
     98 #endif
     99 
    100 // LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
    101 // so, mark a method "always inline" because it is performance sensitive. GCC
    102 // 3.4 supported this but is buggy in various cases and produces unimplemented
    103 // errors, just use it in GCC 4.0 and later.
    104 #if __GNUC__ > 3
    105 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
    106 #elif defined(_MSC_VER)
    107 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
    108 #else
    109 #define LLVM_ATTRIBUTE_ALWAYS_INLINE
    110 #endif
    111 
    112 
    113 #ifdef __GNUC__
    114 #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
    115 #elif defined(_MSC_VER)
    116 #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
    117 #else
    118 #define LLVM_ATTRIBUTE_NORETURN
    119 #endif
    120 
    121 // LLVM_EXTENSION - Support compilers where we have a keyword to suppress
    122 // pedantic diagnostics.
    123 #ifdef __GNUC__
    124 #define LLVM_EXTENSION __extension__
    125 #else
    126 #define LLVM_EXTENSION
    127 #endif
    128 
    129 // LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
    130 #if __has_feature(attribute_deprecated_with_message)
    131 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    132   decl __attribute__((deprecated(message)))
    133 #elif defined(__GNUC__)
    134 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    135   decl __attribute__((deprecated))
    136 #elif defined(_MSC_VER)
    137 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    138   __declspec(deprecated(message)) decl
    139 #else
    140 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    141   decl
    142 #endif
    143 
    144 // LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
    145 // to an expression which states that it is undefined behavior for the
    146 // compiler to reach this point.  Otherwise is not defined.
    147 #if defined(__clang__) || (__GNUC__ > 4) \
    148  || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
    149 # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
    150 #endif
    151 
    152 #endif
    153