summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2015-01-08 10:59:24 +0100
committerStephan Bergmann <sbergman@redhat.com>2015-01-08 10:59:39 +0100
commit44d0e286c8c7a0ddb8e14fb2c3afe5af35311ef7 (patch)
tree0de5ccf34bd1579f41a1950cdaed421bb9216b61
parentbb65b09678d4b6da657f6ccc180d8ff5096e3006 (diff)
loplugin:cstylecast: improve detection of C code
Change-Id: Id5dd1ee1a29c4e1c7cb2b58419d6ccb1f032bffe
-rw-r--r--compilerplugins/clang/compat.hxx8
-rw-r--r--compilerplugins/clang/cstylecast.cxx42
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,