Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / compilerplugins / clang / simplifydynamiccast.cxx
blob3b94f284de1eed06247091dd722718fad8ea5e76
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 "plugin.hxx"
19 namespace
21 class SimplifyDynamicCast : public loplugin::FilteringPlugin<SimplifyDynamicCast>
23 public:
24 explicit SimplifyDynamicCast(loplugin::InstantiationData const& data)
25 : FilteringPlugin(data)
29 virtual void run() override
31 // StringRef fn(handler.getMainFileName());
32 // if (loplugin::isSamePathname(fn, WORKDIR "/YaccTarget/unoidl/source/sourceprovider-parser.cxx"))
33 // return;
35 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
38 bool TraverseIfStmt(IfStmt*);
39 bool VisitCXXStaticCastExpr(CXXStaticCastExpr const*);
41 private:
42 std::vector<QualType> dynamicCastVec;
43 std::vector<Decl const*> dynamicCastSubExprVec;
44 std::vector<IfStmt const*> ifVec;
47 bool SimplifyDynamicCast::TraverseIfStmt(IfStmt* ifStmt)
49 CXXDynamicCastExpr const* dynamicCastExpr = nullptr;
50 if (Expr const* condExpr = ifStmt->getCond())
52 condExpr = condExpr->IgnoreParenImpCasts();
53 dynamicCastExpr = dyn_cast<CXXDynamicCastExpr>(condExpr);
54 if (!dynamicCastExpr)
56 if (auto binaryOp = dyn_cast<BinaryOperator>(condExpr))
58 if (binaryOp->getOpcode() == BO_NE)
59 dynamicCastExpr
60 = dyn_cast<CXXDynamicCastExpr>(binaryOp->getLHS()->IgnoreParenImpCasts());
64 Decl const* subExprDecl = nullptr;
65 if (dynamicCastExpr)
67 auto subExprDeclRefExpr
68 = dyn_cast<DeclRefExpr>(dynamicCastExpr->getSubExpr()->IgnoreParenImpCasts());
69 if (!subExprDeclRefExpr)
70 dynamicCastExpr = nullptr;
71 else
72 subExprDecl = subExprDeclRefExpr->getDecl();
74 if (dynamicCastExpr)
76 auto qt = dynamicCastExpr->getTypeAsWritten();
77 dynamicCastVec.push_back(qt);
78 dynamicCastSubExprVec.push_back(subExprDecl);
79 ifVec.push_back(ifStmt);
81 bool ret = RecursiveASTVisitor::TraverseIfStmt(ifStmt);
82 if (dynamicCastExpr)
84 dynamicCastVec.pop_back();
85 dynamicCastSubExprVec.pop_back();
86 ifVec.pop_back();
88 return ret;
91 bool SimplifyDynamicCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const* staticCastExpr)
93 if (ignoreLocation(staticCastExpr))
94 return true;
95 if (dynamicCastVec.empty())
96 return true;
98 auto qt = staticCastExpr->getTypeAsWritten();
99 auto it = std::find(dynamicCastVec.begin(), dynamicCastVec.end(), qt);
100 if (it == dynamicCastVec.end())
101 return true;
102 int idx = it - dynamicCastVec.begin();
103 auto subExprDecl = dyn_cast<DeclRefExpr>(staticCastExpr->getSubExpr()->IgnoreParenImpCasts());
104 if (!subExprDecl)
105 return true;
106 if (dynamicCastSubExprVec[idx] != subExprDecl->getDecl())
107 return true;
108 report(DiagnosticsEngine::Warning, "simplify, use var in if", staticCastExpr->getBeginLoc())
109 << staticCastExpr->getSourceRange();
110 auto ifStmt = ifVec[idx];
111 report(DiagnosticsEngine::Note, "if here", ifStmt->getBeginLoc()) << ifStmt->getSourceRange();
112 return true;
115 loplugin::Plugin::Registration<SimplifyDynamicCast> X("simplifydynamiccast", true);
118 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */