summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/redundantpointerops.cxx
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-09-01 09:34:37 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-09-04 08:44:19 +0200
commit326295bf10985a19ac913f988980c8761c301967 (patch)
tree0b02ea6717888077e73c4837aafddd6a10dfc183 /compilerplugins/clang/redundantpointerops.cxx
parentdfaceb70ec2f6feda6a73b8be00a7f168dfe075b (diff)
new loplugin:redundantpointerops
Change-Id: I8428d86ea9628d69c2b40b36feee3da428a9fe1d Reviewed-on: https://gerrit.libreoffice.org/41787 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/redundantpointerops.cxx')
-rw-r--r--compilerplugins/clang/redundantpointerops.cxx129
1 files changed, 129 insertions, 0 deletions
diff --git a/compilerplugins/clang/redundantpointerops.cxx b/compilerplugins/clang/redundantpointerops.cxx
new file mode 100644
index 000000000000..6a88cdb13d70
--- /dev/null
+++ b/compilerplugins/clang/redundantpointerops.cxx
@@ -0,0 +1,129 @@
+/* -*- 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 <cassert>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <set>
+
+#include <clang/AST/CXXInheritance.h>
+#include "compat.hxx"
+#include "plugin.hxx"
+
+/**
+ * Look for:
+ * (&x)->y
+ * which can be tranformed to:
+ * x.y
+ * And
+ * &*x
+ * which can be:
+ * x
+ *
+ * @TODO
+ * (*x).y
+ * which can be:
+ * x->y
+ */
+
+namespace {
+
+class RedundantPointerOps:
+ public RecursiveASTVisitor<RedundantPointerOps>, public loplugin::Plugin
+{
+public:
+ explicit RedundantPointerOps(InstantiationData const & data): Plugin(data) {}
+
+ virtual void run() override
+ {
+ TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+ }
+
+ bool VisitFunctionDecl(FunctionDecl const *);
+ bool VisitMemberExpr(MemberExpr const *);
+ bool VisitUnaryOperator(UnaryOperator const *);
+};
+
+bool RedundantPointerOps::VisitFunctionDecl(FunctionDecl const * functionDecl)
+{
+ if (ignoreLocation(functionDecl))
+ return true;
+ //functionDecl->dump();
+ return true;
+}
+
+bool RedundantPointerOps::VisitMemberExpr(MemberExpr const * memberExpr)
+{
+ if (ignoreLocation(memberExpr))
+ return true;
+ if (memberExpr->getLocStart().isMacroID())
+ return true;
+ auto base = memberExpr->getBase()->IgnoreParenImpCasts();
+ //parentStmt(parentStmt(memberExpr))->dump();
+ if (memberExpr->isArrow())
+ {
+ if (auto unaryOp = dyn_cast<UnaryOperator>(base))
+ {
+ if (unaryOp->getOpcode() == UO_AddrOf)
+ report(
+ DiagnosticsEngine::Warning, "'&' followed by '->', rather use '.'",
+ memberExpr->getLocStart())
+ << memberExpr->getSourceRange();
+
+ }
+ else if (auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(base))
+ {
+ if (operatorCallExpr->getOperator() == OO_Amp)
+ report(
+ DiagnosticsEngine::Warning, "'&' followed by '->', rather use '.'",
+ memberExpr->getLocStart())
+ << memberExpr->getSourceRange();
+
+ }
+ }
+// else
+// {
+// if (auto unaryOp = dyn_cast<UnaryOperator>(base))
+// {
+// if (unaryOp->getOpcode() == UO_Deref)
+// report(
+// DiagnosticsEngine::Warning, "'*' followed by '.', rather use '->'",
+// memberExpr->getLocStart())
+// << memberExpr->getSourceRange();
+//
+// }
+// }
+ return true;
+}
+
+bool RedundantPointerOps::VisitUnaryOperator(UnaryOperator const * unaryOperator)
+{
+ if (ignoreLocation(unaryOperator))
+ return true;
+ if (unaryOperator->getLocStart().isMacroID())
+ return true;
+ if (unaryOperator->getOpcode() != UO_Deref)
+ return true;
+ auto innerOp = dyn_cast<UnaryOperator>(unaryOperator->getSubExpr()->IgnoreParenImpCasts());
+ if (!innerOp || innerOp->getOpcode() != UO_AddrOf)
+ return true;
+
+ report(
+ DiagnosticsEngine::Warning, "'&' followed by '*', rather use '.'",
+ unaryOperator->getLocStart())
+ << unaryOperator->getSourceRange();
+ return true;
+}
+
+loplugin::Plugin::Registration< RedundantPointerOps > X("redundantpointerops");
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */