[libcxx] Allow use of <atomic> in C++03. Try 3.

Summary:
After putting this question up on cfe-dev I have decided that it would be best to allow the use of `<atomic>` in C++03. Although static initialization is a concern the syntax required to get it is C++11 only. Meaning that C++11 constant static initialization cannot silently break in C++03, it will always cause a syntax error. Furthermore `ATOMIC_VAR_INIT` and `ATOMIC_FLAG_INIT` remain defined in C++03 even though they cannot be used because C++03 usages will cause better error messages.

The main change in this patch is to replace `__has_feature(cxx_atomic)`, which only returns true when C++ >= 11, to `__has_extension(c_atomic)` which returns true whenever clang supports the required atomic builtins.


This patch adds the following macros:
* `_LIBCPP_HAS_C_ATOMIC_IMP`      - Defined on clang versions which provide the C `_Atomic` keyword.
* `_LIBCPP_HAS_GCC_ATOMIC_IMP` - Defined on GCC > 4.7. We must use the fallback atomic implementation.
* `_LIBCPP_HAS_NO_ATOMIC_HEADER` - Defined when it is not safe to include `<atomic>`.

`_LIBCPP_HAS_C_ATOMIC_IMP` and `_LIBCPP_HAS_GCC_ATOMIC_IMP` are mutually exclusive, only one should be defined. If neither is defined then `<atomic>` is not implemented and including `<atomic>` will issue an error.

Reviewers: chandlerc, jroelofs, mclow.lists

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D11555

llvm-svn: 245463
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 749adeba3d655f27abec2a3589a612a15d8be21c
diff --git a/include/memory b/include/memory
index 750034b..38ce433 100644
--- a/include/memory
+++ b/include/memory
@@ -612,7 +612,7 @@
     #include <cassert>
 #endif
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #  include <atomic>
 #endif
 
@@ -5381,7 +5381,9 @@
 basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only
+// enabled with clang.
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 class _LIBCPP_TYPE_VIS __sp_mut
 {
@@ -5507,7 +5509,7 @@
     return atomic_compare_exchange_weak(__p, __v, __w);
 }
 
-#endif  // __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#endif  // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 //enum class
 struct _LIBCPP_TYPE_VIS pointer_safety