File indexing completed on 2024-05-12 05:40:57
0001 /* 0002 SPDX-FileCopyrightText: 2016 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "qstring-insensitive-allocation.h" 0008 #include "StringUtils.h" 0009 #include "Utils.h" 0010 #include "clazy_stl.h" 0011 0012 #include <clang/AST/Expr.h> 0013 #include <clang/AST/Stmt.h> 0014 #include <clang/Basic/LLVM.h> 0015 #include <llvm/Support/Casting.h> 0016 0017 #include <vector> 0018 0019 using namespace clang; 0020 0021 QStringInsensitiveAllocation::QStringInsensitiveAllocation(const std::string &name, ClazyContext *context) 0022 : CheckBase(name, context, Option_CanIgnoreIncludes) 0023 { 0024 } 0025 0026 static bool isInterestingCall1(CallExpr *call) 0027 { 0028 FunctionDecl *func = call->getDirectCallee(); 0029 if (!func) { 0030 return false; 0031 } 0032 0033 static const std::vector<std::string> methods{"QString::toUpper", "QString::toLower"}; 0034 return clazy::contains(methods, clazy::qualifiedMethodName(func)); 0035 } 0036 0037 static bool isInterestingCall2(CallExpr *call) 0038 { 0039 FunctionDecl *func = call->getDirectCallee(); 0040 if (!func) { 0041 return false; 0042 } 0043 0044 static const std::vector<std::string> methods{"QString::endsWith", "QString::startsWith", "QString::contains", "QString::compare"}; 0045 return clazy::contains(methods, clazy::qualifiedMethodName(func)); 0046 } 0047 0048 void QStringInsensitiveAllocation::VisitStmt(clang::Stmt *stmt) 0049 { 0050 std::vector<CallExpr *> calls = Utils::callListForChain(dyn_cast<CallExpr>(stmt)); 0051 if (calls.size() < 2) { 0052 return; 0053 } 0054 0055 CallExpr *call1 = calls[calls.size() - 1]; 0056 CallExpr *call2 = calls[calls.size() - 2]; 0057 0058 if (!isInterestingCall1(call1) || !isInterestingCall2(call2)) { 0059 return; 0060 } 0061 0062 emitWarning(stmt->getBeginLoc(), "unneeded allocation"); 0063 }