[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 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@296732 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -47,18 +47,17 @@ Visibility Macros
|
|||||||
A synonym for `_LIBCPP_INLINE_VISIBILITY`
|
A synonym for `_LIBCPP_INLINE_VISIBILITY`
|
||||||
|
|
||||||
**_LIBCPP_TYPE_VIS**
|
**_LIBCPP_TYPE_VIS**
|
||||||
|
Mark a type's typeinfo, vtable and members as having default visibility.
|
||||||
|
This attribute cannot be used on class templates.
|
||||||
|
|
||||||
|
**_LIBCPP_TEMPLATE_VIS**
|
||||||
Mark a type's typeinfo and vtable as having default visibility.
|
Mark a type's typeinfo and vtable as having default visibility.
|
||||||
`_LIBCPP_TYPE_VIS`. This macro has no effect on the visibility of the
|
This macro has no effect on the visibility of the type's member functions.
|
||||||
type's member functions. This attribute cannot be used on class templates.
|
|
||||||
|
|
||||||
**GCC Behavior**: GCC does not support Clang's `type_visibility(...)`
|
**GCC Behavior**: GCC does not support Clang's `type_visibility(...)`
|
||||||
attribute. With GCC the `visibility(...)` attribute is used and member
|
attribute. With GCC the `visibility(...)` attribute is used and member
|
||||||
functions are affected.
|
functions are affected.
|
||||||
|
|
||||||
**_LIBCPP_TEMPLATE_VIS**
|
|
||||||
The same as `_LIBCPP_TYPE_VIS` except that it may be applied to class
|
|
||||||
templates.
|
|
||||||
|
|
||||||
**Windows Behavior**: DLLs do not support dllimport/export on class templates.
|
**Windows Behavior**: DLLs do not support dllimport/export on class templates.
|
||||||
The macro has an empty definition on this platform.
|
The macro has an empty definition on this platform.
|
||||||
|
|
||||||
|
|||||||
@@ -628,18 +628,22 @@ namespace std {
|
|||||||
|
|
||||||
#ifndef _LIBCPP_TYPE_VIS
|
#ifndef _LIBCPP_TYPE_VIS
|
||||||
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
|
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
|
||||||
# if __has_attribute(__type_visibility__)
|
|
||||||
# define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default")))
|
|
||||||
# else
|
|
||||||
# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
|
# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
|
||||||
# endif
|
|
||||||
# else
|
# else
|
||||||
# define _LIBCPP_TYPE_VIS
|
# define _LIBCPP_TYPE_VIS
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _LIBCPP_TEMPLATE_VIS
|
#ifndef _LIBCPP_TEMPLATE_VIS
|
||||||
# define _LIBCPP_TEMPLATE_VIS _LIBCPP_TYPE_VIS
|
# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
|
||||||
|
# if __has_attribute(__type_visibility__)
|
||||||
|
# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__type_visibility__("default")))
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_TEMPLATE_VIS __attribute__ ((__visibility__("default")))
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define _LIBCPP_TEMPLATE_VIS
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _LIBCPP_FUNC_VIS_ONLY
|
#ifndef _LIBCPP_FUNC_VIS_ONLY
|
||||||
|
|||||||
@@ -92,13 +92,16 @@ public:
|
|||||||
|
|
||||||
const locale& operator=(const locale&) _NOEXCEPT;
|
const locale& operator=(const locale&) _NOEXCEPT;
|
||||||
|
|
||||||
template <class _Facet> locale combine(const locale&) const;
|
template <class _Facet>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
|
locale combine(const locale&) const;
|
||||||
|
|
||||||
// locale operations:
|
// locale operations:
|
||||||
string name() const;
|
string name() const;
|
||||||
bool operator==(const locale&) const;
|
bool operator==(const locale&) const;
|
||||||
bool operator!=(const locale& __y) const {return !(*this == __y);}
|
bool operator!=(const locale& __y) const {return !(*this == __y);}
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
|
bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
|
||||||
const basic_string<_CharT, _Traits, _Allocator>&) const;
|
const basic_string<_CharT, _Traits, _Allocator>&) const;
|
||||||
|
|
||||||
|
|||||||
@@ -316,20 +316,24 @@ public:
|
|||||||
|
|
||||||
void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
|
void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
|
||||||
template <class _Predicate>
|
template <class _Predicate>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
void wait(unique_lock<mutex>& __lk, _Predicate __pred);
|
void wait(unique_lock<mutex>& __lk, _Predicate __pred);
|
||||||
|
|
||||||
template <class _Clock, class _Duration>
|
template <class _Clock, class _Duration>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
cv_status
|
cv_status
|
||||||
wait_until(unique_lock<mutex>& __lk,
|
wait_until(unique_lock<mutex>& __lk,
|
||||||
const chrono::time_point<_Clock, _Duration>& __t);
|
const chrono::time_point<_Clock, _Duration>& __t);
|
||||||
|
|
||||||
template <class _Clock, class _Duration, class _Predicate>
|
template <class _Clock, class _Duration, class _Predicate>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
bool
|
bool
|
||||||
wait_until(unique_lock<mutex>& __lk,
|
wait_until(unique_lock<mutex>& __lk,
|
||||||
const chrono::time_point<_Clock, _Duration>& __t,
|
const chrono::time_point<_Clock, _Duration>& __t,
|
||||||
_Predicate __pred);
|
_Predicate __pred);
|
||||||
|
|
||||||
template <class _Rep, class _Period>
|
template <class _Rep, class _Period>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
cv_status
|
cv_status
|
||||||
wait_for(unique_lock<mutex>& __lk,
|
wait_for(unique_lock<mutex>& __lk,
|
||||||
const chrono::duration<_Rep, _Period>& __d);
|
const chrono::duration<_Rep, _Period>& __d);
|
||||||
|
|||||||
@@ -133,12 +133,14 @@ public:
|
|||||||
void notify_all() _NOEXCEPT;
|
void notify_all() _NOEXCEPT;
|
||||||
|
|
||||||
template <class _Lock>
|
template <class _Lock>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
void wait(_Lock& __lock);
|
void wait(_Lock& __lock);
|
||||||
template <class _Lock, class _Predicate>
|
template <class _Lock, class _Predicate>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
void wait(_Lock& __lock, _Predicate __pred);
|
void wait(_Lock& __lock, _Predicate __pred);
|
||||||
|
|
||||||
template <class _Lock, class _Clock, class _Duration>
|
template <class _Lock, class _Clock, class _Duration>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
cv_status
|
cv_status
|
||||||
wait_until(_Lock& __lock,
|
wait_until(_Lock& __lock,
|
||||||
const chrono::time_point<_Clock, _Duration>& __t);
|
const chrono::time_point<_Clock, _Duration>& __t);
|
||||||
|
|||||||
@@ -582,6 +582,7 @@ public:
|
|||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
|
wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
|
||||||
template <class _Clock, class _Duration>
|
template <class _Clock, class _Duration>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
future_status
|
future_status
|
||||||
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
|
wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
|
||||||
|
|
||||||
@@ -1674,6 +1675,7 @@ class _LIBCPP_TYPE_VIS promise<void>
|
|||||||
public:
|
public:
|
||||||
promise();
|
promise();
|
||||||
template <class _Allocator>
|
template <class _Allocator>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
promise(allocator_arg_t, const _Allocator& __a);
|
promise(allocator_arg_t, const _Allocator& __a);
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ public:
|
|||||||
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
|
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
|
||||||
{return try_lock_until(chrono::steady_clock::now() + __d);}
|
{return try_lock_until(chrono::steady_clock::now() + __d);}
|
||||||
template <class _Clock, class _Duration>
|
template <class _Clock, class _Duration>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
|
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
|
||||||
void unlock() _NOEXCEPT;
|
void unlock() _NOEXCEPT;
|
||||||
};
|
};
|
||||||
@@ -291,6 +292,7 @@ public:
|
|||||||
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
|
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
|
||||||
{return try_lock_until(chrono::steady_clock::now() + __d);}
|
{return try_lock_until(chrono::steady_clock::now() + __d);}
|
||||||
template <class _Clock, class _Duration>
|
template <class _Clock, class _Duration>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
|
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
|
||||||
void unlock() _NOEXCEPT;
|
void unlock() _NOEXCEPT;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ public:
|
|||||||
return try_lock_until(chrono::steady_clock::now() + __rel_time);
|
return try_lock_until(chrono::steady_clock::now() + __rel_time);
|
||||||
}
|
}
|
||||||
template <class _Clock, class _Duration>
|
template <class _Clock, class _Duration>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
bool
|
bool
|
||||||
try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
|
try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
|
||||||
void unlock();
|
void unlock();
|
||||||
@@ -235,6 +236,7 @@ public:
|
|||||||
return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
|
return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
|
||||||
}
|
}
|
||||||
template <class _Clock, class _Duration>
|
template <class _Clock, class _Duration>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
bool
|
bool
|
||||||
try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
|
try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
|
||||||
void unlock_shared();
|
void unlock_shared();
|
||||||
|
|||||||
@@ -298,9 +298,12 @@ public:
|
|||||||
!is_same<typename decay<_Fp>::type, thread>::value
|
!is_same<typename decay<_Fp>::type, thread>::value
|
||||||
>::type
|
>::type
|
||||||
>
|
>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
explicit thread(_Fp&& __f, _Args&&... __args);
|
explicit thread(_Fp&& __f, _Args&&... __args);
|
||||||
#else // _LIBCPP_HAS_NO_VARIADICS
|
#else // _LIBCPP_HAS_NO_VARIADICS
|
||||||
template <class _Fp> explicit thread(_Fp __f);
|
template <class _Fp>
|
||||||
|
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
|
||||||
|
explicit thread(_Fp __f);
|
||||||
#endif
|
#endif
|
||||||
~thread();
|
~thread();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user