[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