[Libreoffice-commits] core.git: compilerplugins/clang

Noel Grandin noel.grandin at collabora.co.uk
Wed Feb 1 12:50:17 UTC 2017


 compilerplugins/clang/check.hxx                     |    2 +
 compilerplugins/clang/cppunitassertequals.cxx       |    5 ++-
 compilerplugins/clang/rendercontext.cxx             |    9 ++----
 compilerplugins/clang/sallogareas.cxx               |    8 ++---
 compilerplugins/clang/sfxpoolitem.cxx               |   15 +++++------
 compilerplugins/clang/staticmethods.cxx             |    2 -
 compilerplugins/clang/store/changefunctioncalls.cxx |    6 ++--
 compilerplugins/clang/stringconcat.cxx              |    6 ++--
 compilerplugins/clang/stringconstant.cxx            |    3 --
 compilerplugins/clang/unusedvariablecheck.cxx       |   27 +++++++++++---------
 compilerplugins/clang/weakobject.cxx                |   22 ++++++++--------
 11 files changed, 58 insertions(+), 47 deletions(-)

New commits:
commit 994e38e336beeacbd983faafac480afc94d3947e
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Thu Jan 26 15:36:47 2017 +0200

    loplugin: use TypeCheck instead of getQualifiedNameAsString
    
    since the latter is rather slow
    
    Change-Id: Ib73cdb923585580777c2265b561c1808e93b2baa
    Reviewed-on: https://gerrit.libreoffice.org/33585
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/compilerplugins/clang/check.hxx b/compilerplugins/clang/check.hxx
index 40f205d..8c3edf7 100644
--- a/compilerplugins/clang/check.hxx
+++ b/compilerplugins/clang/check.hxx
@@ -33,6 +33,8 @@ class TypeCheck {
 public:
     explicit TypeCheck(clang::QualType type): type_(type) {}
 
+    explicit TypeCheck(clang::TypeDecl const * decl): type_(decl->getTypeForDecl(), 0) {}
+
     explicit operator bool() const { return !type_.isNull(); }
 
     TypeCheck NonConstVolatile() const;
diff --git a/compilerplugins/clang/cppunitassertequals.cxx b/compilerplugins/clang/cppunitassertequals.cxx
index f14dde63..e9f4c02 100644
--- a/compilerplugins/clang/cppunitassertequals.cxx
+++ b/compilerplugins/clang/cppunitassertequals.cxx
@@ -13,6 +13,7 @@
 #include <fstream>
 #include <set>
 #include "plugin.hxx"
+#include "check.hxx"
 
 /**
   Check for calls to CPPUNIT_ASSERT when it should be using CPPUNIT_ASSERT_EQUALS
@@ -87,7 +88,9 @@ void CppunitAssertEquals::checkExpr(const Stmt* stmt)
         return;
     }
     const FunctionDecl* functionDecl = callExpr->getDirectCallee()->getCanonicalDecl();
-    if (!functionDecl || functionDecl->getQualifiedNameAsString().find("Asserter::failIf") == std::string::npos) {
+    if (!functionDecl ||
+        !loplugin::DeclCheck(functionDecl).Function("failIf").Namespace("Asserter").Namespace("CppUnit").GlobalNamespace())
+    {
         return;
     }
     report(
diff --git a/compilerplugins/clang/rendercontext.cxx b/compilerplugins/clang/rendercontext.cxx
index e3d1da4..2ea4a0c 100644
--- a/compilerplugins/clang/rendercontext.cxx
+++ b/compilerplugins/clang/rendercontext.cxx
@@ -11,6 +11,7 @@
 #include <iostream>
 
 #include "plugin.hxx"
+#include "check.hxx"
 #include "clang/AST/CXXInheritance.h"
 
 // Check for calls to OutputDevice methods that are not passing through RenderContext
@@ -51,15 +52,13 @@ bool RenderContext::TraverseFunctionDecl(const FunctionDecl * pFunctionDecl)
     // Ignore methods inside the OutputDevice class
     const CXXMethodDecl *pCXXMethodDecl = dyn_cast<CXXMethodDecl>(pFunctionDecl);
     if (pCXXMethodDecl) {
-        std::string aParentName = pCXXMethodDecl->getParent()->getQualifiedNameAsString();
-        if (aParentName == "OutputDevice")
+        if (loplugin::TypeCheck(pCXXMethodDecl->getParent()).Class("OutputDevice").GlobalNamespace())
             return true;
     }
     // we are only currently interested in methods where the first parameter is RenderContext
     if (pFunctionDecl->getNumParams() == 0)
         return true;
-    string arg0 = pFunctionDecl->getParamDecl( 0 )->getType().getAsString();
-    if ( arg0.find("RenderContext") != std::string::npos ) {
+    if ( loplugin::TypeCheck(pFunctionDecl->getParamDecl( 0 )->getType()).Class("RenderContext").GlobalNamespace() ) {
         return true;
     }
     mbChecking = true;
@@ -76,7 +75,7 @@ bool RenderContext::VisitCXXMemberCallExpr(const CXXMemberCallExpr* pCXXMemberCa
         return true;
     }
     const CXXRecordDecl *pCXXRecordDecl = pCXXMemberCallExpr->getRecordDecl();
-    if (pCXXRecordDecl->getQualifiedNameAsString() != "OutputDevice") {
+    if (!loplugin::TypeCheck(pCXXRecordDecl).Class("OutputDevice").GlobalNamespace()) {
         return true;
     }
     // ignore a handful of methods. They will most probably still be present in Window for use during processing outside of the Paint()
diff --git a/compilerplugins/clang/sallogareas.cxx b/compilerplugins/clang/sallogareas.cxx
index d549187..e0ccf0b 100644
--- a/compilerplugins/clang/sallogareas.cxx
+++ b/compilerplugins/clang/sallogareas.cxx
@@ -10,6 +10,7 @@
  */
 
 #include "sallogareas.hxx"
+#include "check.hxx"
 
 #include <clang/Lex/Lexer.h>
 
@@ -50,12 +51,11 @@ bool SalLogAreas::VisitCallExpr( const CallExpr* call )
         return true;
     if( const FunctionDecl* func = call->getDirectCallee())
         {
-        // Optimize, getQualifiedNameAsString() is reportedly expensive.
         if( func->getNumParams() == 4 && func->getIdentifier() != NULL
             && ( func->getName() == "sal_detail_log" || func->getName() == "log" ))
             {
-            string qualifiedName = func->getQualifiedNameAsString();
-            if( qualifiedName == "sal_detail_log" || qualifiedName == "sal::detail::log" )
+            auto tc = loplugin::DeclCheck(func);
+            if( tc.Function("sal_detail_log") || tc.Function("log").Namespace("detail").Namespace("sal").GlobalNamespace() )
                 {
                 // The SAL_DETAIL_LOG_STREAM macro expands to two calls to sal::detail::log(),
                 // so do not warn repeatedly about the same macro (the area->getLocStart() of all the calls
@@ -73,7 +73,7 @@ bool SalLogAreas::VisitCallExpr( const CallExpr* call )
                             area->getLocStart());
                     return true;
                     }
-                if( inFunction->getQualifiedNameAsString() == "sal::detail::log" )
+                if( loplugin::DeclCheck(inFunction).Function("log").Namespace("detail").Namespace("sal").GlobalNamespace() )
                     return true; // This function only forwards to sal_detail_log, so ok.
                 if( call->getArg( 1 )->isNullPointerConstant( compiler.getASTContext(),
                     Expr::NPC_ValueDependentIsNotNull ) != Expr::NPCK_NotNull )
diff --git a/compilerplugins/clang/sfxpoolitem.cxx b/compilerplugins/clang/sfxpoolitem.cxx
index f01adf5..b182517 100644
--- a/compilerplugins/clang/sfxpoolitem.cxx
+++ b/compilerplugins/clang/sfxpoolitem.cxx
@@ -12,6 +12,7 @@
 
 #include "plugin.hxx"
 #include "compat.hxx"
+#include "check.hxx"
 #include "clang/AST/CXXInheritance.h"
 
 /*
@@ -39,7 +40,7 @@ bool BaseCheckNotSfxPoolItemSubclass(
 #endif
     )
 {
-    if (BaseDefinition && BaseDefinition->getQualifiedNameAsString() == "SfxPoolItem") {
+    if (BaseDefinition && loplugin::TypeCheck(BaseDefinition).Class("SfxPoolItem").GlobalNamespace()) {
         return false;
     }
     return true;
@@ -48,7 +49,7 @@ bool BaseCheckNotSfxPoolItemSubclass(
 bool isDerivedFromSfxPoolItem(const CXXRecordDecl *decl) {
     if (!decl)
         return false;
-    if (decl->getQualifiedNameAsString() == "SfxPoolItem")
+    if (loplugin::TypeCheck(decl).Class("SfxPoolItem").GlobalNamespace())
         return true;
     if (!decl->hasDefinition()) {
         return false;
@@ -70,7 +71,7 @@ bool BaseCheckNotSwMsgPoolItemSubclass(
 #endif
     )
 {
-    if (BaseDefinition && BaseDefinition->getQualifiedNameAsString() == "SwMsgPoolItem") {
+    if (BaseDefinition && loplugin::TypeCheck(BaseDefinition).Class("SwMsgPoolItem")) {
         return false;
     }
     return true;
@@ -79,7 +80,7 @@ bool BaseCheckNotSwMsgPoolItemSubclass(
 bool isDerivedFromSwMsgPoolItem(const CXXRecordDecl *decl) {
     if (!decl)
         return false;
-    if (decl->getQualifiedNameAsString() == "SwMsgPoolItem")
+    if (loplugin::TypeCheck(decl).Class("SwMsgPoolItem").GlobalNamespace())
         return true;
     if (!decl->hasDefinition()) {
         return false;
@@ -118,12 +119,12 @@ bool SfxPoolItem::VisitCXXRecordDecl(const CXXRecordDecl* decl)
         return true;
     }
     // the enum types do some weird stuff involving SfxEnumItemInterface
-    std::string sRecordName = decl->getQualifiedNameAsString();
-    if (sRecordName == "SfxEnumItem" || sRecordName == "SfxAllEnumItem")
+    auto tc = loplugin::TypeCheck(decl);
+    if (tc.Class("SfxEnumItem").GlobalNamespace() || tc.Class("SfxAllEnumItem").GlobalNamespace())
         return true;
 
     // the new field is only used for reading and writing to storage
-    if (sRecordName == "SvxCharSetColorItem")
+    if (tc.Class("SvxCharSetColorItem").GlobalNamespace())
         return true;
 
     for (auto it = decl->method_begin(); it != decl->method_end(); ++it) {
diff --git a/compilerplugins/clang/staticmethods.cxx b/compilerplugins/clang/staticmethods.cxx
index 588e534..f33f10f 100644
--- a/compilerplugins/clang/staticmethods.cxx
+++ b/compilerplugins/clang/staticmethods.cxx
@@ -46,7 +46,7 @@ bool BaseCheckNotTestFixtureSubclass(
 #endif
     )
 {
-    if (BaseDefinition->getQualifiedNameAsString().compare("CppUnit::TestFixture") == 0) {
+    if (loplugin::TypeCheck(BaseDefinition).Class("TestFixture").Namespace("CppUnit").GlobalNamespace()) {
         return false;
     }
     return true;
diff --git a/compilerplugins/clang/store/changefunctioncalls.cxx b/compilerplugins/clang/store/changefunctioncalls.cxx
index abc8ce6..a728ad5 100644
--- a/compilerplugins/clang/store/changefunctioncalls.cxx
+++ b/compilerplugins/clang/store/changefunctioncalls.cxx
@@ -27,6 +27,7 @@ This can be easily adjusted for different modifications to a function:
 */
 
 #include "plugin.hxx"
+#include "check.hxx"
 
 namespace loplugin
 {
@@ -61,15 +62,14 @@ bool ChangeFunctionCalls::VisitCallExpr( const CallExpr* call )
     //    if( const FunctionDecl* func = dyn_cast_or_null< FunctionDecl >( call->getCalleeDecl()))
     if( const FunctionDecl* func = call->getDirectCallee())
         {
-        // Optimize, getQualifiedNameAsString() is reportedly expensive,
         // so first check fast details like number of arguments or the (unqualified)
         // name before checking the fully qualified name.
         // See FunctionDecl for all the API about the function.
         if( func->getNumParams() == 1 && func->getIdentifier() != NULL
             && ( func->getName() == "bar" ))
             {
-            string qualifiedName = func->getQualifiedNameAsString();
-            if( qualifiedName == "bar" )
+            auto qt = loplugin::DeclCheck(func);
+            if( qt.Function("bar").GlobalNamespace() )
                 {
                 // Further checks about arguments. Check mainly ParmVarDecl, VarDecl,
                 // ValueDecl and QualType for Clang API details.
diff --git a/compilerplugins/clang/stringconcat.cxx b/compilerplugins/clang/stringconcat.cxx
index a944f4f..670d892 100644
--- a/compilerplugins/clang/stringconcat.cxx
+++ b/compilerplugins/clang/stringconcat.cxx
@@ -8,6 +8,7 @@
  */
 
 #include "plugin.hxx"
+#include "check.hxx"
 
 namespace {
 
@@ -26,8 +27,9 @@ Expr const * stripCtor(Expr const * expr) {
     if (e3 == nullptr) {
         return expr;
     }
-    auto const n = e3->getConstructor()->getQualifiedNameAsString();
-    if (n != "rtl::OString::OString" && n != "rtl::OUString::OUString") {
+    auto qt = loplugin::DeclCheck(e3->getConstructor());
+    if (!qt.Function("OString").Class("OString").Namespace("rtl").GlobalNamespace() &&
+        !qt.Function("OUString").Class("OUString").Namespace("rtl").GlobalNamespace()) {
         return expr;
     }
     if (e3->getNumArgs() != 2) {
diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx
index 9ae672a..426f8bd 100644
--- a/compilerplugins/clang/stringconstant.cxx
+++ b/compilerplugins/clang/stringconstant.cxx
@@ -1626,8 +1626,7 @@ void StringConstant::handleOUStringCtor(
     if (e3 == nullptr) {
         return;
     }
-    if (e3->getConstructor()->getQualifiedNameAsString()
-         != "rtl::OUString::OUString")
+    if (!loplugin::DeclCheck(e3->getConstructor()).Function("OUString").Class("OUString").Namespace("rtl").GlobalNamespace())
     {
         return;
     }
diff --git a/compilerplugins/clang/unusedvariablecheck.cxx b/compilerplugins/clang/unusedvariablecheck.cxx
index db6a45e..50b41d5 100644
--- a/compilerplugins/clang/unusedvariablecheck.cxx
+++ b/compilerplugins/clang/unusedvariablecheck.cxx
@@ -17,6 +17,7 @@
 #if !HAVE_GCC_ATTRIBUTE_WARN_UNUSED_STL
 
 #include "compat.hxx"
+#include "check.hxx"
 #include "unusedvariablecheck.hxx"
 
 #include <clang/AST/Attr.h>
@@ -56,11 +57,11 @@ bool BaseCheckNotSomethingInterestingSubclass(
 #endif
     )
 {
-    if (BaseDefinition && BaseDefinition->getQualifiedNameAsString().compare("Dialog") == 0) {
-        return false;
-    }
-    if (BaseDefinition && BaseDefinition->getQualifiedNameAsString().compare("SfxPoolItem") == 0) {
-        return false;
+    if (BaseDefinition) {
+        auto tc = loplugin::TypeCheck(BaseDefinition);
+        if (tc.Class("Dialog").GlobalNamespace() || tc.Class("SfxPoolItem").GlobalNamespace()) {
+            return false;
+        }
     }
     return true;
 }
@@ -68,9 +69,10 @@ bool BaseCheckNotSomethingInterestingSubclass(
 bool isDerivedFromSomethingInteresting(const CXXRecordDecl *decl) {
     if (!decl)
         return false;
-    if (decl->getQualifiedNameAsString() == "Dialog")
+    auto tc = loplugin::TypeCheck(decl);
+    if (tc.Class("Dialog"))
         return true;
-    if (decl->getQualifiedNameAsString() == "SfxPoolItem")
+    if (tc.Class("SfxPoolItem"))
         return true;
     if (!decl->hasDefinition()) {
         return false;
@@ -113,11 +115,14 @@ bool UnusedVariableCheck::VisitVarDecl( const VarDecl* var )
             }
         if( !warn_unused )
             {
-            string n = type->getQualifiedNameAsString();
+            auto tc = loplugin::TypeCheck(type);
             // Check some common non-LO types.
-            if( n == "std::string" || n == "std::basic_string"
-                || n == "std::list" || n == "std::__debug::list"
-                || n == "std::vector" || n == "std::__debug::vector" )
+            if( tc.Class("string").Namespace("std").GlobalNamespace()
+                || tc.Class("basic_string").Namespace("std").GlobalNamespace()
+                || tc.Class("list").Namespace("std").GlobalNamespace()
+                || tc.Class("list").Namespace("__debug").Namespace("std").GlobalNamespace()
+                || tc.Class("vector").Namespace("std").GlobalNamespace()
+                || tc.Class("vector" ).Namespace("__debug").Namespace("std").GlobalNamespace())
                 warn_unused = true;
             if (!warn_unused && isDerivedFromSomethingInteresting(type))
                   warn_unused = true;
diff --git a/compilerplugins/clang/weakobject.cxx b/compilerplugins/clang/weakobject.cxx
index 7c36f93..9ccbb8a 100644
--- a/compilerplugins/clang/weakobject.cxx
+++ b/compilerplugins/clang/weakobject.cxx
@@ -117,8 +117,8 @@ public:
                     // Allow this convenient shortcut:
                     auto td = dyn_cast<TypeDecl>(pCalled->getParent());
                     if (td != nullptr
-                        && (loplugin::TypeCheck(QualType(td->getTypeForDecl(), 0)).Class("OWeakObject").Namespace("cppu")
-                            || loplugin::TypeCheck(QualType(td->getTypeForDecl(), 0)).Class("OWeakAggObject").Namespace("cppu")))
+                        && (loplugin::TypeCheck(td).Class("OWeakObject").Namespace("cppu").GlobalNamespace()
+                            || loplugin::TypeCheck(td).Class("OWeakAggObject").Namespace("cppu").GlobalNamespace()))
                     {
                         return true;
                     }
@@ -131,15 +131,15 @@ public:
         }
 
         // whitelist
-        auto const name(pMethodDecl->getParent()->getQualifiedNameAsString());
-        if (   name == "cppu::OWeakAggObject" // conditional call
-            || name == "cppu::WeakComponentImplHelperBase" // extra magic
-            || name == "cppu::WeakAggComponentImplHelperBase" // extra magic
-            || name == "DOM::CDOMImplementation" // a static oddity
-            || name == "SwXTextFrame" // ambiguous, 3 parents
-            || name == "SwXTextDocument" // ambiguous, ~4 parents
-            || name == "SdStyleSheet" // same extra magic as WeakComponentImplHelperBase
-            || name == "SdXImpressDocument" // same extra magic as WeakComponentImplHelperBase
+        auto tc  = loplugin::TypeCheck(pMethodDecl->getParent());
+        if (   tc.Class("OWeakAggObject").Namespace("cppu").GlobalNamespace() // conditional call
+            || tc.Class("WeakComponentImplHelperBase").Namespace("cppu").GlobalNamespace() // extra magic
+            || tc.Class("WeakAggComponentImplHelperBase").Namespace("cppu").GlobalNamespace() // extra magic
+            || tc.Class("CDOMImplementation").Namespace("DOM").GlobalNamespace() // a static oddity
+            || tc.Class("SwXTextFrame").GlobalNamespace() // ambiguous, 3 parents
+            || tc.Class("SwXTextDocument").GlobalNamespace() // ambiguous, ~4 parents
+            || tc.Class("SdStyleSheet").GlobalNamespace() // same extra magic as WeakComponentImplHelperBase
+            || tc.Class("SdXImpressDocument").GlobalNamespace() // same extra magic as WeakComponentImplHelperBase
            )
         {
             return true;


More information about the Libreoffice-commits mailing list