File indexing completed on 2024-05-12 05:40:56
0001 /* 0002 SPDX-FileCopyrightText: 2019 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "overloaded-signal.h" 0008 #include "AccessSpecifierManager.h" 0009 #include "FunctionUtils.h" 0010 #include "QtUtils.h" 0011 #include "TypeUtils.h" 0012 #include "Utils.h" 0013 0014 #include <ClazyContext.h> 0015 #include <clang/AST/AST.h> 0016 0017 using namespace clang; 0018 0019 OverloadedSignal::OverloadedSignal(const std::string &name, ClazyContext *context) 0020 : CheckBase(name, context) 0021 { 0022 context->enableAccessSpecifierManager(); 0023 } 0024 0025 void OverloadedSignal::VisitDecl(clang::Decl *decl) 0026 { 0027 AccessSpecifierManager *accessSpecifierManager = m_context->accessSpecifierManager; 0028 auto *method = dyn_cast<CXXMethodDecl>(decl); 0029 if (!accessSpecifierManager || !method) { 0030 return; 0031 } 0032 0033 if (method->isThisDeclarationADefinition() && !method->hasInlineBody()) { 0034 return; 0035 } 0036 0037 CXXRecordDecl *record = method->getParent(); 0038 0039 const bool methodIsSignal = accessSpecifierManager->qtAccessSpecifierType(method) == QtAccessSpecifier_Signal; 0040 if (!methodIsSignal) { 0041 return; 0042 } 0043 0044 const StringRef methodName = clazy::name(method); 0045 CXXRecordDecl *p = record; // baseClass starts at record so we check overloaded methods there 0046 while (p) { 0047 for (auto *m : p->methods()) { 0048 if (clazy::name(m) == methodName) { 0049 if (!clazy::parametersMatch(m, method)) { 0050 if (p == record) { 0051 emitWarning(decl, "signal " + methodName.str() + " is overloaded"); 0052 continue; // No point in spitting more warnings for the same signal 0053 } 0054 emitWarning(decl, "signal " + methodName.str() + " is overloaded (with " + p->getBeginLoc().printToString(sm()) + ")"); 0055 } 0056 } 0057 } 0058 0059 p = clazy::getQObjectBaseClass(p); 0060 } 0061 }