When an always_inline function is used prior to the functions definition,
the compiler may not be able to inline it as requested by the attribute.
GCC flags the `basic_string(CharT const*)` function as one such example.
This patch supresses the warning, and the problem, by moving the
definition of the string constructor to the inline declaration.
This ensures the body is available when it is first ODR used.
llvm-svn: 337235
shrink_to_fit() ends up doing a lot work to get information that we
already know since we just called clear(). This change seems concise
enough to be worth the couple extra lines and my benchmarks show that it
is indeed a pretty decent win. It looks like the same thing is going on
twice in __copy_assign_alloc(), but I didn't want to go overboard since
this is my first contribution to llvm/libc++.
Patch by Timothy VanSlyke!
Differential Revision: https://reviews.llvm.org/D41976
llvm-svn: 327064
The non-const data() member of std::string is only exposed
in C++17 and beyond. However std::string is externally instantiated
and so the member function needs to be exposed to be externally instantiated.
On Linux and OS X this shouldn't cause a problem, because
_LIBCPP_INLINE_VISIBILITY ensures the symbol is always inlined.
However on Windows, the symbol gets marked dllimport, but
there is no definition to import, causing link errors.
llvm-svn: 318690
Previously this macro used 0/1 to indicate if it was set.
This is unlike all other libc++ configuration macros which
use ifdef/ifndef.
This patch makes this macro consistent with everything else.
llvm-svn: 315995
This function template is referenced inside class basic_string as a
friend function. The extern template declaration needs to be above that
friend declaration to actually take effect.
This is important because this function was marked as exported in
r307966, so without the extern template taking effect, it can leak into
other DSOs as a visible symbol.
llvm-svn: 309474
Once upon a time, extern templates used to be a Microsoft extension, so
cl would warn about their usage, and libc++ suppressed that warning.
They've long since been standardized, so the warning is defunct. (libc++
also doesn't currently support building with cl anyway.)
llvm-svn: 307997
It has an extern template instantiation declaration in the headers and a
corresponding instantiation definition in the library, so we must mark
it with _LIBCPP_FUNC_VIS to make it available outside the library.
This doesn't cause any ABI changes as-is since we don't build libc++
with hidden visibility (so the function is exported anyway). It's needed
for building libc++ with hidden visibility, however.
Clarify the Windows behavior for extern function templates while I'm
here, since this exercises that behavior.
llvm-svn: 307966
When using LIBCXX_ABI_UNSTABLE=YES, clang-cl gave the following warning:
P:\llvm_master\src\llvm\projects\libcxx\include\string(683,51):
warning: enumerator value is not representable in the underlying type
'int' [-Wmicrosoft-enum-value]
Fixed by switching from enums to static const size_type.
https://reviews.llvm.org/D35174
llvm-svn: 307751
The string literal operators have implicit instantiations of
basic_string<char> and basic_string<wchar>, which prevent the dllimport
on the subsequent explicit instantiation declarations from having an
effect. Hoisting the explicit instantiations above the implicit ones
fixes the issue.
I think it's pretty unfortunate that the ordering has such an effect,
and I'd fixed the same issue for dllexport in r288682. dllimport is more
complicated from a codegen perspective, however, and clang's behavior of
ignoring the dllimport when there's a previous implicit instantiation is
consistent with cl, so changing the order is our only recourse.
llvm-svn: 306632
Summary:
This patch improves how libc++ handles min/max macros within the headers. Previously libc++ would undef them and emit a warning.
This patch changes libc++ to use `#pragma push_macro` to save the macro before undefining it, and `#pragma pop_macro` to restore the macros and the end of the header.
Reviewers: mclow.lists, bcraig, compnerd, EricWF
Reviewed By: EricWF
Subscribers: cfe-commits, krytarowski
Differential Revision: https://reviews.llvm.org/D33080
llvm-svn: 304357
Summary:
__compressed_pair takes and passes it's constructor arguments by value. This causes arguments to be moved 3 times instead of once. This patch addresses that issue and fixes `constexpr` on the constructors.
I would rather have this fix than D27564, and I'm fairly confident it's not ABI breaking but I'm not 100% sure.
I prefer this solution because it removes a lot of code and makes the implementation *much* smaller.
Reviewers: mclow.lists, K-ballo
Reviewed By: K-ballo
Subscribers: K-ballo, cfe-commits
Differential Revision: https://reviews.llvm.org/D27565
llvm-svn: 300140
This is effectively a partial revert of r278356, which started inlining
basic_string::__init. Even if we want to help the compiler along with
an inlinehint, we shouldn't hamstring it by forcing it to inline all the
time.
Libc++ uses always_inline widely as a limit-the-ABI-hack, but since
__init is already on the dylib boundary, it makes no sense here and just
harms the debugging experience at -O0.
rdar://problem/31013102
llvm-svn: 299290
basic_string::replace() has the below line
__sz += __n2 - __n1;
which fails overflow checks if __n1 > __n2, as the negative result
from the subtraction then overflows the original __sz when added to
it.
This behavior is valid as unsigned integer overflow is defined to wrap
around the maximum value and that produces the correct final value for
__sz. Therefore, we disable this check on this function.
llvm-svn: 297355
When building libc++ with hidden visibility, we want explicit template
instantiations to export members. This is consistent with existing
Windows behavior, and is necessary for clients to be able to link
against a hidden visibility built libc++ without running into lots of
missing symbols.
An unfortunate side effect, however, is that any template methods of a
class with an explicit instantiation will get default visibility when
instantiated, unless the methods are explicitly marked inline or hidden
visibility. This is not desirable for clients of libc++ headers who wish
to control their visibility, and led to PR30642.
Annotate all problematic methods with an explicit visibility specifier
to avoid this. The problematic methods were found by running
https://github.com/smeenai/bad-visibility-finder against the libc++
headers after making the _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS change. The
methods were marked with the new _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
macro, which was created for this purpose.
It should be noted that _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS was originally
intended to expand to default visibility, and was changed to expanding
to default type visibility to fix PR30642. The visibility macro
documentation was not updated accordingly, however, so this change makes
the macro consistent with its documentation again, while explicitly
fixing the methods which resulted in that PR.
Differential Revision: https://reviews.llvm.org/D29157
llvm-svn: 296731
Summary:
This patch fixes http://llvm.org/PR31938. The description below is copy/pasted from the bug:
The standard says:
template<class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT>>
class basic_string {
using value_type = typename traits::char_type;
// ...
basic_string(const charT* s, const Allocator& a = Allocator());
};
libc++ actually chooses to declare the constructor as
basic_string(const value_type* s, const Allocator& a = Allocator());
The implicit deduction guides from class template argument deduction make what was previously an implementation detail visible:
std::basic_string s = "foo"; // error, can't deduce charT.
The constructor in question is in the libc++ DSO, but fortunately it looks like fixing this will not result in an ABI break.
@rsmith How does this look? I did more than just the constructors mentioned in the PR, but IDK how far to take it.
Reviewers: mclow.lists, rsmith
Reviewed By: rsmith
Subscribers: cfe-commits, rsmith
Differential Revision: https://reviews.llvm.org/D29863
llvm-svn: 295393
Visible definitions for basic_string::assign are sometimes emitted in
the dylib depending on the version of LLVM used to compile libc++.
This can cause the check-cxx-abilist target to fail.
This patch attempts marks the basic_string::assign templates as inline
to prevent this. That way the export list is consistent across LLVM
versions.
llvm-svn: 294100
When support for `basic_string_view` was added to string it also
added new assignment operators from `basic_string_view`. These caused
ambiguity when assigning from a braced initializer. This patch fixes
that regression by making the basic_string_view assignment operator
rank lower in overload resolution by making it a template.
llvm-svn: 292276
The name _LIBCPP_TYPE_VIS_ONLY is no longer accurate because both
_LIBCPP_TYPE_VIS and _LIBCPP_TYPE_VIS_ONLY expand to
__attribute__((__type_visibility__)) with Clang. The only remaining difference
is that _LIBCPP_TYPE_VIS_ONLY can be applied to templates whereas
_LIBCPP_TYPE_VIS cannot (due to dllimport/dllexport not being allowed on
templates).
This patch renames _LIBCPP_TYPE_VIS_ONLY to _LIBCPP_TEMPLATE_VIS.
llvm-svn: 291035
Adding both 'inline' and 'always_inline' to the destructor has been contentious.
However most of the performance benefits can be gained by only adding 'inline',
and there is no reason to hold up that change while discussing the other.
llvm-svn: 285538
path uses string::append to construct, append, and concatenate paths. Unfortunatly
string::append has a strong exception safety guaranteed and if it can't prove
that the iterator operations don't throw then it will allocate a temporary
string copy to append to. However this extra allocation and copy is very
undesirable for path which doesn't have the same exception guarantees.
To work around this this patch adds string::__append_forward_unsafe which exposes
the std::string::append interface for forward iterators without enforcing
that the iterator is noexcept.
llvm-svn: 285532
Author: laxmansole
Reviewers: howard.hinnant
mclow.lists
Subscribers: EricWF, flyingforyou, evandro
Differential Revision: https://reviews.llvm.org/D25624
Reapplying the patch as the bug https://llvm.org/bugs/show_bug.cgi?id=30341 is fixed.
Currently basic_string's destructor is not getting inlined. So adding 'inline' attribute to ~basic_string().
Worked in collaboration with Aditya Kumar.
llvm-svn: 285456
Summary:
This patch fixes a number of problems with the visibility macros across GCC (on Unix) and Windows (DLL import/export semantics). All of the visibility macros are now documented under `DesignDocs/VisibilityMacros.rst`. Now I'll no longer forget the subtleties of each!
This patch adds two new visibility macros:
* `_LIBCPP_ENUM_VIS` for controlling the typeinfo of enum types. Only Clang supports this.
* `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` for redefining visibility on explicit instantiation declarations. Clang and Windows require this.
After applying this patch GCC only emits one -Wattribute warning opposed to 30+.
Reviewers: mclow.lists, EricWF
Subscribers: beanz, mgorny, cfe-commits
Differential Revision: https://reviews.llvm.org/D24602
llvm-svn: 281673
This patch causes a couple of issues:
1) It triggers http://llvm.org/PR30341. Although the bug is not truly a libc++
bug it breaks the LLVM build using libc++. Reverting this patch is only
a temporary workaround until Clang is fixed.
2) It adds yet another ABI incompatibility when libc++.so is compiled with GCC.
Specifically GCC doesn't ignore the _LIBCPP_INLINE_VISIBILITY on the out-of-line
definition when compiling the dylib. This causes the externally instantiated
~basic_string symbol to have hidden visibility.
This patch should be recommitted after addressing (1) and (2). (2) can be fixed
by adding _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY which is defined as
__attribute__((visibility("default"), always_inline)) as opposed to
_LIBCPP_INLINE_VISIBILITY which makes the symbol hidden.
llvm-svn: 281562
Author: laxmansole
Reviewers: howard.hinnant
mclow.lists
Subscribers: EricWF, flyingforyou, evandro
Differential Revision: https://reviews.llvm.org/D22834
Currently basic_string's destructor is not getting inlined. So adding 'inline' attribute to ~basic_string().
Worked in collaboration with Aditya Kumar.
llvm-svn: 280944