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/.
9 #ifndef LO_CLANG_SHARED_PLUGINS
17 #include <clang/AST/CXXInheritance.h>
25 * which can be transformed to:
40 class RedundantPointerOps
:
41 public loplugin::FilteringPlugin
<RedundantPointerOps
>
44 explicit RedundantPointerOps(loplugin::InstantiationData
const & data
): FilteringPlugin(data
) {}
46 virtual void run() override
49 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
52 bool VisitFunctionDecl(FunctionDecl
const *);
53 bool VisitMemberExpr(MemberExpr
const *);
54 bool VisitUnaryOperator(UnaryOperator
const *);
57 bool RedundantPointerOps::VisitFunctionDecl(FunctionDecl
const * functionDecl
)
59 if (ignoreLocation(functionDecl
))
61 // if (functionDecl->getIdentifier() && functionDecl->getName() == "function6b")
62 // functionDecl->dump();
66 bool RedundantPointerOps::VisitMemberExpr(MemberExpr
const * memberExpr
)
68 if (ignoreLocation(memberExpr
))
70 if (memberExpr
->getBeginLoc().isMacroID())
72 auto base
= memberExpr
->getBase()->IgnoreParenImpCasts();
73 //parentStmt(parentStmt(memberExpr))->dump();
74 if (memberExpr
->isArrow())
76 if (auto unaryOp
= dyn_cast
<UnaryOperator
>(base
))
78 if (unaryOp
->getOpcode() == UO_AddrOf
)
80 DiagnosticsEngine::Warning
,
81 "'&' followed by '->' operating on %0, rather use '.'",
82 memberExpr
->getBeginLoc())
83 << memberExpr
->getBase()->getType()->getPointeeType()
84 << memberExpr
->getSourceRange();
87 else if (auto operatorCallExpr
= dyn_cast
<CXXOperatorCallExpr
>(base
))
89 if (operatorCallExpr
->getOperator() == OO_Amp
)
91 DiagnosticsEngine::Warning
,
92 "'&' followed by '->' operating on %0, rather use '.'",
93 memberExpr
->getBeginLoc())
94 << memberExpr
->getBase()->getType()->getPointeeType()
95 << memberExpr
->getSourceRange();
98 else if (auto cxxMemberCallExpr
= dyn_cast
<CXXMemberCallExpr
>(base
))
100 auto methodDecl
= cxxMemberCallExpr
->getMethodDecl();
101 if (methodDecl
->getIdentifier() && methodDecl
->getName() == "get")
103 auto const e
= cxxMemberCallExpr
->getImplicitObjectArgument();
104 if (loplugin::isSmartPointerType(e
))
106 DiagnosticsEngine::Warning
,
107 "'get()' followed by '->' operating on %0, just use '->'",
108 memberExpr
->getBeginLoc())
109 << e
->IgnoreImpCasts()->getType().getLocalUnqualifiedType()
110 << memberExpr
->getSourceRange();
116 // if (auto unaryOp = dyn_cast<UnaryOperator>(base))
118 // if (unaryOp->getOpcode() == UO_Deref)
120 // DiagnosticsEngine::Warning, "'*' followed by '.', rather use '->'",
121 // memberExpr->getLocStart())
122 // << memberExpr->getSourceRange();
129 bool RedundantPointerOps::VisitUnaryOperator(UnaryOperator
const * unaryOperator
)
131 if (ignoreLocation(unaryOperator
))
133 if (unaryOperator
->getBeginLoc().isMacroID())
135 if (unaryOperator
->getOpcode() != UO_Deref
)
137 auto subExpr
= unaryOperator
->getSubExpr()->IgnoreParenImpCasts();
138 auto innerOp
= dyn_cast
<UnaryOperator
>(subExpr
);
139 if (innerOp
&& innerOp
->getOpcode() == UO_AddrOf
)
141 DiagnosticsEngine::Warning
, "'&' followed by '*' operating on %0, rather use '.'",
142 unaryOperator
->getBeginLoc())
143 << innerOp
->getSubExpr()->getType() << unaryOperator
->getSourceRange();
144 if (auto cxxMemberCallExpr
= dyn_cast
<CXXMemberCallExpr
>(subExpr
))
146 auto methodDecl
= cxxMemberCallExpr
->getMethodDecl();
147 if (methodDecl
->getIdentifier() && methodDecl
->getName() == "get")
149 auto const e
= cxxMemberCallExpr
->getImplicitObjectArgument();
150 if (loplugin::isSmartPointerType(e
))
152 DiagnosticsEngine::Warning
,
153 "'*' followed by '.get()' operating on %0, just use '*'",
154 unaryOperator
->getBeginLoc())
155 << e
->IgnoreImpCasts()->getType().getLocalUnqualifiedType()
156 << unaryOperator
->getSourceRange();
162 loplugin::Plugin::Registration
< RedundantPointerOps
> redundantpointerops("redundantpointerops");
166 #endif // LO_CLANG_SHARED_PLUGINS
168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */