njames93 updated this revision to Diff 237505.
njames93 added a comment.

- Fix perf alias documentation


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72553/new/

https://reviews.llvm.org/D72553

Files:
  clang-tools-extra/clang-tidy/llvm/CMakeLists.txt
  clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp
  clang-tools-extra/clang-tidy/llvm/PreferPreIncrementCheck.cpp
  clang-tools-extra/clang-tidy/llvm/PreferPreIncrementCheck.h
  clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/llvm-prefer-pre-increment.rst
  clang-tools-extra/docs/clang-tidy/checks/performance-prefer-pre-increment.rst
  
clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment-disable-cpp-opcalls.cpp
  clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment.c
  clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment.cpp
@@ -0,0 +1,82 @@
+// RUN: %check_clang_tidy %s llvm-prefer-pre-increment %t
+
+template <typename T>
+class Iterator {
+  T *Current;
+
+public:
+  Iterator(T *Pointer) : Current(Pointer) {}
+  T &operator*() const { return *Current; }
+  Iterator &operator++() { return ++Current, *this; }
+  Iterator operator++(int) {
+    Iterator Copy = *this;
+    ++Current;
+    return Copy;
+  }
+  Iterator &operator--() { return --Current, *this; }
+  Iterator operator--(int) {
+    Iterator Copy = *this;
+    --Current;
+    return Copy;
+  }
+};
+
+template <typename T>
+class PostfixIterator {
+  T *Current;
+
+public:
+  PostfixIterator(T *Pointer) : Current(Pointer) {}
+  T &operator*() const { return *Current; }
+  PostfixIterator operator++(int) {
+    PostfixIterator Copy = *this;
+    ++Current;
+    return Copy;
+  }
+  PostfixIterator operator--(int) {
+    PostfixIterator Copy = *this;
+    --Current;
+    return Copy;
+  }
+};
+
+void foo() {
+  int Array[32];
+  Iterator<int> It(&Array[0]);
+  It++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++It;
+  It--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES: {{^}}  --It;
+  (*It)++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++(*It);
+  (*It)--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES: {{^}}  --(*It);
+
+  *It++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  *It--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+
+  PostfixIterator<int> PfIt(&Array[0]);
+  PfIt++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES-NOT: {{^}}  ++PfIt;
+  PfIt--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES-NOT: {{^}}  --PfIt;
+  (*PfIt)++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++(*PfIt);
+  (*PfIt)--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES: {{^}}  --(*PfIt);
+
+  *PfIt++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  *PfIt--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+}
Index: clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment.c
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment.c
@@ -0,0 +1,123 @@
+// RUN: %check_clang_tidy %s llvm-prefer-pre-increment %t
+
+#define INC(X) X++
+#define DEC(X) X--
+
+void foo(int A) {
+  for (int I = 0; I < 10; I++) {
+    // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Use Pre-increment instead of Post-increment
+    // CHECK-FIXES: {{^}}  for (int I = 0; I < 10; ++I) {
+  }
+  for (int I = 0; I < 10; ++I) {
+    // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  }
+  for (int I = 0; I < 10; A = I++) {
+    // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  }
+
+  for (int I = 10; I < 0; I--) {
+    // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Use Pre-decrement instead of Post-decrement
+    // CHECK-FIXES: {{^}}  for (int I = 10; I < 0; --I) {
+  }
+  for (int I = 10; I < 0; --I) {
+    // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+  }
+  for (int I = 10; I < 0; A = I--) {
+    // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+  }
+
+  for (int I = 0; I < 10; INC(I)) {
+    // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Use Pre-increment instead of Post-increment
+  }
+  for (int I = 0; I < 10; DEC(I)) {
+    // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Use Pre-decrement instead of Post-decrement
+  }
+  for (int I = 0; I < 10; A = INC(I)) {
+    // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  }
+}
+
+void bar(int *Begin, int *End) {
+  for (int *I = Begin; I != End;) {
+    *I++ = 0;
+    // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  }
+  for (int *I = Begin; I != End; I++) {
+    // CHECK-MESSAGES: [[@LINE-1]]:34: warning: Use Pre-increment instead of Post-increment
+    // CHECK-FIXES: {{^}}  for (int *I = Begin; I != End; ++I) {
+    *I = 0;
+  }
+  for (int *I = Begin; I != End; ++I) {
+    // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+    *I = 0;
+  }
+  for (int *I = Begin; I != End; I++){
+    // CHECK-MESSAGES: [[@LINE-1]]:34: warning: Use Pre-increment instead of Post-increment
+    // CHECK-FIXES: {{^}}  for (int *I = Begin; I != End; ++I) {
+    (*I)++; // c1
+    // CHECK-MESSAGES: [[@LINE-1]]:5: warning: Use Pre-increment instead of Post-increment
+    // CHECK-FIXES: {{^}}    ++(*I); // c1
+    (*I)++; // c2
+    // CHECK-MESSAGES: [[@LINE-1]]:5: warning: Use Pre-increment instead of Post-increment
+    // CHECK-FIXES: {{^}}    ++(*I); // c2
+    (*I)++; // c3
+    // CHECK-MESSAGES: [[@LINE-1]]:5: warning: Use Pre-increment instead of Post-increment
+    // CHECK-FIXES: {{^}}    ++(*I); // c3
+  }
+}
+
+int handle(int);
+
+void baz(){
+  int I = 0;
+  handle(I++);
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  int J = I++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  if (J++) {
+  }
+  // CHECK-MESSAGES-NOT: [[@LINE-2]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  switch (J++) {}
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  while (J++) {
+  }
+  // CHECK-MESSAGES-NOT: [[@LINE-2]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  do {
+  } while (J++);
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  for (; J++;) {
+  }
+  // CHECK-MESSAGES-NOT: [[@LINE-2]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  J++ ? J-- : J++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  J++ ?: J--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  J++;
+  // CHECK-MESSAGES: [[@LINE-1]]:{{3}}: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++J;
+}
+
+struct Foo {
+  int Bar;
+};
+
+struct Baz {
+  struct Foo Bar;
+};
+
+int foobar(struct Baz Foobar, struct Foo *Bar) {
+  Foobar.Bar.Bar++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++Foobar.Bar.Bar;
+  Bar->Bar++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++Bar->Bar;
+  Foobar.
+  Bar.
+  Bar++;
+  // CHECK-MESSAGES: [[@LINE-3]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES:      {{^}}  ++Foobar.
+  // CHECK-FIXES-NEXT: {{^}}  Bar.
+  // CHECK-FIXES-NEXT: {{^}}  Bar;
+  return Bar->Bar++;
+}
Index: clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment-disable-cpp-opcalls.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-pre-increment-disable-cpp-opcalls.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy %s llvm-prefer-pre-increment %t -- \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: llvm-prefer-pre-increment.TransformCxxOpCalls, value: 0}]}'
+
+template <typename T>
+class Iterator {
+  T *Current;
+
+public:
+  Iterator(T *Pointer) : Current(Pointer) {}
+  T &operator*() const { return *Current; }
+  Iterator &operator++() { return ++Current, *this; }
+  Iterator operator++(int) {
+    Iterator Copy = *this;
+    ++Current;
+    return Copy;
+  }
+  Iterator &operator--() { return --Current, *this; }
+  Iterator operator--(int) {
+    Iterator Copy = *this;
+    --Current;
+    return Copy;
+  }
+};
+
+template <typename T>
+class PostfixIterator {
+  T *Current;
+
+public:
+  PostfixIterator(T *Pointer) : Current(Pointer) {}
+  T &operator*() const { return *Current; }
+  PostfixIterator operator++(int) {
+    PostfixIterator Copy = *this;
+    ++Current;
+    return Copy;
+  }
+  PostfixIterator operator--(int) {
+    PostfixIterator Copy = *this;
+    --Current;
+    return Copy;
+  }
+};
+
+void foo() {
+  int Array[32];
+  Iterator<int> It(&Array[0]);
+  It++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES-NOT: {{^}}  ++It;
+  It--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES-NOT: {{^}}  --It;
+  (*It)++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++(*It);
+  (*It)--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES: {{^}}  --(*It);
+
+  *It++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  *It--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+
+  PostfixIterator<int> PfIt(&Array[0]);
+  PfIt++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES-NOT: {{^}}  ++PfIt;
+  PfIt--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES-NOT: {{^}}  --PfIt;
+  (*PfIt)++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-increment instead of Post-increment
+  // CHECK-FIXES: {{^}}  ++(*PfIt);
+  (*PfIt)--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use Pre-decrement instead of Post-decrement
+  // CHECK-FIXES: {{^}}  --(*PfIt);
+
+  *PfIt++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:4: warning: Use Pre-increment instead of Post-increment
+  *PfIt--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:4: warning: Use Pre-decrement instead of Post-decrement
+}
Index: clang-tools-extra/docs/clang-tidy/checks/performance-prefer-pre-increment.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/performance-prefer-pre-increment.rst
@@ -0,0 +1,10 @@
+.. title:: clang-tidy - performance-prefer-pre-increment
+.. meta::
+   :http-equiv=refresh: 5;URL=llvm-prefer-pre-increment.html
+
+performance-prefer-pre-increment
+================================
+
+The performance-prefer-pre-incrementcheck is an alias, please see
+`llvm-prefer-pre-increment <llvm-prefer-pre-increment.html>`_
+for more information.
Index: clang-tools-extra/docs/clang-tidy/checks/llvm-prefer-pre-increment.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/llvm-prefer-pre-increment.rst
@@ -0,0 +1,33 @@
+.. title:: clang-tidy - llvm-prefer-pre-increment
+
+llvm-prefer-pre-increment
+=========================
+
+Flags usages of the unary postfix increment and decrement operators where the
+result isnt used which could be replaced with the more efficient prefix variety.
+
+.. code-block:: c++
+
+  // Finds these
+  for (int I = 0; I < 10; I++) {}
+  (*Ptr)++;
+  // Replaces with
+  for (int I = 0; I < 10; ++I) {}
+  ++(*Ptr);
+
+  // Doesn't replace these
+  *Ptr++ = 0;
+  call(I++);
+  Index = I++;
+
+Options
+-------
+
+.. option:: TransformCxxOpCalls
+
+   Enables checking postfix operations on classes and structures that overload
+   both the prefix and postfix operator ``++`` or ``--``.
+   Default value is `1`.
+
+This check helps to enforce this `LLVM Coding Standards recommendation
+<https://llvm.org/docs/CodingStandards.html#prefer-preincrement>`_.
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -176,6 +176,7 @@
    `llvm-include-order <llvm-include-order.html>`_, "Yes"
    `llvm-namespace-comment <llvm-namespace-comment.html>`_,
    `llvm-prefer-isa-or-dyn-cast-in-conditionals <llvm-prefer-isa-or-dyn-cast-in-conditionals.html>`_, "Yes"
+   `llvm-prefer-pre-increment <llvm-prefer-pre-increment.html>`_, "Yes"
    `llvm-prefer-register-over-unsigned <llvm-prefer-register-over-unsigned.html>`_, "Yes"
    `llvm-twine-local <llvm-twine-local.html>`_, "Yes"
    `misc-definitions-in-headers <misc-definitions-in-headers.html>`_, "Yes"
@@ -397,6 +398,7 @@
    `hicpp-use-nullptr <hicpp-use-nullptr.html>`_, `modernize-use-nullptr <modernize-use-nullptr.html>`_, "Yes"
    `hicpp-use-override <hicpp-use-override.html>`_, `modernize-use-override <modernize-use-override.html>`_, "Yes"
    `hicpp-vararg <hicpp-vararg.html>`_, `cppcoreguidelines-pro-type-vararg <cppcoreguidelines-pro-type-vararg.html>`_,
+   `performance-prefer-pre-increment <performance-prefer-pre-increment.html>`_, `llvm-prefer-pre-increment <llvm-prefer-pre-increment.html>`_, "Yes"
 
 .. toctree::
    :glob:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -136,6 +136,12 @@
   Checks Linux kernel code to see if it uses the results from the functions in
   ``linux/err.h``.
 
+- New :doc:`llvm-prefer-pre-increment
+  <clang-tidy/checks/llvm-prefer-pre-increment>` check.
+
+  Flags usages of postfix increment and decrement which could be swapped for
+  their prefix alternatives.
+
 - New :doc:`llvm-prefer-register-over-unsigned
   <clang-tidy/checks/llvm-prefer-register-over-unsigned>` check.
 
@@ -179,6 +185,11 @@
   :doc:`bugprone-bad-signal-to-kill-thread
   <clang-tidy/checks/bugprone-bad-signal-to-kill-thread>` was added.
 
+- New alias :doc:`performance-prefer-pre-increment
+  <clang-tidy/checks/performance-prefer-pre-increment>` to
+  :doc:`llvm-prefer-pre-increment
+  <clang-tidy/checks/llvm-prefer-pre-increment>` was added.
+
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
Index: clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
+++ clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -9,6 +9,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "../llvm/PreferPreIncrementCheck.h"
 #include "FasterStringFindCheck.h"
 #include "ForRangeCopyCheck.h"
 #include "ImplicitConversionInLoopCheck.h"
@@ -51,6 +52,8 @@
         "performance-no-automatic-move");
     CheckFactories.registerCheck<NoexceptMoveConstructorCheck>(
         "performance-noexcept-move-constructor");
+    CheckFactories.registerCheck<llvm_check::PreferPreIncrementCheck>(
+        "performance-prefer-pre-increment");
     CheckFactories.registerCheck<TriviallyDestructibleCheck>(
         "performance-trivially-destructible");
     CheckFactories.registerCheck<TypePromotionInMathFnCheck>(
Index: clang-tools-extra/clang-tidy/llvm/PreferPreIncrementCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/llvm/PreferPreIncrementCheck.h
@@ -0,0 +1,38 @@
+//===--- PreferPreIncrementCheck.h - clang-tidy -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_PREFERPREINCREMENTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_PREFERPREINCREMENTCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace llvm_check {
+
+///  Flags usages of postfix increment and decrement which could be swapped for
+///  their prefix alternatives.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/llvm-prefer-pre-increment.html
+class PreferPreIncrementCheck : public ClangTidyCheck {
+public:
+  PreferPreIncrementCheck(StringRef Name, ClangTidyContext *Context);
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  const bool TransformCxxOpCalls;
+};
+
+} // namespace llvm_check
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_PREFERPREINCREMENTCHECK_H
Index: clang-tools-extra/clang-tidy/llvm/PreferPreIncrementCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/llvm/PreferPreIncrementCheck.cpp
@@ -0,0 +1,118 @@
+//===--- PreferPreIncrementCheck.cpp - clang-tidy -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "PreferPreIncrementCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+#include "llvm/ADT/SmallVector.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace llvm_check {
+
+namespace {
+AST_MATCHER_P(UnaryOperator, isOperator, UnaryOperatorKind, Opcode) {
+  return Node.getOpcode() == Opcode;
+}
+} // namespace
+
+PreferPreIncrementCheck::PreferPreIncrementCheck(StringRef Name,
+                                                 ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      TransformCxxOpCalls(Options.get("TransformCxxOpCalls", 1) != 0) {}
+
+void PreferPreIncrementCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "TransformCxxOpCalls", TransformCxxOpCalls);
+}
+
+void PreferPreIncrementCheck::registerMatchers(MatchFinder *Finder) {
+  // Ignore all unary ops with a parent decl or expr, those use the value
+  // returned. Reordering those would change the behaviour of the expression.
+  // FIXME: Add any more parents which could use the result of the operation.
+  auto BadParents =
+      unless(anyOf(hasParent(decl()), hasParent(expr()),
+                   hasParent(returnStmt()), hasParent(cxxThrowExpr())));
+  auto BoundExpr = expr().bind("ignore");
+  auto BoundChecks =
+      anyOf(hasParent(ifStmt(hasCondition(BoundExpr))),
+            hasParent(forStmt(hasCondition(BoundExpr))),
+            hasParent(switchStmt(hasCondition(BoundExpr))),
+            hasParent(whileStmt(hasCondition(BoundExpr))),
+            hasParent(doStmt(hasCondition(BoundExpr))),
+            hasParent(conditionalOperator(hasCondition(BoundExpr))),
+            hasParent(binaryConditionalOperator(hasCondition(BoundExpr))));
+
+  auto UnusedInParent =
+      allOf(BadParents, unless(allOf(BoundChecks, equalsBoundNode("ignore"))));
+
+  Finder->addMatcher(
+      unaryOperator(isOperator(UnaryOperatorKind::UO_PostInc), UnusedInParent)
+          .bind("op++"),
+      this);
+  Finder->addMatcher(
+      unaryOperator(isOperator(UnaryOperatorKind::UO_PostDec), UnusedInParent)
+          .bind("op--"),
+      this);
+
+  if (!getLangOpts().CPlusPlus || !TransformCxxOpCalls)
+    return;
+
+  auto FindCxxOpCalls = [&](llvm::StringRef PostfixName) {
+    Finder->addMatcher(
+        cxxOperatorCallExpr(
+            UnusedInParent,
+            callee(cxxMethodDecl(
+                hasName(PostfixName), parameterCountIs(1),
+                hasParent(cxxRecordDecl(hasMethod(cxxMethodDecl(
+                    hasName(PostfixName), parameterCountIs(0))))))))
+            .bind(PostfixName),
+        this);
+  };
+  FindCxxOpCalls("operator++");
+  FindCxxOpCalls("operator--");
+}
+
+void PreferPreIncrementCheck::check(const MatchFinder::MatchResult &Result) {
+  auto Apply = [&](SourceRange Range, SourceLocation OpLoc,
+                   const Expr &Expression, bool IsIncrement) {
+    // Warn for all occurances, but don't fix macro usage.
+    DiagnosticBuilder Diag =
+        diag(Range.getBegin(), "Use Pre-%0 instead of Post-%0")
+        << (IsIncrement ? "increment" : "decrement");
+    if (OpLoc.isMacroID() || Range.getBegin().isMacroID() ||
+        Range.getEnd().isMacroID())
+      return;
+    llvm::SmallVector<char, 256> Buffer;
+    Diag << FixItHint::CreateReplacement(
+        Range,
+        ((IsIncrement ? "++" : "--") +
+         tooling::fixit::getText(Expression, *Result.Context).rtrim(("-+")))
+            .toStringRef(Buffer));
+  };
+
+  if (const auto *UnaryOp = Result.Nodes.getNodeAs<UnaryOperator>("op++"))
+    return Apply(UnaryOp->getSourceRange(), UnaryOp->getOperatorLoc(),
+                 *UnaryOp->getSubExpr(), true);
+  if (const auto *UnaryOp = Result.Nodes.getNodeAs<UnaryOperator>("op--"))
+    return Apply(UnaryOp->getSourceRange(), UnaryOp->getOperatorLoc(),
+                 *UnaryOp->getSubExpr(), false);
+  if (const auto *OpCall =
+          Result.Nodes.getNodeAs<CXXOperatorCallExpr>("operator++"))
+    return Apply(OpCall->getSourceRange(), OpCall->getOperatorLoc(),
+                 *OpCall->getExprStmt(), true);
+  if (const auto *OpCall =
+          Result.Nodes.getNodeAs<CXXOperatorCallExpr>("operator--"))
+    return Apply(OpCall->getSourceRange(), OpCall->getOperatorLoc(),
+                 *OpCall->getExprStmt(), false);
+}
+
+} // namespace llvm_check
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp
+++ clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp
@@ -13,6 +13,7 @@
 #include "HeaderGuardCheck.h"
 #include "IncludeOrderCheck.h"
 #include "PreferIsaOrDynCastInConditionalsCheck.h"
+#include "PreferPreIncrementCheck.h"
 #include "PreferRegisterOverUnsignedCheck.h"
 #include "TwineLocalCheck.h"
 
@@ -29,6 +30,8 @@
         "llvm-namespace-comment");
     CheckFactories.registerCheck<PreferIsaOrDynCastInConditionalsCheck>(
         "llvm-prefer-isa-or-dyn-cast-in-conditionals");
+    CheckFactories.registerCheck<PreferPreIncrementCheck>(
+        "llvm-prefer-pre-increment");
     CheckFactories.registerCheck<PreferRegisterOverUnsignedCheck>(
         "llvm-prefer-register-over-unsigned");
     CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local");
Index: clang-tools-extra/clang-tidy/llvm/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/llvm/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/llvm/CMakeLists.txt
@@ -5,6 +5,7 @@
   IncludeOrderCheck.cpp
   LLVMTidyModule.cpp
   PreferIsaOrDynCastInConditionalsCheck.cpp
+  PreferPreIncrementCheck.cpp
   PreferRegisterOverUnsignedCheck.cpp
   TwineLocalCheck.cpp
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to