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