summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2014-08-28 08:58:48 +0200
committerNorbert Thiebaud <nthiebaud@gmail.com>2014-09-07 02:42:30 -0500
commited75aa271956824c89b7c9df2c06e4ad09a74734 (patch)
tree432c17088789736364b2932b9085e5b17a8cc71a /compilerplugins
parent5ca2d1e26513095670b3fd2dce6a464a415cab89 (diff)
create clang plugin to warn about C-style casts
We don't like C-style casts in our nice C++ code Change-Id: I94e7ec90de9275cd6e20c4146d4f3a74bed93c9d Reviewed-on: https://gerrit.libreoffice.org/10367 Reviewed-by: Stephan Bergmann <sbergman@redhat.com> Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com> Tested-by: Norbert Thiebaud <nthiebaud@gmail.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/cstylecast.cxx88
1 files changed, 88 insertions, 0 deletions
diff --git a/compilerplugins/clang/cstylecast.cxx b/compilerplugins/clang/cstylecast.cxx
new file mode 100644
index 000000000000..5183e26ff27e
--- /dev/null
+++ b/compilerplugins/clang/cstylecast.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <string>
+#include "plugin.hxx"
+#include "compat.hxx"
+
+//
+// We don't like using C-style casts in C++ code
+//
+
+namespace {
+
+class CStyleCast:
+ public RecursiveASTVisitor<CStyleCast>, public loplugin::Plugin
+{
+public:
+ explicit CStyleCast(InstantiationData const & data): Plugin(data) {}
+
+ virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
+
+ bool VisitCStyleCastExpr(const CStyleCastExpr * expr);
+};
+
+static const char * recommendedFix(clang::CastKind ck) {
+ switch(ck) {
+ case CK_IntegralToPointer: return "reinterpret_cast";
+ case CK_PointerToIntegral: return "reinterpret_cast";
+ case CK_BaseToDerived: return "static_cast";
+ default: return "???";
+ }
+}
+
+bool CStyleCast::VisitCStyleCastExpr(const CStyleCastExpr * expr) {
+ if (ignoreLocation(expr)) {
+ return true;
+ }
+ // casting to void is typically used when a parameter or field is only used in
+ // debug mode, and we want to eliminate an "unused" warning
+ if( expr->getCastKind() == CK_ToVoid ) {
+ return true;
+ }
+ // ignore integral-type conversions for now, there is unsufficient agreement about
+ // the merits of C++ style casting in this case
+ if( expr->getCastKind() == CK_IntegralCast ) {
+ return true;
+ }
+ if( expr->getCastKind() == CK_NoOp ) {
+ return true;
+ }
+ // ignore pointer-type conversions for now
+ if( expr->getCastKind() == CK_BitCast ) {
+ return true;
+ }
+ SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(
+ expr->getLocStart());
+ StringRef filename = compiler.getSourceManager().getFilename(spellingLocation);
+ // ignore C code
+ if ( filename.endswith(".h") || filename.endswith(".c") ) {
+ return true;
+ }
+ if ( compat::isInMainFile(compiler.getSourceManager(), spellingLocation)
+ ? (filename.startswith(SRCDIR "/sal")) // sal has tons of weird stuff going on that I don't understand enough to fix
+ : (filename.startswith(SRCDIR "/include/tools/solar.h")) ) {
+ return true;
+ }
+ report(
+ DiagnosticsEngine::Warning,
+ "c-style cast, type=%0, from=%1, recommendedFix=%2",
+ expr->getSourceRange().getBegin())
+ << expr->getCastKind()
+ << expr->getSubExprAsWritten()->getType()
+ << recommendedFix(expr->getCastKind())
+ << expr->getSourceRange();
+ return true;
+}
+
+loplugin::Plugin::Registration< CStyleCast > X("cstylecast");
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */