[libc++] Guard warning pragmas

This makes the GCC output even cleaner!

Reviewed By: ldionne, #libc

Spies: mstorsjo, Quuxplusone, Mordante, libcxx-commits

Differential Revision: https://reviews.llvm.org/D119295

NOKEYCHECK=True
GitOrigin-RevId: a7c2a6289c22624f8b21b6c0e3f27047c4d4113d
diff --git a/include/__config b/include/__config
index f7e105b..979dbb5 100644
--- a/include/__config
+++ b/include/__config
@@ -142,6 +142,9 @@
 #  define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
 #endif
 
+#define _LIBCPP_TOSTRING2(x) #x
+#define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
+
 #if __cplusplus < 201103L
 #define _LIBCPP_CXX03_LANG
 #endif
@@ -561,8 +564,6 @@
 
 #elif defined(_LIBCPP_COMPILER_MSVC)
 
-#define _LIBCPP_TOSTRING2(x) #x
-#define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
 #define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x))
 
 #if _MSC_VER < 1900
@@ -1420,6 +1421,23 @@
    // the ABI inconsistent.
 #endif
 
+#ifdef _LIBCPP_COMPILER_CLANG_BASED
+#  define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
+#  define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
+#  define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str))
+#  define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
+#elif defined(_LIBCPP_COMPILER_GCC)
+#  define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
+#  define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
+#  define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
+#  define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str))
+#else
+#  define _LIBCPP_DIAGNOSTIC_PUSH
+#  define _LIBCPP_DIAGNOSTIC_POP
+#  define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
+#  define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
+#endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP_CONFIG
diff --git a/include/__random/random_device.h b/include/__random/random_device.h
index fbf7c05..e82b437 100644
--- a/include/__random/random_device.h
+++ b/include/__random/random_device.h
@@ -28,10 +28,8 @@
 #ifdef _LIBCPP_USING_DEV_RANDOM
     int __f_;
 #elif !defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT)
-#   if defined(__clang__)
-#       pragma clang diagnostic push
-#       pragma clang diagnostic ignored "-Wunused-private-field"
-#   endif
+    _LIBCPP_DIAGNOSTIC_PUSH
+    _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
 
     // Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now
     // use `arc4random()` as of this comment. In order to avoid breaking the ABI, we
@@ -42,9 +40,7 @@
 
     // ... vendors can add workarounds here if they switch to a different representation ...
 
-#   if defined(__clang__)
-#       pragma clang diagnostic pop
-#   endif
+    _LIBCPP_DIAGNOSTIC_POP
 #endif
 
 public:
diff --git a/include/exception b/include/exception
index 3772fe3..5460b73 100644
--- a/include/exception
+++ b/include/exception
@@ -189,15 +189,11 @@
 
 class _LIBCPP_TYPE_VIS exception_ptr
 {
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-private-field"
-#endif
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
     void* __ptr1_;
     void* __ptr2_;
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
+_LIBCPP_DIAGNOSTIC_POP
 public:
     exception_ptr() _NOEXCEPT;
     exception_ptr(nullptr_t) _NOEXCEPT;
diff --git a/include/locale b/include/locale
index b6511c6..ed2b971 100644
--- a/include/locale
+++ b/include/locale
@@ -1486,10 +1486,11 @@
         + ((numeric_limits<_Unsigned>::digits % 3) != 0) // round up
         + 2; // base prefix + terminating null character
     char __nar[__nbuf];
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
+    _LIBCPP_DIAGNOSTIC_PUSH
+    _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+    _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
     int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
-#pragma clang diagnostic pop
+    _LIBCPP_DIAGNOSTIC_POP
     char* __ne = __nar + __nc;
     char* __np = this->__identify_padding(__nar, __ne, __iob);
     // Stage 2 - Widen __nar while adding thousands separators
@@ -1549,8 +1550,9 @@
     char __nar[__nbuf];
     char* __nb = __nar;
     int __nc;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
+    _LIBCPP_DIAGNOSTIC_PUSH
+    _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
+    _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
     if (__specify_precision)
         __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
                                    (int)__iob.precision(), __v);
@@ -1567,7 +1569,7 @@
             __throw_bad_alloc();
         __nbh.reset(__nb);
     }
-#pragma clang diagnostic pop
+    _LIBCPP_DIAGNOSTIC_POP
     char* __ne = __nb + __nc;
     char* __np = this->__identify_padding(__nb, __ne, __iob);
     // Stage 2 - Widen __nar while adding thousands separators
diff --git a/src/future.cpp b/src/future.cpp
index 177fe75..07ae938 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -29,13 +29,9 @@
     return "future";
 }
 
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wswitch"
-#elif defined(__GNUC__) || defined(__GNUG__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wswitch"
-#endif
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wswitch")
+_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wswitch")
 
 string
 __future_error_category::message(int ev) const
@@ -58,11 +54,7 @@
     return string("unspecified future_errc value\n");
 }
 
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#elif defined(__GNUC__) || defined(__GNUG__)
-#pragma GCC diagnostic pop
-#endif
+_LIBCPP_DIAGNOSTIC_POP
 
 const error_category&
 future_category() noexcept
diff --git a/src/hash.cpp b/src/hash.cpp
index b8e921a..daf276f 100644
--- a/src/hash.cpp
+++ b/src/hash.cpp
@@ -11,9 +11,7 @@
 #include "stdexcept"
 #include "type_traits"
 
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
-#endif
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wtautological-constant-out-of-range-compare")
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
diff --git a/src/locale.cpp b/src/locale.cpp
index 56b1a4b..3f8a261 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -49,9 +49,7 @@
 
 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
 // lots of noise in the build log, but no bugs that I know of.
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wsign-conversion"
-#endif
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -5201,12 +5199,8 @@
 {
     freelocale(__loc_);
 }
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wmissing-field-initializers"
-#endif
-#if defined(__GNUG__)
-#pragma GCC   diagnostic ignored "-Wmissing-field-initializers"
-#endif
+
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
 
 template <>
 string
@@ -5352,9 +5346,7 @@
     return result;
 }
 
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wmissing-braces"
-#endif
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
diff --git a/src/support/win32/locale_win32.cpp b/src/support/win32/locale_win32.cpp
index 43e5c9a..67f4d13 100644
--- a/src/support/win32/locale_win32.cpp
+++ b/src/support/win32/locale_win32.cpp
@@ -97,10 +97,10 @@
         ret, n, format, loc, ap);
 #else
     __libcpp_locale_guard __current(loc);
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
+    _LIBCPP_DIAGNOSTIC_PUSH
+    _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
     int result = vsnprintf( ret, n, format, ap );
-#pragma clang diagnostic pop
+    _LIBCPP_DIAGNOSTIC_POP
 #endif
     va_end(ap);
     return result;
diff --git a/src/support/win32/support.cpp b/src/support/win32/support.cpp
index 6d4b371..dbec408 100644
--- a/src/support/win32/support.cpp
+++ b/src/support/win32/support.cpp
@@ -23,10 +23,10 @@
     // Query the count required.
     va_list ap_copy;
     va_copy(ap_copy, ap);
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
+    _LIBCPP_DIAGNOSTIC_PUSH
+    _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
     int count = vsnprintf( NULL, 0, format, ap_copy );
-#pragma clang diagnostic pop
+    _LIBCPP_DIAGNOSTIC_POP
     va_end(ap_copy);
     if (count < 0)
         return count;
@@ -36,10 +36,10 @@
         return -1;
     // If we haven't used exactly what was required, something is wrong.
     // Maybe bug in vsnprintf. Report the error and return.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-nonliteral"
+    _LIBCPP_DIAGNOSTIC_PUSH
+    _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
     if (vsnprintf(p, buffer_size, format, ap) != count) {
-#pragma clang diagnostic pop
+    _LIBCPP_DIAGNOSTIC_POP
         free(p);
         return -1;
     }