From: Eric Fiselier Date: Thu, 20 Apr 2017 22:53:57 +0000 (+0000) Subject: Add __CLANG_ATOMIC__LOCK_FREE macros for use in MSVC compatibility mode. X-Git-Tag: llvmorg-5.0.0-rc1~7109 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b2c8f75a114818cf377c8b16cb0796e015e1b2d;p=platform%2Fupstream%2Fllvm.git Add __CLANG_ATOMIC__LOCK_FREE macros for use in MSVC compatibility mode. Summary: Libc++ currently implements the `ATOMIC__LOCK_FREE` macros using the `__GCC_ATOMIC__LOCK_FREE` macros. However these are not available when MSVC compatibility is enabled even though C11 `_Atomic` is. This prevents libc++ from correctly implementing `ATOMIC__LOCK_FREE`. This patch adds an alternative spelling `__CLANG_ATOMIC__LOCK_FREE` that is enabled with `-fms-compatibility`. Reviewers: rsmith, aaron.ballman, majnemer, zturner, compnerd, jfb, rnk Reviewed By: rsmith Subscribers: BillyONeal, smeenai, jfb, cfe-commits, dschuff Differential Revision: https://reviews.llvm.org/D32265 llvm-svn: 300914 --- diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 88be773..0dd04e8 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -882,14 +882,16 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // The value written by __atomic_test_and_set. // FIXME: This is target-dependent. Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1"); + } + auto addLockFreeMacros = [&](const llvm::Twine &Prefix) { // Used by libc++ and libstdc++ to implement ATOMIC__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(Prefix + #TYPE "_LOCK_FREE", \ + getLockFreeValue(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); @@ -899,12 +901,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DEFINE_LOCK_FREE_MACRO(INT, Int); DEFINE_LOCK_FREE_MACRO(LONG, Long); DEFINE_LOCK_FREE_MACRO(LLONG, LongLong); - Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE", + Builder.defineMacro(Prefix + "POINTER_LOCK_FREE", getLockFreeValue(TI.getPointerWidth(0), TI.getPointerAlign(0), InlineWidthBits)); #undef DEFINE_LOCK_FREE_MACRO - } + }; + addLockFreeMacros("__CLANG_ATOMIC_"); + if (!LangOpts.MSVCCompat) + addLockFreeMacros("__GCC_ATOMIC_"); if (LangOpts.NoInlineDefine) Builder.defineMacro("__NO_INLINE__"); diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c index 7548fba..5fb2011 100644 --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -8846,6 +8846,16 @@ // WEBASSEMBLY32-NEXT:#define __CHAR32_TYPE__ unsigned int // WEBASSEMBLY32-NEXT:#define __CHAR_BIT__ 8 // WEBASSEMBLY32-NOT:#define __CHAR_UNSIGNED__ +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 1 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 // WEBASSEMBLY32-NEXT:#define __CONSTANT_CFSTRINGS__ 1 // WEBASSEMBLY32-NEXT:#define __DBL_DECIMAL_DIG__ 17 // WEBASSEMBLY32-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 @@ -9162,6 +9172,16 @@ // WEBASSEMBLY64-NEXT:#define __CHAR32_TYPE__ unsigned int // WEBASSEMBLY64-NEXT:#define __CHAR_BIT__ 8 // WEBASSEMBLY64-NOT:#define __CHAR_UNSIGNED__ +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 // WEBASSEMBLY64-NEXT:#define __CONSTANT_CFSTRINGS__ 1 // WEBASSEMBLY64-NEXT:#define __DBL_DECIMAL_DIG__ 17 // WEBASSEMBLY64-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 @@ -9637,3 +9657,36 @@ // AVR:#define __WCHAR_MAX__ 32767 // AVR:#define __WCHAR_TYPE__ int // AVR:#define __WINT_TYPE__ int + + +// RUN: %clang_cc1 -E -dM -ffreestanding \ +// RUN: -triple i686-windows-msvc -fms-compatibility < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefix MSVC-X32 %s + +// RUN: %clang_cc1 -E -dM -ffreestanding \ +// RUN: -triple x86_64-windows-msvc -fms-compatibility < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefix MSVC-X64 %s + +// MSVC-X32:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// MSVC-X32-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 +// MSVC-X32-NOT:#define __GCC_ATOMIC{{.*}} + +// MSVC-X64:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// MSVC-X64-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 +// MSVC-X86-NOT:#define __GCC_ATOMIC{{.*}} diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c index 8ebf3ea..eee1cda 100644 --- a/clang/test/Sema/atomic-ops.c +++ b/clang/test/Sema/atomic-ops.c @@ -7,19 +7,29 @@ struct S { char c[3]; }; _Static_assert(__GCC_ATOMIC_BOOL_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_BOOL_LOCK_FREE == __CLANG_ATOMIC_BOOL_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_CHAR_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_CHAR_LOCK_FREE == __CLANG_ATOMIC_CHAR_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_CHAR16_T_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_CHAR16_T_LOCK_FREE == __CLANG_ATOMIC_CHAR16_T_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_CHAR32_T_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_CHAR32_T_LOCK_FREE == __CLANG_ATOMIC_CHAR32_T_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_WCHAR_T_LOCK_FREE == __CLANG_ATOMIC_WCHAR_T_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_SHORT_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_SHORT_LOCK_FREE == __CLANG_ATOMIC_SHORT_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_INT_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_INT_LOCK_FREE == __CLANG_ATOMIC_INT_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_LONG_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_LONG_LOCK_FREE == __CLANG_ATOMIC_LONG_LOCK_FREE, ""); #ifdef __i386__ _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 1, ""); #else _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 2, ""); #endif +_Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == __CLANG_ATOMIC_LLONG_LOCK_FREE, ""); _Static_assert(__GCC_ATOMIC_POINTER_LOCK_FREE == 2, ""); +_Static_assert(__GCC_ATOMIC_POINTER_LOCK_FREE == __CLANG_ATOMIC_POINTER_LOCK_FREE, ""); _Static_assert(__c11_atomic_is_lock_free(1), ""); _Static_assert(__c11_atomic_is_lock_free(2), "");