[Libreoffice-commits] core.git: compilerplugins/clang
Noel Grandin (via logerrit)
logerrit at kemper.freedesktop.org
Mon Oct 28 19:17:56 UTC 2019
compilerplugins/clang/finalclasses.cxx | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
New commits:
commit 4b91b7dfa75d710d6845fd98b491889ec80d9da8
Author: Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Mon Oct 28 18:21:37 2019 +0200
Commit: Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Mon Oct 28 20:17:02 2019 +0100
loplugin:finalclasses look for classes with virtual members
where making them final gives the compiler freedom to de-virtualise some
calls
Change-Id: I5755a41c42d9f23af58b873efae37a1d240fbd89
Reviewed-on: https://gerrit.libreoffice.org/81618
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
diff --git a/compilerplugins/clang/finalclasses.cxx b/compilerplugins/clang/finalclasses.cxx
index 24bc814602fe..e7704ca8fc0c 100644
--- a/compilerplugins/clang/finalclasses.cxx
+++ b/compilerplugins/clang/finalclasses.cxx
@@ -15,9 +15,14 @@
#include <fstream>
/**
-Look for classes that are final i.e. nothing extends them, and have protected fields or members.
+Look for classes that are final i.e. nothing extends them, and have either
+(a) protected fields or members.
+or
+(b) virtual members
-These can be made private.
+In the case of (a), those members/fields can be made private.
+In the case of (b), making the class final means the compiler can devirtualise
+some method class.
The process goes something like this:
$ make check
@@ -88,6 +93,8 @@ bool FinalClasses::VisitCXXRecordDecl(const CXXRecordDecl* decl)
decl = decl->getCanonicalDecl();
if (!decl->hasDefinition())
return true;
+ if (decl->hasAttr<FinalAttr>())
+ return true;
for (auto it = decl->bases_begin(); it != decl->bases_end(); ++it)
{
@@ -100,15 +107,16 @@ bool FinalClasses::VisitCXXRecordDecl(const CXXRecordDecl* decl)
checkBase(spec.getType());
}
+ bool bFoundVirtual = false;
bool bFoundProtected = false;
for (auto it = decl->method_begin(); it != decl->method_end(); ++it) {
auto i = *it;
// ignore methods that are overriding base-class methods, making them private
// isn't useful
- if ( !i->hasAttr<OverrideAttr>() && i->getAccess() == AS_protected ) {
+ if ( !i->hasAttr<OverrideAttr>() && i->getAccess() == AS_protected )
bFoundProtected = true;
- break;
- }
+ if ( i->isVirtual() )
+ bFoundVirtual = true;
}
if (!bFoundProtected)
{
@@ -120,7 +128,7 @@ bool FinalClasses::VisitCXXRecordDecl(const CXXRecordDecl* decl)
}
}
}
- if (!bFoundProtected)
+ if (!bFoundProtected && !bFoundVirtual)
return true;
std::string s = decl->getQualifiedNameAsString();
More information about the Libreoffice-commits
mailing list