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

Stephan Bergmann sbergman at redhat.com
Tue Jul 12 15:53:45 UTC 2016


 compilerplugins/clang/cstylecast.cxx |   68 ++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 29 deletions(-)

New commits:
commit ba94c97644bf75d39eb30de30ef29b44ad83233d
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Jul 12 17:53:16 2016 +0200

    loplugin:cstylecast: Better heuristic...
    
    to determine code shared between C and C++
    
    Change-Id: I1fadf69bf9d0a2bde527b7c3f2ec4c687d70e4ae

diff --git a/compilerplugins/clang/cstylecast.cxx b/compilerplugins/clang/cstylecast.cxx
index ae95bc2..addf5ed 100644
--- a/compilerplugins/clang/cstylecast.cxx
+++ b/compilerplugins/clang/cstylecast.cxx
@@ -8,6 +8,7 @@
  */
 
 #include <cassert>
+#include <limits>
 #include <string>
 #include "plugin.hxx"
 
@@ -74,10 +75,6 @@ bool areSimilar(QualType type1, QualType type2) {
     }
 }
 
-bool hasCLanguageLinkageType(FunctionDecl const * decl) {
-    return decl->isExternC() || decl->isInExternCContext();
-}
-
 QualType resolvePointers(QualType type) {
     while (type->isPointerType()) {
         type = type->getAs<PointerType>()->getPointeeType();
@@ -89,9 +86,7 @@ class CStyleCast:
     public RecursiveASTVisitor<CStyleCast>, public loplugin::Plugin
 {
 public:
-    explicit CStyleCast(InstantiationData const & data):
-        Plugin(data), externCFunction(false)
-    {}
+    explicit CStyleCast(InstantiationData const & data): Plugin(data) {}
 
     virtual void run() override {
         if (compiler.getLangOpts().CPlusPlus) {
@@ -99,14 +94,18 @@ public:
         }
     }
 
-    bool TraverseFunctionDecl(FunctionDecl * decl);
+    bool TraverseLinkageSpecDecl(LinkageSpecDecl * decl);
 
     bool VisitCStyleCastExpr(const CStyleCastExpr * expr);
 
 private:
     bool isConstCast(QualType from, QualType to);
 
-    bool externCFunction;
+    bool isFromCIncludeFile(SourceLocation spellingLocation) const;
+
+    bool isSharedCAndCppCode(SourceLocation location) const;
+
+    unsigned int externCContexts_ = 0;
 };
 
 const char * recommendedFix(clang::CastKind ck) {
@@ -118,17 +117,12 @@ const char * recommendedFix(clang::CastKind ck) {
     }
 }
 
-bool CStyleCast::TraverseFunctionDecl(FunctionDecl * decl) {
-    bool ext = hasCLanguageLinkageType(decl)
-        && decl->isThisDeclarationADefinition();
-    if (ext) {
-        assert(!externCFunction);
-        externCFunction = true;
-    }
-    bool ret = RecursiveASTVisitor::TraverseFunctionDecl(decl);
-    if (ext) {
-        externCFunction = false;
-    }
+bool CStyleCast::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) {
+    assert(externCContexts_ != std::numeric_limits<unsigned int>::max()); //TODO
+    ++externCContexts_;
+    bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl(decl);
+    assert(externCContexts_ != 0);
+    --externCContexts_;
     return ret;
 }
 
@@ -166,6 +160,9 @@ bool CStyleCast::VisitCStyleCastExpr(const CStyleCastExpr * expr) {
             perf = "const_cast";
         }
     }
+    if (isSharedCAndCppCode(expr->getLocStart())) {
+        return true;
+    }
     std::string incompFrom;
     std::string incompTo;
     if( expr->getCastKind() == CK_BitCast ) {
@@ -178,15 +175,6 @@ bool CStyleCast::VisitCStyleCastExpr(const CStyleCastExpr * expr) {
             incompTo = "incomplete ";
         }
     }
-    if (externCFunction || expr->getLocStart().isMacroID()) {
-        SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(
-            expr->getLocStart());
-        StringRef filename = compiler.getSourceManager().getFilename(spellingLocation);
-        // ignore C code
-        if ( filename.endswith(".h") ) {
-            return true;
-        }
-    }
     if (perf == nullptr) {
         perf = recommendedFix(expr->getCastKind());
     }
@@ -225,6 +213,28 @@ bool CStyleCast::isConstCast(QualType from, QualType to) {
     return areSimilar(from, to);
 }
 
+bool CStyleCast::isFromCIncludeFile(SourceLocation spellingLocation) const {
+    return !compiler.getSourceManager().isInMainFile(spellingLocation)
+        && (StringRef(
+                compiler.getSourceManager().getPresumedLoc(spellingLocation)
+                .getFilename())
+            .endswith(".h"));
+}
+
+bool CStyleCast::isSharedCAndCppCode(SourceLocation location) const {
+    while (compiler.getSourceManager().isMacroArgExpansion(location)) {
+        location = compiler.getSourceManager().getImmediateMacroCallerLoc(
+            location);
+    }
+    // Assume that code is intended to be shared between C and C++ if it comes
+    // from an include file ending in .h, and is either in an extern "C" context
+    // or the body of a macro definition:
+    return
+        isFromCIncludeFile(compiler.getSourceManager().getSpellingLoc(location))
+        && (externCContexts_ != 0
+            || compiler.getSourceManager().isMacroBodyExpansion(location));
+}
+
 loplugin::Plugin::Registration< CStyleCast > X("cstylecast");
 
 }


More information about the Libreoffice-commits mailing list