/* -*- 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. *
*/ #ifndef LO_CLANG_SHARED_PLUGINS
/* Look for places where we are using cow_wrapper, but we are calling a const method on the impl object with a non-const pointer, which means we will unnecessarily trigger a copy.
*/
namespace
{ class Cow_Wrapper : public loplugin::FilteringPlugin<Cow_Wrapper>
{ public: explicit Cow_Wrapper(loplugin::InstantiationData const& data)
: FilteringPlugin(data)
{
}
bool Cow_Wrapper::VisitCXXMemberCallExpr(const CXXMemberCallExpr* memberCallExpr)
{ if (ignoreLocation(memberCallExpr)) returntrue; auto methodDecl = memberCallExpr->getMethodDecl(); if (!methodDecl || !methodDecl->isConst()) returntrue;
auto expr = memberCallExpr->getImplicitObjectArgument()->IgnoreImplicit()->IgnoreParens(); auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(expr);
if (operatorCallExpr && operatorCallExpr->getOperator() == OO_Arrow)
{ auto arrowMethodDecl = dyn_cast_or_null<CXXMethodDecl>(operatorCallExpr->getDirectCallee()); if (!arrowMethodDecl) returntrue; if (arrowMethodDecl->isConst()) returntrue; auto dc = loplugin::DeclCheck(arrowMethodDecl->getParent())
.Class("cow_wrapper")
.Namespace("o3tl")
.GlobalNamespace(); if (!dc) returntrue;
} elseif (operatorCallExpr)
{ auto methodDecl2 = dyn_cast_or_null<CXXMethodDecl>(operatorCallExpr->getDirectCallee()); if (!methodDecl2) returntrue; auto dc = loplugin::DeclCheck(methodDecl2->getParent())
.Class("cow_wrapper")
.Namespace("o3tl")
.GlobalNamespace(); if (!dc) returntrue;
} elseif (auto callExpr = dyn_cast<CallExpr>(expr))
{ if (!isa<ImplicitCastExpr>(callExpr->getCallee())) // std::as_const shows up as this returntrue; if (callExpr->getNumArgs() < 1) returntrue; auto arg0 = dyn_cast<CXXOperatorCallExpr>(callExpr->getArg(0)); if (!arg0) returntrue; auto starMethodDecl = dyn_cast_or_null<CXXMethodDecl>(arg0->getDirectCallee()); if (!starMethodDecl) returntrue; auto dc = loplugin::DeclCheck(starMethodDecl->getParent())
.Class("cow_wrapper")
.Namespace("o3tl")
.GlobalNamespace(); if (!dc) returntrue;
} else returntrue;
report(DiagnosticsEngine::Warning, "calling const method on o3tl::cow_wrapper impl class via non-const pointer, rather use " "std::as_const to prevent triggering an unnecessary copy",
memberCallExpr->getBeginLoc())
<< memberCallExpr->getSourceRange(); returntrue;
}
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.