Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 16d1054

Browse files
authored
[libc++] Remove _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS (llvm#111964)
This macro isn't required if we define all the functions inline. In fact, quite a few of the marked functions have already been inlined. This patch basically only moves code around and adds `_LIBCPP_HIDE_FROM_ABI` to the places where it's been missing so far. This also removes inlining hints, since it dropps `inline` in some places, but that shouldn't make much of a difference. The functions tend to be either really small, so should be inlined anyways, or are big enough that they shouldn't be inlined even with an inlinehint.
1 parent 3f38cd0 commit 16d1054

File tree

12 files changed

+672
-849
lines changed

12 files changed

+672
-849
lines changed

libcxx/.clang-format

-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ AttributeMacros: [
3737
'_LIBCPP_HIDDEN',
3838
'_LIBCPP_HIDE_FROM_ABI_AFTER_V1',
3939
'_LIBCPP_HIDE_FROM_ABI',
40-
'_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS',
4140
'_LIBCPP_NO_SANITIZE',
4241
'_LIBCPP_NO_UNIQUE_ADDRESS',
4342
'_LIBCPP_NOALIAS',

libcxx/docs/DesignDocs/VisibilityMacros.rst

-29
Original file line numberDiff line numberDiff line change
@@ -105,35 +105,6 @@ Visibility Macros
105105
the extern template declaration) as exported on Windows, as discussed above.
106106
On all other platforms, this macro has an empty definition.
107107

108-
**_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS**
109-
Mark a symbol as hidden so it will not be exported from shared libraries. This
110-
is intended specifically for method templates of either classes marked with
111-
`_LIBCPP_TYPE_VIS` or classes with an extern template instantiation
112-
declaration marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS`.
113-
114-
When building libc++ with hidden visibility, we want explicit template
115-
instantiations to export members, which is consistent with existing Windows
116-
behavior. We also want classes annotated with `_LIBCPP_TYPE_VIS` to export
117-
their members, which is again consistent with existing Windows behavior.
118-
Both these changes are necessary for clients to be able to link against a
119-
libc++ DSO built with hidden visibility without encountering missing symbols.
120-
121-
An unfortunate side effect, however, is that method templates of classes
122-
either marked `_LIBCPP_TYPE_VIS` or with extern template instantiation
123-
declarations marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` also get default
124-
visibility when instantiated. These methods are often implicitly instantiated
125-
inside other libraries which use the libc++ headers, and will therefore end up
126-
being exported from those libraries, since those implicit instantiations will
127-
receive default visibility. This is not acceptable for libraries that wish to
128-
control their visibility, and led to PR30642.
129-
130-
Consequently, all such problematic method templates are explicitly marked
131-
either hidden (via this macro) or inline, so that they don't leak into client
132-
libraries. The problematic methods were found by running
133-
`bad-visibility-finder <https://github.com/smeenai/bad-visibility-finder>`_
134-
against the libc++ headers after making `_LIBCPP_TYPE_VIS` and
135-
`_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility.
136-
137108
Links
138109
=====
139110

libcxx/include/__condition_variable/condition_variable.h

+85-97
Original file line numberDiff line numberDiff line change
@@ -39,60 +39,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3939
_LIBCPP_DECLARE_STRONG_ENUM(cv_status){no_timeout, timeout};
4040
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
4141

42-
class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
43-
__libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
44-
45-
public:
46-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
47-
48-
# if _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
49-
~condition_variable() = default;
50-
# else
51-
~condition_variable();
52-
# endif
53-
54-
condition_variable(const condition_variable&) = delete;
55-
condition_variable& operator=(const condition_variable&) = delete;
56-
57-
void notify_one() _NOEXCEPT;
58-
void notify_all() _NOEXCEPT;
59-
60-
void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
61-
template <class _Predicate>
62-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS void wait(unique_lock<mutex>& __lk, _Predicate __pred);
63-
64-
template <class _Clock, class _Duration>
65-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
66-
wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t);
67-
68-
template <class _Clock, class _Duration, class _Predicate>
69-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
70-
wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred);
71-
72-
template <class _Rep, class _Period>
73-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
74-
wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d);
75-
76-
template <class _Rep, class _Period, class _Predicate>
77-
bool _LIBCPP_HIDE_FROM_ABI
78-
wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
79-
80-
typedef __libcpp_condvar_t* native_handle_type;
81-
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
82-
83-
private:
84-
void
85-
__do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
86-
# if _LIBCPP_HAS_COND_CLOCKWAIT
87-
_LIBCPP_HIDE_FROM_ABI void
88-
__do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
89-
# endif
90-
template <class _Clock>
91-
_LIBCPP_HIDE_FROM_ABI void
92-
__do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
93-
};
94-
#endif // _LIBCPP_HAS_THREADS
95-
9642
template <class _Rep, class _Period, __enable_if_t<is_floating_point<_Rep>::value, int> = 0>
9743
inline _LIBCPP_HIDE_FROM_ABI chrono::nanoseconds __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) {
9844
using namespace chrono;
@@ -140,64 +86,106 @@ inline _LIBCPP_HIDE_FROM_ABI chrono::nanoseconds __safe_nanosecond_cast(chrono::
14086
return nanoseconds(__result);
14187
}
14288

143-
#if _LIBCPP_HAS_THREADS
144-
template <class _Predicate>
145-
void condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) {
146-
while (!__pred())
147-
wait(__lk);
148-
}
89+
class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
90+
__libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
14991

150-
template <class _Clock, class _Duration>
151-
cv_status condition_variable::wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) {
152-
using namespace chrono;
153-
using __clock_tp_ns = time_point<_Clock, nanoseconds>;
92+
public:
93+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
15494

155-
typename _Clock::time_point __now = _Clock::now();
156-
if (__t <= __now)
157-
return cv_status::timeout;
95+
# if _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
96+
~condition_variable() = default;
97+
# else
98+
~condition_variable();
99+
# endif
158100

159-
__clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch()));
101+
condition_variable(const condition_variable&) = delete;
102+
condition_variable& operator=(const condition_variable&) = delete;
160103

161-
__do_timed_wait(__lk, __t_ns);
162-
return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
163-
}
104+
void notify_one() _NOEXCEPT;
105+
void notify_all() _NOEXCEPT;
106+
107+
void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
164108

165-
template <class _Clock, class _Duration, class _Predicate>
166-
bool condition_variable::wait_until(
167-
unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) {
168-
while (!__pred()) {
169-
if (wait_until(__lk, __t) == cv_status::timeout)
170-
return __pred();
109+
template <class _Predicate>
110+
_LIBCPP_HIDE_FROM_ABI void wait(unique_lock<mutex>& __lk, _Predicate __pred) {
111+
while (!__pred())
112+
wait(__lk);
171113
}
172-
return true;
173-
}
174114

175-
template <class _Rep, class _Period>
176-
cv_status condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d) {
177-
using namespace chrono;
178-
if (__d <= __d.zero())
179-
return cv_status::timeout;
180-
using __ns_rep = nanoseconds::rep;
181-
steady_clock::time_point __c_now = steady_clock::now();
115+
template <class _Clock, class _Duration>
116+
_LIBCPP_HIDE_FROM_ABI cv_status
117+
wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) {
118+
using namespace chrono;
119+
using __clock_tp_ns = time_point<_Clock, nanoseconds>;
120+
121+
typename _Clock::time_point __now = _Clock::now();
122+
if (__t <= __now)
123+
return cv_status::timeout;
124+
125+
__clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch()));
126+
127+
__do_timed_wait(__lk, __t_ns);
128+
return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
129+
}
130+
131+
template <class _Clock, class _Duration, class _Predicate>
132+
_LIBCPP_HIDE_FROM_ABI bool
133+
wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) {
134+
while (!__pred()) {
135+
if (wait_until(__lk, __t) == cv_status::timeout)
136+
return __pred();
137+
}
138+
return true;
139+
}
140+
141+
template <class _Rep, class _Period>
142+
_LIBCPP_HIDE_FROM_ABI cv_status wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d) {
143+
using namespace chrono;
144+
if (__d <= __d.zero())
145+
return cv_status::timeout;
146+
using __ns_rep = nanoseconds::rep;
147+
steady_clock::time_point __c_now = steady_clock::now();
182148

183149
# if _LIBCPP_HAS_COND_CLOCKWAIT
184-
using __clock_tp_ns = time_point<steady_clock, nanoseconds>;
185-
__ns_rep __now_count_ns = std::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
150+
using __clock_tp_ns = time_point<steady_clock, nanoseconds>;
151+
__ns_rep __now_count_ns = std::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
186152
# else
187-
using __clock_tp_ns = time_point<system_clock, nanoseconds>;
188-
__ns_rep __now_count_ns = std::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
153+
using __clock_tp_ns = time_point<system_clock, nanoseconds>;
154+
__ns_rep __now_count_ns = std::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
189155
# endif
190156

191-
__ns_rep __d_ns_count = std::__safe_nanosecond_cast(__d).count();
157+
__ns_rep __d_ns_count = std::__safe_nanosecond_cast(__d).count();
192158

193-
if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
194-
__do_timed_wait(__lk, __clock_tp_ns::max());
195-
} else {
196-
__do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
159+
if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
160+
__do_timed_wait(__lk, __clock_tp_ns::max());
161+
} else {
162+
__do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
163+
}
164+
165+
return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout;
197166
}
198167

199-
return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout;
200-
}
168+
template <class _Rep, class _Period, class _Predicate>
169+
bool _LIBCPP_HIDE_FROM_ABI
170+
wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
171+
172+
typedef __libcpp_condvar_t* native_handle_type;
173+
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
174+
175+
private:
176+
void
177+
__do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
178+
# if _LIBCPP_HAS_COND_CLOCKWAIT
179+
_LIBCPP_HIDE_FROM_ABI void
180+
__do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
181+
# endif
182+
template <class _Clock>
183+
_LIBCPP_HIDE_FROM_ABI void
184+
__do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
185+
};
186+
#endif // _LIBCPP_HAS_THREADS
187+
188+
#if _LIBCPP_HAS_THREADS
201189

202190
template <class _Rep, class _Period, class _Predicate>
203191
inline bool

libcxx/include/__config

-8
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,6 @@ typedef __char32_t char32_t;
383383
# endif
384384

385385
# define _LIBCPP_HIDDEN
386-
# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
387386
# define _LIBCPP_TEMPLATE_VIS
388387
# define _LIBCPP_TEMPLATE_DATA_VIS
389388
# define _LIBCPP_NAMESPACE_VISIBILITY
@@ -407,13 +406,6 @@ typedef __char32_t char32_t;
407406
# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_VISIBILITY("default")
408407
# endif
409408

410-
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
411-
// The inline should be removed once PR32114 is resolved
412-
# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN
413-
# else
414-
# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
415-
# endif
416-
417409
// This is kept to avoid a huge library-wide diff in the first step.
418410
// TODO: Remove this in a follow-up patch
419411
# define _LIBCPP_TEMPLATE_VIS

libcxx/include/__locale

+14-18
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4545

4646
class _LIBCPP_EXPORTED_FROM_ABI locale;
4747

48+
template <class _CharT>
49+
class collate;
50+
4851
template <class _Facet>
4952
_LIBCPP_HIDE_FROM_ABI bool has_facet(const locale&) _NOEXCEPT;
5053

@@ -84,7 +87,12 @@ public:
8487
const locale& operator=(const locale&) _NOEXCEPT;
8588

8689
template <class _Facet>
87-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS locale combine(const locale&) const;
90+
_LIBCPP_HIDE_FROM_ABI locale combine(const locale& __other) const {
91+
if (!std::has_facet<_Facet>(__other))
92+
__throw_runtime_error("locale::combine: locale missing facet");
93+
94+
return locale(*this, std::addressof(const_cast<_Facet&>(std::use_facet<_Facet>(__other))));
95+
}
8896

8997
// locale operations:
9098
string name() const;
@@ -93,8 +101,11 @@ public:
93101
_LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const { return !(*this == __y); }
94102
# endif
95103
template <class _CharT, class _Traits, class _Allocator>
96-
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
97-
operator()(const basic_string<_CharT, _Traits, _Allocator>&, const basic_string<_CharT, _Traits, _Allocator>&) const;
104+
_LIBCPP_HIDE_FROM_ABI bool operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
105+
const basic_string<_CharT, _Traits, _Allocator>& __y) const {
106+
return std::use_facet<std::collate<_CharT> >(*this).compare(
107+
__x.data(), __x.data() + __x.size(), __y.data(), __y.data() + __y.size()) < 0;
108+
}
98109

99110
// global locale objects:
100111
static locale global(const locale&);
@@ -155,14 +166,6 @@ inline _LIBCPP_HIDE_FROM_ABI locale::locale(const locale& __other, _Facet* __f)
155166
__install_ctor(__other, __f, __f ? __f->id.__get() : 0);
156167
}
157168

158-
template <class _Facet>
159-
locale locale::combine(const locale& __other) const {
160-
if (!std::has_facet<_Facet>(__other))
161-
std::__throw_runtime_error("locale::combine: locale missing facet");
162-
163-
return locale(*this, std::addressof(const_cast<_Facet&>(std::use_facet<_Facet>(__other))));
164-
}
165-
166169
template <class _Facet>
167170
inline _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale& __l) _NOEXCEPT {
168171
return __l.has_facet(_Facet::id);
@@ -289,13 +292,6 @@ protected:
289292
};
290293
# endif
291294

292-
template <class _CharT, class _Traits, class _Allocator>
293-
bool locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
294-
const basic_string<_CharT, _Traits, _Allocator>& __y) const {
295-
return std::use_facet<std::collate<_CharT> >(*this).compare(
296-
__x.data(), __x.data() + __x.size(), __y.data(), __y.data() + __y.size()) < 0;
297-
}
298-
299295
// template <class charT> class ctype
300296

301297
class _LIBCPP_EXPORTED_FROM_ABI ctype_base {

0 commit comments

Comments
 (0)