jfb created this revision.
jfb added reviewers: mclow.lists, rsmith.
jfb added a subscriber: cfe-commits.
Herald added subscribers: dschuff, jfb.
This was voted into C++17 at last week's Jacksonville meeting. The final
P0152R1 paper will be in the upcoming post-Jacksonville mailing, and is also
available here:
http://jfbastien.github.io/papers/P0152R1.html
The libc++ part of this implementation is in the following code review:
<TODO inter-dependent code reviews...>
http://reviews.llvm.org/D17950
Files:
lib/Frontend/InitPreprocessor.cpp
test/Lexer/cxx-features.cpp
test/Preprocessor/init.c
Index: test/Preprocessor/init.c
===================================================================
--- test/Preprocessor/init.c
+++ test/Preprocessor/init.c
@@ -3282,7 +3282,10 @@
// MIPSN32BE: #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
// MIPSN32BE: #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
// MIPSN32BE: #define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// MIPSN32BE: #define __GCC_ATOMIC_DOUBLE_LOCK_FREE 2
+// MIPSN32BE: #define __GCC_ATOMIC_FLOAT_LOCK_FREE 2
// MIPSN32BE: #define __GCC_ATOMIC_INT_LOCK_FREE 2
+// MIPSN32BE: #define __GCC_ATOMIC_LDOUBLE_LOCK_FREE 1
// MIPSN32BE: #define __GCC_ATOMIC_LLONG_LOCK_FREE 2
// MIPSN32BE: #define __GCC_ATOMIC_LONG_LOCK_FREE 2
// MIPSN32BE: #define __GCC_ATOMIC_POINTER_LOCK_FREE 2
@@ -3372,6 +3375,12 @@
// MIPSN32BE: #define __LDBL_MIN_10_EXP__ (-4931)
// MIPSN32BE: #define __LDBL_MIN_EXP__ (-16381)
// MIPSN32BE: #define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// MIPSN32BE: #define __LLVM_ATOMIC_16_BYTES_LOCK_FREE 1
+// MIPSN32BE: #define __LLVM_ATOMIC_1_BYTES_LOCK_FREE 2
+// MIPSN32BE: #define __LLVM_ATOMIC_2_BYTES_LOCK_FREE 2
+// MIPSN32BE: #define __LLVM_ATOMIC_4_BYTES_LOCK_FREE 2
+// MIPSN32BE: #define __LLVM_ATOMIC_8_BYTES_LOCK_FREE 2
+// MIPSN32BE: #define __LLVM_LOCK_FREE_IS_SIZE_BASED 1
// MIPSN32BE: #define __LONG_LONG_MAX__ 9223372036854775807LL
// MIPSN32BE: #define __LONG_MAX__ 2147483647L
// MIPSN32BE: #define __MIPSEB 1
@@ -3587,7 +3596,10 @@
// MIPSN32EL: #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
// MIPSN32EL: #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
// MIPSN32EL: #define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// MIPSN32EL: #define __GCC_ATOMIC_DOUBLE_LOCK_FREE 2
+// MIPSN32EL: #define __GCC_ATOMIC_FLOAT_LOCK_FREE 2
// MIPSN32EL: #define __GCC_ATOMIC_INT_LOCK_FREE 2
+// MIPSN32EL: #define __GCC_ATOMIC_LDOUBLE_LOCK_FREE 1
// MIPSN32EL: #define __GCC_ATOMIC_LLONG_LOCK_FREE 2
// MIPSN32EL: #define __GCC_ATOMIC_LONG_LOCK_FREE 2
// MIPSN32EL: #define __GCC_ATOMIC_POINTER_LOCK_FREE 2
@@ -3678,6 +3690,12 @@
// MIPSN32EL: #define __LDBL_MIN_EXP__ (-16381)
// MIPSN32EL: #define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
// MIPSN32EL: #define __LITTLE_ENDIAN__ 1
+// MIPSN32EL: #define __LLVM_ATOMIC_16_BYTES_LOCK_FREE 1
+// MIPSN32EL: #define __LLVM_ATOMIC_1_BYTES_LOCK_FREE 2
+// MIPSN32EL: #define __LLVM_ATOMIC_2_BYTES_LOCK_FREE 2
+// MIPSN32EL: #define __LLVM_ATOMIC_4_BYTES_LOCK_FREE 2
+// MIPSN32EL: #define __LLVM_ATOMIC_8_BYTES_LOCK_FREE 2
+// MIPSN32EL: #define __LLVM_LOCK_FREE_IS_SIZE_BASED 1
// MIPSN32EL: #define __LONG_LONG_MAX__ 9223372036854775807LL
// MIPSN32EL: #define __LONG_MAX__ 2147483647L
// MIPSN32EL: #define __MIPSEL 1
@@ -7614,7 +7632,10 @@
// X86_64-CLOUDABI:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
// X86_64-CLOUDABI:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
// X86_64-CLOUDABI:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __GCC_ATOMIC_DOUBLE_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __GCC_ATOMIC_FLOAT_LOCK_FREE 2
// X86_64-CLOUDABI:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __GCC_ATOMIC_LDOUBLE_LOCK_FREE 2
// X86_64-CLOUDABI:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
// X86_64-CLOUDABI:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
// X86_64-CLOUDABI:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
@@ -7705,6 +7726,12 @@
// X86_64-CLOUDABI:#define __LDBL_MIN_EXP__ (-16381)
// X86_64-CLOUDABI:#define __LDBL_MIN__ 3.36210314311209350626e-4932L
// X86_64-CLOUDABI:#define __LITTLE_ENDIAN__ 1
+// X86_64-CLOUDABI:#define __LLVM_ATOMIC_16_BYTES_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __LLVM_ATOMIC_1_BYTES_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __LLVM_ATOMIC_2_BYTES_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __LLVM_ATOMIC_4_BYTES_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __LLVM_ATOMIC_8_BYTES_LOCK_FREE 2
+// X86_64-CLOUDABI:#define __LLVM_LOCK_FREE_IS_SIZE_BASED 1
// X86_64-CLOUDABI:#define __LONG_LONG_MAX__ 9223372036854775807LL
// X86_64-CLOUDABI:#define __LONG_MAX__ 9223372036854775807L
// X86_64-CLOUDABI:#define __LP64__ 1
@@ -8478,7 +8505,10 @@
// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_DOUBLE_LOCK_FREE 1
+// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_FLOAT_LOCK_FREE 2
// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LDOUBLE_LOCK_FREE 1
// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
@@ -8570,6 +8600,12 @@
// WEBASSEMBLY32-NEXT:#define __LDBL_MIN_EXP__ (-16381)
// WEBASSEMBLY32-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
// WEBASSEMBLY32-NEXT:#define __LITTLE_ENDIAN__ 1
+// WEBASSEMBLY32-NEXT:#define __LLVM_ATOMIC_16_BYTES_LOCK_FREE 1
+// WEBASSEMBLY32-NEXT:#define __LLVM_ATOMIC_1_BYTES_LOCK_FREE 2
+// WEBASSEMBLY32-NEXT:#define __LLVM_ATOMIC_2_BYTES_LOCK_FREE 2
+// WEBASSEMBLY32-NEXT:#define __LLVM_ATOMIC_4_BYTES_LOCK_FREE 2
+// WEBASSEMBLY32-NEXT:#define __LLVM_ATOMIC_8_BYTES_LOCK_FREE 1
+// WEBASSEMBLY32-NEXT:#define __LLVM_LOCK_FREE_IS_SIZE_BASED 1
// WEBASSEMBLY32-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL
// WEBASSEMBLY32-NEXT:#define __LONG_MAX__ 2147483647L
// WEBASSEMBLY32-NOT:#define __LP64__
@@ -8793,7 +8829,10 @@
// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_DOUBLE_LOCK_FREE 2
+// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_FLOAT_LOCK_FREE 2
// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LDOUBLE_LOCK_FREE 1
// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
@@ -8885,6 +8924,12 @@
// WEBASSEMBLY64-NEXT:#define __LDBL_MIN_EXP__ (-16381)
// WEBASSEMBLY64-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
// WEBASSEMBLY64-NEXT:#define __LITTLE_ENDIAN__ 1
+// WEBASSEMBLY64-NEXT:#define __LLVM_ATOMIC_16_BYTES_LOCK_FREE 1
+// WEBASSEMBLY64-NEXT:#define __LLVM_ATOMIC_1_BYTES_LOCK_FREE 2
+// WEBASSEMBLY64-NEXT:#define __LLVM_ATOMIC_2_BYTES_LOCK_FREE 2
+// WEBASSEMBLY64-NEXT:#define __LLVM_ATOMIC_4_BYTES_LOCK_FREE 2
+// WEBASSEMBLY64-NEXT:#define __LLVM_ATOMIC_8_BYTES_LOCK_FREE 2
+// WEBASSEMBLY64-NEXT:#define __LLVM_LOCK_FREE_IS_SIZE_BASED 1
// WEBASSEMBLY64-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL
// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
// WEBASSEMBLY64-NEXT:#define __LP64__ 1
@@ -9057,4 +9102,3 @@
// RUN: %clang_cc1 -E -dM -ffreestanding -triple x86_64-windows-cygnus < /dev/null | FileCheck -match-full-lines -check-prefix CYGWIN-X64 %s
// CYGWIN-X64: #define __USER_LABEL_PREFIX__
-
Index: test/Lexer/cxx-features.cpp
===================================================================
--- test/Lexer/cxx-features.cpp
+++ test/Lexer/cxx-features.cpp
@@ -1,133 +1,141 @@
// RUN: %clang_cc1 -std=c++98 -verify %s
// RUN: %clang_cc1 -std=c++11 -verify %s
// RUN: %clang_cc1 -std=c++1y -fsized-deallocation -verify %s
-// RUN: %clang_cc1 -std=c++1y -fsized-deallocation -fconcepts-ts -DCONCEPTS_TS=1 -verify %s
+// RUN: %clang_cc1 -std=c++14 -fsized-deallocation -verify %s
+// RUN: %clang_cc1 -std=c++1z -fsized-deallocation -verify %s
+// RUN: %clang_cc1 -std=c++1z -fsized-deallocation -fconcepts-ts -DCONCEPTS_TS=1 -verify %s
// RUN: %clang_cc1 -fcoroutines -DCOROUTINES -verify %s
// expected-no-diagnostics
// FIXME using `defined` in a macro has undefined behavior.
#if __cplusplus < 201103L
-#define check(macro, cxx98, cxx11, cxx1y) cxx98 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx98
-#elif __cplusplus < 201304L
-#define check(macro, cxx98, cxx11, cxx1y) cxx11 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx11
+#define check(macro, cxx98, cxx11, cxx14, cxx1z) cxx98 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx98
+#elif __cplusplus < 201402L
+#define check(macro, cxx98, cxx11, cxx14, cxx1z) cxx11 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx11
+#elif __cplusplus < 201406L
+#define check(macro, cxx98, cxx11, cxx14, cxx1z) cxx14 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx14
#else
-#define check(macro, cxx98, cxx11, cxx1y) cxx1y == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx1y
+#define check(macro, cxx98, cxx11, cxx14, cxx1z) cxx1z == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx1z
#endif
-#if check(binary_literals, 0, 0, 201304)
+#if check(binary_literals, 0, 0, 201304, 201304)
#error "wrong value for __cpp_binary_literals"
#endif
-#if check(digit_separators, 0, 0, 201309)
+#if check(digit_separators, 0, 0, 201309, 201309)
#error "wrong value for __cpp_digit_separators"
#endif
-#if check(init_captures, 0, 0, 201304)
+#if check(init_captures, 0, 0, 201304, 201304)
#error "wrong value for __cpp_init_captures"
#endif
-#if check(generic_lambdas, 0, 0, 201304)
+#if check(generic_lambdas, 0, 0, 201304, 201304)
#error "wrong value for __cpp_generic_lambdas"
#endif
-#if check(sized_deallocation, 0, 0, 201309)
+#if check(sized_deallocation, 0, 0, 201309, 201309)
#error "wrong value for __cpp_sized_deallocation"
#endif
-#if check(constexpr, 0, 200704, 201304)
+#if check(constexpr, 0, 200704, 201304, 201304)
#error "wrong value for __cpp_constexpr"
#endif
-#if check(decltype_auto, 0, 0, 201304)
+#if check(decltype_auto, 0, 0, 201304, 201304)
#error "wrong value for __cpp_decltype_auto"
#endif
-#if check(return_type_deduction, 0, 0, 201304)
+#if check(return_type_deduction, 0, 0, 201304, 201304)
#error "wrong value for __cpp_return_type_deduction"
#endif
-#if check(runtime_arrays, 0, 0, 0)
+#if check(runtime_arrays, 0, 0, 0, 0)
#error "wrong value for __cpp_runtime_arrays"
#endif
-#if check(aggregate_nsdmi, 0, 0, 201304)
+#if check(aggregate_nsdmi, 0, 0, 201304, 201304)
#error "wrong value for __cpp_aggregate_nsdmi"
#endif
-#if check(variable_templates, 0, 0, 201304)
+#if check(variable_templates, 0, 0, 201304, 201304)
#error "wrong value for __cpp_variable_templates"
#endif
-#if check(unicode_characters, 0, 200704, 200704)
+#if check(unicode_characters, 0, 200704, 200704, 200704)
#error "wrong value for __cpp_unicode_characters"
#endif
-#if check(raw_strings, 0, 200710, 200710)
+#if check(raw_strings, 0, 200710, 200710, 200710)
#error "wrong value for __cpp_raw_strings"
#endif
-#if check(unicode_literals, 0, 200710, 200710)
+#if check(unicode_literals, 0, 200710, 200710, 200710)
#error "wrong value for __cpp_unicode_literals"
#endif
-#if check(user_defined_literals, 0, 200809, 200809)
+#if check(user_defined_literals, 0, 200809, 200809, 200809)
#error "wrong value for __cpp_user_defined_literals"
#endif
-#if check(lambdas, 0, 200907, 200907)
+#if check(lambdas, 0, 200907, 200907, 200907)
#error "wrong value for __cpp_lambdas"
#endif
-#if check(range_based_for, 0, 200907, 200907)
+#if check(range_based_for, 0, 200907, 200907, 200907)
#error "wrong value for __cpp_range_based_for"
#endif
-#if check(static_assert, 0, 200410, 200410)
+#if check(static_assert, 0, 200410, 200410, 200410)
#error "wrong value for __cpp_static_assert"
#endif
-#if check(decltype, 0, 200707, 200707)
+#if check(decltype, 0, 200707, 200707, 200707)
#error "wrong value for __cpp_decltype"
#endif
-#if check(attributes, 0, 200809, 200809)
+#if check(attributes, 0, 200809, 200809, 200809)
#error "wrong value for __cpp_attributes"
#endif
-#if check(rvalue_references, 0, 200610, 200610)
+#if check(rvalue_references, 0, 200610, 200610, 200610)
#error "wrong value for __cpp_rvalue_references"
#endif
-#if check(variadic_templates, 0, 200704, 200704)
+#if check(variadic_templates, 0, 200704, 200704, 200704)
#error "wrong value for __cpp_variadic_templates"
#endif
-#if check(initializer_lists, 0, 200806, 200806)
+#if check(initializer_lists, 0, 200806, 200806, 200806)
#error "wrong value for __cpp_initializer_lists"
#endif
-#if check(delegating_constructors, 0, 200604, 200604)
+#if check(delegating_constructors, 0, 200604, 200604, 200604)
#error "wrong value for __cpp_delegating_constructors"
#endif
-#if check(nsdmi, 0, 200809, 200809)
+#if check(nsdmi, 0, 200809, 200809, 200809)
#error "wrong value for __cpp_nsdmi"
#endif
-#if check(inheriting_constructors, 0, 200802, 200802)
+#if check(inheriting_constructors, 0, 200802, 200802, 200802)
#error "wrong value for __cpp_inheriting_constructors"
#endif
-#if check(ref_qualifiers, 0, 200710, 200710)
+#if check(ref_qualifiers, 0, 200710, 200710, 200710)
#error "wrong value for __cpp_ref_qualifiers"
#endif
-#if check(alias_templates, 0, 200704, 200704)
+#if check(alias_templates, 0, 200704, 200704, 200704)
#error "wrong value for __cpp_alias_templates"
#endif
-#if check(experimental_concepts, 0, 0, CONCEPTS_TS)
+#if check(lib_atomic_is_always_lock_free, 0, 0, 0, 201603)
+#error "wrong value for __cpp_lib_atomic_is_always_lock_free"
+#endif
+
+#if check(experimental_concepts, 0, 0, CONCEPTS_TS, CONCEPTS_TS)
#error "wrong value for __cpp_experimental_concepts"
#endif
Index: lib/Frontend/InitPreprocessor.cpp
===================================================================
--- lib/Frontend/InitPreprocessor.cpp
+++ lib/Frontend/InitPreprocessor.cpp
@@ -286,20 +286,35 @@
DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
}
+/// Get values for:
+/// - ATOMIC_*_LOCK_FREE macros
+/// - constexpr is_always_lock_free
+struct LockFree {
+ enum Value { Never, Sometimes, Always }; // Values specified by C standard.
+
+ // Currently LLVM always bases lock-freeness on the size of the type, and not
+ // on type of address. Were this to change then constexpr is_always_lock_free
+ // couldn't base its value solely on sizeof(T).
+ static bool getIsSizeBased() { return true; }
+
+ static Value getValue(unsigned TypeWidth, unsigned TypeAlign,
+ unsigned InlineWidth) {
+ // Fully-aligned, power-of-2 sizes no larger than the inline width will be
+ // inlined as lock-free operations.
+ if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 &&
+ TypeWidth <= InlineWidth)
+ return Always;
+ // We cannot be certain what operations the lib calls might be able to
+ // implement as lock-free on future processors.
+ return Sometimes;
+ }
-/// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with
-/// the specified properties.
-static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign,
- unsigned InlineWidth) {
- // Fully-aligned, power-of-2 sizes no larger than the inline
- // width will be inlined as lock-free operations.
- if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 &&
- TypeWidth <= InlineWidth)
- return "2"; // "always lock free"
- // We cannot be certain what operations the lib calls might be
- // able to implement as lock-free on future processors.
- return "1"; // "sometimes lock free"
-}
+ static const char *getString(unsigned TypeWidth, unsigned TypeAlign,
+ unsigned InlineWidth) {
+ static const char *str[] = {"0", "1", "2"};
+ return str[getValue(TypeWidth, TypeAlign, InlineWidth)];
+ }
+};
/// \brief Add definitions required for a smooth interaction between
/// Objective-C++ automated reference counting and libstdc++ (4.2).
@@ -459,6 +474,12 @@
Builder.defineMacro("__cpp_aggregate_nsdmi", "201304");
Builder.defineMacro("__cpp_variable_templates", "201304");
}
+
+ // C++17 features.
+ if (LangOpts.CPlusPlus1z) {
+ Builder.defineMacro("__cpp_lib_atomic_is_always_lock_free", "201603");
+ }
+
if (LangOpts.SizedDeallocation)
Builder.defineMacro("__cpp_sized_deallocation", "201309");
if (LangOpts.ConceptsTS)
@@ -813,11 +834,11 @@
// Used by libstdc++ to implement ATOMIC_<foo>_LOCK_FREE.
unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth();
-#define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \
- Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \
- getLockFreeValue(TI.get##Type##Width(), \
- TI.get##Type##Align(), \
- InlineWidthBits));
+#define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \
+ Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \
+ LockFree::getString(TI.get##Type##Width(), \
+ TI.get##Type##Align(), \
+ InlineWidthBits));
DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
DEFINE_LOCK_FREE_MACRO(CHAR, Char);
DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
@@ -827,10 +848,33 @@
DEFINE_LOCK_FREE_MACRO(INT, Int);
DEFINE_LOCK_FREE_MACRO(LONG, Long);
DEFINE_LOCK_FREE_MACRO(LLONG, LongLong);
+ DEFINE_LOCK_FREE_MACRO(FLOAT, Float);
+ DEFINE_LOCK_FREE_MACRO(DOUBLE, Double);
+ DEFINE_LOCK_FREE_MACRO(LDOUBLE, LongDouble);
Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE",
- getLockFreeValue(TI.getPointerWidth(0),
- TI.getPointerAlign(0),
- InlineWidthBits));
+ LockFree::getString(TI.getPointerWidth(0),
+ TI.getPointerAlign(0),
+ InlineWidthBits));
+#undef DEFINE_LOCK_FREE_MACRO
+
+ // Used by libc++ to implement constexpr is_always_lock_free.
+ Builder.defineMacro("__LLVM_LOCK_FREE_IS_SIZE_BASED",
+ LockFree::getIsSizeBased() ? "1" : "0");
+#define DEFINE_LOCK_FREE_MACRO(BYTES) \
+ Builder.defineMacro( \
+ "__LLVM_ATOMIC_" #BYTES "_BYTES_LOCK_FREE", \
+ LockFree::getString(BYTES * 8, BYTES * 8, InlineWidthBits));
+ if (LockFree::getIsSizeBased()) {
+ DEFINE_LOCK_FREE_MACRO(1);
+ DEFINE_LOCK_FREE_MACRO(2);
+ DEFINE_LOCK_FREE_MACRO(4);
+ DEFINE_LOCK_FREE_MACRO(8);
+ DEFINE_LOCK_FREE_MACRO(16);
+ // constexpr is_always_lock_free is optimistic, it's therefore acceptable
+ // to state "0" even if the implementation is actually always
+ // lock-free. If architectures support wider lock-free operations then
+ // more macro definitions can be appended.
+ }
#undef DEFINE_LOCK_FREE_MACRO
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits