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

Noel Grandin noel.grandin at collabora.co.uk
Fri Oct 27 12:04:33 UTC 2017


 compilerplugins/clang/constantparam.cxx   |   28 ++-----
 compilerplugins/clang/constparams.cxx     |   91 +---------------------
 compilerplugins/clang/functionaddress.hxx |  120 ++++++++++++++++++++++++++++++
 compilerplugins/clang/plugin.hxx          |    5 -
 4 files changed, 138 insertions(+), 106 deletions(-)

New commits:
commit 569c7da252be05366980ae88ce30ef17f6e61d8c
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Fri Oct 27 10:54:31 2017 +0200

    extract some common code for checking if a functions address was taken
    
    Change-Id: I292b4e9bf17c83f83ff43ac4c5870d33092d0c71

diff --git a/compilerplugins/clang/constantparam.cxx b/compilerplugins/clang/constantparam.cxx
index 426e86995040..edc99c37699f 100644
--- a/compilerplugins/clang/constantparam.cxx
+++ b/compilerplugins/clang/constantparam.cxx
@@ -15,6 +15,7 @@
 #include "plugin.hxx"
 #include "compat.hxx"
 #include "check.hxx"
+#include "functionaddress.hxx"
 
 /*
   Find params on methods where the param is only ever passed as a single constant value.
@@ -53,10 +54,10 @@ bool operator < (const MyCallSiteInfo &lhs, const MyCallSiteInfo &rhs)
 static std::set<MyCallSiteInfo> callSet;
 
 class ConstantParam:
-    public RecursiveASTVisitor<ConstantParam>, public loplugin::Plugin
+    public loplugin::FunctionAddress<ConstantParam>
 {
 public:
-    explicit ConstantParam(InstantiationData const & data): Plugin(data) {}
+    explicit ConstantParam(InstantiationData const & data): loplugin::FunctionAddress<ConstantParam>(data) {}
 
     virtual void run() override
     {
@@ -70,6 +71,13 @@ public:
 
         TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
 
+        // this catches places that take the address of a method
+        for (auto functionDecl : getFunctionsWithAddressTaken())
+        {
+            for (unsigned i = 0; i < functionDecl->getNumParams(); ++i)
+                addToCallSet(functionDecl, i, functionDecl->getParamDecl(i)->getName(), "unknown3");
+        }
+
         // dump all our output in one write call - this is to try and limit IO "crosstalk" between multiple processes
         // writing to the same logfile
 
@@ -87,7 +95,6 @@ public:
     bool shouldVisitImplicitCode () const { return true; }
 
     bool VisitCallExpr( const CallExpr* );
-    bool VisitDeclRefExpr( const DeclRefExpr* );
     bool VisitCXXConstructExpr( const CXXConstructExpr* );
 private:
     void addToCallSet(const FunctionDecl* functionDecl, int paramIndex, llvm::StringRef paramName, const std::string& callValue);
@@ -277,21 +284,6 @@ bool ConstantParam::VisitCallExpr(const CallExpr * callExpr) {
     return true;
 }
 
-// this catches places that take the address of a method
-bool ConstantParam::VisitDeclRefExpr( const DeclRefExpr* declRefExpr )
-{
-    const Decl* decl = declRefExpr->getDecl();
-    const FunctionDecl* functionDecl = dyn_cast<FunctionDecl>(decl);
-    if (!functionDecl)
-        return true;
-    functionDecl = functionDecl->getCanonicalDecl();
-    for (unsigned i = 0; i < functionDecl->getNumParams(); ++i)
-    {
-        addToCallSet(functionDecl, i, functionDecl->getParamDecl(i)->getName(), "unknown3");
-    }
-    return true;
-}
-
 bool ConstantParam::VisitCXXConstructExpr( const CXXConstructExpr* constructExpr )
 {
     const CXXConstructorDecl* constructorDecl = constructExpr->getConstructor();
diff --git a/compilerplugins/clang/constparams.cxx b/compilerplugins/clang/constparams.cxx
index bf715d16e91a..8396f2dad6ec 100644
--- a/compilerplugins/clang/constparams.cxx
+++ b/compilerplugins/clang/constparams.cxx
@@ -16,6 +16,7 @@
 #include "plugin.hxx"
 #include "compat.hxx"
 #include "check.hxx"
+#include "functionaddress.hxx"
 
 /**
    Find pointer and reference params that can be declared const.
@@ -31,10 +32,10 @@ static bool startswith(const std::string& rStr, const char* pSubStr) {
 }
 
 class ConstParams:
-    public RecursiveASTVisitor<ConstParams>, public loplugin::Plugin
+    public loplugin::FunctionAddress<ConstParams>
 {
 public:
-    explicit ConstParams(InstantiationData const & data): Plugin(data) {}
+    explicit ConstParams(InstantiationData const & data): loplugin::FunctionAddress<ConstParams>(data) {}
 
     virtual void run() override {
         std::string fn( compiler.getSourceManager().getFileEntryForID(
@@ -63,8 +64,8 @@ public:
             if (paramCannotBeConstSet.find(pParmVarDecl) == paramCannotBeConstSet.end()) {
                 auto functionDecl = parmToFunction[pParmVarDecl];
                 auto canonicalDecl = functionDecl->getCanonicalDecl();
-                if (ignoredFunctions_.find(canonicalDecl)
-                    != ignoredFunctions_.end())
+                if (getFunctionsWithAddressTaken().find(canonicalDecl)
+                    != getFunctionsWithAddressTaken().end())
                 {
                     continue;
                 }
@@ -86,86 +87,6 @@ public:
         }
     }
 
-    bool TraverseCallExpr(CallExpr * expr) {
-        auto const saved = callee_;
-        callee_ = expr->getCallee();
-        auto const ret = RecursiveASTVisitor::TraverseCallExpr(expr);
-        callee_ = saved;
-        return ret;
-    }
-
-    bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * expr) {
-        auto const saved = callee_;
-        callee_ = expr->getCallee();
-        auto const ret = RecursiveASTVisitor::TraverseCXXOperatorCallExpr(expr);
-        callee_ = saved;
-        return ret;
-    }
-
-    bool TraverseCXXMemberCallExpr(CXXMemberCallExpr * expr) {
-        auto const saved = callee_;
-        callee_ = expr->getCallee();
-        auto const ret = RecursiveASTVisitor::TraverseCXXMemberCallExpr(expr);
-        callee_ = saved;
-        return ret;
-    }
-
-    bool TraverseCUDAKernelCallExpr(CUDAKernelCallExpr * expr) {
-        auto const saved = callee_;
-        callee_ = expr->getCallee();
-        auto const ret = RecursiveASTVisitor::TraverseCUDAKernelCallExpr(expr);
-        callee_ = saved;
-        return ret;
-    }
-
-    bool TraverseUserDefinedLiteral(UserDefinedLiteral * expr) {
-        auto const saved = callee_;
-        callee_ = expr->getCallee();
-        auto const ret = RecursiveASTVisitor::TraverseUserDefinedLiteral(expr);
-        callee_ = saved;
-        return ret;
-    }
-
-    bool VisitImplicitCastExpr(ImplicitCastExpr const * expr) {
-        if (expr == callee_) {
-            return true;
-        }
-        if (ignoreLocation(expr)) {
-            return true;
-        }
-        if (expr->getCastKind() != CK_FunctionToPointerDecay) {
-            return true;
-        }
-        auto const dre = dyn_cast<DeclRefExpr>(
-            expr->getSubExpr()->IgnoreParens());
-        if (dre == nullptr) {
-            return true;
-        }
-        auto const fd = dyn_cast<FunctionDecl>(dre->getDecl());
-        if (fd == nullptr) {
-            return true;
-        }
-        ignoredFunctions_.insert(fd->getCanonicalDecl());
-        return true;
-    }
-
-    bool VisitUnaryAddrOf(UnaryOperator const * expr) {
-        if (ignoreLocation(expr)) {
-            return true;
-        }
-        auto const dre = dyn_cast<DeclRefExpr>(
-            expr->getSubExpr()->IgnoreParenImpCasts());
-        if (dre == nullptr) {
-            return true;
-        }
-        auto const fd = dyn_cast<FunctionDecl>(dre->getDecl());
-        if (fd == nullptr) {
-            return true;
-        }
-        ignoredFunctions_.insert(fd->getCanonicalDecl());
-        return true;
-    }
-
     bool VisitFunctionDecl(const FunctionDecl *);
     bool VisitDeclRefExpr(const DeclRefExpr *);
 
@@ -176,8 +97,6 @@ private:
     std::unordered_set<const ParmVarDecl*> interestingParamSet;
     std::unordered_map<const ParmVarDecl*, const FunctionDecl*> parmToFunction;
     std::unordered_set<const ParmVarDecl*> paramCannotBeConstSet;
-    std::unordered_set<FunctionDecl const *> ignoredFunctions_;
-    Expr const * callee_ = nullptr;
 };
 
 bool ConstParams::VisitFunctionDecl(const FunctionDecl * functionDecl)
diff --git a/compilerplugins/clang/functionaddress.hxx b/compilerplugins/clang/functionaddress.hxx
new file mode 100644
index 000000000000..dc34262a50b0
--- /dev/null
+++ b/compilerplugins/clang/functionaddress.hxx
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_COMPILERPLUGINS_CLANG_FUNCTIONADDRESS_HXX
+#define INCLUDED_COMPILERPLUGINS_CLANG_FUNCTIONADDRESS_HXX
+
+#include <clang/AST/RecursiveASTVisitor.h>
+#include <unordered_set>
+#include "plugin.hxx"
+
+/**
+ * Common code for checking if the address of a function was taken.
+ */
+namespace loplugin {
+
+template<typename Derived>
+class FunctionAddress : public RecursiveASTVisitor<Derived>, public loplugin::Plugin
+{
+public:
+    explicit FunctionAddress( const InstantiationData& data ) : loplugin::Plugin(data) {}
+
+    bool TraverseCallExpr(CallExpr * expr) {
+        auto const saved = callee_;
+        callee_ = expr->getCallee();
+        auto const ret = RecursiveASTVisitor<Derived>::TraverseCallExpr(expr);
+        callee_ = saved;
+        return ret;
+    }
+
+    bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * expr) {
+        auto const saved = callee_;
+        callee_ = expr->getCallee();
+        auto const ret = RecursiveASTVisitor<Derived>::TraverseCXXOperatorCallExpr(expr);
+        callee_ = saved;
+        return ret;
+    }
+
+    bool TraverseCXXMemberCallExpr(CXXMemberCallExpr * expr) {
+        auto const saved = callee_;
+        callee_ = expr->getCallee();
+        auto const ret = RecursiveASTVisitor<Derived>::TraverseCXXMemberCallExpr(expr);
+        callee_ = saved;
+        return ret;
+    }
+
+    bool TraverseCUDAKernelCallExpr(CUDAKernelCallExpr * expr) {
+        auto const saved = callee_;
+        callee_ = expr->getCallee();
+        auto const ret = RecursiveASTVisitor<Derived>::TraverseCUDAKernelCallExpr(expr);
+        callee_ = saved;
+        return ret;
+    }
+
+    bool TraverseUserDefinedLiteral(UserDefinedLiteral * expr) {
+        auto const saved = callee_;
+        callee_ = expr->getCallee();
+        auto const ret = RecursiveASTVisitor<Derived>::TraverseUserDefinedLiteral(expr);
+        callee_ = saved;
+        return ret;
+    }
+
+    bool VisitImplicitCastExpr(ImplicitCastExpr const * expr) {
+        if (expr == callee_) {
+            return true;
+        }
+        if (ignoreLocation(expr)) {
+            return true;
+        }
+        if (expr->getCastKind() != CK_FunctionToPointerDecay) {
+            return true;
+        }
+        auto const dre = dyn_cast<DeclRefExpr>(
+            expr->getSubExpr()->IgnoreParens());
+        if (dre == nullptr) {
+            return true;
+        }
+        auto const fd = dyn_cast<FunctionDecl>(dre->getDecl());
+        if (fd == nullptr) {
+            return true;
+        }
+        ignoredFunctions_.insert(fd->getCanonicalDecl());
+        return true;
+    }
+
+    bool VisitUnaryAddrOf(UnaryOperator const * expr) {
+        if (ignoreLocation(expr)) {
+            return true;
+        }
+        auto const dre = dyn_cast<DeclRefExpr>(
+            expr->getSubExpr()->IgnoreParenImpCasts());
+        if (dre == nullptr) {
+            return true;
+        }
+        auto const fd = dyn_cast<FunctionDecl>(dre->getDecl());
+        if (fd == nullptr) {
+            return true;
+        }
+        ignoredFunctions_.insert(fd->getCanonicalDecl());
+        return true;
+    }
+
+protected:
+    std::unordered_set<FunctionDecl const *> const & getFunctionsWithAddressTaken() { return ignoredFunctions_; }
+
+private:
+    std::unordered_set<FunctionDecl const *> ignoredFunctions_;
+    Expr const * callee_ = nullptr;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx
index 1f57dfeb0ffa..69349236a42d 100644
--- a/compilerplugins/clang/plugin.hxx
+++ b/compilerplugins/clang/plugin.hxx
@@ -56,11 +56,12 @@ public:
     enum { isPPCallback = false };
     // Returns location right after the end of the token that starts at the given location.
     SourceLocation locationAfterToken( SourceLocation location );
-protected:
-    DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation()) const;
     bool ignoreLocation( SourceLocation loc );
     bool ignoreLocation( const Decl* decl );
     bool ignoreLocation( const Stmt* stmt );
+
+protected:
+    DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation()) const;
     CompilerInstance& compiler;
     PluginHandler& handler;
     /**


More information about the Libreoffice-commits mailing list