diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2021-09-30 13:54:26 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2021-10-03 19:50:44 +0200 |
commit | ad1557f5d775739230e0e2252c293948977b42a0 (patch) | |
tree | 610e2e849d87583888c0c658088044d6dc3966a5 /compilerplugins | |
parent | 7e7dd7f152bc7457437f541e7ff88d69e9f8e765 (diff) |
A more lightweight O[U]StringConcatenation
...compared to a full-blown O[U]String, for temporary objects holding an
O[U]StringConcat result that can then be used as a std::[u16]string_view.
It's instructive to see how some invocations of operator ==, operator !=, and
O[U]StringBuffer::insert with an O[U]StringConcat argument required implicit
materialization of an O[U]String temporary, and how that expensive operation has
now been made explicit with the explicit O[U]StringConcatenation ctor.
(The additional operator == and operator != overloads are necessary because the
overloads taking two std::[u16]string_view parameters wouldn't even be found
here with ADL. And the OUString-related ones would cause ambiguities in at
least sal/qa/rtl/strings/test_oustring_stringliterals.cxx built with
RTL_STRING_UNITTEST, so have simply been disabled for that special test-code
case.)
Change-Id: Id29799fa8da21a09ff9794cbc7cc9b366e6803b8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122890
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/stringview.cxx | 24 | ||||
-rw-r--r-- | compilerplugins/clang/test/stringview.cxx | 6 |
2 files changed, 24 insertions, 6 deletions
diff --git a/compilerplugins/clang/stringview.cxx b/compilerplugins/clang/stringview.cxx index 0c060ce93513..4043d7a67e60 100644 --- a/compilerplugins/clang/stringview.cxx +++ b/compilerplugins/clang/stringview.cxx @@ -162,7 +162,13 @@ void StringView::handleSubExprThatCouldBeView(Expr const* subExpr) void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) { QualType argType; - bool charArg = false; + enum + { + None, + OrChar, + ViaConcatenation + } extra + = None; auto const d = expr->getConstructor(); switch (d->getNumParams()) { @@ -174,7 +180,7 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) if (t->isAnyCharacterType()) { argType = expr->getArg(0)->IgnoreImplicit()->getType(); - charArg = true; + extra = OrChar; break; } loplugin::TypeCheck tc(t); @@ -195,6 +201,13 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) argType = expr->getArg(0)->IgnoreImplicit()->getType(); break; } + if (tc.RvalueReference().Struct("OStringConcat").Namespace("rtl").GlobalNamespace() + || tc.RvalueReference().Struct("OUStringConcat").Namespace("rtl").GlobalNamespace()) + { + argType = expr->getArg(0)->IgnoreImplicit()->getType(); + extra = ViaConcatenation; + break; + } return; } case 2: @@ -214,7 +227,7 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) { if (val->getExtValue() == 1) { - charArg = true; + extra = OrChar; } } } @@ -239,13 +252,14 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) report(DiagnosticsEngine::Warning, "instead of an %0%select{| constructed from a %2}1, pass a" " '%select{std::string_view|std::u16string_view}3'" - "%select{| (or an '%select{rtl::OStringChar|rtl::OUStringChar}3')}4", + "%select{| (or an '%select{rtl::OStringChar|rtl::OUStringChar}3')|" + " via '%select{rtl::OStringConcatenation|rtl::OUStringConcatenation}3'}4", expr->getExprLoc()) << expr->getType() << (argType.isNull() ? 0 : 1) << argType << (loplugin::TypeCheck(expr->getType()).Class("OString").Namespace("rtl").GlobalNamespace() ? 0 : 1) - << charArg << expr->getSourceRange(); + << extra << expr->getSourceRange(); } void StringView::handleCXXMemberCallExpr(CXXMemberCallExpr const* expr) diff --git a/compilerplugins/clang/test/stringview.cxx b/compilerplugins/clang/test/stringview.cxx index 34accb6e6448..be7b8db3ea95 100644 --- a/compilerplugins/clang/test/stringview.cxx +++ b/compilerplugins/clang/test/stringview.cxx @@ -99,7 +99,7 @@ void f4(OUString s1, OUString s2) } } -void f5(char const* s1, sal_Int32 n1, char16_t const* s2, sal_Int32 n2) +void f5(char const* s1, sal_Int32 n1, char16_t const* s2, sal_Int32 n2, OString s3, OUString s4) { // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString()); @@ -118,6 +118,8 @@ void f5(char const* s1, sal_Int32 n1, char16_t const* s2, sal_Int32 n2) call_view(OString(std::string_view("foo"))); // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'OStringNumber<int>', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString(OString::number(0))); + // expected-error-re@+1 {{instead of an 'rtl::OString' constructed from a 'typename std::enable_if_t<ToStringHelper<OString>::allowOStringConcat && ToStringHelper<OString>::allowOStringConcat, OStringConcat<OString, OString>{{ ?}}>' (aka 'rtl::OStringConcat<rtl::OString, rtl::OString>'), pass a 'std::string_view' via 'rtl::OStringConcatenation' [loplugin:stringview]}} + call_view(OString(s3 + s3)); // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString()); // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char [4]', pass a 'std::u16string_view' [loplugin:stringview]}} @@ -141,6 +143,8 @@ void f5(char const* s1, sal_Int32 n1, char16_t const* s2, sal_Int32 n2) call_view(OUString(std::u16string_view(u"foo"))); // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'OUStringNumber<int>', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(OUString::number(0))); + // expected-error-re@+1 {{instead of an 'rtl::OUString' constructed from a 'typename std::enable_if_t<ToStringHelper<OUString>::allowOUStringConcat && ToStringHelper<OUString>::allowOUStringConcat, OUStringConcat<OUString, OUString>{{ ?}}>' (aka 'rtl::OUStringConcat<rtl::OUString, rtl::OUString>'), pass a 'std::u16string_view' via 'rtl::OUStringConcatenation' [loplugin:stringview]}} + call_view(OUString(s4 + s4)); } void f5(OUString s) |