summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/literaltoboolconversion.cxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-07-11 21:30:34 +0200
committerStephan Bergmann <sbergman@redhat.com>2016-07-11 21:30:34 +0200
commit3510a48794ebe5d34364301a0bdaca10e66258dd (patch)
tree0d7cf4457d6da5d25c2ab534d58c5fa1f4c4f644 /compilerplugins/clang/literaltoboolconversion.cxx
parent27ca06cbca5a483695009089a1107dbf55b3b9f5 (diff)
loplugin:literaltoboolconversion: Better heuristic...
to determine code shared between C and C++ Change-Id: Ib1f3892b388ebd6a67cc88831a99dfb4ccdfbc2f
Diffstat (limited to 'compilerplugins/clang/literaltoboolconversion.cxx')
-rw-r--r--compilerplugins/clang/literaltoboolconversion.cxx33
1 files changed, 30 insertions, 3 deletions
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 <cassert>
+#include <limits>
+
#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<unsigned int>::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;
}
}