Apply [[nodebug]] to typedefs throughout the STL.

When applied to a typedef or alias template, the [[nodebug]] attribute
makes the typedef transparent to the debugger, so instead of seeing
`std::__function::__alloc_func<remove_reference<void(&)()>::type,
allocator<remove_reference<void(&)()>, void()>::_Target` you see
`void(&)()` as the type of the variable in your debugger.

Removing all this SFINAE noise from debug info has huge binary size
wins, in addition to improving the readability.

For now this change is on by default. Users can override it by
specifying -D_LIBCPP_NODEBUG_TYPE=

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@363117 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/__config b/include/__config
index 6a1e0f5..ef2795b 100644
--- a/include/__config
+++ b/include/__config
@@ -1272,12 +1272,21 @@
 #  define _LIBCPP_FALLTHROUGH() ((void)0)
 #endif
 
-#if defined(_LIBCPP_COMPILER_CLANG) || defined(_LIBCPP_COMPILER_GCC)
-#define _LIBCPP_NODEBUG __attribute__((nodebug))
+#if __has_attribute(__nodebug__)
+#define _LIBCPP_NODEBUG __attribute__((__nodebug__))
 #else
 #define _LIBCPP_NODEBUG
 #endif
 
+#ifndef _LIBCPP_NODEBUG_TYPE
+#if __has_attribute(__nodebug__) && \
+    (defined(_LIBCPP_COMPILER_CLANG) && _LIBCPP_CLANG_VER >= 900)
+#define _LIBCPP_NODEBUG_TYPE __attribute__((nodebug))
+#else
+#define _LIBCPP_NODEBUG_TYPE
+#endif
+#endif // !defined(_LIBCPP_NODEBUG_TYPE)
+
 #if defined(_LIBCPP_ABI_MICROSOFT) && \
     (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases))
 #  define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
diff --git a/include/__functional_base b/include/__functional_base
index 8da8324..9587d7a 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -125,7 +125,7 @@
     : public __maybe_derive_from_unary_function<_Tp>,
       public __maybe_derive_from_binary_function<_Tp>
 {
-    typedef typename _Tp::result_type result_type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::result_type result_type;
 };
 
 template <class _Tp>
@@ -146,19 +146,19 @@
 template <class _Rp>
 struct __weak_result_type<_Rp ()>
 {
-    typedef _Rp result_type;
+    typedef _LIBCPP_NODEBUG_TYPE  _Rp result_type;
 };
 
 template <class _Rp>
 struct __weak_result_type<_Rp (&)()>
 {
-    typedef _Rp result_type;
+    typedef _LIBCPP_NODEBUG_TYPE  _Rp result_type;
 };
 
 template <class _Rp>
 struct __weak_result_type<_Rp (*)()>
 {
-    typedef _Rp result_type;
+    typedef _LIBCPP_NODEBUG_TYPE  _Rp result_type;
 };
 
 // 1 argument case
@@ -610,7 +610,7 @@
 template <class _Tp, class _Alloc, class ..._Args>
 struct __uses_alloc_ctor_imp
 {
-    typedef typename __uncvref<_Alloc>::type _RawAlloc;
+    typedef _LIBCPP_NODEBUG_TYPE typename __uncvref<_Alloc>::type _RawAlloc;
     static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value;
     static const bool __ic =
         is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
diff --git a/include/__tuple b/include/__tuple
index 0381031..8f2e72d 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -58,19 +58,19 @@
 template <size_t _Ip, class _Tp>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp>
 {
-    typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
 template <size_t _Ip, class _Tp>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp>
 {
-    typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
 template <size_t _Ip, class _Tp>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp>
 {
-    typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
 template <class _Tp> struct __tuple_like : false_type {};
@@ -99,7 +99,7 @@
 
 template<typename _Tp, size_t ..._Extra> struct __repeat;
 template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> {
-  typedef __integer_sequence<_Tp,
+  typedef _LIBCPP_NODEBUG_TYPE __integer_sequence<_Tp,
                            _Np...,
                            sizeof...(_Np) + _Np...,
                            2 * sizeof...(_Np) + _Np...,
@@ -253,7 +253,7 @@
 namespace __indexer_detail {
 
 template <size_t _Idx, class _Tp>
-struct __indexed { using type = _Tp; };
+struct __indexed { using type _LIBCPP_NODEBUG_TYPE = _Tp; };
 
 template <class _Types, class _Indexes> struct __indexer;
 
@@ -268,7 +268,7 @@
 } // namespace __indexer_detail
 
 template <size_t _Idx, class ..._Types>
-using __type_pack_element = typename decltype(
+using __type_pack_element _LIBCPP_NODEBUG_TYPE = typename decltype(
     __indexer_detail::__at_index<_Idx>(
         __indexer_detail::__indexer<
             __tuple_types<_Types...>,
@@ -281,7 +281,7 @@
 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...>>
 {
     static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range");
-    typedef __type_pack_element<_Ip, _Types...> type;
+    typedef _LIBCPP_NODEBUG_TYPE __type_pack_element<_Ip, _Types...> type;
 };
 
 
@@ -301,34 +301,34 @@
 };
 template <>
 struct __apply_cv_mf<false, true, false> {
-  template <class _Tp> using __apply = const _Tp;
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = const _Tp;
 };
 template <>
 struct __apply_cv_mf<false, false, true> {
-  template <class _Tp> using __apply = volatile _Tp;
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = volatile _Tp;
 };
 template <>
 struct __apply_cv_mf<false, true, true> {
-  template <class _Tp> using __apply = const volatile _Tp;
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = const volatile _Tp;
 };
 template <>
 struct __apply_cv_mf<true, false, false> {
-  template <class _Tp> using __apply = _Tp&;
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = _Tp&;
 };
 template <>
 struct __apply_cv_mf<true, true, false> {
-  template <class _Tp> using __apply = const _Tp&;
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = const _Tp&;
 };
 template <>
 struct __apply_cv_mf<true, false, true> {
-  template <class _Tp> using __apply = volatile _Tp&;
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE  = volatile _Tp&;
 };
 template <>
 struct __apply_cv_mf<true, true, true> {
-  template <class _Tp> using __apply = const volatile _Tp&;
+  template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = const volatile _Tp&;
 };
 template <class _Tp, class _RawTp = typename remove_reference<_Tp>::type>
-using __apply_cv_t = __apply_cv_mf<
+using __apply_cv_t _LIBCPP_NODEBUG_TYPE  = __apply_cv_mf<
     is_lvalue_reference<_Tp>::value,
     is_const<_RawTp>::value,
     is_volatile<_RawTp>::value>;
@@ -347,7 +347,7 @@
 struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> {
   // Specialization for pair, tuple, and __tuple_types
   template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>>
-  using __apply_quals = __tuple_types<
+  using __apply_quals _LIBCPP_NODEBUG_TYPE = __tuple_types<
       typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>...
     >;
 };
@@ -375,12 +375,12 @@
 
 template <class ..._Types, size_t _Ep>
 struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> {
-  typedef __tuple_types<_Types...> type;
+  typedef _LIBCPP_NODEBUG_TYPE __tuple_types<_Types...> type;
 };
 
 template <class ..._Types, size_t _Ep>
 struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> {
-  typedef __tuple_types<_Types...> type;
+  typedef _LIBCPP_NODEBUG_TYPE __tuple_types<_Types...> type;
 };
 
 template <bool ..._Preds>
@@ -454,12 +454,12 @@
 template <size_t _Ip, class ..._Tp>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> >
 {
-    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
 };
 
 #if _LIBCPP_STD_VER > 11
 template <size_t _Ip, class ..._Tp>
-using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;
+using tuple_element_t _LIBCPP_NODEBUG_TYPE  = typename tuple_element <_Ip, _Tp...>::type;
 #endif
 
 template <bool _IsTuple, class _SizeTrait, size_t _Expected>
@@ -471,7 +471,7 @@
 
 template <class _Tuple, size_t _ExpectedSize,
           class _RawTuple = typename __uncvref<_Tuple>::type>
-using __tuple_like_with_size = __tuple_like_with_size_imp<
+using __tuple_like_with_size _LIBCPP_NODEBUG_TYPE = __tuple_like_with_size_imp<
                                    __tuple_like<_RawTuple>::value,
                                    tuple_size<_RawTuple>, _ExpectedSize
                               >;
diff --git a/include/functional b/include/functional
index e2eac0e..c0a89f7 100644
--- a/include/functional
+++ b/include/functional
@@ -1488,8 +1488,8 @@
     __compressed_pair<_Fp, _Ap> __f_;
 
   public:
-    typedef _Fp _Target;
-    typedef _Ap _Alloc;
+    typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
+    typedef _LIBCPP_NODEBUG_TYPE _Ap _Alloc;
 
     _LIBCPP_INLINE_VISIBILITY
     const _Target& __target() const { return __f_.first(); }
@@ -1566,7 +1566,7 @@
   _Fp __f_;
 
 public:
-  typedef _Fp _Target;
+  typedef _LIBCPP_NODEBUG_TYPE _Fp _Target;
 
   _LIBCPP_INLINE_VISIBILITY
   const _Target& __target() const { return __f_; }
diff --git a/include/memory b/include/memory
index 6a8755e..b8a2706 100644
--- a/include/memory
+++ b/include/memory
@@ -743,7 +743,7 @@
 template <class _Ptr>
 struct __pointer_traits_element_type<_Ptr, true>
 {
-    typedef typename _Ptr::element_type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::element_type type;
 };
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -751,13 +751,13 @@
 template <template <class, class...> class _Sp, class _Tp, class ..._Args>
 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>
 {
-    typedef typename _Sp<_Tp, _Args...>::element_type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::element_type type;
 };
 
 template <template <class, class...> class _Sp, class _Tp, class ..._Args>
 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>
 {
-    typedef _Tp type;
+    typedef _LIBCPP_NODEBUG_TYPE _Tp type;
 };
 
 #else  // _LIBCPP_HAS_NO_VARIADICS
@@ -824,13 +824,13 @@
 template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
 struct __pointer_traits_difference_type
 {
-    typedef ptrdiff_t type;
+    typedef _LIBCPP_NODEBUG_TYPE ptrdiff_t type;
 };
 
 template <class _Ptr>
 struct __pointer_traits_difference_type<_Ptr, true>
 {
-    typedef typename _Ptr::difference_type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::difference_type type;
 };
 
 template <class _Tp, class _Up>
@@ -848,9 +848,9 @@
 struct __pointer_traits_rebind
 {
 #ifndef _LIBCPP_CXX03_LANG
-    typedef typename _Tp::template rebind<_Up> type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up> type;
 #else
-    typedef typename _Tp::template rebind<_Up>::other type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
 #endif
 };
 
@@ -860,9 +860,9 @@
 struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>
 {
 #ifndef _LIBCPP_CXX03_LANG
-    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
 #else
-    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
 #endif
 };
 
@@ -1013,13 +1013,13 @@
 template <class _Tp, class _Dp, bool = __has_pointer_type<_Dp>::value>
 struct __pointer_type
 {
-    typedef typename _Dp::pointer type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Dp::pointer type;
 };
 
 template <class _Tp, class _Dp>
 struct __pointer_type<_Tp, _Dp, false>
 {
-    typedef _Tp* type;
+    typedef _LIBCPP_NODEBUG_TYPE _Tp* type;
 };
 
 }  // __pointer_type_imp
@@ -1027,7 +1027,7 @@
 template <class _Tp, class _Dp>
 struct __pointer_type
 {
-    typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
 };
 
 template <class _Tp, class = void>
@@ -1040,14 +1040,14 @@
 template <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>
 struct __const_pointer
 {
-    typedef typename _Alloc::const_pointer type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::const_pointer type;
 };
 
 template <class _Tp, class _Ptr, class _Alloc>
 struct __const_pointer<_Tp, _Ptr, _Alloc, false>
 {
 #ifndef _LIBCPP_CXX03_LANG
-    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp> type;
+    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const _Tp> type;
 #else
     typedef typename pointer_traits<_Ptr>::template rebind<const _Tp>::other type;
 #endif
@@ -1063,16 +1063,16 @@
 template <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>
 struct __void_pointer
 {
-    typedef typename _Alloc::void_pointer type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::void_pointer type;
 };
 
 template <class _Ptr, class _Alloc>
 struct __void_pointer<_Ptr, _Alloc, false>
 {
 #ifndef _LIBCPP_CXX03_LANG
-    typedef typename pointer_traits<_Ptr>::template rebind<void> type;
+    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<void> type;
 #else
-    typedef typename pointer_traits<_Ptr>::template rebind<void>::other type;
+    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<void>::other type;
 #endif
 };
 
@@ -1086,16 +1086,16 @@
 template <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>
 struct __const_void_pointer
 {
-    typedef typename _Alloc::const_void_pointer type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::const_void_pointer type;
 };
 
 template <class _Ptr, class _Alloc>
 struct __const_void_pointer<_Ptr, _Alloc, false>
 {
 #ifndef _LIBCPP_CXX03_LANG
-    typedef typename pointer_traits<_Ptr>::template rebind<const void> type;
+    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const void> type;
 #else
-    typedef typename pointer_traits<_Ptr>::template rebind<const void>::other type;
+    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const void>::other type;
 #endif
 };
 
@@ -1161,13 +1161,13 @@
 template <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
 struct __size_type
 {
-    typedef typename make_unsigned<_DiffType>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename make_unsigned<_DiffType>::type type;
 };
 
 template <class _Alloc, class _DiffType>
 struct __size_type<_Alloc, _DiffType, true>
 {
-    typedef typename _Alloc::size_type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::size_type type;
 };
 
 template <class _Tp, class = void>
@@ -1181,13 +1181,13 @@
 template <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
 struct __propagate_on_container_copy_assignment
 {
-    typedef false_type type;
+    typedef _LIBCPP_NODEBUG_TYPE false_type type;
 };
 
 template <class _Alloc>
 struct __propagate_on_container_copy_assignment<_Alloc, true>
 {
-    typedef typename _Alloc::propagate_on_container_copy_assignment type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_copy_assignment type;
 };
 
 template <class _Tp, class = void>
@@ -1207,7 +1207,7 @@
 template <class _Alloc>
 struct __propagate_on_container_move_assignment<_Alloc, true>
 {
-    typedef typename _Alloc::propagate_on_container_move_assignment type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_move_assignment type;
 };
 
 template <class _Tp, class = void>
@@ -1227,7 +1227,7 @@
 template <class _Alloc>
 struct __propagate_on_container_swap<_Alloc, true>
 {
-    typedef typename _Alloc::propagate_on_container_swap type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_swap type;
 };
 
 template <class _Tp, class = void>
@@ -1241,13 +1241,13 @@
 template <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
 struct __is_always_equal
 {
-    typedef typename _VSTD::is_empty<_Alloc>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _VSTD::is_empty<_Alloc>::type type;
 };
 
 template <class _Alloc>
 struct __is_always_equal<_Alloc, true>
 {
-    typedef typename _Alloc::is_always_equal type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::is_always_equal type;
 };
 
 template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
@@ -1270,7 +1270,7 @@
 template <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>
 struct __allocator_traits_rebind
 {
-    typedef typename _Tp::template rebind<_Up>::other type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
 };
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -1278,13 +1278,13 @@
 template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
 struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>
 {
-    typedef typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;
 };
 
 template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
 struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
 {
-    typedef _Alloc<_Up, _Args...> type;
+    typedef _LIBCPP_NODEBUG_TYPE _Alloc<_Up, _Args...> type;
 };
 
 #else  // _LIBCPP_HAS_NO_VARIADICS
@@ -1492,13 +1492,13 @@
 template <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value>
 struct __alloc_traits_difference_type
 {
-    typedef typename pointer_traits<_Ptr>::difference_type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::difference_type type;
 };
 
 template <class _Alloc, class _Ptr>
 struct __alloc_traits_difference_type<_Alloc, _Ptr, true>
 {
-    typedef typename _Alloc::difference_type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::difference_type type;
 };
 
 template <class _Tp>
@@ -1768,7 +1768,7 @@
 struct __rebind_alloc_helper
 {
 #ifndef _LIBCPP_CXX03_LANG
-    typedef typename _Traits::template rebind_alloc<_Tp>        type;
+    typedef _LIBCPP_NODEBUG_TYPE typename _Traits::template rebind_alloc<_Tp>        type;
 #else
     typedef typename _Traits::template rebind_alloc<_Tp>::other type;
 #endif
@@ -2209,8 +2209,8 @@
 template <class _T1, class _T2>
 class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
                           private __compressed_pair_elem<_T2, 1> {
-  typedef __compressed_pair_elem<_T1, 0> _Base1;
-  typedef __compressed_pair_elem<_T2, 1> _Base2;
+  typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T1, 0> _Base1;
+  typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T2, 1> _Base2;
 
   // NOTE: This static assert should never fire because __compressed_pair
   // is *almost never* used in a scenario where it's possible for T1 == T2.
@@ -2401,7 +2401,7 @@
 public:
   typedef _Tp element_type;
   typedef _Dp deleter_type;
-  typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
+  typedef _LIBCPP_NODEBUG_TYPE typename __pointer_type<_Tp, deleter_type>::type pointer;
 
   static_assert(!is_rvalue_reference<deleter_type>::value,
                 "the specified deleter type cannot be an rvalue reference");
@@ -2412,38 +2412,38 @@
   struct __nat { int __for_bool_; };
 
 #ifndef _LIBCPP_CXX03_LANG
-  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
+  typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
 
   template <bool _Dummy>
-  using _LValRefType =
+  using _LValRefType _LIBCPP_NODEBUG_TYPE =
       typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
 
   template <bool _Dummy>
-  using _GoodRValRefType =
+  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
       typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
 
   template <bool _Dummy>
-  using _BadRValRefType =
+  using _BadRValRefType _LIBCPP_NODEBUG_TYPE  =
       typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
 
   template <bool _Dummy, class _Deleter = typename __dependent_type<
                              __identity<deleter_type>, _Dummy>::type>
-  using _EnableIfDeleterDefaultConstructible =
+  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
       typename enable_if<is_default_constructible<_Deleter>::value &&
                          !is_pointer<_Deleter>::value>::type;
 
   template <class _ArgType>
-  using _EnableIfDeleterConstructible =
+  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
       typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
 
   template <class _UPtr, class _Up>
-  using _EnableIfMoveConvertible = typename enable_if<
+  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
       is_convertible<typename _UPtr::pointer, pointer>::value &&
       !is_array<_Up>::value
   >::type;
 
   template <class _UDel>
-  using _EnableIfDeleterConvertible = typename enable_if<
+  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
       (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
       (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
     >::type;
@@ -2684,35 +2684,35 @@
   typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
 
   template <bool _Dummy>
-  using _LValRefType =
+  using _LValRefType _LIBCPP_NODEBUG_TYPE =
       typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
 
   template <bool _Dummy>
-  using _GoodRValRefType =
+  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
       typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
 
   template <bool _Dummy>
-  using _BadRValRefType =
+  using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
       typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
 
   template <bool _Dummy, class _Deleter = typename __dependent_type<
                              __identity<deleter_type>, _Dummy>::type>
-  using _EnableIfDeleterDefaultConstructible =
+  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE  =
       typename enable_if<is_default_constructible<_Deleter>::value &&
                          !is_pointer<_Deleter>::value>::type;
 
   template <class _ArgType>
-  using _EnableIfDeleterConstructible =
+  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
       typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
 
   template <class _Pp>
-  using _EnableIfPointerConvertible = typename enable_if<
+  using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
       _CheckArrayPointerConversion<_Pp>::value
   >::type;
 
   template <class _UPtr, class _Up,
         class _ElemT = typename _UPtr::element_type>
-  using _EnableIfMoveConvertible = typename enable_if<
+  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
       is_array<_Up>::value &&
       is_same<pointer, element_type*>::value &&
       is_same<typename _UPtr::pointer, _ElemT*>::value &&
@@ -2720,13 +2720,13 @@
     >::type;
 
   template <class _UDel>
-  using _EnableIfDeleterConvertible = typename enable_if<
+  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
       (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
       (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
     >::type;
 
   template <class _UDel>
-  using _EnableIfDeleterAssignable = typename enable_if<
+  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE  = typename enable_if<
       is_assignable<_Dp&, _UDel&&>::value
     >::type;
 
@@ -3206,10 +3206,10 @@
 template <class _Alloc>
 class __allocator_destructor
 {
-    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits;
 public:
-    typedef typename __alloc_traits::pointer pointer;
-    typedef typename __alloc_traits::size_type size_type;
+    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer;
+    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type;
 private:
     _Alloc& __alloc_;
     size_type __s_;
diff --git a/include/tuple b/include/tuple
index b283666..4e9b5eb 100644
--- a/include/tuple
+++ b/include/tuple
@@ -952,7 +952,7 @@
 typename tuple_element<_Ip, tuple<_Tp...> >::type&
 get(tuple<_Tp...>& __t) _NOEXCEPT
 {
-    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
     return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
 }
 
@@ -961,7 +961,7 @@
 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
 get(const tuple<_Tp...>& __t) _NOEXCEPT
 {
-    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
     return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
 }
 
@@ -970,7 +970,7 @@
 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
 get(tuple<_Tp...>&& __t) _NOEXCEPT
 {
-    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
     return static_cast<type&&>(
              static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
 }
@@ -980,7 +980,7 @@
 const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
 get(const tuple<_Tp...>&& __t) _NOEXCEPT
 {
-    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
     return static_cast<const type&&>(
              static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
 }
@@ -1199,7 +1199,7 @@
 template <class ..._Ttypes, class ..._Utypes>
 struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
 {
-    typedef tuple<_Ttypes..., _Utypes...> type;
+    typedef _LIBCPP_NODEBUG_TYPE tuple<_Ttypes..., _Utypes...> type;
 };
 
 template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
@@ -1210,7 +1210,7 @@
 template <class ..._Types, class _Tuple0>
 struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
 {
-    typedef typename __tuple_cat_type<tuple<_Types...>,
+    typedef _LIBCPP_NODEBUG_TYPE typename __tuple_cat_type<tuple<_Types...>,
             typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
                                                                            type;
 };
@@ -1240,7 +1240,7 @@
 template <>
 struct __tuple_cat_return<>
 {
-    typedef tuple<> type;
+    typedef _LIBCPP_NODEBUG_TYPE tuple<> type;
 };
 
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -1256,7 +1256,7 @@
 template <class ..._Types, size_t ..._I0, class _Tuple0>
 struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
 {
-    typedef typename remove_reference<_Tuple0>::type _T0;
+    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
     typedef tuple<_Types..., typename __apply_cv<_Tuple0,
                           typename tuple_element<_I0, _T0>::type>::type&&...> type;
 };
@@ -1303,8 +1303,8 @@
     typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
     operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
     {
-        typedef typename remove_reference<_Tuple0>::type _T0;
-        typedef typename remove_reference<_Tuple1>::type _T1;
+        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
+        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple1>::type _T1;
         return __tuple_cat<
            tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
            typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
@@ -1323,7 +1323,7 @@
 typename __tuple_cat_return<_Tuple0, _Tuples...>::type
 tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
 {
-    typedef typename remove_reference<_Tuple0>::type _T0;
+    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
     return __tuple_cat<tuple<>, __tuple_indices<>,
                   typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
                   (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
diff --git a/include/type_traits b/include/type_traits
index d17bd09..30e9c91 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -1088,13 +1088,13 @@
 template <class _Tp, bool = is_reference<_Tp>::value ||
                             is_function<_Tp>::value  ||
                             is_const<_Tp>::value     >
-struct __add_const             {typedef _Tp type;};
+struct __add_const             {typedef _LIBCPP_NODEBUG_TYPE  _Tp type;};
 
 template <class _Tp>
-struct __add_const<_Tp, false> {typedef const _Tp type;};
+struct __add_const<_Tp, false> {typedef _LIBCPP_NODEBUG_TYPE  const _Tp type;};
 
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const
-    {typedef typename __add_const<_Tp>::type type;};
+    {typedef _LIBCPP_NODEBUG_TYPE  typename __add_const<_Tp>::type type;};
 
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
@@ -1111,7 +1111,7 @@
 struct __add_volatile<_Tp, false> {typedef volatile _Tp type;};
 
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile
-    {typedef typename __add_volatile<_Tp>::type type;};
+    {typedef _LIBCPP_NODEBUG_TYPE typename __add_volatile<_Tp>::type type;};
 
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
@@ -1120,7 +1120,7 @@
 // add_cv
 
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv
-    {typedef typename add_const<typename add_volatile<_Tp>::type>::type type;};
+    {typedef _LIBCPP_NODEBUG_TYPE typename add_const<typename add_volatile<_Tp>::type>::type type;};
 
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
@@ -1128,10 +1128,10 @@
 
 // remove_reference
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference        {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&>  {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference        {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&>  {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
 #endif
 
 #if _LIBCPP_STD_VER > 11
@@ -1140,11 +1140,11 @@
 
 // add_lvalue_reference
 
-template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl            { typedef _Tp  type; };
-template <class _Tp                                       > struct __add_lvalue_reference_impl<_Tp, true> { typedef _Tp& type; };
+template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl            { typedef _LIBCPP_NODEBUG_TYPE _Tp  type; };
+template <class _Tp                                       > struct __add_lvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; };
 
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_lvalue_reference
-{typedef typename __add_lvalue_reference_impl<_Tp>::type type;};
+{typedef _LIBCPP_NODEBUG_TYPE typename  __add_lvalue_reference_impl<_Tp>::type type;};
 
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
@@ -1152,11 +1152,11 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_rvalue_reference_impl            { typedef _Tp   type; };
-template <class _Tp                                       > struct __add_rvalue_reference_impl<_Tp, true> { typedef _Tp&& type; };
+template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_rvalue_reference_impl            { typedef _LIBCPP_NODEBUG_TYPE  _Tp   type; };
+template <class _Tp                                       > struct __add_rvalue_reference_impl<_Tp, true> { typedef _LIBCPP_NODEBUG_TYPE  _Tp&& type; };
 
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference
-{typedef typename __add_rvalue_reference_impl<_Tp>::type type;};
+{typedef _LIBCPP_NODEBUG_TYPE  typename __add_rvalue_reference_impl<_Tp>::type type;};
 
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
@@ -1185,17 +1185,17 @@
 
 template <class _Tp>
 struct __uncvref  {
-    typedef typename remove_cv<typename remove_reference<_Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename remove_cv<typename remove_reference<_Tp>::type>::type type;
 };
 
 template <class _Tp>
 struct __unconstref {
-    typedef typename remove_const<typename remove_reference<_Tp>::type>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename remove_const<typename remove_reference<_Tp>::type>::type type;
 };
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Tp>
-using __uncvref_t = typename __uncvref<_Tp>::type;
+using __uncvref_t _LIBCPP_NODEBUG_TYPE = typename __uncvref<_Tp>::type;
 #endif
 
 // __is_same_uncvref
@@ -1220,11 +1220,11 @@
 
 // remove_pointer
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer                      {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*>                {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const>          {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile>       {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer                      {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*>                {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const>          {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile>       {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
 
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type;
@@ -1236,12 +1236,12 @@
         bool = __is_referenceable<_Tp>::value ||
                 is_same<typename remove_cv<_Tp>::type, void>::value>
 struct __add_pointer_impl
-    {typedef typename remove_reference<_Tp>::type* type;};
+    {typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type* type;};
 template <class _Tp> struct __add_pointer_impl<_Tp, false>
-    {typedef _Tp type;};
+    {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
 
 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_pointer
-    {typedef typename __add_pointer_impl<_Tp>::type type;};
+    {typedef _LIBCPP_NODEBUG_TYPE typename __add_pointer_impl<_Tp>::type type;};
 
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type;
@@ -1379,13 +1379,13 @@
 
 template <class _Up, bool>
 struct __decay {
-    typedef typename remove_cv<_Up>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename remove_cv<_Up>::type type;
 };
 
 template <class _Up>
 struct __decay<_Up, true> {
 public:
-    typedef typename conditional
+    typedef _LIBCPP_NODEBUG_TYPE typename conditional
                      <
                          is_array<_Up>::value,
                          typename remove_extent<_Up>::type*,
@@ -1402,9 +1402,9 @@
 struct _LIBCPP_TEMPLATE_VIS decay
 {
 private:
-    typedef typename remove_reference<_Tp>::type _Up;
+    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type _Up;
 public:
-    typedef typename __decay<_Up, __is_referenceable<_Up>::value>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename __decay<_Up, __is_referenceable<_Up>::value>::type type;
 };
 
 #if _LIBCPP_STD_VER > 11
@@ -2003,26 +2003,26 @@
 template <class _Hp, class _Tp, size_t _Size>
 struct __find_first<__type_list<_Hp, _Tp>, _Size, true>
 {
-    typedef _Hp type;
+    typedef _LIBCPP_NODEBUG_TYPE _Hp type;
 };
 
 template <class _Hp, class _Tp, size_t _Size>
 struct __find_first<__type_list<_Hp, _Tp>, _Size, false>
 {
-    typedef typename __find_first<_Tp, _Size>::type type;
+    typedef _LIBCPP_NODEBUG_TYPE typename __find_first<_Tp, _Size>::type type;
 };
 
 template <class _Tp, class _Up, bool = is_const<typename remove_reference<_Tp>::type>::value,
                              bool = is_volatile<typename remove_reference<_Tp>::type>::value>
 struct __apply_cv
 {
-    typedef _Up type;
+    typedef _LIBCPP_NODEBUG_TYPE _Up type;
 };
 
 template <class _Tp, class _Up>
 struct __apply_cv<_Tp, _Up, true, false>
 {
-    typedef const _Up type;
+    typedef _LIBCPP_NODEBUG_TYPE const _Up type;
 };
 
 template <class _Tp, class _Up>
@@ -2136,7 +2136,7 @@
                                             true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()
                                             )>::type>
 {
-  typedef typename decay<decltype(
+  typedef _LIBCPP_NODEBUG_TYPE typename decay<decltype(
                          true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()
                          )>::type type;
 };
@@ -2218,7 +2218,7 @@
 
 // is_assignable
 
-template<typename, typename _Tp> struct __select_2nd { typedef _Tp type; };
+template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
 
 template <class _Tp, class _Arg>
 typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type
@@ -2349,7 +2349,7 @@
 typename remove_reference<_Tp>::type&&
 move(_Tp&& __t) _NOEXCEPT
 {
-    typedef typename remove_reference<_Tp>::type _Up;
+    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type _Up;
     return static_cast<_Up&&>(__t);
 }
 
diff --git a/include/utility b/include/utility
index 3eea6f3..4e38678 100644
--- a/include/utility
+++ b/include/utility
@@ -349,7 +349,7 @@
     }
 #else
     template <bool _Val>
-    using _EnableB = typename enable_if<_Val, bool>::type;
+    using _EnableB _LIBCPP_NODEBUG_TYPE = typename enable_if<_Val, bool>::type;
 
     struct _CheckArgs {
       template <class _U1, class _U2>
@@ -376,7 +376,7 @@
     };
 
     template <bool _MaybeEnable>
-    using _CheckArgsDep = typename conditional<
+    using _CheckArgsDep _LIBCPP_NODEBUG_TYPE = typename conditional<
       _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
 
     struct _CheckTupleLikeConstructor {
@@ -398,7 +398,7 @@
     };
 
     template <class _Tuple>
-    using _CheckTLC = typename conditional<
+    using _CheckTLC _LIBCPP_NODEBUG_TYPE = typename conditional<
         __tuple_like_with_size<_Tuple, 2>::value
             && !is_same<typename decay<_Tuple>::type, pair>::value,
         _CheckTupleLikeConstructor,
@@ -637,10 +637,10 @@
 }
 
 template <class _Tp>
-struct __unwrap_reference { typedef _Tp type; };
+struct __unwrap_reference { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
 
 template <class _Tp>
-struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _Tp& type; };
+struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG_TYPE _Tp& type; };
 
 #if _LIBCPP_STD_VER > 17
 template <class _Tp>
@@ -695,13 +695,13 @@
 template <class _T1, class _T2>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
 {
-    typedef _T1 type;
+    typedef _LIBCPP_NODEBUG_TYPE _T1 type;
 };
 
 template <class _T1, class _T2>
 struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
 {
-    typedef _T2 type;
+    typedef _LIBCPP_NODEBUG_TYPE _T2 type;
 };
 
 template <size_t _Ip> struct __get_pair;
@@ -880,11 +880,11 @@
 #if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE)
 
 template <class _Tp, _Tp _Ep>
-using __make_integer_sequence = __make_integer_seq<integer_sequence, _Tp, _Ep>;
+using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = __make_integer_seq<integer_sequence, _Tp, _Ep>;
 
 #else
 
-template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked =
+template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked _LIBCPP_NODEBUG_TYPE  =
   typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
 
 template <class _Tp, _Tp _Ep>
@@ -895,11 +895,11 @@
     static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length");
     // Workaround GCC bug by preventing bad installations when 0 <= _Ep
     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
-    typedef __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
+    typedef _LIBCPP_NODEBUG_TYPE  __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type;
 };
 
 template <class _Tp, _Tp _Ep>
-using __make_integer_sequence = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
+using __make_integer_sequence _LIBCPP_NODEBUG_TYPE = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
 
 #endif
 
@@ -1590,29 +1590,29 @@
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Key, class _Hash>
-using __check_hash_requirements = integral_constant<bool,
+using __check_hash_requirements _LIBCPP_NODEBUG_TYPE  = integral_constant<bool,
     is_copy_constructible<_Hash>::value &&
     is_move_constructible<_Hash>::value &&
     __invokable_r<size_t, _Hash, _Key const&>::value
 >;
 
 template <class _Key, class _Hash = std::hash<_Key> >
-using __has_enabled_hash = integral_constant<bool,
+using __has_enabled_hash _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
     __check_hash_requirements<_Key, _Hash>::value &&
     is_default_constructible<_Hash>::value
 >;
 
 #if _LIBCPP_STD_VER > 14
 template <class _Type, class>
-using __enable_hash_helper_imp = _Type;
+using __enable_hash_helper_imp _LIBCPP_NODEBUG_TYPE  = _Type;
 
 template <class _Type, class ..._Keys>
-using __enable_hash_helper = __enable_hash_helper_imp<_Type,
+using __enable_hash_helper _LIBCPP_NODEBUG_TYPE  = __enable_hash_helper_imp<_Type,
   typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type
 >;
 #else
 template <class _Type, class ...>
-using __enable_hash_helper = _Type;
+using __enable_hash_helper _LIBCPP_NODEBUG_TYPE = _Type;
 #endif
 
 #endif // !_LIBCPP_CXX03_LANG