Skip to content

Commit a9c9183

Browse files
committed
[libc++] Use the using_if_exists attribute when provided
As discussed on cfe-dev [1], use the using_if_exists Clang attribute when the compiler supports it. This makes it easier to port libc++ on top of new platforms that don't fully support the C Standard library. Previously, libc++ would fail to build when trying to import a missing declaration in a <cXXXX> header. With the attribute, the declaration will simply not be imported into namespace std, and hence it won't be available for libc++ to use. In many cases, the declarations were *not* actually required for libc++ to work (they were only surfaced for users to use them as std::XXXX), so not importing them into namespace std is acceptable. The same thing could be achieved by conscious usage of `#ifdef` along with platform detection, however that quickly creates a maintenance problem as libc++ is ported to new platforms. Furthermore, this problem is exacerbated when mixed with vendor internal-only platforms, which can lead to difficulties maintaining a downstream fork of the library. For the time being, we only use the using_if_exists attribute when it is supported. At some point in the future, we will start removing #ifdef paths that are unnecessary when the attribute is supported, and folks who need those #ifdef paths will be required to use a compiler that supports the attribute. [1]: http://lists.llvm.org/pipermail/cfe-dev/2020-June/066038.html Differential Revision: https://reviews.llvm.org/D90257
1 parent 86c2449 commit a9c9183

17 files changed

+513
-507
lines changed

libcxx/include/__config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,12 @@ typedef unsigned int char32_t;
880880
# define _LIBCPP_EXPLICIT
881881
#endif
882882

883+
#if __has_attribute(using_if_exists)
884+
# define _LIBCPP_USING_IF_EXISTS __attribute__((using_if_exists))
885+
#else
886+
# define _LIBCPP_USING_IF_EXISTS
887+
#endif
888+
883889
#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
884890
# define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx
885891
# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \

libcxx/include/cctype

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,20 +100,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD
100100
#endif
101101

102102

103-
using ::isalnum;
104-
using ::isalpha;
105-
using ::isblank;
106-
using ::iscntrl;
107-
using ::isdigit;
108-
using ::isgraph;
109-
using ::islower;
110-
using ::isprint;
111-
using ::ispunct;
112-
using ::isspace;
113-
using ::isupper;
114-
using ::isxdigit;
115-
using ::tolower;
116-
using ::toupper;
103+
using ::isalnum _LIBCPP_USING_IF_EXISTS;
104+
using ::isalpha _LIBCPP_USING_IF_EXISTS;
105+
using ::isblank _LIBCPP_USING_IF_EXISTS;
106+
using ::iscntrl _LIBCPP_USING_IF_EXISTS;
107+
using ::isdigit _LIBCPP_USING_IF_EXISTS;
108+
using ::isgraph _LIBCPP_USING_IF_EXISTS;
109+
using ::islower _LIBCPP_USING_IF_EXISTS;
110+
using ::isprint _LIBCPP_USING_IF_EXISTS;
111+
using ::ispunct _LIBCPP_USING_IF_EXISTS;
112+
using ::isspace _LIBCPP_USING_IF_EXISTS;
113+
using ::isupper _LIBCPP_USING_IF_EXISTS;
114+
using ::isxdigit _LIBCPP_USING_IF_EXISTS;
115+
using ::tolower _LIBCPP_USING_IF_EXISTS;
116+
using ::toupper _LIBCPP_USING_IF_EXISTS;
117117

118118
_LIBCPP_END_NAMESPACE_STD
119119

libcxx/include/cfenv

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,20 @@ int feupdateenv(const fenv_t* envp);
6161

6262
_LIBCPP_BEGIN_NAMESPACE_STD
6363

64-
using ::fenv_t;
65-
using ::fexcept_t;
66-
67-
using ::feclearexcept;
68-
using ::fegetexceptflag;
69-
using ::feraiseexcept;
70-
using ::fesetexceptflag;
71-
using ::fetestexcept;
72-
using ::fegetround;
73-
using ::fesetround;
74-
using ::fegetenv;
75-
using ::feholdexcept;
76-
using ::fesetenv;
77-
using ::feupdateenv;
64+
using ::fenv_t _LIBCPP_USING_IF_EXISTS;
65+
using ::fexcept_t _LIBCPP_USING_IF_EXISTS;
66+
67+
using ::feclearexcept _LIBCPP_USING_IF_EXISTS;
68+
using ::fegetexceptflag _LIBCPP_USING_IF_EXISTS;
69+
using ::feraiseexcept _LIBCPP_USING_IF_EXISTS;
70+
using ::fesetexceptflag _LIBCPP_USING_IF_EXISTS;
71+
using ::fetestexcept _LIBCPP_USING_IF_EXISTS;
72+
using ::fegetround _LIBCPP_USING_IF_EXISTS;
73+
using ::fesetround _LIBCPP_USING_IF_EXISTS;
74+
using ::fegetenv _LIBCPP_USING_IF_EXISTS;
75+
using ::feholdexcept _LIBCPP_USING_IF_EXISTS;
76+
using ::fesetenv _LIBCPP_USING_IF_EXISTS;
77+
using ::feupdateenv _LIBCPP_USING_IF_EXISTS;
7878

7979
_LIBCPP_END_NAMESPACE_STD
8080

libcxx/include/cinttypes

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,13 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
244244

245245
_LIBCPP_BEGIN_NAMESPACE_STD
246246

247-
using::imaxdiv_t;
248-
using::imaxabs;
249-
using::imaxdiv;
250-
using::strtoimax;
251-
using::strtoumax;
252-
using::wcstoimax;
253-
using::wcstoumax;
247+
using ::imaxdiv_t _LIBCPP_USING_IF_EXISTS;
248+
using ::imaxabs _LIBCPP_USING_IF_EXISTS;
249+
using ::imaxdiv _LIBCPP_USING_IF_EXISTS;
250+
using ::strtoimax _LIBCPP_USING_IF_EXISTS;
251+
using ::strtoumax _LIBCPP_USING_IF_EXISTS;
252+
using ::wcstoimax _LIBCPP_USING_IF_EXISTS;
253+
using ::wcstoumax _LIBCPP_USING_IF_EXISTS;
254254

255255
_LIBCPP_END_NAMESPACE_STD
256256

libcxx/include/clocale

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ lconv* localeconv();
4343

4444
_LIBCPP_BEGIN_NAMESPACE_STD
4545

46-
using ::lconv;
46+
using ::lconv _LIBCPP_USING_IF_EXISTS;
4747
#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
48-
using ::setlocale;
48+
using ::setlocale _LIBCPP_USING_IF_EXISTS;
4949
#endif
50-
using ::localeconv;
50+
using ::localeconv _LIBCPP_USING_IF_EXISTS;
5151

5252
_LIBCPP_END_NAMESPACE_STD
5353

0 commit comments

Comments
 (0)