[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-10 Thread Cong Liu via Phabricator via cfe-commits
congliu updated this revision to Diff 219576.
congliu marked 6 inline comments as done.
congliu added a comment.

Addressed Haojian's comments.


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

https://reviews.llvm.org/D67135

Files:
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
  clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp

Index: clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
===
--- clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
+++ clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- \
+// RUN: -format-style=llvm \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: performance-inefficient-vector-operation.EnableProto, value: 1}]}'
 
 namespace std {
 
@@ -62,13 +65,35 @@
 
 int Op(int);
 
+namespace proto2 {
+class MessageLite {};
+class Message : public MessageLite {};
+} // namespace proto2
+
+class FooProto : public proto2::Message {
+ public:
+  int *add_x();  // repeated int x;
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+  int add_z() const; // optional int add_z;
+};
+
+class BarProto : public proto2::Message {
+ public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
 void f(std::vector& t) {
   {
 std::vector v0;
 // CHECK-FIXES: v0.reserve(10);
 for (int i = 0; i < 10; ++i)
   v0.push_back(i);
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the vector capacity before the loop
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
   }
   {
 std::vector v1;
@@ -162,6 +187,15 @@
 }
   }
 
+  {
+FooProto foo;
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop; consider pre-allocating the container capacity before the loop
+}
+  }
+
   //  Non-fixed Cases 
   {
 std::vector z0;
@@ -274,4 +308,54 @@
   z12.push_back(e);
 }
   }
+
+  {
+FooProto foo;
+foo.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+foo.add_x(-1);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+BarProto bar;
+bar.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x();
+  bar.add_x();
+}
+  }
+  {
+FooProto foo;
+foo.mutable_y();
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_z->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_z();
+}
+  }
 }
Index: clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,6 +6,10 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
+It can also find calls that add element to protobuf repeated field in a loop
+without calling Reserve() before the loop. Calling Reserve() first can avoid
+unnecessary memory reallocations.
+
 Currently, the check only detects following kinds of loops with a single
 statement body:
 
@@ -21,6 +25,13 @@
 // statement before the for statement.
   }
 
+  SomeProto p;
+  for (int i = 0; i < n; ++i) {
+p.add_xxx(n);
+// This will trigger the warning since the add_xxx may cause multiple memory
+// relloacations. This can be avoid by inserting a
+// 'p.mutable_xxx().Reserve(n)' statement before the for statement.
+  }
 
 * For-range loops like ``for (range-declaration : range_expression)``, the type
   of ``range_expression`` can be ``std::vector``, ``std::array``,
@@ -47,3 +58,8 @@
 

[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-12 Thread Cong Liu via Phabricator via cfe-commits
congliu updated this revision to Diff 219988.
congliu marked an inline comment as done.
congliu added a comment.

Addressed Haojian's comment.


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

https://reviews.llvm.org/D67135

Files:
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
  clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp

Index: clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
===
--- clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
+++ clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- \
+// RUN: -format-style=llvm \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: performance-inefficient-vector-operation.EnableProto, value: 1}]}'
 
 namespace std {
 
@@ -62,13 +65,35 @@
 
 int Op(int);
 
+namespace proto2 {
+class MessageLite {};
+class Message : public MessageLite {};
+} // namespace proto2
+
+class FooProto : public proto2::Message {
+ public:
+  int *add_x();  // repeated int x;
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+  int add_z() const; // optional int add_z;
+};
+
+class BarProto : public proto2::Message {
+ public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
 void f(std::vector& t) {
   {
 std::vector v0;
 // CHECK-FIXES: v0.reserve(10);
 for (int i = 0; i < 10; ++i)
   v0.push_back(i);
-  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the vector capacity before the loop
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
   }
   {
 std::vector v1;
@@ -162,6 +187,15 @@
 }
   }
 
+  {
+FooProto foo;
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop; consider pre-allocating the container capacity before the loop
+}
+  }
+
   //  Non-fixed Cases 
   {
 std::vector z0;
@@ -274,4 +308,54 @@
   z12.push_back(e);
 }
   }
+
+  {
+FooProto foo;
+foo.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+foo.add_x(-1);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+BarProto bar;
+bar.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x();
+  bar.add_x();
+}
+  }
+  {
+FooProto foo;
+foo.mutable_y();
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_z()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_z();
+}
+  }
 }
Index: clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,6 +6,10 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
+It can also find calls that add element to protobuf repeated field in a loop
+without calling Reserve() before the loop. Calling Reserve() first can avoid
+unnecessary memory reallocations.
+
 Currently, the check only detects following kinds of loops with a single
 statement body:
 
@@ -21,6 +25,13 @@
 // statement before the for statement.
   }
 
+  SomeProto p;
+  for (int i = 0; i < n; ++i) {
+p.add_xxx(n);
+// This will trigger the warning since the add_xxx may cause multiple memory
+// relloacations. This can be avoid by inserting a
+// 'p.mutable_xxx().Reserve(n)' statement before the for statement.
+  }
 
 * For-range loops like ``for (range-declaration : range_expression)``, the type
   of ``range_expression`` can be ``std::vector``, ``std::array``,
@@ -47,3 +5

[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-13 Thread Cong Liu via Phabricator via cfe-commits
congliu added a comment.

Could someone commit this for me? I failed to commit this change...


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

https://reviews.llvm.org/D67135



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67135: Support proto repeated field in performence-inefficient-vector-operation

2019-09-03 Thread Cong Liu via Phabricator via cfe-commits
congliu created this revision.
congliu added a reviewer: gribozavr.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Finds calls that add element to protobuf repeated field in a loop without 
calling Reserve() before the loop. Calling Reserve() first can avoid 
unnecessary memory reallocations.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D67135

Files:
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
  clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp

Index: clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
===
--- clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
+++ clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- \
+// RUN: -format-style=llvm \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: performance-inefficient-vector-operation.EnableProto, value: 1}]}'
 
 namespace std {
 
@@ -62,6 +65,27 @@
 
 int Op(int);
 
+namespace proto2 {
+class MessageLite {};
+class Message : public MessageLite {};
+} // namespace proto2
+
+class FooProto : public proto2::Message {
+public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
+class BarProto : public proto2::Message {
+public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
 void f(std::vector& t) {
   {
 std::vector v0;
@@ -162,6 +186,24 @@
 }
   }
 
+  {
+FooProto foo;
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop; consider pre-allocating the repeated field capacity before the loop
+}
+  }
+  {
+FooProto foo;
+foo.mutable_y();
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop
+}
+  }
+
   //  Non-fixed Cases 
   {
 std::vector z0;
@@ -274,4 +316,39 @@
   z12.push_back(e);
 }
   }
+
+  {
+FooProto foo;
+foo.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+foo.add_x(-1);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+BarProto bar;
+bar.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x();
+  bar.add_x();
+}
+  }
 }
Index: clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,6 +6,10 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
+When EnableProto, also finds calls that add element to protobuf repeated field
+in a loop without calling Reserve() before the loop. Calling Reserve() first
+can avoid unnecessary memory reallocations.
+
 Currently, the check only detects following kinds of loops with a single
 statement body:
 
@@ -21,6 +25,13 @@
 // statement before the for statement.
   }
 
+  SomeProto p;
+  for (int i = 0; i < n; ++i) {
+p.add_xxx(n);
+// This will trigger the warning since the add_xxx may cause multiple memory
+// relloacations. This can be avoid by inserting a
+// 'p.mutable_xxx().Reserve(n)' statement before the for statement.
+  }
 
 * For-range loops like ``for (range-declaration : range_expression)``, the type
   of ``range_expression`` can be ``std::vector``, ``std::array``,
Index: clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
===
--- clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
+++ clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
@@ -18,6 +18,9 @@
 /// Finds possible inefficient `std::vector` operations (e.g. `push_back`) in
 /// for

[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-04 Thread Cong Liu via Phabricator via cfe-commits
congliu updated this revision to Diff 218782.
congliu added a comment.

Updated option descriptions.


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

https://reviews.llvm.org/D67135

Files:
  
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst


Index: 
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- 
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ 
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,9 +6,9 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
-When EnableProto, also finds calls that add element to protobuf repeated field
-in a loop without calling Reserve() before the loop. Calling Reserve() first
-can avoid unnecessary memory reallocations.
+It can also find calls that add element to protobuf repeated field in a loop
+without calling Reserve() before the loop. Calling Reserve() first can avoid
+unnecessary memory reallocations.
 
 Currently, the check only detects following kinds of loops with a single
 statement body:
@@ -58,3 +58,8 @@
 
Semicolon-separated list of names of vector-like classes. By default only
``::std::vector`` is considered.
+
+.. option:: EnableProto
+   When non-zero, the check will also warn on inefficient operations for proto
+   repeated fields. Otherwise, the check only warns on inefficient vector
+   operations. Default is `0`.


Index: clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,9 +6,9 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
-When EnableProto, also finds calls that add element to protobuf repeated field
-in a loop without calling Reserve() before the loop. Calling Reserve() first
-can avoid unnecessary memory reallocations.
+It can also find calls that add element to protobuf repeated field in a loop
+without calling Reserve() before the loop. Calling Reserve() first can avoid
+unnecessary memory reallocations.
 
 Currently, the check only detects following kinds of loops with a single
 statement body:
@@ -58,3 +58,8 @@
 
Semicolon-separated list of names of vector-like classes. By default only
``::std::vector`` is considered.
+
+.. option:: EnableProto
+   When non-zero, the check will also warn on inefficient operations for proto
+   repeated fields. Otherwise, the check only warns on inefficient vector
+   operations. Default is `0`.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-04 Thread Cong Liu via Phabricator via cfe-commits
congliu added a comment.

In D67135#1657034 , @lebedev.ri wrote:

> I'm not sure this is the correct approach.
>  I'd think the check instead should be parametrized, so this patch should 
> become just extending the config.


Could you elaborate how the parameterized check will look like? By `config` did 
you mean the check options?


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

https://reviews.llvm.org/D67135



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-04 Thread Cong Liu via Phabricator via cfe-commits
congliu updated this revision to Diff 218789.
congliu added a comment.

Uploaded the correct diff...


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

https://reviews.llvm.org/D67135

Files:
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
  clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp

Index: clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
===
--- clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
+++ clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- \
+// RUN: -format-style=llvm \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: performance-inefficient-vector-operation.EnableProto, value: 1}]}'
 
 namespace std {
 
@@ -62,6 +65,27 @@
 
 int Op(int);
 
+namespace proto2 {
+class MessageLite {};
+class Message : public MessageLite {};
+} // namespace proto2
+
+class FooProto : public proto2::Message {
+public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
+class BarProto : public proto2::Message {
+public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
 void f(std::vector& t) {
   {
 std::vector v0;
@@ -162,6 +186,24 @@
 }
   }
 
+  {
+FooProto foo;
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop; consider pre-allocating the repeated field capacity before the loop
+}
+  }
+  {
+FooProto foo;
+foo.mutable_y();
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop
+}
+  }
+
   //  Non-fixed Cases 
   {
 std::vector z0;
@@ -274,4 +316,39 @@
   z12.push_back(e);
 }
   }
+
+  {
+FooProto foo;
+foo.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+foo.add_x(-1);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+BarProto bar;
+bar.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x();
+  bar.add_x();
+}
+  }
 }
Index: clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,6 +6,10 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
+It can also find calls that add element to protobuf repeated field in a loop
+without calling Reserve() before the loop. Calling Reserve() first can avoid
+unnecessary memory reallocations.
+
 Currently, the check only detects following kinds of loops with a single
 statement body:
 
@@ -21,6 +25,13 @@
 // statement before the for statement.
   }
 
+  SomeProto p;
+  for (int i = 0; i < n; ++i) {
+p.add_xxx(n);
+// This will trigger the warning since the add_xxx may cause multiple memory
+// relloacations. This can be avoid by inserting a
+// 'p.mutable_xxx().Reserve(n)' statement before the for statement.
+  }
 
 * For-range loops like ``for (range-declaration : range_expression)``, the type
   of ``range_expression`` can be ``std::vector``, ``std::array``,
@@ -47,3 +58,8 @@
 
Semicolon-separated list of names of vector-like classes. By default only
``::std::vector`` is considered.
+
+.. option:: EnableProto
+   When non-zero, the check will also warn on inefficient operations for proto
+   repeated fields. Otherwise, the check only warns on inefficient vector
+   operations. Default is `0`.
Index: clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
===
--- clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
+++ clang-tools-extra/clang-tidy/perf

[PATCH] D67302: Configure my project to use arcanist.

2019-09-06 Thread Cong Liu via Phabricator via cfe-commits
congliu created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67302

Files:
  clang-tools-extra/.arcconfig
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
  clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp

Index: clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
===
--- clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
+++ clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- \
+// RUN: -format-style=llvm \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: performance-inefficient-vector-operation.EnableProto, value: 1}]}'
 
 namespace std {
 
@@ -62,6 +65,28 @@
 
 int Op(int);
 
+namespace proto2 {
+class MessageLite {};
+class Message : public MessageLite {};
+} // namespace proto2
+
+class FooProto : public proto2::Message {
+ public:
+  int *add_x();  // repeated int x;
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+  int add_z() const; // optional int add_z;
+};
+
+class BarProto : public proto2::Message {
+ public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
 void f(std::vector& t) {
   {
 std::vector v0;
@@ -162,6 +187,15 @@
 }
   }
 
+  {
+FooProto foo;
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop; consider pre-allocating the repeated field capacity before the loop
+}
+  }
+
   //  Non-fixed Cases 
   {
 std::vector z0;
@@ -274,4 +308,54 @@
   z12.push_back(e);
 }
   }
+
+  {
+FooProto foo;
+foo.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+foo.add_x(-1);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+BarProto bar;
+bar.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x();
+  bar.add_x();
+}
+  }
+  {
+FooProto foo;
+foo.mutable_y();
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_z->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_z();
+}
+  }
 }
Index: clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,6 +6,10 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
+It can also find calls that add element to protobuf repeated field in a loop
+without calling Reserve() before the loop. Calling Reserve() first can avoid
+unnecessary memory reallocations.
+
 Currently, the check only detects following kinds of loops with a single
 statement body:
 
@@ -21,6 +25,13 @@
 // statement before the for statement.
   }
 
+  SomeProto p;
+  for (int i = 0; i < n; ++i) {
+p.add_xxx(n);
+// This will trigger the warning since the add_xxx may cause multiple memory
+// relloacations. This can be avoid by inserting a
+// 'p.mutable_xxx().Reserve(n)' statement before the for statement.
+  }
 
 * For-range loops like ``for (range-declaration : range_expression)``, the type
   of ``range_expression`` can be ``std::vector``, ``std::array``,
@@ -47,3 +58,8 @@
 
Semicolon-separated list of names of vector-like classes. By default only
``::std::vector`` is considered.
+
+.. option:: EnableProto
+   When non-zero, the check will also warn on inefficient operations for proto
+   repeated fields. Otherwise, the check only warns on inefficient vector
+   operations. Default is `0`.
Index: clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
=

[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-06 Thread Cong Liu via Phabricator via cfe-commits
congliu updated this revision to Diff 219180.
congliu marked 7 inline comments as done.
congliu added a comment.

Addressed Haojian's comments.

- Do not warn when there is reference to the proto variable between its 
declaration and the loop body.
- Exclude const methods.
- Update tests.


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

https://reviews.llvm.org/D67135

Files:
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
  clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
  
clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
  clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp

Index: clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
===
--- clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
+++ clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- \
+// RUN: -format-style=llvm \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: performance-inefficient-vector-operation.EnableProto, value: 1}]}'
 
 namespace std {
 
@@ -62,6 +65,28 @@
 
 int Op(int);
 
+namespace proto2 {
+class MessageLite {};
+class Message : public MessageLite {};
+} // namespace proto2
+
+class FooProto : public proto2::Message {
+ public:
+  int *add_x();  // repeated int x;
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+  int add_z() const; // optional int add_z;
+};
+
+class BarProto : public proto2::Message {
+ public:
+  int *add_x();
+  void add_x(int x);
+  void mutable_x();
+  void mutable_y();
+};
+
 void f(std::vector& t) {
   {
 std::vector v0;
@@ -162,6 +187,15 @@
 }
   }
 
+  {
+FooProto foo;
+// CHECK-FIXES: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'add_x' is called inside a loop; consider pre-allocating the repeated field capacity before the loop
+}
+  }
+
   //  Non-fixed Cases 
   {
 std::vector z0;
@@ -274,4 +308,54 @@
   z12.push_back(e);
 }
   }
+
+  {
+FooProto foo;
+foo.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+foo.add_x(-1);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+BarProto bar;
+bar.mutable_x();
+// CHECK-FIXES-NOT: foo.mutable_x->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x();
+  bar.add_x();
+}
+  }
+  {
+FooProto foo;
+foo.mutable_y();
+// CHECK-FIXES-NOT: foo.mutable_x()->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_x(i);
+}
+  }
+  {
+FooProto foo;
+// CHECK-FIXES-NOT: foo.mutable_z->Reserve(5);
+for (int i = 0; i < 5; i++) {
+  foo.add_z();
+}
+  }
 }
Index: clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
+++ clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst
@@ -6,6 +6,10 @@
 Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
 ``emplace_back``) that may cause unnecessary memory reallocations.
 
+It can also find calls that add element to protobuf repeated field in a loop
+without calling Reserve() before the loop. Calling Reserve() first can avoid
+unnecessary memory reallocations.
+
 Currently, the check only detects following kinds of loops with a single
 statement body:
 
@@ -21,6 +25,13 @@
 // statement before the for statement.
   }
 
+  SomeProto p;
+  for (int i = 0; i < n; ++i) {
+p.add_xxx(n);
+// This will trigger the warning since the add_xxx may cause multiple memory
+// relloacations. This can be avoid by inserting a
+// 'p.mutable_xxx().Reserve(n)' statement before the for statement.
+  }
 
 * For-range loops like ``for (range-declaration : range_expression)``, the type
   of ``range_expression`` can be ``std::vector``, ``std::array``,
@@ -47,3 +58,8 @@
 
Semicolon-separated list of names of vector-like classes. By default only
``::std::vector`` is considered.
+
+.. option:: EnableProto
+   When non-zero, the check will also warn on inefficient operations for proto
+   repeated fields. Otherwise, the check only warns 

[PATCH] D67135: [clang-tidy] performance-inefficient-vector-operation: Support proto repeated field

2019-09-06 Thread Cong Liu via Phabricator via cfe-commits
congliu added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp:227
+std::string MutableFieldName =
+("mutable_" + ProtoAddFieldCall->getMethodDecl()->getName().substr(4))
+.str();

hokein wrote:
> nit: getName().drop_front(sizeof("add_")).
Used 'sizeof("add_")-1' since "add_" is const char [5].



Comment at: 
clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp:233
+  if (Matches.empty()) {
+// There is no method with name "mutable_xxx".
+return;

hokein wrote:
> for repeated fields, there should be `add_foo`, `mutable_foo` methods in the 
> proto generated code 
> (https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#repeatednumeric).
> 
> So I think we can remove this check here.
I intended to rule out the corner cases when a proto field name is "add_xxx". 
But now I think checking whether there is a "mutable_xxx" method is not a 
effective way to rule out the corner case. A simpler way is just checking 
whether add_xxx is const... I have updated the matcher to exclude const methods.



Comment at: 
clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp:249
+match.getNodeAs("maybe_reallocation");
+// Skip cases where "mutable_xxx" or "add_xxx" is called before the
+// loop.

hokein wrote:
> the heuristic is limited, and will fail the cases like below:
> 
> ```
> MyProto proto;
> set_proto_xxx_size(&proto);
> for (int i = 0; i < n; ++i) {
>proto.add_xxx(i);
> }
> ```
> 
> In the vector case, we do a more strict check, maybe we do the same way as 
> well (but it will make the check fail to spot some cases)...
Good point. Let's avoid those false positives.


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

https://reviews.llvm.org/D67135



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits