Skip to content

Commit bda3c7d

Browse files
committed
[libc++] Make _LIBCPP_TYPE_VIS export members
Summary: Most classes annotated with _LIBCPP_TYPE_VIS need to have at least some of their members exported, otherwise we have a lot of link errors when linking against a libc++ built with hidden visibility. This also makes _LIBCPP_TYPE_VIS be consistent across platforms, since on Windows it already exports members. With this change made, any template methods of a class marked _LIBCPP_TYPE_VIS will also get default visibility when instantiatied, which is not desirable for clients of libc++ headers who wish to control their visibility; this is the same issue as PR30642. Annotate all problematic methods with an explicit visibility specifier to avoid this. The problematic methods were found by running bad-visibility-finder [1] against the libc++ headers after making the _LIBCPP_TYPE_VIS change. The small methods were marked for inlining; the larger ones hidden. [1] https://github.com/smeenai/bad-visibility-finder Reviewers: mclow.lists, EricWF Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25208 llvm-svn: 296732
1 parent bad28c4 commit bda3c7d

File tree

9 files changed

+35
-14
lines changed

9 files changed

+35
-14
lines changed

libcxx/docs/DesignDocs/VisibilityMacros.rst

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,17 @@ Visibility Macros
4747
A synonym for `_LIBCPP_INLINE_VISIBILITY`
4848

4949
**_LIBCPP_TYPE_VIS**
50+
Mark a type's typeinfo, vtable and members as having default visibility.
51+
This attribute cannot be used on class templates.
52+
53+
**_LIBCPP_TEMPLATE_VIS**
5054
Mark a type's typeinfo and vtable as having default visibility.
51-
`_LIBCPP_TYPE_VIS`. This macro has no effect on the visibility of the
52-
type's member functions. This attribute cannot be used on class templates.
55+
This macro has no effect on the visibility of the type's member functions.
5356

5457
**GCC Behavior**: GCC does not support Clang's `type_visibility(...)`
5558
attribute. With GCC the `visibility(...)` attribute is used and member
5659
functions are affected.
5760

58-
**_LIBCPP_TEMPLATE_VIS**
59-
The same as `_LIBCPP_TYPE_VIS` except that it may be applied to class
60-
templates.
61-
6261
**Windows Behavior**: DLLs do not support dllimport/export on class templates.
6362
The macro has an empty definition on this platform.
6463

libcxx/include/__config

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -628,18 +628,22 @@ namespace std {
628628

629629
#ifndef _LIBCPP_TYPE_VIS
630630
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
631-
# if __has_attribute(__type_visibility__)
632-
# define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default")))
633-
# else
634-
# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
635-
# endif
631+
# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
636632
# else
637633
# define _LIBCPP_TYPE_VIS
638634
# endif
639635
#endif
640636

641637
#ifndef _LIBCPP_TEMPLATE_VIS
642-
# define _LIBCPP_TEMPLATE_VIS _LIBCPP_TYPE_VIS
638+
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
639+
# if __has_attribute(__type_visibility__)
640+
# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__type_visibility__("default")))
641+
# else
642+
# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__visibility__("default")))
643+
# endif
644+
# else
645+
# define _LIBCPP_TEMPLATE_VIS
646+
# endif
643647
#endif
644648

645649
#ifndef _LIBCPP_FUNC_VIS_ONLY

libcxx/include/__locale

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,16 @@ public:
9292

9393
const locale& operator=(const locale&) _NOEXCEPT;
9494

95-
template <class _Facet> locale combine(const locale&) const;
95+
template <class _Facet>
96+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
97+
locale combine(const locale&) const;
9698

9799
// locale operations:
98100
string name() const;
99101
bool operator==(const locale&) const;
100102
bool operator!=(const locale& __y) const {return !(*this == __y);}
101103
template <class _CharT, class _Traits, class _Allocator>
104+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
102105
bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
103106
const basic_string<_CharT, _Traits, _Allocator>&) const;
104107

libcxx/include/__mutex_base

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,20 +316,24 @@ public:
316316

317317
void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
318318
template <class _Predicate>
319+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
319320
void wait(unique_lock<mutex>& __lk, _Predicate __pred);
320321

321322
template <class _Clock, class _Duration>
323+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
322324
cv_status
323325
wait_until(unique_lock<mutex>& __lk,
324326
const chrono::time_point<_Clock, _Duration>& __t);
325327

326328
template <class _Clock, class _Duration, class _Predicate>
329+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
327330
bool
328331
wait_until(unique_lock<mutex>& __lk,
329332
const chrono::time_point<_Clock, _Duration>& __t,
330333
_Predicate __pred);
331334

332335
template <class _Rep, class _Period>
336+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
333337
cv_status
334338
wait_for(unique_lock<mutex>& __lk,
335339
const chrono::duration<_Rep, _Period>& __d);

libcxx/include/condition_variable

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,14 @@ public:
133133
void notify_all() _NOEXCEPT;
134134

135135
template <class _Lock>
136+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
136137
void wait(_Lock& __lock);
137138
template <class _Lock, class _Predicate>
138139
_LIBCPP_INLINE_VISIBILITY
139140
void wait(_Lock& __lock, _Predicate __pred);
140141

141142
template <class _Lock, class _Clock, class _Duration>
143+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
142144
cv_status
143145
wait_until(_Lock& __lock,
144146
const chrono::time_point<_Clock, _Duration>& __t);

libcxx/include/future

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ public:
582582
_LIBCPP_INLINE_VISIBILITY
583583
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
584584
template <class _Clock, class _Duration>
585+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
585586
future_status
586587
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
587588

@@ -1674,6 +1675,7 @@ class _LIBCPP_TYPE_VIS promise<void>
16741675
public:
16751676
promise();
16761677
template <class _Allocator>
1678+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
16771679
promise(allocator_arg_t, const _Allocator& __a);
16781680
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
16791681
_LIBCPP_INLINE_VISIBILITY

libcxx/include/mutex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ public:
248248
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
249249
{return try_lock_until(chrono::steady_clock::now() + __d);}
250250
template <class _Clock, class _Duration>
251+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
251252
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
252253
void unlock() _NOEXCEPT;
253254
};
@@ -291,6 +292,7 @@ public:
291292
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
292293
{return try_lock_until(chrono::steady_clock::now() + __d);}
293294
template <class _Clock, class _Duration>
295+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
294296
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
295297
void unlock() _NOEXCEPT;
296298
};

libcxx/include/shared_mutex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ public:
220220
return try_lock_until(chrono::steady_clock::now() + __rel_time);
221221
}
222222
template <class _Clock, class _Duration>
223+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
223224
bool
224225
try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
225226
void unlock();
@@ -235,6 +236,7 @@ public:
235236
return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
236237
}
237238
template <class _Clock, class _Duration>
239+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
238240
bool
239241
try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
240242
void unlock_shared();

libcxx/include/thread

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,12 @@ public:
298298
!is_same<typename decay<_Fp>::type, thread>::value
299299
>::type
300300
>
301+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
301302
explicit thread(_Fp&& __f, _Args&&... __args);
302303
#else // _LIBCPP_HAS_NO_VARIADICS
303-
template <class _Fp> explicit thread(_Fp __f);
304+
template <class _Fp>
305+
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
306+
explicit thread(_Fp __f);
304307
#endif
305308
~thread();
306309

0 commit comments

Comments
 (0)