1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 #include <clang/AST/CXXInheritance.h>
23 * which can be transformed to:
38 class RedundantPointerOps
:
39 public RecursiveASTVisitor
<RedundantPointerOps
>, public loplugin::Plugin
42 explicit RedundantPointerOps(loplugin::InstantiationData
const & data
): Plugin(data
) {}
44 virtual void run() override
46 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
49 bool VisitFunctionDecl(FunctionDecl
const *);
50 bool VisitMemberExpr(MemberExpr
const *);
51 bool VisitUnaryOperator(UnaryOperator
const *);
54 bool RedundantPointerOps::VisitFunctionDecl(FunctionDecl
const * functionDecl
)
56 if (ignoreLocation(functionDecl
))
58 //functionDecl->dump();
62 bool RedundantPointerOps::VisitMemberExpr(MemberExpr
const * memberExpr
)
64 if (ignoreLocation(memberExpr
))
66 if (memberExpr
->getLocStart().isMacroID())
68 auto base
= memberExpr
->getBase()->IgnoreParenImpCasts();
69 //parentStmt(parentStmt(memberExpr))->dump();
70 if (memberExpr
->isArrow())
72 if (auto unaryOp
= dyn_cast
<UnaryOperator
>(base
))
74 if (unaryOp
->getOpcode() == UO_AddrOf
)
76 DiagnosticsEngine::Warning
, "'&' followed by '->', rather use '.'",
77 memberExpr
->getLocStart())
78 << memberExpr
->getSourceRange();
81 else if (auto operatorCallExpr
= dyn_cast
<CXXOperatorCallExpr
>(base
))
83 if (operatorCallExpr
->getOperator() == OO_Amp
)
85 DiagnosticsEngine::Warning
, "'&' followed by '->', rather use '.'",
86 memberExpr
->getLocStart())
87 << memberExpr
->getSourceRange();
93 // if (auto unaryOp = dyn_cast<UnaryOperator>(base))
95 // if (unaryOp->getOpcode() == UO_Deref)
97 // DiagnosticsEngine::Warning, "'*' followed by '.', rather use '->'",
98 // memberExpr->getLocStart())
99 // << memberExpr->getSourceRange();
106 bool RedundantPointerOps::VisitUnaryOperator(UnaryOperator
const * unaryOperator
)
108 if (ignoreLocation(unaryOperator
))
110 if (unaryOperator
->getLocStart().isMacroID())
112 if (unaryOperator
->getOpcode() != UO_Deref
)
114 auto innerOp
= dyn_cast
<UnaryOperator
>(unaryOperator
->getSubExpr()->IgnoreParenImpCasts());
115 if (!innerOp
|| innerOp
->getOpcode() != UO_AddrOf
)
119 DiagnosticsEngine::Warning
, "'&' followed by '*', rather use '.'",
120 unaryOperator
->getLocStart())
121 << unaryOperator
->getSourceRange();
125 loplugin::Plugin::Registration
< RedundantPointerOps
> X("redundantpointerops");
129 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */