From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- build/clang-plugin/MustOverrideChecker.cpp | 60 ++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 build/clang-plugin/MustOverrideChecker.cpp (limited to 'build/clang-plugin/MustOverrideChecker.cpp') diff --git a/build/clang-plugin/MustOverrideChecker.cpp b/build/clang-plugin/MustOverrideChecker.cpp new file mode 100644 index 0000000000..b19ae94aac --- /dev/null +++ b/build/clang-plugin/MustOverrideChecker.cpp @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MustOverrideChecker.h" +#include "CustomMatchers.h" + +void MustOverrideChecker::registerMatchers(MatchFinder *AstMatcher) { + AstMatcher->addMatcher(cxxRecordDecl(isDefinition()).bind("class"), this); +} + +void MustOverrideChecker::registerPPCallbacks(CompilerInstance &CI) { + this->CI = &CI; +} + +void MustOverrideChecker::check(const MatchFinder::MatchResult &Result) { + auto D = Result.Nodes.getNodeAs("class"); + + // Look through all of our immediate bases to find methods that need to be + // overridden + typedef std::vector OverridesVector; + OverridesVector MustOverrides; + for (const auto &Base : D->bases()) { + // The base is either a class (CXXRecordDecl) or it's a templated class... + CXXRecordDecl *Parent = Base.getType() + .getDesugaredType(D->getASTContext()) + ->getAsCXXRecordDecl(); + // The parent might not be resolved to a type yet. In this case, we can't + // do any checking here. For complete correctness, we should visit + // template instantiations, but this case is likely to be rare, so we will + // ignore it until it becomes important. + if (!Parent) { + continue; + } + Parent = Parent->getDefinition(); + for (const auto &M : Parent->methods()) { + if (hasCustomAttribute(M)) + MustOverrides.push_back(M); + } + } + + for (auto &O : MustOverrides) { + bool Overridden = false; + for (const auto &M : D->methods()) { + // The way that Clang checks if a method M overrides its parent method + // is if the method has the same name but would not overload. + if (getNameChecked(M) == getNameChecked(O) && + !CI->getSema().IsOverload(M, O, false)) { + Overridden = true; + break; + } + } + if (!Overridden) { + diag(D->getLocation(), "%0 must override %1", DiagnosticIDs::Error) + << D->getDeclName() << O->getDeclName(); + diag(O->getLocation(), "function to override is here", + DiagnosticIDs::Note); + } + } +} -- cgit v1.2.3