From 3510a48794ebe5d34364301a0bdaca10e66258dd Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Mon, 11 Jul 2016 21:30:34 +0200 Subject: loplugin:literaltoboolconversion: Better heuristic... to determine code shared between C and C++ Change-Id: Ib1f3892b388ebd6a67cc88831a99dfb4ccdfbc2f --- compilerplugins/clang/literaltoboolconversion.cxx | 33 ++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'compilerplugins/clang/literaltoboolconversion.cxx') diff --git a/compilerplugins/clang/literaltoboolconversion.cxx b/compilerplugins/clang/literaltoboolconversion.cxx index 26a661eb9e02..973527d30af9 100644 --- a/compilerplugins/clang/literaltoboolconversion.cxx +++ b/compilerplugins/clang/literaltoboolconversion.cxx @@ -7,6 +7,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include +#include + #include "clang/Lex/Lexer.h" #include "plugin.hxx" @@ -26,11 +29,17 @@ public: bool VisitImplicitCastExpr(ImplicitCastExpr const * expr); + bool TraverseLinkageSpecDecl(LinkageSpecDecl * decl); + private: bool isFromCIncludeFile(SourceLocation spellingLocation) const; + bool isSharedCAndCppCode(SourceLocation location) const; + void handleImplicitCastSubExpr( ImplicitCastExpr const * castExpr, Expr const * subExpr); + + unsigned int externCContexts_ = 0; }; bool LiteralToBoolConversion::VisitImplicitCastExpr( @@ -46,6 +55,15 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr( return true; } +bool LiteralToBoolConversion::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) { + assert(externCContexts_ != std::numeric_limits::max()); //TODO + ++externCContexts_; + bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl(decl); + assert(externCContexts_ != 0); + --externCContexts_; + return ret; +} + bool LiteralToBoolConversion::isFromCIncludeFile( SourceLocation spellingLocation) const { @@ -56,6 +74,17 @@ bool LiteralToBoolConversion::isFromCIncludeFile( .endswith(".h")); } +bool LiteralToBoolConversion::isSharedCAndCppCode(SourceLocation location) const +{ + // 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)); +} + void LiteralToBoolConversion::handleImplicitCastSubExpr( ImplicitCastExpr const * castExpr, Expr const * subExpr) { @@ -99,9 +128,7 @@ void LiteralToBoolConversion::handleImplicitCastSubExpr( loc = compiler.getSourceManager().getImmediateExpansionRange( loc).first; } - if (isFromCIncludeFile( - compiler.getSourceManager().getSpellingLoc(loc))) - { + if (isSharedCAndCppCode(loc)) { return; } } -- cgit