File indexing completed on 2024-04-21 05:38:47
0001 /* 0002 SPDX-FileCopyrightText: 2015 Klarälvdalens Datakonsult AB a KDAB Group company info@kdab.com 0003 SPDX-FileContributor: Sérgio Martins <sergio.martins@kdab.com> 0004 0005 SPDX-FileCopyrightText: 2015 Sergio Martins <smartins@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #ifndef FUNCTION_UTILS_H 0011 #define FUNCTION_UTILS_H 0012 0013 // Contains utility functions regarding functions and methods 0014 0015 #include "HierarchyUtils.h" 0016 #include "StringUtils.h" 0017 #include "Utils.h" 0018 0019 #include <clang/AST/Decl.h> 0020 0021 namespace clazy 0022 { 0023 inline clang::ValueDecl *valueDeclForCallArgument(clang::CallExpr *call, unsigned int argIndex) 0024 { 0025 if (!call || call->getNumArgs() <= argIndex) { 0026 return nullptr; 0027 } 0028 0029 clang::Expr *firstArg = call->getArg(argIndex); 0030 auto *declRef = 0031 llvm::isa<clang::DeclRefExpr>(firstArg) ? llvm::cast<clang::DeclRefExpr>(firstArg) : clazy::getFirstChildOfType2<clang::DeclRefExpr>(firstArg); 0032 if (!declRef) { 0033 return nullptr; 0034 } 0035 0036 return declRef->getDecl(); 0037 } 0038 0039 inline bool parametersMatch(const clang::FunctionDecl *f1, const clang::FunctionDecl *f2) 0040 { 0041 if (!f1 || !f2) { 0042 return false; 0043 } 0044 0045 auto params1 = f1->parameters(); 0046 auto params2 = f2->parameters(); 0047 0048 if (params1.size() != params2.size()) { 0049 return false; 0050 } 0051 0052 for (int i = 0, e = params1.size(); i < e; ++i) { 0053 clang::ParmVarDecl *p1 = params1[i]; 0054 clang::ParmVarDecl *p2 = params2[i]; 0055 0056 if (p1->getType() != p2->getType()) { 0057 return false; 0058 } 0059 } 0060 0061 return true; 0062 } 0063 0064 /** 0065 * Returns true if a class contains a method with a specific signature. 0066 * (method->getParent() doesn't need to equal record) 0067 */ 0068 inline bool classImplementsMethod(const clang::CXXRecordDecl *record, const clang::CXXMethodDecl *method) 0069 { 0070 if (!method->getDeclName().isIdentifier()) { 0071 return false; 0072 } 0073 0074 llvm::StringRef methodName = clazy::name(method); 0075 for (auto *m : record->methods()) { 0076 #if LLVM_VERSION_MAJOR >= 18 0077 if (!m->isPureVirtual() && clazy::name(m) == methodName && parametersMatch(m, method)) { 0078 #else 0079 if (!m->isPure() && clazy::name(m) == methodName && parametersMatch(m, method)) { 0080 #endif 0081 return true; 0082 } 0083 } 0084 0085 return false; 0086 } 0087 0088 } 0089 #endif