summaryrefslogtreecommitdiffstats
path: root/compilerplugins/clang/unnecessaryvirtual.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'compilerplugins/clang/unnecessaryvirtual.cxx')
-rw-r--r--compilerplugins/clang/unnecessaryvirtual.cxx21
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;