diff options
-rw-r--r-- | compilerplugins/clang/compat.hxx | 8 | ||||
-rw-r--r-- | compilerplugins/clang/cstylecast.cxx | 42 |
2 files changed, 43 insertions, 7 deletions
diff --git a/compilerplugins/clang/compat.hxx b/compilerplugins/clang/compat.hxx index e0e3cbbc7d92..44452bd58733 100644 --- a/compilerplugins/clang/compat.hxx +++ b/compilerplugins/clang/compat.hxx @@ -56,6 +56,14 @@ inline bool isExternCContext(clang::DeclContext const & ctxt) { #endif } +inline bool isInExternCContext(clang::FunctionDecl const & decl) { +#if (__clang_major__ == 3 && __clang_minor__ >= 4) || __clang_major__ > 3 + return decl.isInExternCContext(); +#else + return isExternalCContext(*decl.getCanonicalDecl()->getDeclContext()); +#endif +} + #if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3 typedef clang::LinkageInfo LinkageInfo; #else diff --git a/compilerplugins/clang/cstylecast.cxx b/compilerplugins/clang/cstylecast.cxx index 5492dc4eefb9..53b7d8802db6 100644 --- a/compilerplugins/clang/cstylecast.cxx +++ b/compilerplugins/clang/cstylecast.cxx @@ -7,6 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <cassert> #include <string> #include "plugin.hxx" #include "compat.hxx" @@ -17,6 +18,10 @@ namespace { +bool hasCLanguageLinkageType(FunctionDecl const * decl) { + return decl->isExternC() || compat::isInExternCContext(*decl); +} + QualType resolvePointers(QualType type) { while (type->isPointerType()) { type = type->getAs<PointerType>()->getPointeeType(); @@ -28,7 +33,9 @@ class CStyleCast: public RecursiveASTVisitor<CStyleCast>, public loplugin::Plugin { public: - explicit CStyleCast(InstantiationData const & data): Plugin(data) {} + explicit CStyleCast(InstantiationData const & data): + Plugin(data), externCFunction(false) + {} virtual void run() override { if (compiler.getLangOpts().CPlusPlus) { @@ -36,7 +43,12 @@ public: } } + bool TraverseFunctionDecl(FunctionDecl * decl); + bool VisitCStyleCastExpr(const CStyleCastExpr * expr); + +private: + bool externCFunction; }; static const char * recommendedFix(clang::CastKind ck) { @@ -48,6 +60,20 @@ static 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; + } + return ret; +} + bool CStyleCast::VisitCStyleCastExpr(const CStyleCastExpr * expr) { if (ignoreLocation(expr)) { return true; @@ -89,12 +115,14 @@ bool CStyleCast::VisitCStyleCastExpr(const CStyleCastExpr * expr) { if( expr->getCastKind() == CK_Dependent ) { return true; } - SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc( - expr->getLocStart()); - StringRef filename = compiler.getSourceManager().getFilename(spellingLocation); - // ignore C code - if ( filename.endswith(".h") ) { - return true; + 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; + } } report( DiagnosticsEngine::Warning, |