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 #ifdef __GNUC__ // aka 'ATTRIBUTE_CONST' but following LLVM Conventions.
     53 #define LLVM_ATTRIBUTE_READNONE __attribute__((__const__))
     54 #else
     55 #define LLVM_ATTRIBUTE_READNONE
     56 #endif
     57 
     58 #ifdef __GNUC__  // aka 'ATTRIBUTE_PURE' but following LLVM Conventions.
     59 #define LLVM_ATTRIBUTE_READONLY __attribute__((__pure__))
     60 #else
     61 #define LLVM_ATTRIBUTE_READONLY
     62 #endif
     63 
     64 #if (__GNUC__ >= 4)
     65 #define BUILTIN_EXPECT(EXPR, VALUE) __builtin_expect((EXPR), (VALUE))
     66 #else
     67 #define BUILTIN_EXPECT(EXPR, VALUE) (EXPR)
     68 #endif
     69 
     70 // C++ doesn't support 'extern template' of template specializations.  GCC does,
     71 // but requires __extension__ before it.  In the header, use this:
     72 //   EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
     73 // in the .cpp file, use this:
     74 //   TEMPLATE_INSTANTIATION(class foo<bar>);
     75 #ifdef __GNUC__
     76 #define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
     77 #define TEMPLATE_INSTANTIATION(X) template X
     78 #else
     79 #define EXTERN_TEMPLATE_INSTANTIATION(X)
     80 #define TEMPLATE_INSTANTIATION(X)
     81 #endif
     82 
     83 // LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
     84 // mark a method "not for inlining".
     85 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
     86 #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
     87 #elif defined(_MSC_VER)
     88 #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
     89 #else
     90 #define LLVM_ATTRIBUTE_NOINLINE
     91 #endif
     92 
     93 // LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
     94 // so, mark a method "always inline" because it is performance sensitive. GCC
     95 // 3.4 supported this but is buggy in various cases and produces unimplemented
     96 // errors, just use it in GCC 4.0 and later.
     97 #if __GNUC__ > 3
     98 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
     99 #elif defined(_MSC_VER)
    100 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
    101 #else
    102 #define LLVM_ATTRIBUTE_ALWAYS_INLINE
    103 #endif
    104 
    105 
    106 #ifdef __GNUC__
    107 #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
    108 #elif defined(_MSC_VER)
    109 #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
    110 #else
    111 #define LLVM_ATTRIBUTE_NORETURN
    112 #endif
    113 
    114 // LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
    115 #if __has_feature(attribute_deprecated_with_message)
    116 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    117   decl __attribute__((deprecated(message)))
    118 #elif defined(__GNUC__)
    119 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    120   decl __attribute__((deprecated))
    121 #elif defined(_MSC_VER)
    122 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    123   __declspec(deprecated(message)) decl
    124 #else
    125 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
    126   decl
    127 #endif
    128 
    129 // LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
    130 // to an expression which states that it is undefined behavior for the
    131 // compiler to reach this point.  Otherwise is not defined.
    132 #if defined(__clang__) || (__GNUC__ > 4) \
    133  || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
    134 # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
    135 #endif
    136 
    137 #endif
    138