summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2022-04-15 12:25:12 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-04-19 18:31:10 +0200
commitab699bfdb3375f7142a50cc35322e2924c9e5945 (patch)
tree8f935378a1ee272f4316a50f902e214d50ce8cc6
parentf393785a146433cccd5bbecf1e49b5f1485ec5a7 (diff)
new loplugin:stringviewvar looks for OUString vars that can be
... that can be string_view Change-Id: I0ddf66725e08b58e866a764f57200dd188b9f639 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133066 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--basctl/source/basicide/localizationmgr.cxx6
-rw-r--r--chart2/source/controller/accessibility/AccessibleBase.cxx2
-rw-r--r--chart2/source/controller/main/ChartController_Properties.cxx2
-rw-r--r--chart2/source/controller/main/ChartController_Window.cxx4
-rw-r--r--chart2/source/controller/main/DragMethod_PieSegment.cxx2
-rw-r--r--chart2/source/tools/ObjectIdentifier.cxx16
-rw-r--r--compilerplugins/clang/stringviewvar.cxx406
-rw-r--r--compilerplugins/clang/test/stringviewvar.cxx65
-rw-r--r--desktop/source/deployment/misc/dp_platform.cxx8
-rw-r--r--desktop/source/lib/init.cxx18
-rw-r--r--desktop/source/migration/migration.cxx4
-rw-r--r--filter/source/xsltdialog/typedetectionimport.cxx10
-rw-r--r--oox/source/dump/pptxdumper.cxx37
-rw-r--r--sc/source/core/tool/dbdata.cxx6
-rw-r--r--sfx2/source/sidebar/ResourceManager.cxx6
-rw-r--r--solenv/CompilerTest_compilerplugins_clang.mk1
-rw-r--r--svgio/source/svgreader/svgtextpathnode.cxx4
-rw-r--r--sw/source/core/graphic/ndgrf.cxx4
-rw-r--r--sw/source/filter/html/swhtml.cxx2
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx2
-rw-r--r--vcl/source/font/FeatureParser.cxx11
-rw-r--r--xmloff/source/chart/SchXMLTools.cxx5
22 files changed, 548 insertions, 73 deletions
diff --git a/basctl/source/basicide/localizationmgr.cxx b/basctl/source/basicide/localizationmgr.cxx
index 6dd07a021d32..279fd7555801 100644
--- a/basctl/source/basicide/localizationmgr.cxx
+++ b/basctl/source/basicide/localizationmgr.cxx
@@ -975,7 +975,7 @@ void LocalizationMgr::resetResourceForDialog( const Reference< container::XNameC
return;
// Dialog as control
- OUString aDummyName;
+ std::u16string_view aDummyName;
Any aDialogCtrl;
aDialogCtrl <<= xDialogModel;
Reference< XStringResourceResolver > xDummyStringResolver;
@@ -1002,7 +1002,7 @@ void LocalizationMgr::setResourceIDsForDialog( const Reference< container::XName
return;
// Dialog as control
- OUString aDummyName;
+ std::u16string_view aDummyName;
Any aDialogCtrl;
aDialogCtrl <<= xDialogModel;
Reference< XStringResourceResolver > xDummyStringResolver;
@@ -1084,7 +1084,7 @@ void LocalizationMgr::copyResourceForDialog(
if( !xDialogModel.is() || !xSourceStringResolver.is() || !xTargetStringResourceManager.is() )
return;
- OUString aDummyName;
+ std::u16string_view aDummyName;
Any aDialogCtrl;
aDialogCtrl <<= xDialogModel;
implHandleControlResourceProperties
diff --git a/chart2/source/controller/accessibility/AccessibleBase.cxx b/chart2/source/controller/accessibility/AccessibleBase.cxx
index 904c91e99365..4def612c215e 100644
--- a/chart2/source/controller/accessibility/AccessibleBase.cxx
+++ b/chart2/source/controller/accessibility/AccessibleBase.cxx
@@ -719,7 +719,7 @@ Color AccessibleBase::getColor( eColorType eColType )
if( eType == OBJECTTYPE_LEGEND_ENTRY )
{
// for colors get the data series/point properties
- OUString aParentParticle( ObjectIdentifier::getFullParentParticle( aObjectCID ));
+ std::u16string_view aParentParticle( ObjectIdentifier::getFullParentParticle( aObjectCID ));
aObjectCID = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
}
diff --git a/chart2/source/controller/main/ChartController_Properties.cxx b/chart2/source/controller/main/ChartController_Properties.cxx
index b04e43a82cfa..99c768da772e 100644
--- a/chart2/source/controller/main/ChartController_Properties.cxx
+++ b/chart2/source/controller/main/ChartController_Properties.cxx
@@ -678,7 +678,7 @@ OUString lcl_getFormatCIDforSelectedCID( const OUString& rSelectedCID )
// some legend entries are handled as if they were data series
if( eObjectType==OBJECTTYPE_LEGEND_ENTRY )
{
- OUString aParentParticle( ObjectIdentifier::getFullParentParticle( rSelectedCID ) );
+ std::u16string_view aParentParticle( ObjectIdentifier::getFullParentParticle( rSelectedCID ) );
aFormatCID = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
}
diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx
index a6bae9b002a7..8808da531bd2 100644
--- a/chart2/source/controller/main/ChartController_Window.cxx
+++ b/chart2/source/controller/main/ChartController_Window.cxx
@@ -711,7 +711,7 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt )
}
else
{
- OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) );
+ std::u16string_view aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) );
if( aDragMethodServiceName == ObjectIdentifier::getPieSegmentDragMethodServiceName() )
pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getChartModel() );
}
@@ -1420,7 +1420,7 @@ bool ChartController::execute_KeyInput( const KeyEvent& rKEvt )
nCode == KEY_DOWN )
{
bDrag = true;
- OUString aParameter( ObjectIdentifier::getDragParameterString( m_aSelection.getSelectedCID() ));
+ std::u16string_view aParameter( ObjectIdentifier::getDragParameterString( m_aSelection.getSelectedCID() ));
sal_Int32 nOffsetPercentDummy( 0 );
awt::Point aMinimumPosition( 0, 0 );
awt::Point aMaximumPosition( 0, 0 );
diff --git a/chart2/source/controller/main/DragMethod_PieSegment.cxx b/chart2/source/controller/main/DragMethod_PieSegment.cxx
index 3adc6103e6ab..0859ada4ab23 100644
--- a/chart2/source/controller/main/DragMethod_PieSegment.cxx
+++ b/chart2/source/controller/main/DragMethod_PieSegment.cxx
@@ -46,7 +46,7 @@ DragMethod_PieSegment::DragMethod_PieSegment( DrawViewWrapper& rDrawViewWrapper
, m_aDragDirection(1000.0,1000.0)
, m_fDragRange( 1.0 )
{
- OUString aParameter( ObjectIdentifier::getDragParameterString( m_aObjectCID ) );
+ std::u16string_view aParameter( ObjectIdentifier::getDragParameterString( m_aObjectCID ) );
sal_Int32 nOffsetPercent(0);
awt::Point aMinimumPosition(0,0);
diff --git a/chart2/source/tools/ObjectIdentifier.cxx b/chart2/source/tools/ObjectIdentifier.cxx
index e1b05d023630..a117873b6e38 100644
--- a/chart2/source/tools/ObjectIdentifier.cxx
+++ b/chart2/source/tools/ObjectIdentifier.cxx
@@ -302,10 +302,10 @@ OUString ObjectIdentifier::createClassifiedIdentifierForObject(
OUString aRet;
enum ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
- const OUString aObjectID;
+ const std::u16string_view aObjectID;
OUString aParentParticle;
- const OUString aDragMethodServiceName;
- const OUString aDragParameterString;
+ const std::u16string_view aDragMethodServiceName;
+ const std::u16string_view aDragParameterString;
try
{
@@ -697,8 +697,8 @@ bool ObjectIdentifier::isDragableObject( std::u16string_view rClassifiedIdentifi
bReturn = true;
break;
default:
- OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( rClassifiedIdentifier ) );
- bReturn = !aDragMethodServiceName.isEmpty();
+ std::u16string_view aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( rClassifiedIdentifier ) );
+ bReturn = !aDragMethodServiceName.empty();
break;
}
return bReturn;
@@ -761,10 +761,10 @@ bool ObjectIdentifier::areSiblings( const OUString& rCID1, const OUString& rCID2
bRet=false;
else
{
- OUString aParent1( ObjectIdentifier::getFullParentParticle( rCID1 ) );
- if( !aParent1.isEmpty() )
+ std::u16string_view aParent1( ObjectIdentifier::getFullParentParticle( rCID1 ) );
+ if( !aParent1.empty() )
{
- OUString aParent2( ObjectIdentifier::getFullParentParticle( rCID2 ) );
+ std::u16string_view aParent2( ObjectIdentifier::getFullParentParticle( rCID2 ) );
bRet=aParent1 == aParent2;
}
//legend entries are special:
diff --git a/compilerplugins/clang/stringviewvar.cxx b/compilerplugins/clang/stringviewvar.cxx
new file mode 100644
index 000000000000..2aedde049bdf
--- /dev/null
+++ b/compilerplugins/clang/stringviewvar.cxx
@@ -0,0 +1,406 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cassert>
+#include <set>
+#include <vector>
+
+#include "config_clang.h"
+
+#include "check.hxx"
+#include "functionaddress.hxx"
+#include "plugin.hxx"
+
+// Find various of type rtl::O[U]String that can be converted to std::[u16]string_view instead.
+
+// This can generate false positives e.g.
+// OUString sSave( aToken );
+// aToken.append("foo");
+// aToken = sSave;
+// where the data that is backing the view is modified and then the view is used to assign to
+// the same source data.
+
+namespace
+{
+enum class StringType
+{
+ None,
+ RtlOstring,
+ RtlOustring
+};
+
+StringType relevantStringType(QualType type)
+{
+ loplugin::TypeCheck const c(type);
+ if (c.Class("OString").Namespace("rtl"))
+ {
+ return StringType::RtlOstring;
+ }
+ else if (c.Class("OUString").Namespace("rtl"))
+ {
+ return StringType::RtlOustring;
+ }
+ else
+ {
+ return StringType::None;
+ }
+}
+
+bool relevantVarDecl(VarDecl const* decl)
+{
+ auto const t1 = decl->getType();
+ if (relevantStringType(t1.getNonReferenceType()) == StringType::None)
+ {
+ return false;
+ }
+ if (isa<ParmVarDecl>(decl))
+ {
+ return false;
+ }
+ return true;
+}
+
+DeclRefExpr const* relevantDeclRefExpr(Expr const* expr)
+{
+ //TODO: Look through BO_Comma and AbstractConditionalOperator
+ auto const e = dyn_cast<DeclRefExpr>(expr->IgnoreParenImpCasts());
+ if (e == nullptr)
+ {
+ return nullptr;
+ }
+ auto const d = dyn_cast<VarDecl>(e->getDecl());
+ if (d == nullptr)
+ {
+ return nullptr;
+ }
+ if (!relevantVarDecl(d))
+ {
+ return nullptr;
+ }
+ return e;
+}
+
+bool isStringView(QualType qt)
+{
+ return bool(loplugin::TypeCheck(qt).ClassOrStruct("basic_string_view").StdNamespace());
+}
+
+DeclRefExpr const* relevantImplicitCastExpr(ImplicitCastExpr const* expr)
+{
+ if (!isStringView(expr->getType()))
+ {
+ return nullptr;
+ }
+ return relevantDeclRefExpr(expr->getSubExprAsWritten());
+}
+
+DeclRefExpr const* relevantCStyleCastExpr(CStyleCastExpr const* expr)
+{
+ if (expr->getCastKind() != CK_ToVoid)
+ {
+ return nullptr;
+ }
+ return relevantDeclRefExpr(expr->getSubExprAsWritten());
+}
+
+DeclRefExpr const* relevantCXXMemberCallExpr(CXXMemberCallExpr const* expr)
+{
+ StringType t = relevantStringType(expr->getObjectType());
+ if (t == StringType::None)
+ {
+ return nullptr;
+ }
+ bool good = false;
+ auto const d = expr->getMethodDecl();
+ if (d->getOverloadedOperator() == OO_Subscript)
+ {
+ good = true;
+ }
+ else if (auto const i = d->getIdentifier())
+ {
+ auto const n = i->getName();
+ if (n == "endsWith" || n == "isEmpty" || n == "startsWith" || n == "subView"
+ || n == "indexOf" || n == "lastIndexOf" || n == "compareTo" || n == "match"
+ || n == "trim" || n == "toInt32" || n == "toInt64" || n == "toDouble"
+ || n == "equalsIgnoreAsciiCase" || n == "compareToIgnoreAsciiCase" || n == "getToken"
+ || n == "copy")
+ {
+ good = true;
+ }
+#if 0
+ //TODO: rtl::O[U]String::getLength would be awkward to replace with
+ // std::[u16]string_view::length/size due to the sal_Int32 vs. std::size_t return type
+ // mismatch (C++20 ssize might make that easier, though); and while rtl::OString::getStr is
+ // documented to be NUL-terminated (so not eligible for replacement with
+ // std::string_view::data in general), rtl::OUString::getStr is not (so should be eligible
+ // for replacement with std::u16string_view::data, but some call sites might nevertheless
+ // incorrectly rely on NUL termination, so any replacement would need careful review):
+ if (n == "getLength" || (t == StringType::RtlOustring && n == "getStr"))
+ {
+ good = true;
+ }
+#endif
+ }
+ if (!good)
+ {
+ return nullptr;
+ }
+ return relevantDeclRefExpr(expr->getImplicitObjectArgument());
+}
+
+SmallVector<DeclRefExpr const*, 2> wrap(DeclRefExpr const* expr)
+{
+ if (expr == nullptr)
+ {
+ return {};
+ }
+ return { expr };
+}
+
+SmallVector<DeclRefExpr const*, 2> relevantCXXOperatorCallExpr(CXXOperatorCallExpr const* expr)
+{
+ auto const op = expr->getOperator();
+ if (op == OO_Subscript)
+ {
+ auto const e = expr->getArg(0);
+ if (relevantStringType(e->getType()) == StringType::None)
+ {
+ return {};
+ }
+ return wrap(relevantDeclRefExpr(e));
+ }
+ if (expr->isComparisonOp() || (op == OO_Plus && expr->getNumArgs() == 2))
+ {
+ SmallVector<DeclRefExpr const*, 2> v;
+ if (auto const e = relevantDeclRefExpr(expr->getArg(0)))
+ {
+ v.push_back(e);
+ }
+ if (auto const e = relevantDeclRefExpr(expr->getArg(1)))
+ {
+ v.push_back(e);
+ }
+ return v;
+ }
+ if (op == OO_PlusEqual)
+ {
+ if (relevantStringType(expr->getArg(0)->getType()) != StringType::RtlOustring)
+ {
+ return {};
+ }
+ return wrap(relevantDeclRefExpr(expr->getArg(1)));
+ }
+ if (op == OO_Equal)
+ {
+ if (!isStringView(expr->getArg(1)->getType()))
+ {
+ return {};
+ }
+ return wrap(relevantDeclRefExpr(expr->getArg(0)));
+ }
+ return {};
+}
+
+static const Expr* IgnoreImplicitAndConversionOperator(const Expr* expr)
+{
+ expr = expr->IgnoreImplicit();
+ if (auto memberCall = dyn_cast<CXXMemberCallExpr>(expr))
+ {
+ if (auto conversionDecl = dyn_cast_or_null<CXXConversionDecl>(memberCall->getMethodDecl()))
+ {
+ if (!conversionDecl->isExplicit())
+ expr = memberCall->getImplicitObjectArgument()->IgnoreImplicit();
+ }
+ }
+ return expr;
+}
+
+class StringViewVar final
+ : public loplugin::FunctionAddress<loplugin::FilteringPlugin<StringViewVar>>
+{
+public:
+ explicit StringViewVar(loplugin::InstantiationData const& data)
+ : FunctionAddress(data)
+ {
+ }
+
+ bool VisitVarDecl(VarDecl* decl)
+ {
+ if (ignoreLocation(decl))
+ {
+ return true;
+ }
+ if (decl->hasGlobalStorage())
+ {
+ return true;
+ }
+ if (!decl->isThisDeclarationADefinition())
+ {
+ return true;
+ }
+ if (!relevantVarDecl(decl))
+ {
+ return true;
+ }
+ if (decl->getInit())
+ {
+ auto expr = IgnoreImplicitAndConversionOperator(decl->getInit());
+ if (auto castExpr = dyn_cast<CXXFunctionalCastExpr>(expr))
+ {
+ expr = IgnoreImplicitAndConversionOperator(castExpr->getSubExpr());
+ }
+ if (auto cxxConstruct = dyn_cast<CXXConstructExpr>(expr))
+ {
+ if (cxxConstruct->getNumArgs() == 0)
+ currentVars_.insert(decl); // default constructor
+ else if (cxxConstruct->getNumArgs() == 1
+ && isStringView(cxxConstruct->getArg(0)->getType()))
+ currentVars_.insert(decl);
+ }
+ }
+ return true;
+ }
+
+ bool TraverseImplicitCastExpr(ImplicitCastExpr* expr)
+ {
+ if (ignoreLocation(expr))
+ {
+ return true;
+ }
+ auto const e = relevantImplicitCastExpr(expr);
+ if (e == nullptr)
+ {
+ return FunctionAddress::TraverseImplicitCastExpr(expr);
+ }
+ currentGoodUses_.insert(e);
+ auto const ret = FunctionAddress::TraverseImplicitCastExpr(expr);
+ currentGoodUses_.erase(e);
+ return ret;
+ }
+
+ bool TraverseCStyleCastExpr(CStyleCastExpr* expr)
+ {
+ if (ignoreLocation(expr))
+ {
+ return true;
+ }
+ auto const e = relevantCStyleCastExpr(expr);
+ if (e == nullptr)
+ {
+ return FunctionAddress::TraverseCStyleCastExpr(expr);
+ }
+ currentGoodUses_.insert(e);
+ auto const ret = FunctionAddress::TraverseCStyleCastExpr(expr);
+ currentGoodUses_.erase(e);
+ return ret;
+ }
+
+ bool TraverseCXXMemberCallExpr(CXXMemberCallExpr* expr)
+ {
+ if (ignoreLocation(expr))
+ {
+ return true;
+ }
+ auto const e = relevantCXXMemberCallExpr(expr);
+ if (e == nullptr)
+ {
+ return FunctionAddress::TraverseCXXMemberCallExpr(expr);
+ }
+ currentGoodUses_.insert(e);
+ auto const ret = FunctionAddress::TraverseCXXMemberCallExpr(expr);
+ currentGoodUses_.erase(e);
+ return ret;
+ }
+
+ bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr* expr)
+ {
+ if (ignoreLocation(expr))
+ {
+ return true;
+ }
+ auto const es = relevantCXXOperatorCallExpr(expr);
+ if (es.empty())
+ {
+ return FunctionAddress::TraverseCXXOperatorCallExpr(expr);
+ }
+ currentGoodUses_.insert(es.begin(), es.end());
+ auto const ret = FunctionAddress::TraverseCXXOperatorCallExpr(expr);
+ for (auto const i : es)
+ {
+ currentGoodUses_.erase(i);
+ }
+ return ret;
+ }
+
+ bool VisitDeclRefExpr(DeclRefExpr* expr)
+ {
+ if (!FunctionAddress::VisitDeclRefExpr(expr))
+ {
+ return false;
+ }
+ if (ignoreLocation(expr))
+ {
+ return true;
+ }
+ if (currentGoodUses_.find(expr) != currentGoodUses_.end())
+ {
+ return true;
+ }
+ if (auto const d = dyn_cast<VarDecl>(expr->getDecl()))
+ {
+ currentVars_.erase(d);
+ }
+ return true;
+ }
+
+private:
+ void run() override
+ {
+ if (!compiler.getLangOpts().CPlusPlus)
+ {
+ return;
+ }
+ if (compiler.getPreprocessor().getIdentifierInfo("NDEBUG")->hasMacroDefinition())
+ {
+ return;
+ }
+ StringRef fn(handler.getMainFileName());
+ // leave the string QA tests alone
+ if (loplugin::hasPathnamePrefix(fn, SRCDIR "/sal/qa/"))
+ {
+ return;
+ }
+ // false +
+ if (loplugin::hasPathnamePrefix(fn, SRCDIR "/svtools/source/svrtf/parrtf.cxx"))
+ {
+ return;
+ }
+ if (!TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()))
+ {
+ return;
+ }
+ for (auto const i : currentVars_)
+ {
+ auto const t = relevantStringType(i->getType().getNonReferenceType());
+ report(DiagnosticsEngine::Warning,
+ "replace var of type %0 with "
+ "'%select{std::string_view|std::u16string_view}1'",
+ i->getLocation())
+ << i->getType() << (int(t) - 1) << i->getSourceRange();
+ }
+ }
+
+ std::set<VarDecl const*> currentVars_;
+ std::set<DeclRefExpr const*> currentGoodUses_;
+};
+
+static loplugin::Plugin::Registration<StringViewVar> reg("stringviewvar");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/compilerplugins/clang/test/stringviewvar.cxx b/compilerplugins/clang/test/stringviewvar.cxx
new file mode 100644
index 000000000000..016f0fcc85a9
--- /dev/null
+++ b/compilerplugins/clang/test/stringviewvar.cxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#undef NDEBUG
+
+#include "sal/config.h"
+#include <string_view>
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "sal/types.h"
+
+void f1(std::string_view sv)
+{
+ // expected-error@+1 {{replace var of type 'rtl::OString' with 'std::string_view' [loplugin:stringviewvar]}}
+ OString s1(sv);
+ (void)s1;
+}
+
+void f2(const OString s1)
+{
+ // no warning expected
+ OString s2(s1);
+ (void)s2;
+}
+
+std::string_view f3a();
+void f3()
+{
+ // expected-error@+1 {{replace var of type 'rtl::OString' with 'std::string_view' [loplugin:stringviewvar]}}
+ OString s1 = OString(f3a());
+ (void)s1;
+}
+
+void f4a(const OString&);
+void f4(std::string_view sv)
+{
+ // no warning expected
+ OString s1(sv);
+ f4a(s1);
+}
+
+void f5(std::string_view sv)
+{
+ // expected-error@+1 {{replace var of type 'rtl::OString' with 'std::string_view' [loplugin:stringviewvar]}}
+ OString s1(sv);
+ if (s1 == "xxxx")
+ f5(sv);
+}
+
+void f6(std::u16string_view sv)
+{
+ // expected-error@+1 {{replace var of type 'rtl::OUString' with 'std::u16string_view' [loplugin:stringviewvar]}}
+ OUString s6;
+ s6 = sv;
+ (void)s6;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/desktop/source/deployment/misc/dp_platform.cxx b/desktop/source/deployment/misc/dp_platform.cxx
index 90dee4a6d1c2..879e617b7258 100644
--- a/desktop/source/deployment/misc/dp_platform.cxx
+++ b/desktop/source/deployment/misc/dp_platform.cxx
@@ -173,12 +173,12 @@ bool platform_fits( std::u16string_view platform_string )
sal_Int32 index = 0;
for (;;)
{
- const OUString token(
+ const std::u16string_view token(
o3tl::trim(o3tl::getToken(platform_string, 0, ',', index )) );
// check if this platform:
- if (token.equalsIgnoreAsciiCase( StrPlatform::get() ) ||
- (token.indexOf( '_' ) < 0 && /* check OS part only */
- token.equalsIgnoreAsciiCase( StrOperatingSystem::get() )))
+ if (o3tl::equalsIgnoreAsciiCase( token, StrPlatform::get() ) ||
+ (token.find( '_' ) == std::u16string_view::npos && /* check OS part only */
+ o3tl::equalsIgnoreAsciiCase( token, StrOperatingSystem::get() )))
{
return true;
}
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index e017ec4d9985..7b99ed49fdc9 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2837,7 +2837,8 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
// Check if watermark for pdf is passed by filteroptions...
// It is not a real filter option so it must be filtered out.
- OUString watermarkText, sFullSheetPreview;
+ OUString watermarkText;
+ std::u16string_view sFullSheetPreview;
int aIndex = -1;
if ((aIndex = aFilterOptions.indexOf(",Watermark=")) >= 0)
{
@@ -2853,7 +2854,7 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+16);
}
- bool bFullSheetPreview = sFullSheetPreview == "true";
+ bool bFullSheetPreview = sFullSheetPreview == u"true";
// Select a pdf version if specified a valid one. If not specified then ignore.
// If invalid then fail.
@@ -2861,19 +2862,18 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
if ((aIndex = aFilterOptions.indexOf(",PDFVer=")) >= 0)
{
int bIndex = aFilterOptions.indexOf("PDFVEREND");
- OUString sPdfVer;
- sPdfVer = aFilterOptions.subView(aIndex+8, bIndex-(aIndex+8));
+ std::u16string_view sPdfVer = aFilterOptions.subView(aIndex+8, bIndex-(aIndex+8));
aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+9);
- if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-1b"))
+ if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF/A-1b"))
pdfVer = 1;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-2b"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF/A-2b"))
pdfVer = 2;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-3b"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF/A-3b"))
pdfVer = 3;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.5"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF-1.5"))
pdfVer = 15;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.6"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF-1.6"))
pdfVer = 16;
else
{
diff --git a/desktop/source/migration/migration.cxx b/desktop/source/migration/migration.cxx
index 42a02fa2cf76..6014d0e74935 100644
--- a/desktop/source/migration/migration.cxx
+++ b/desktop/source/migration/migration.cxx
@@ -941,8 +941,8 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat
OUString sParentNodeName = elem.m_sParentNodeName;
sal_Int32 nIndex = 0;
do {
- OUString sToken( o3tl::trim(o3tl::getToken(sParentNodeName, 0, '|', nIndex)) );
- if (sToken.isEmpty())
+ std::u16string_view sToken( o3tl::trim(o3tl::getToken(sParentNodeName, 0, '|', nIndex)) );
+ if (sToken.empty())
break;
sal_Int32 nCount = xTemp->getCount();
diff --git a/filter/source/xsltdialog/typedetectionimport.cxx b/filter/source/xsltdialog/typedetectionimport.cxx
index 5fc5ae582951..be5766927fbc 100644
--- a/filter/source/xsltdialog/typedetectionimport.cxx
+++ b/filter/source/xsltdialog/typedetectionimport.cxx
@@ -136,14 +136,14 @@ std::unique_ptr<filter_info_impl> TypeDetectionImporter::createFilterForNode( No
pFilter->maType = getSubdata( 1, aComma, aData );
pFilter->maDocumentService = getSubdata( 2, aComma, aData );
- OUString aFilterService( getSubdata( 3, aComma, aData ) );
+ std::u16string_view aFilterService( getSubdata( 3, aComma, aData ) );
pFilter->maFlags = o3tl::toInt32(getSubdata( 4, aComma, aData ));
// parse filter user data
sal_Unicode aDelim(';');
- OUString aFilterUserData( getSubdata( 5, aComma, aData ) );
+ std::u16string_view aFilterUserData( getSubdata( 5, aComma, aData ) );
- OUString aAdapterService( getSubdata( 0, aDelim, aFilterUserData ) );
+ std::u16string_view aAdapterService( getSubdata( 0, aDelim, aFilterUserData ) );
//Import/ExportService
pFilter->mbNeedsXSLT2 = OUString(getSubdata( 1, aDelim, aFilterUserData )).toBoolean();
pFilter->maImportService = getSubdata( 2, aDelim, aFilterUserData );
@@ -182,10 +182,10 @@ std::unique_ptr<filter_info_impl> TypeDetectionImporter::createFilterForNode( No
if( pFilter->maFlags == 0 )
bOk = false;
- if( aFilterService != "com.sun.star.comp.Writer.XmlFilterAdaptor" )
+ if( aFilterService != u"com.sun.star.comp.Writer.XmlFilterAdaptor" )
bOk = false;
- if( aAdapterService != "com.sun.star.documentconversion.XSLTFilter" )
+ if( aAdapterService != u"com.sun.star.documentconversion.XSLTFilter" )
bOk = false;
if( pFilter->maExtension.isEmpty() )
diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx
index dba538593aae..c65b792063b2 100644
--- a/oox/source/dump/pptxdumper.cxx
+++ b/oox/source/dump/pptxdumper.cxx
@@ -24,6 +24,7 @@
#include <oox/dump/xlsbdumper.hxx>
#include <oox/helper/zipstorage.hxx>
#include <oox/ole/olestorage.hxx>
+#include <o3tl/string_view.hxx>
#ifdef DBG_UTIL
@@ -42,41 +43,41 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent )
void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
- OUString aExt( InputOutputHelper::getFileNameExtension( rStrmName ) );
- if( aExt.equalsIgnoreAsciiCase("pptx") ||
- aExt.equalsIgnoreAsciiCase("potx") )
+ std::u16string_view aExt( InputOutputHelper::getFileNameExtension( rStrmName ) );
+ if( o3tl::equalsIgnoreAsciiCase(aExt, u"pptx") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"potx") )
{
Dumper( getContext(), rxStrm, rSysFileName ).dump();
}
#ifdef FIXME
else if(
- aExt.equalsIgnoreAsciiCase("xlsb") ||
- aExt.equalsIgnoreAsciiCase("xlsm") ||
- aExt.equalsIgnoreAsciiCase("xlsx") ||
- aExt.equalsIgnoreAsciiCase("xltm") ||
- aExt.equalsIgnoreAsciiCase("xltx") )
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlsb") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlsm") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlsx") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xltm") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xltx") )
{
::oox::dump::xlsb::Dumper( getContext(), rxStrm, rSysFileName ).dump();
}
else if(
- aExt.equalsIgnoreAsciiCase("xla") ||
- aExt.equalsIgnoreAsciiCase("xlc") ||
- aExt.equalsIgnoreAsciiCase("xlm") ||
- aExt.equalsIgnoreAsciiCase("xls") ||
- aExt.equalsIgnoreAsciiCase("xlt") ||
- aExt.equalsIgnoreAsciiCase("xlw") )
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xla") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlc") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlm") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xls") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlt") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlw") )
{
::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump();
}
#endif
else if(
- aExt.equalsIgnoreAsciiCase("xml") ||
- aExt.equalsIgnoreAsciiCase("vml") ||
- aExt.equalsIgnoreAsciiCase("rels") )
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xml") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"vml") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"rels") )
{
XmlStreamObject( *this, rxStrm, rSysFileName ).dump();
}
- else if( aExt.equalsIgnoreAsciiCase("bin") )
+ else if( o3tl::equalsIgnoreAsciiCase(aExt, u"bin") )
{
if( rStrgPath == "ppt" && rStrmName == "vbaProject.bin" )
{
diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx
index f7e22dea2a03..e060fb25e422 100644
--- a/sc/source/core/tool/dbdata.cxx
+++ b/sc/source/core/tool/dbdata.cxx
@@ -1016,13 +1016,13 @@ OUString lcl_IncrementNumberInNamedRange(ScDBCollection::NamedDBs& namedDBs,
sal_Int32 nOldNumber = 1;
if (nLastIndex >= 0)
{
- OUString sLastPart(sOldName.subView(nLastIndex));
- nOldNumber = sLastPart.toInt32();
+ std::u16string_view sLastPart(sOldName.subView(nLastIndex));
+ nOldNumber = o3tl::toInt32(sLastPart);
// When no number found, add number at the end.
// When there is a literal "0" at the end, keep the "lastIndex" from above
// (OUString::toInt32() also returns 0 on failure)
- if (nOldNumber == 0 && sLastPart != "0")
+ if (nOldNumber == 0 && sLastPart != u"0")
{
nOldNumber = 1;
nLastIndex = sOldName.getLength();
diff --git a/sfx2/source/sidebar/ResourceManager.cxx b/sfx2/source/sidebar/ResourceManager.cxx
index 56700a223fbb..320faf48fe5e 100644
--- a/sfx2/source/sidebar/ResourceManager.cxx
+++ b/sfx2/source/sidebar/ResourceManager.cxx
@@ -520,7 +520,7 @@ void ResourceManager::ReadContextList (
continue;
}
- const OUString sInitialState(o3tl::trim(o3tl::getToken(sValue, 0, ',', nCharacterIndex)));
+ const std::u16string_view sInitialState(o3tl::trim(o3tl::getToken(sValue, 0, ',', nCharacterIndex)));
// The fourth argument is optional.
const OUString sMenuCommandOverride(
@@ -599,9 +599,9 @@ void ResourceManager::ReadContextList (
// Setup the flag that controls whether a deck/pane is
// initially visible/expanded.
bool bIsInitiallyVisible;
- if (sInitialState == "visible")
+ if (sInitialState == u"visible")
bIsInitiallyVisible = true;
- else if (sInitialState == "hidden")
+ else if (sInitialState == u"hidden")
bIsInitiallyVisible = false;
else
{
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk
index 2520dd2192e9..123e6951edb3 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -94,6 +94,7 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
compilerplugins/clang/test/stringstatic \
compilerplugins/clang/test/stringview \
compilerplugins/clang/test/stringviewparam \
+ compilerplugins/clang/test/stringviewvar \
compilerplugins/clang/test/trivialconstructor \
compilerplugins/clang/test/trivialdestructor \
compilerplugins/clang/test/typedefparam \
diff --git a/svgio/source/svgreader/svgtextpathnode.cxx b/svgio/source/svgreader/svgtextpathnode.cxx
index 3b341eea3d40..9b177383677f 100644
--- a/svgio/source/svgreader/svgtextpathnode.cxx
+++ b/svgio/source/svgreader/svgtextpathnode.cxx
@@ -150,10 +150,10 @@ namespace svgio::svgreader
if(basegfx::fTools::more(fSnippetWidth, 0.0))
{
const OUString aText(getSource().getText());
- const OUString aTrimmedChars(o3tl::trim(aText.subView(nIndex, nLength)));
+ const std::u16string_view aTrimmedChars(o3tl::trim(aText.subView(nIndex, nLength)));
const double fEndPos(mfPosition + fSnippetWidth);
- if(!aTrimmedChars.isEmpty() && (mfPosition < mfBasegfxPathLength || fEndPos > 0.0))
+ if(!aTrimmedChars.empty() && (mfPosition < mfBasegfxPathLength || fEndPos > 0.0))
{
const double fHalfSnippetWidth(fSnippetWidth * 0.5);
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
index 3eabac3a84b5..82cbb57c12f3 100644
--- a/sw/source/core/graphic/ndgrf.cxx
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -577,8 +577,8 @@ void SwGrfNode::InsertLink( std::u16string_view rGrfName, const OUString& rFltNa
{
sal_Int32 nTmp = 0;
const OUString sApp{ o3tl::getToken(rGrfName, 0, sfx2::cTokenSeparator, nTmp ) };
- const OUString sTopic{ o3tl::getToken(rGrfName, 0, sfx2::cTokenSeparator, nTmp ) };
- const OUString sItem{ rGrfName.substr( nTmp ) };
+ const std::u16string_view sTopic{ o3tl::getToken(rGrfName, 0, sfx2::cTokenSeparator, nTmp ) };
+ const std::u16string_view sItem{ rGrfName.substr( nTmp ) };
rIDLA.GetLinkManager().InsertDDELink( mxLink.get(), sApp, sTopic, sItem );
}
else
diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx
index b40633119673..2c19733d66b3 100644
--- a/sw/source/filter/html/swhtml.cxx
+++ b/sw/source/filter/html/swhtml.cxx
@@ -2057,7 +2057,7 @@ void SwHTMLParser::NextToken( HtmlTokenId nToken )
if( ' ' == aToken[ 3 ] &&
' ' == aToken[ aToken.getLength()-3 ] )
{
- OUString aComment( aToken.subView( 3, aToken.getLength()-5 ) );
+ std::u16string_view aComment( aToken.subView( 3, aToken.getLength()-5 ) );
InsertComment(comphelper::string::strip(aComment, ' '));
}
else
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 88df3b95f46d..c80ea4972e9a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -8507,7 +8507,7 @@ void DocxAttributeOutput::HiddenField(const SwField& rField)
OUString aTrueFalse = rField.GetPar2();
sal_Int32 nPos = aTrueFalse.indexOf('|');
OUString aTrue;
- OUString aFalse;
+ std::u16string_view aFalse;
if (nPos == -1)
{
aTrue = aTrueFalse;
diff --git a/vcl/source/font/FeatureParser.cxx b/vcl/source/font/FeatureParser.cxx
index 32e407671336..5182cea7aace 100644
--- a/vcl/source/font/FeatureParser.cxx
+++ b/vcl/source/font/FeatureParser.cxx
@@ -10,6 +10,7 @@
#include <vcl/font/FeatureParser.hxx>
#include <vcl/font/Feature.hxx>
+#include <o3tl/string_view.hxx>
namespace vcl::font
{
@@ -30,18 +31,18 @@ FeatureParser::FeatureParser(std::u16string_view rFontName)
if (nPrefixIdx == std::u16string_view::npos)
return;
- OUString sName(rFontName.substr(++nPrefixIdx));
+ std::u16string_view sName(rFontName.substr(++nPrefixIdx));
sal_Int32 nIndex = 0;
do
{
- OUString sToken = sName.getToken(0, vcl::font::FeatureSeparator, nIndex);
+ std::u16string_view sToken = o3tl::getToken(sName, 0, vcl::font::FeatureSeparator, nIndex);
sal_Int32 nInnerIdx{ 0 };
- OUString sID = sToken.getToken(0, '=', nInnerIdx);
+ std::u16string_view sID = o3tl::getToken(sToken, 0, '=', nInnerIdx);
- if (sID == "lang")
+ if (sID == u"lang")
{
- m_sLanguage = sToken.getToken(0, '=', nInnerIdx);
+ m_sLanguage = o3tl::getToken(sToken, 0, '=', nInnerIdx);
}
else
{
diff --git a/xmloff/source/chart/SchXMLTools.cxx b/xmloff/source/chart/SchXMLTools.cxx
index 828d550e9f56..2e90a3e37f5e 100644
--- a/xmloff/source/chart/SchXMLTools.cxx
+++ b/xmloff/source/chart/SchXMLTools.cxx
@@ -48,6 +48,7 @@
#include <comphelper/processfactory.hxx>
#include <tools/diagnose_ex.h>
#include <sal/log.hxx>
+#include <o3tl/string_view.hxx>
#include <algorithm>
#include <map>
@@ -94,8 +95,8 @@ sal_Int32 lcl_getBuildIDFromGenerator( std::u16string_view rGenerator )
size_t nBegin = rGenerator.find( sBuildCompare );
if( nBegin != std::u16string_view::npos )
{
- OUString sBuildId( rGenerator.substr( nBegin + sBuildCompare.getLength() ) );
- nBuildId = sBuildId.toInt32();
+ std::u16string_view sBuildId = rGenerator.substr( nBegin + sBuildCompare.getLength() );
+ nBuildId = o3tl::toInt32(sBuildId);
}
return nBuildId;
}