Index: lib/Frontend/InitPreprocessor.cpp =================================================================== --- lib/Frontend/InitPreprocessor.cpp +++ lib/Frontend/InitPreprocessor.cpp @@ -882,14 +882,16 @@ // 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 @@ 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__"); Index: test/Preprocessor/init.c =================================================================== --- test/Preprocessor/init.c +++ 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{{.*}} Index: test/Sema/atomic-ops.c =================================================================== --- test/Sema/atomic-ops.c +++ 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), "");