File indexing completed on 2024-04-28 16:57:50
0001 /* 0002 This file is part of the clazy static checker. 0003 0004 Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com 0005 Author: Sérgio Martins <sergio.martins@kdab.com> 0006 0007 Copyright (C) 2015 Sergio Martins <smartins@kde.org> 0008 0009 This library is free software; you can redistribute it and/or 0010 modify it under the terms of the GNU Library General Public 0011 License as published by the Free Software Foundation; either 0012 version 2 of the License, or (at your option) any later version. 0013 0014 This library is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 Library General Public License for more details. 0018 0019 You should have received a copy of the GNU Library General Public License 0020 along with this library; see the file COPYING.LIB. If not, write to 0021 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0022 Boston, MA 02110-1301, USA. 0023 */ 0024 0025 #ifndef FUNCTION_UTILS_H 0026 #define FUNCTION_UTILS_H 0027 0028 // Contains utility functions regarding functions and methods 0029 0030 #include "Utils.h" 0031 #include "HierarchyUtils.h" 0032 #include "StringUtils.h" 0033 0034 #include <clang/AST/Decl.h> 0035 0036 #include <string> 0037 0038 namespace clazy { 0039 0040 inline bool hasCharPtrArgument(clang::FunctionDecl *func, int expected_arguments = -1) 0041 { 0042 if (expected_arguments != -1 && (int)func->param_size() != expected_arguments) 0043 return false; 0044 0045 for (auto param : Utils::functionParameters(func)) { 0046 clang::QualType qt = param->getType(); 0047 const clang::Type *t = qt.getTypePtrOrNull(); 0048 if (!t) 0049 continue; 0050 0051 const clang::Type *realT = t->getPointeeType().getTypePtrOrNull(); 0052 0053 if (!realT) 0054 continue; 0055 0056 if (realT->isCharType()) 0057 return true; 0058 } 0059 0060 return false; 0061 } 0062 0063 inline clang::ValueDecl *valueDeclForCallArgument(clang::CallExpr *call, unsigned int argIndex) 0064 { 0065 if (!call || call->getNumArgs() <= argIndex) 0066 return nullptr; 0067 0068 clang::Expr *firstArg = call->getArg(argIndex); 0069 auto declRef = llvm::isa<clang::DeclRefExpr>(firstArg) ? llvm::cast<clang::DeclRefExpr>(firstArg) 0070 : clazy::getFirstChildOfType2<clang::DeclRefExpr>(firstArg); 0071 if (!declRef) 0072 return nullptr; 0073 0074 return declRef->getDecl(); 0075 } 0076 0077 inline bool parametersMatch(const clang::FunctionDecl *f1, const clang::FunctionDecl *f2) 0078 { 0079 if (!f1 || !f2) 0080 return false; 0081 0082 auto params1 = f1->parameters(); 0083 auto params2 = f2->parameters(); 0084 0085 if (params1.size() != params2.size()) 0086 return false; 0087 0088 for (int i = 0, e = params1.size(); i < e; ++i) { 0089 clang::ParmVarDecl *p1 = params1[i]; 0090 clang::ParmVarDecl *p2 = params2[i]; 0091 0092 if (p1->getType() != p2->getType()) 0093 return false; 0094 } 0095 0096 return true; 0097 } 0098 0099 /** 0100 * Returns true if a class contains a method with a specific signature. 0101 * (method->getParent() doesn't need to equal record) 0102 */ 0103 inline bool classImplementsMethod(const clang::CXXRecordDecl *record, const clang::CXXMethodDecl *method) 0104 { 0105 if (!method->getDeclName().isIdentifier()) 0106 return false; 0107 0108 llvm::StringRef methodName = clazy::name(method); 0109 for (auto m : record->methods()) { 0110 if (!m->isPure() && clazy::name(m) == methodName && parametersMatch(m, method)) 0111 return true; 0112 } 0113 0114 return false; 0115 } 0116 0117 } 0118 #endif