diff options
Diffstat (limited to 'compilerplugins/clang/unnecessaryvirtual.cxx')
-rw-r--r-- | compilerplugins/clang/unnecessaryvirtual.cxx | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/compilerplugins/clang/unnecessaryvirtual.cxx b/compilerplugins/clang/unnecessaryvirtual.cxx index 9f3a3eecf444..b376f97c9b07 100644 --- a/compilerplugins/clang/unnecessaryvirtual.cxx +++ b/compilerplugins/clang/unnecessaryvirtual.cxx @@ -12,6 +12,8 @@ #include <iostream> #include <set> #include <unordered_set> +#include "config_clang.h" +#include "compat.hxx" #include "plugin.hxx" #include <fstream> @@ -61,6 +63,8 @@ public: virtual void run() override { + handler.enableTreeWideAnalysisMode(); + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); // dump all our output in one write call - this is to try and limit IO "crosstalk" between multiple processes @@ -107,9 +111,6 @@ std::string niceName(const CXXMethodDecl* cxxMethodDecl) bool UnnecessaryVirtual::VisitCXXMethodDecl( const CXXMethodDecl* methodDecl ) { - if (ignoreLocation(methodDecl)) { - return true; - } if (!methodDecl->isVirtual() || methodDecl->isDeleted()) { return true; } @@ -131,6 +132,8 @@ bool UnnecessaryVirtual::VisitCXXMethodDecl( const CXXMethodDecl* methodDecl ) return true; methodDecl = methodDecl->getCanonicalDecl(); + if (!methodDecl) + return true; std::string aNiceName = niceName(methodDecl); // for destructors, we need to check if any of the superclass' destructors are virtual @@ -146,8 +149,11 @@ bool UnnecessaryVirtual::VisitCXXMethodDecl( const CXXMethodDecl* methodDecl ) if (baseSpecifier->getType()->isRecordType()) { const CXXRecordDecl* superclassCXXRecordDecl = baseSpecifier->getType()->getAsCXXRecordDecl(); - std::string aOverriddenNiceName = niceName(superclassCXXRecordDecl->getDestructor()); - overridingSet.insert(aOverriddenNiceName); + if (superclassCXXRecordDecl->getDestructor()) + { + std::string aOverriddenNiceName = niceName(superclassCXXRecordDecl->getDestructor()); + overridingSet.insert(aOverriddenNiceName); + } } } return true; @@ -161,7 +167,8 @@ bool UnnecessaryVirtual::VisitCXXMethodDecl( const CXXMethodDecl* methodDecl ) { const CXXMethodDecl *overriddenMethod = *iter; // we only care about the first level override to establish that a virtual qualifier was useful. - if (overriddenMethod->isPure() || overriddenMethod->size_overridden_methods() == 0) + if (compat::isPureVirtual(overriddenMethod) + || overriddenMethod->size_overridden_methods() == 0) { std::string aOverriddenNiceName = niceName(overriddenMethod); overridingSet.insert(aOverriddenNiceName); @@ -173,6 +180,8 @@ bool UnnecessaryVirtual::VisitCXXMethodDecl( const CXXMethodDecl* methodDecl ) void UnnecessaryVirtual::MarkRootOverridesNonEmpty( const CXXMethodDecl* methodDecl ) { + if (!methodDecl) + return; if (methodDecl->size_overridden_methods() == 0) { nonEmptySet.insert(niceName(methodDecl)); return; |