/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * Based on LLVM/Clang. * * This file is distributed under the University of Illinois Open Source * License. See LICENSE.TXT for details. *
*/
/* Look for places where we can pass by move && param and so avoid unnecessary copies. Empirically, when we are passing a container type to a function, 80% of the time, we are passing a local temporary that can be moved instead of being copied.
TODO this could be a lot smarter, with ignoring false+ e.g. when copying a param in a loop
*/
namespace
{ class MoveParam : public loplugin::FilteringPlugin<MoveParam>
{ public: explicit MoveParam(loplugin::InstantiationData const& data)
: FilteringPlugin(data)
{
}
virtualbool preRun() override
{
std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn); if (loplugin::hasPathnamePrefix(fn, SRCDIR "/filter/source/msfilter/escherex.cxx")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/sc/source/ui/docshell/docfunc.cxx")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/sc/source/ui/view/viewfunc.cxx")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/basegfx/source/polygon/b2dpolygontools.cxx")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/basegfx/source/polygon/b3dpolygontools.cxx")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/connectivity/source/commontools/dbtools.cxx")) returnfalse; returntrue;
}
virtualvoid run() override
{ if (preRun())
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
bool MoveParam::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr* callExpr)
{ if (ignoreLocation(callExpr)) returntrue; if (!callExpr->isAssignmentOp()) returntrue; auto qt = callExpr->getType(); if (!isContainerType(qt)) returntrue; auto declRef = dyn_cast<DeclRefExpr>(callExpr->getArg(1)->IgnoreParenImpCasts()); if (!declRef) returntrue;
auto parmVarDecl = dyn_cast_or_null<ParmVarDecl>(declRef->getDecl()); if (!parmVarDecl) returntrue;
if (!loplugin::TypeCheck(parmVarDecl->getType()).LvalueReference().Const()) returntrue;
StringRef aFileName = getFilenameOfLocation(
compiler.getSourceManager().getSpellingLoc(parmVarDecl->getBeginLoc())); if (loplugin::hasPathnamePrefix(aFileName,
SRCDIR "/svx/source/sidebar/line/LineWidthValueSet.cxx")) returntrue;
report(DiagnosticsEngine::Warning, "rather use move && param1", callExpr->getBeginLoc());
returntrue;
}
bool MoveParam::VisitCXXConstructExpr(const CXXConstructExpr* constructExpr)
{ if (ignoreLocation(constructExpr->getBeginLoc())) returntrue; if (isInUnoIncludeFile(constructExpr->getBeginLoc())) returntrue;
auto qt = constructExpr->getType(); if (!isContainerType(qt)) returntrue;
if (constructExpr->getNumArgs() != 1) returntrue;
auto declRef = dyn_cast<DeclRefExpr>(constructExpr->getArg(0)->IgnoreParenImpCasts()); if (!declRef) returntrue;
auto parmVarDecl = dyn_cast_or_null<ParmVarDecl>(declRef->getDecl()); if (!parmVarDecl) returntrue;
if (!loplugin::TypeCheck(parmVarDecl->getType()).LvalueReference().Const()) returntrue;
StringRef aFileName = getFilenameOfLocation(
compiler.getSourceManager().getSpellingLoc(parmVarDecl->getBeginLoc())); if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/drawinglayer/primitive2d/Primitive2DContainer.hxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName,
SRCDIR "/include/drawinglayer/primitive3d/baseprimitive3d.hxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/svx/source/svdraw/svdmrkv.cxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/editeng/swafopt.hxx")) returntrue; if (loplugin::hasPathnamePrefix(
aFileName, SRCDIR "/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName,
SRCDIR "/chart2/source/tools/InternalDataProvider.cxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/sc/source/core/data/attrib.cxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/sw/source/core/doc/docfmt.cxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/configmgr/source/modifications.cxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/svx/source/dialog/srchdlg.cxx")) returntrue; if (loplugin::hasPathnamePrefix(aFileName,
SRCDIR "/stoc/source/servicemanager/servicemanager.cxx")) returntrue;
report(DiagnosticsEngine::Warning, "rather use move && param3", constructExpr->getBeginLoc());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.