File indexing completed on 2024-05-19 05:41:39
0001 /* 0002 SPDX-FileCopyrightText: 2017 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "install-event-filter.h" 0008 #include "HierarchyUtils.h" 0009 #include "TypeUtils.h" 0010 #include "Utils.h" 0011 0012 #include <clang/AST/Decl.h> 0013 #include <clang/AST/DeclCXX.h> 0014 #include <clang/AST/Expr.h> 0015 #include <clang/AST/ExprCXX.h> 0016 #include <clang/AST/Stmt.h> 0017 #include <clang/Basic/LLVM.h> 0018 #include <llvm/Support/Casting.h> 0019 0020 class ClazyContext; 0021 0022 using namespace clang; 0023 0024 InstallEventFilter::InstallEventFilter(const std::string &name, ClazyContext *context) 0025 : CheckBase(name, context, Option_CanIgnoreIncludes) 0026 { 0027 } 0028 0029 void InstallEventFilter::VisitStmt(clang::Stmt *stmt) 0030 { 0031 auto *memberCallExpr = dyn_cast<CXXMemberCallExpr>(stmt); 0032 if (!memberCallExpr || memberCallExpr->getNumArgs() != 1) { 0033 return; 0034 } 0035 0036 FunctionDecl *func = memberCallExpr->getDirectCallee(); 0037 if (!func || func->getQualifiedNameAsString() != "QObject::installEventFilter") { 0038 return; 0039 } 0040 0041 Expr *expr = memberCallExpr->getImplicitObjectArgument(); 0042 if (!expr) { 0043 return; 0044 } 0045 0046 if (!isa<CXXThisExpr>(clazy::getFirstChildAtDepth(expr, 1))) { 0047 return; 0048 } 0049 0050 Expr *arg1 = memberCallExpr->getArg(0); 0051 arg1 = arg1 ? arg1->IgnoreCasts() : nullptr; 0052 0053 CXXRecordDecl *record = clazy::typeAsRecord(arg1); 0054 auto methods = Utils::methodsFromString(record, "eventFilter"); 0055 0056 for (auto *method : methods) { 0057 if (method->getQualifiedNameAsString() != "QObject::eventFilter") { // It overrides it, probably on purpose then, don't warn. 0058 return; 0059 } 0060 } 0061 0062 emitWarning(stmt, "'this' should usually be the filter object, not the monitored one."); 0063 }