File indexing completed on 2024-05-19 05:41:39
0001 /* 0002 SPDX-FileCopyrightText: 2016 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "child-event-qobject-cast.h" 0008 #include "HierarchyUtils.h" 0009 #include "QtUtils.h" 0010 #include "StringUtils.h" 0011 #include "clazy_stl.h" 0012 0013 #include <clang/AST/Decl.h> 0014 #include <clang/AST/DeclBase.h> 0015 #include <clang/AST/DeclCXX.h> 0016 #include <clang/AST/Expr.h> 0017 #include <clang/AST/ExprCXX.h> 0018 #include <clang/AST/Stmt.h> 0019 #include <clang/Basic/LLVM.h> 0020 #include <llvm/ADT/StringRef.h> 0021 #include <llvm/Support/Casting.h> 0022 0023 #include <vector> 0024 0025 class ClazyContext; 0026 0027 using namespace clang; 0028 0029 ChildEventQObjectCast::ChildEventQObjectCast(const std::string &name, ClazyContext *context) 0030 : CheckBase(name, context, Option_CanIgnoreIncludes) 0031 { 0032 } 0033 0034 void ChildEventQObjectCast::VisitDecl(Decl *decl) 0035 { 0036 auto *childEventMethod = dyn_cast<CXXMethodDecl>(decl); 0037 if (!childEventMethod) { 0038 return; 0039 } 0040 0041 Stmt *body = decl->getBody(); 0042 if (!body) { 0043 return; 0044 } 0045 0046 auto methodName = childEventMethod->getNameAsString(); 0047 if (!clazy::equalsAny(methodName, {"event", "childEvent", "eventFilter"})) { 0048 return; 0049 } 0050 0051 if (!clazy::isQObject(childEventMethod->getParent())) { 0052 return; 0053 } 0054 0055 auto callExprs = clazy::getStatements<CallExpr>(body, &(sm())); 0056 for (auto *callExpr : callExprs) { 0057 if (callExpr->getNumArgs() != 1) { 0058 continue; 0059 } 0060 0061 FunctionDecl *fdecl = callExpr->getDirectCallee(); 0062 if (fdecl && clazy::name(fdecl) == "qobject_cast") { 0063 auto *childCall = dyn_cast<CXXMemberCallExpr>(callExpr->getArg(0)); 0064 // The call to event->child() 0065 if (!childCall) { 0066 continue; 0067 } 0068 0069 auto *childFDecl = childCall->getDirectCallee(); 0070 if (!childFDecl || childFDecl->getQualifiedNameAsString() != "QChildEvent::child") { 0071 continue; 0072 } 0073 0074 emitWarning(childCall, "qobject_cast in childEvent"); 0075 } 0076 } 0077 }