diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-07-11 16:32:28 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-07-11 16:32:28 +0200 |
commit | 6f8d047519c8e80371a646ce4bad8f7304aab6ea (patch) | |
tree | f79b5a6cae706b3d4422a02bd109824eb8a2eeaa /compilerplugins | |
parent | c726059adf71f9c812df3363b4902c52023827b6 (diff) |
loplugin:salbool: Better heuristic to determine code shared between C and C++
Change-Id: I09c9c57d5adeb665cc2508fad9727085a3289bfb
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/salbool.cxx | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/compilerplugins/clang/salbool.cxx b/compilerplugins/clang/salbool.cxx index 4b123c77b020..e5e9754d7961 100644 --- a/compilerplugins/clang/salbool.cxx +++ b/compilerplugins/clang/salbool.cxx @@ -9,6 +9,7 @@ #include <algorithm> #include <cassert> +#include <limits> #include <set> #include <string> @@ -144,14 +145,19 @@ public: bool TraverseStaticAssertDecl(StaticAssertDecl * decl); + bool TraverseLinkageSpecDecl(LinkageSpecDecl * decl); + private: bool isFromCIncludeFile(SourceLocation spellingLocation) const; + bool isSharedCAndCppCode(SourceLocation location) const; + bool isInSpecialMainFile(SourceLocation spellingLocation) const; bool rewrite(SourceLocation location); std::set<VarDecl const *> varDecls_; + unsigned int externCContexts_ = 0; }; void SalBool::run() { @@ -282,10 +288,9 @@ bool SalBool::VisitCStyleCastExpr(CStyleCastExpr * expr) { StringRef name { Lexer::getImmediateMacroName( loc, compiler.getSourceManager(), compiler.getLangOpts()) }; if (name == "sal_False" || name == "sal_True") { - auto callLoc = compiler.getSourceManager().getSpellingLoc( - compiler.getSourceManager().getImmediateMacroCallerLoc( - loc)); - if (!isFromCIncludeFile(callLoc)) { + auto callLoc = compiler.getSourceManager() + .getImmediateMacroCallerLoc(loc); + if (!isSharedCAndCppCode(callLoc)) { SourceLocation argLoc; if (compat::isMacroArgExpansion( compiler, expr->getLocStart(), &argLoc) @@ -301,17 +306,19 @@ bool SalBool::VisitCStyleCastExpr(CStyleCastExpr * expr) { } bool b = name == "sal_True"; if (rewriter != nullptr) { + auto callSpellLoc = compiler.getSourceManager() + .getSpellingLoc(callLoc); unsigned n = Lexer::MeasureTokenLength( - callLoc, compiler.getSourceManager(), + callSpellLoc, compiler.getSourceManager(), compiler.getLangOpts()); if (StringRef( compiler.getSourceManager().getCharacterData( - callLoc), + callSpellLoc), n) == name) { return replaceText( - callLoc, n, b ? "true" : "false"); + callSpellLoc, n, b ? "true" : "false"); } } report( @@ -725,6 +732,15 @@ bool SalBool::TraverseStaticAssertDecl(StaticAssertDecl * decl) { || RecursiveASTVisitor::TraverseStaticAssertDecl(decl); } +bool SalBool::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) { + assert(externCContexts_ != std::numeric_limits<unsigned int>::max()); //TODO + ++externCContexts_; + bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl(decl); + assert(externCContexts_ != 0); + --externCContexts_; + return ret; +} + bool SalBool::isFromCIncludeFile(SourceLocation spellingLocation) const { return !compiler.getSourceManager().isInMainFile(spellingLocation) && (StringRef( @@ -733,6 +749,16 @@ bool SalBool::isFromCIncludeFile(SourceLocation spellingLocation) const { .endswith(".h")); } +bool SalBool::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)); +} + bool SalBool::isInSpecialMainFile(SourceLocation spellingLocation) const { if (!compiler.getSourceManager().isInMainFile(spellingLocation)) { return false; |