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>
22 class SimplifyDynamicCast
: public loplugin::FilteringPlugin
<SimplifyDynamicCast
>
25 explicit SimplifyDynamicCast(loplugin::InstantiationData
const& data
)
26 : FilteringPlugin(data
)
30 virtual void run() override
32 // StringRef fn(handler.getMainFileName());
33 // if (loplugin::isSamePathname(fn, WORKDIR "/YaccTarget/unoidl/source/sourceprovider-parser.cxx"))
36 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
39 bool TraverseIfStmt(IfStmt
*);
40 bool VisitCXXStaticCastExpr(CXXStaticCastExpr
const*);
43 std::vector
<QualType
> dynamicCastVec
;
44 std::vector
<Decl
const*> dynamicCastSubExprVec
;
45 std::vector
<IfStmt
const*> ifVec
;
48 bool SimplifyDynamicCast::TraverseIfStmt(IfStmt
* ifStmt
)
50 auto condExpr
= ifStmt
->getCond()->IgnoreParenImpCasts();
51 auto dynamicCastExpr
= dyn_cast
<CXXDynamicCastExpr
>(condExpr
);
54 if (auto binaryOp
= dyn_cast
<BinaryOperator
>(condExpr
))
56 if (binaryOp
->getOpcode() == BO_NE
)
58 = dyn_cast
<CXXDynamicCastExpr
>(binaryOp
->getLHS()->IgnoreParenImpCasts());
61 Decl
const* subExprDecl
= nullptr;
64 auto subExprDeclRefExpr
65 = dyn_cast
<DeclRefExpr
>(dynamicCastExpr
->getSubExpr()->IgnoreParenImpCasts());
66 if (!subExprDeclRefExpr
)
67 dynamicCastExpr
= nullptr;
69 subExprDecl
= subExprDeclRefExpr
->getDecl();
73 auto qt
= dynamicCastExpr
->getTypeAsWritten();
74 dynamicCastVec
.push_back(qt
);
75 dynamicCastSubExprVec
.push_back(subExprDecl
);
76 ifVec
.push_back(ifStmt
);
78 bool ret
= RecursiveASTVisitor::TraverseIfStmt(ifStmt
);
81 dynamicCastVec
.pop_back();
82 dynamicCastSubExprVec
.pop_back();
88 bool SimplifyDynamicCast::VisitCXXStaticCastExpr(CXXStaticCastExpr
const* staticCastExpr
)
90 if (ignoreLocation(staticCastExpr
))
92 if (dynamicCastVec
.empty())
95 auto qt
= staticCastExpr
->getTypeAsWritten();
96 auto it
= std::find(dynamicCastVec
.begin(), dynamicCastVec
.end(), qt
);
97 if (it
== dynamicCastVec
.end())
99 int idx
= it
- dynamicCastVec
.begin();
100 auto subExprDecl
= dyn_cast
<DeclRefExpr
>(staticCastExpr
->getSubExpr()->IgnoreParenImpCasts());
103 if (dynamicCastSubExprVec
[idx
] != subExprDecl
->getDecl())
105 report(DiagnosticsEngine::Warning
, "simplify, use var in if",
106 compat::getBeginLoc(staticCastExpr
))
107 << staticCastExpr
->getSourceRange();
108 auto ifStmt
= ifVec
[idx
];
109 report(DiagnosticsEngine::Note
, "if here", compat::getBeginLoc(ifStmt
))
110 << ifStmt
->getSourceRange();
114 loplugin::Plugin::Registration
<SimplifyDynamicCast
> X("simplifydynamiccast", true);
117 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */