bump product version to 6.4.0.3
[LibreOffice.git] / compilerplugins / clang / simplifydynamiccast.cxx
blobb1f06179ee718e1fbaf0f4532ffc81cedf3b6dab
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <cassert>
11 #include <string>
12 #include <iostream>
13 #include <fstream>
14 #include <set>
16 #include <clang/AST/CXXInheritance.h>
17 #include "compat.hxx"
18 #include "plugin.hxx"
20 namespace
22 class SimplifyDynamicCast : public loplugin::FilteringPlugin<SimplifyDynamicCast>
24 public:
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"))
34 // return;
36 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
39 bool TraverseIfStmt(IfStmt*);
40 bool VisitCXXStaticCastExpr(CXXStaticCastExpr const*);
42 private:
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);
52 if (!dynamicCastExpr)
54 if (auto binaryOp = dyn_cast<BinaryOperator>(condExpr))
56 if (binaryOp->getOpcode() == BO_NE)
57 dynamicCastExpr
58 = dyn_cast<CXXDynamicCastExpr>(binaryOp->getLHS()->IgnoreParenImpCasts());
61 Decl const* subExprDecl = nullptr;
62 if (dynamicCastExpr)
64 auto subExprDeclRefExpr
65 = dyn_cast<DeclRefExpr>(dynamicCastExpr->getSubExpr()->IgnoreParenImpCasts());
66 if (!subExprDeclRefExpr)
67 dynamicCastExpr = nullptr;
68 else
69 subExprDecl = subExprDeclRefExpr->getDecl();
71 if (dynamicCastExpr)
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);
79 if (dynamicCastExpr)
81 dynamicCastVec.pop_back();
82 dynamicCastSubExprVec.pop_back();
83 ifVec.pop_back();
85 return ret;
88 bool SimplifyDynamicCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const* staticCastExpr)
90 if (ignoreLocation(staticCastExpr))
91 return true;
92 if (dynamicCastVec.empty())
93 return true;
95 auto qt = staticCastExpr->getTypeAsWritten();
96 auto it = std::find(dynamicCastVec.begin(), dynamicCastVec.end(), qt);
97 if (it == dynamicCastVec.end())
98 return true;
99 int idx = it - dynamicCastVec.begin();
100 auto subExprDecl = dyn_cast<DeclRefExpr>(staticCastExpr->getSubExpr()->IgnoreParenImpCasts());
101 if (!subExprDecl)
102 return true;
103 if (dynamicCastSubExprVec[idx] != subExprDecl->getDecl())
104 return true;
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();
111 return true;
114 loplugin::Plugin::Registration<SimplifyDynamicCast> X("simplifydynamiccast", true);
117 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */