Compiler.h revision b9d565ac998fc857b20786bae08bb30719eb966b
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_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references?
23/// This implies that <utility> provides the one-argument std::move;  it
24/// does not imply the existence of any other C++ library features.
25#if (__has_feature(cxx_rvalue_references)   \
26     || defined(__GXX_EXPERIMENTAL_CXX0X__) \
27     || _MSC_VER >= 1600)
28#define LLVM_USE_RVALUE_REFERENCES 1
29#else
30#define LLVM_USE_RVALUE_REFERENCES 0
31#endif
32
33/// llvm_move - Expands to ::std::move if the compiler supports
34/// r-value references; otherwise, expands to the argument.
35#if LLVM_USE_RVALUE_REFERENCES
36#define llvm_move(value) (::std::move(value))
37#else
38#define llvm_move(value) (value)
39#endif
40
41/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it.
42/// Use to mark functions as uncallable. Member functions with this should
43/// be declared private so that some behaivor is kept in C++03 mode.
44///
45/// class DontCopy {
46/// private:
47///   DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION;
48///   DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION;
49/// public:
50///   ...
51/// };
52#if (__has_feature(cxx_deleted_functions) \
53     || defined(__GXX_EXPERIMENTAL_CXX0X__))
54     // No version of MSVC currently supports this.
55#define LLVM_DELETED_FUNCTION = delete
56#else
57#define LLVM_DELETED_FUNCTION
58#endif
59
60/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
61/// into a shared library, then the class should be private to the library and
62/// not accessible from outside it.  Can also be used to mark variables and
63/// functions, making them private to any shared library they are linked into.
64#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
65#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
66#else
67#define LLVM_LIBRARY_VISIBILITY
68#endif
69
70#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
71#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
72#else
73#define LLVM_ATTRIBUTE_USED
74#endif
75
76// Some compilers warn about unused functions. When a function is sometimes
77// used or not depending on build settings (e.g. a function only called from
78// within "assert"), this attribute can be used to suppress such warnings.
79//
80// However, it shouldn't be used for unused *variables*, as those have a much
81// more portable solution:
82//   (void)unused_var_name;
83// Prefer cast-to-void wherever it is sufficient.
84#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
85#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
86#else
87#define LLVM_ATTRIBUTE_UNUSED
88#endif
89
90#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
91#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
92#else
93#define LLVM_ATTRIBUTE_WEAK
94#endif
95
96#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions.
97#define LLVM_READNONE __attribute__((__const__))
98#else
99#define LLVM_READNONE
100#endif
101
102#ifdef __GNUC__  // aka 'PURE' but following LLVM Conventions.
103#define LLVM_READONLY __attribute__((__pure__))
104#else
105#define LLVM_READONLY
106#endif
107
108#if (__GNUC__ >= 4)
109#define BUILTIN_EXPECT(EXPR, VALUE) __builtin_expect((EXPR), (VALUE))
110#else
111#define BUILTIN_EXPECT(EXPR, VALUE) (EXPR)
112#endif
113
114
115// C++ doesn't support 'extern template' of template specializations.  GCC does,
116// but requires __extension__ before it.  In the header, use this:
117//   EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
118// in the .cpp file, use this:
119//   TEMPLATE_INSTANTIATION(class foo<bar>);
120#ifdef __GNUC__
121#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
122#define TEMPLATE_INSTANTIATION(X) template X
123#else
124#define EXTERN_TEMPLATE_INSTANTIATION(X)
125#define TEMPLATE_INSTANTIATION(X)
126#endif
127
128// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
129// mark a method "not for inlining".
130#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
131#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
132#elif defined(_MSC_VER)
133#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
134#else
135#define LLVM_ATTRIBUTE_NOINLINE
136#endif
137
138// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
139// so, mark a method "always inline" because it is performance sensitive. GCC
140// 3.4 supported this but is buggy in various cases and produces unimplemented
141// errors, just use it in GCC 4.0 and later.
142#if __GNUC__ > 3
143#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
144#elif defined(_MSC_VER)
145#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
146#else
147#define LLVM_ATTRIBUTE_ALWAYS_INLINE
148#endif
149
150
151#ifdef __GNUC__
152#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
153#elif defined(_MSC_VER)
154#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
155#else
156#define LLVM_ATTRIBUTE_NORETURN
157#endif
158
159// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
160// pedantic diagnostics.
161#ifdef __GNUC__
162#define LLVM_EXTENSION __extension__
163#else
164#define LLVM_EXTENSION
165#endif
166
167// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
168#if __has_feature(attribute_deprecated_with_message)
169# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
170  decl __attribute__((deprecated(message)))
171#elif defined(__GNUC__)
172# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
173  decl __attribute__((deprecated))
174#elif defined(_MSC_VER)
175# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
176  __declspec(deprecated(message)) decl
177#else
178# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
179  decl
180#endif
181
182// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
183// to an expression which states that it is undefined behavior for the
184// compiler to reach this point.  Otherwise is not defined.
185#if defined(__clang__) || (__GNUC__ > 4) \
186 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
187# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
188#endif
189
190#endif
191