File indexing completed on 2024-05-12 05:40:59
0001 /* 0002 SPDX-FileCopyrightText: 2017 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "virtual-signal.h" 0008 #include "AccessSpecifierManager.h" 0009 #include "ClazyContext.h" 0010 #include "QtUtils.h" 0011 0012 #include <clang/AST/DeclCXX.h> 0013 #include <clang/Basic/LLVM.h> 0014 #include <llvm/Support/Casting.h> 0015 0016 namespace clang 0017 { 0018 class Decl; 0019 } // namespace clang 0020 0021 using namespace clang; 0022 0023 VirtualSignal::VirtualSignal(const std::string &name, ClazyContext *context) 0024 : CheckBase(name, context) 0025 { 0026 context->enableAccessSpecifierManager(); 0027 } 0028 0029 void VirtualSignal::VisitDecl(Decl *stmt) 0030 { 0031 auto *method = dyn_cast<CXXMethodDecl>(stmt); 0032 if (!method || !method->isVirtual()) { 0033 return; 0034 } 0035 0036 AccessSpecifierManager *accessSpecifierManager = m_context->accessSpecifierManager; 0037 if (!accessSpecifierManager) { 0038 return; 0039 } 0040 0041 QtAccessSpecifierType qst = accessSpecifierManager->qtAccessSpecifierType(method); 0042 if (qst == QtAccessSpecifier_Signal) { 0043 for (const auto *m : method->overridden_methods()) { 0044 if (const auto *baseClass = m->getParent()) { 0045 if (!clazy::isQObject(baseClass)) { 0046 // It's possible that the signal is overriding a method from a non-QObject base class 0047 // if the derived class inherits both QObject and some other interface. 0048 return; 0049 } 0050 } 0051 } 0052 0053 emitWarning(method, "signal is virtual"); 0054 } 0055 }