/** * Lookup candidates function of name \a methodName within the QObject derivative \a objClass * its bases, or its private implementation */ static llvm::SmallVector<clang::CXXMethodDecl *, 10> lookUpCandidates(const clang::CXXRecordDecl* objClass, llvm::StringRef methodName) { llvm::SmallVector<clang::CXXMethodDecl *, 10> candidates; clang::CXXMethodDecl *d_func = nullptr; auto classIt = objClass; while (classIt) { if (!classIt->getDefinition()) break; for (auto mi = classIt->method_begin(); mi != classIt->method_end(); ++mi) { if (!(*mi)->getIdentifier()) continue; if ((*mi)->getName() == methodName) candidates.push_back(*mi); if (!d_func && (*mi)->getName() == "d_func" && !getResultType(*mi).isNull()) d_func = *mi; } // Look in the first base (because the QObject need to be the first base class) classIt = classIt->getNumBases() == 0 ? nullptr : classIt->bases_begin()->getType()->getAsCXXRecordDecl(); if (d_func && !classIt && candidates.empty()) { classIt = getResultType(d_func)->getPointeeCXXRecordDecl(); d_func = nullptr; } } return candidates; }
virtual void run(const ast_matchers::MatchFinder::MatchResult &result) { auto decl = result.Nodes.getNodeAs<CXXRecordDecl>("inheritsQListIterator"); if (decl==nullptr) { return; } if (!decl->hasDefinition()) return; // this is needed so bases_begin doesn't crash auto it = decl->bases_begin(); for (; it && it != decl->bases_end(); ++it) { auto str = getText(*result.SourceManager,it->getLocStart(),it->getLocEnd()) ; if (! findNreplace(str,"QListIterator<(\\w+)>","std::list<$1*>::iterator") ) return; Replace->insert(Replacement(*result.SourceManager, it, str)); } }