Re: [PATCH] D13893: Roll-back r250822.

2016-02-03 Thread Angel Garcia via cfe-commits
angelgarcia added a subscriber: angelgarcia.
angelgarcia added a comment.

The compiler complained about creating constant instances of classes
without a user provided constructor (which is the case for the ASTMatchers).

I gave up this change because it broke the build for a huge amount of
people and I didn't want that to happen again.


Repository:
  rL LLVM

http://reviews.llvm.org/D13893



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


Re: [PATCH] D14442: Allow the alias to be of a different type.

2015-11-06 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 39530.
angelgarcia added a comment.

The test revealed a (already existing) bug. If we called getName() on a 
CXXConversionDecl, we would get the following assertion:

include/clang/AST/Decl.h:170: llvm::StringRef clang::NamedDecl::getName() 
const: Assertion `Name.isIdentifier() && "Name is not a simple identifier"' 
failed.

Solved now.


http://reviews.llvm.org/D14442

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -159,14 +159,33 @@
   // CHECK-FIXES: for (int Alias : IntArr)
   // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)
 
-  struct IntRef { IntRef(const int& i); };
+  struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
   for (int I = 0; I < N; ++I) {
 IntRef Int(IntArr[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (int I : IntArr)
   // CHECK-FIXES-NEXT: IntRef Int(I);
 
+  int *PtrArr[N];
+  for (unsigned I = 0; I < N; ++I) {
+const int* const P = PtrArr[I];
+printf("%d\n", *P);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto P : PtrArr)
+  // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
+  IntRef Refs[N];
+  for (unsigned I = 0; I < N; ++I) {
+int *P = Refs[I];
+printf("%d\n", *P);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Ref : Refs)
+  // CHECK-FIXES-NEXT: int *P = Ref;
+  // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
   // Ensure that removing the alias doesn't leave empty lines behind.
   for (int I = 0; I < N; ++I) {
 auto &X = IntArr[I];
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -342,21 +342,27 @@
   if (!VDecl->hasInit())
 return false;
 
-  const Expr *Init =
-  digThroughConstructors(VDecl->getInit()->IgnoreParenImpCasts());
+  bool OnlyCasts = true;
+  const Expr *Init = VDecl->getInit()->IgnoreParenImpCasts();
+  if (Init && isa(Init)) {
+Init = digThroughConstructors(Init);
+OnlyCasts = false;
+  }
   if (!Init)
 return false;
 
   // Check that the declared type is the same as (or a reference to) the
   // container type.
-  QualType InitType = Init->getType();
-  QualType DeclarationType = VDecl->getType();
-  if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
-DeclarationType = DeclarationType.getNonReferenceType();
+  if (!OnlyCasts) {
+QualType InitType = Init->getType();
+QualType DeclarationType = VDecl->getType();
+if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
+  DeclarationType = DeclarationType.getNonReferenceType();
 
-  if (InitType.isNull() || DeclarationType.isNull() ||
-  !Context->hasSameUnqualifiedType(DeclarationType, InitType))
-return false;
+if (InitType.isNull() || DeclarationType.isNull() ||
+!Context->hasSameUnqualifiedType(DeclarationType, InitType))
+  return false;
+  }
 
   switch (Init->getStmtClass()) {
   case Stmt::ArraySubscriptExprClass: {
@@ -384,8 +390,8 @@
 const auto *MemCall = cast(Init);
 // This check is needed because getMethodDecl can return nullptr if the
 // callee is a member function pointer.
-if (MemCall->getMethodDecl() &&
-MemCall->getMethodDecl()->getName() == "at") {
+const auto *MDecl = MemCall->getMethodDecl();
+if (MDecl && !isa(MDecl) && MDecl->getName() == "at") {
   assert(MemCall->getNumArgs() == 1);
   return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar);
 }


Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -159,14 +159,33 @@
   // CHECK-FIXES: for (int Alias : IntArr)
   // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)
 
-  struct IntRef { IntRef(const int& i); };
+  struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
   for (int I = 0; I < N; ++I) {
 IntRef Int(IntArr[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (int I : IntArr)
   // CHECK-FIXES-NEXT: IntRef Int(I);
 
+  int *PtrArr[N];
+  for (unsigned I = 0; I < N; ++I) {
+const int* const P = PtrArr[I];
+printf("%d\n", *P);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto P : PtrArr)
+  // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
+  IntRef

Re: [PATCH] D14442: Allow the alias to be of a different type.

2015-11-06 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

No. There is a test for that just before the one I added.


http://reviews.llvm.org/D14442



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


[PATCH] D14442: Allow the alias to be of a different type.

2015-11-06 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Consider a declaration an alias even if it doesn't have the same unqualified 
type than the container element, as long as one can be converted to the other 
using only implicit casts.

http://reviews.llvm.org/D14442

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -167,6 +167,15 @@
   // CHECK-FIXES: for (int I : IntArr)
   // CHECK-FIXES-NEXT: IntRef Int(I);
 
+  int *PtrArr[N];
+  for (unsigned I = 0; I < N; ++I) {
+const int* const P = PtrArr[I];
+printf("%d\n", *P);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto P : PtrArr)
+  // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
   // Ensure that removing the alias doesn't leave empty lines behind.
   for (int I = 0; I < N; ++I) {
 auto &X = IntArr[I];
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -342,21 +342,27 @@
   if (!VDecl->hasInit())
 return false;
 
-  const Expr *Init =
-  digThroughConstructors(VDecl->getInit()->IgnoreParenImpCasts());
+  bool OnlyCasts = true;
+  const Expr *Init = VDecl->getInit()->IgnoreParenImpCasts();
+  if (Init && isa(Init)) {
+Init = digThroughConstructors(Init);
+OnlyCasts = false;
+  }
   if (!Init)
 return false;
 
   // Check that the declared type is the same as (or a reference to) the
   // container type.
-  QualType InitType = Init->getType();
-  QualType DeclarationType = VDecl->getType();
-  if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
-DeclarationType = DeclarationType.getNonReferenceType();
+  if (!OnlyCasts) {
+QualType InitType = Init->getType();
+QualType DeclarationType = VDecl->getType();
+if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
+  DeclarationType = DeclarationType.getNonReferenceType();
 
-  if (InitType.isNull() || DeclarationType.isNull() ||
-  !Context->hasSameUnqualifiedType(DeclarationType, InitType))
-return false;
+if (InitType.isNull() || DeclarationType.isNull() ||
+!Context->hasSameUnqualifiedType(DeclarationType, InitType))
+  return false;
+  }
 
   switch (Init->getStmtClass()) {
   case Stmt::ArraySubscriptExprClass: {


Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -167,6 +167,15 @@
   // CHECK-FIXES: for (int I : IntArr)
   // CHECK-FIXES-NEXT: IntRef Int(I);
 
+  int *PtrArr[N];
+  for (unsigned I = 0; I < N; ++I) {
+const int* const P = PtrArr[I];
+printf("%d\n", *P);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto P : PtrArr)
+  // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
   // Ensure that removing the alias doesn't leave empty lines behind.
   for (int I = 0; I < N; ++I) {
 auto &X = IntArr[I];
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -342,21 +342,27 @@
   if (!VDecl->hasInit())
 return false;
 
-  const Expr *Init =
-  digThroughConstructors(VDecl->getInit()->IgnoreParenImpCasts());
+  bool OnlyCasts = true;
+  const Expr *Init = VDecl->getInit()->IgnoreParenImpCasts();
+  if (Init && isa(Init)) {
+Init = digThroughConstructors(Init);
+OnlyCasts = false;
+  }
   if (!Init)
 return false;
 
   // Check that the declared type is the same as (or a reference to) the
   // container type.
-  QualType InitType = Init->getType();
-  QualType DeclarationType = VDecl->getType();
-  if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
-DeclarationType = DeclarationType.getNonReferenceType();
+  if (!OnlyCasts) {
+QualType InitType = Init->getType();
+QualType DeclarationType = VDecl->getType();
+if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
+  DeclarationType = DeclarationType.getNonReferenceType();
 
-  if (InitType.isNull() || DeclarationType.isNull() ||
-  !Context->hasSameUnqualifiedType(DeclarationType, InitType))
-return false;
+if (InitType.isNull() || DeclarationType.isNull() ||
+!Context->hasSameUnqualifiedType(DeclarationType, InitType))
+  return false;
+  }
 
   switch (Init->getStmtClass()) {
   c

[PATCH] D14438: Use the old index identifier by default, instead of 'elem'.

2015-11-06 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added a subscriber: cfe-commits.

Use the old index name in the cases where the check would come up with an 
invented name.

http://reviews.llvm.org/D14438

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-camelback.cpp
  test/clang-tidy/modernize-loop-convert-const.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -14,8 +14,8 @@
 printf("%d\n", ARR[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int ELEM : ARR)
-  // CHECK-FIXES-NEXT: printf("%d\n", ELEM);
+  // CHECK-FIXES: for (int I : ARR)
+  // CHECK-FIXES-NEXT: printf("%d\n", I);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I]);
@@ -36,50 +36,6 @@
 printf("%d\n", NUMS[I] + NUM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int ELEM : NUMS)
-  // CHECK-FIXES-NEXT: printf("%d\n", ELEM + NUM);
-
-  int ELEM = 0;
-  for (int I = 0; I < N; ++I) {
-printf("%d\n", NUMS[I] + NUM + ELEM);
-  }
-  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int NUMS_I : NUMS)
-  // CHECK-FIXES-NEXT: printf("%d\n", NUMS_I + NUM + ELEM);
-
-  int NUMS_I = 0;
-  for (int I = 0; I < N; ++I) {
-printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I);
-  }
-  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int NUMS_ELEM : NUMS)
-  // CHECK-FIXES-NEXT: printf("%d\n", NUMS_ELEM + NUM + ELEM + NUMS_I);
-
-  int NUMS_ELEM = 0;
-  for (int I = 0; I < N; ++I) {
-printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM);
-  }
-  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
-  // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + NUM + ELEM + NUMS_I + NUMS_ELEM);
-
-  int GIVE_ME_NAME_0 = 0;
-  for (int I = 0; I < N; ++I) {
-printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
-  }
-  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
-  // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
-
-  int NUMS_J = 0;
-  for (int I = 0; I < N; ++I) {
-for (int J = 0; J < N; ++J) {
-  printf("%d\n", NUMS[I] + NUMS[J] + NUM + ELEM + NUMS_I + NUMS_J + NUMS_ELEM);
-}
-  }
-  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
-  // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
-  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
-  // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_J + NUMS_ELEM);
+  // CHECK-FIXES: for (int I : NUMS)
+  // CHECK-FIXES-NEXT: printf("%d\n", I + NUM);
 }
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -14,8 +14,8 @@
 printf("%d\n", arr[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int elem : arr)
-  // CHECK-FIXES-NEXT: printf("%d\n", elem);
+  // CHECK-FIXES: for (int i : arr)
+  // CHECK-FIXES-NEXT: printf("%d\n", i);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i]);
@@ -36,50 +36,6 @@
 printf("%d\n", nums[i] + num);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int elem : nums)
-  // CHECK-FIXES-NEXT: printf("%d\n", elem + num);
-
-  int elem = 0;
-  for (int i = 0; i < n; ++i) {
-printf("%d\n", nums[i] + num + elem);
-  }
-  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int nums_i : nums)
-  // CHECK-FIXES-NEXT: printf("%d\n", nums_i + num + elem);
-
-  int nums_i = 0;
-  for (int i = 0; i < n; ++i) {
-printf("%d\n", nums[i] + num + elem + nums_i);
-  }
-  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int nums_elem : nums)
-  // CHECK-FIXES-NEXT: printf("%d\n", nums_elem + num + elem + nums_i);
-
-  int nums_elem = 0;
-  for (int i = 0; i < n; ++i) {
-printf("%d\n", nums[i] +

[PATCH] D14437: Avoid naming conflicts with the old index in modernize-loop-convert.

2015-11-06 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

The old index declaration is going to be removed anyway, so we can reuse its 
name if it is the best candidate for the new index.

http://reviews.llvm.org/D14437

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -325,6 +325,23 @@
   // CHECK-FIXES-NEXT: (void)NumsI;
 }
 
+void oldIndexConflict() {
+  for (int Num = 0; Num < N; ++Num) {
+printf("Num: %d\n", Nums[Num]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Num : Nums)
+  // CHECK-FIXES-NEXT: printf("Num: %d\n", Num);
+
+  S Things;
+  for (S::iterator Thing = Things.begin(), End = Things.end(); Thing != End; 
++Thing) {
+printf("Thing: %d %d\n", Thing->X, (*Thing).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Thing : Things)
+  // CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X);
+}
+
 void macroConflict() {
   S MAXs;
   for (S::iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -820,14 +820,14 @@
   if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) {
 IteratorName = ContainerName.substr(0, Len - 1);
 // E.g.: (auto thing : things)
-if (!declarationExists(IteratorName))
+if (!declarationExists(IteratorName) || IteratorName == 
OldIndex->getName())
   return IteratorName;
   }
 
   if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) {
 IteratorName = ContainerName.substr(0, Len - 2);
 // E.g.: (auto thing : things_)
-if (!declarationExists(IteratorName))
+if (!declarationExists(IteratorName) || IteratorName == 
OldIndex->getName())
   return IteratorName;
   }
 
@@ -849,12 +849,12 @@
 
   IteratorName = AppendWithStyle(ContainerName, OldIndex->getName());
   // E.g.: (auto container_i : container)
-  if (!declarationExists(IteratorName))
+  if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName())
 return IteratorName;
 
   IteratorName = AppendWithStyle(ContainerName, Elem);
   // E.g.: (auto container_elem : container)
-  if (!declarationExists(IteratorName))
+  if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName())
 return IteratorName;
 
   // Someone defeated my naming scheme...
@@ -875,7 +875,8 @@
   int Attempt = 0;
   do {
 IteratorName = GiveMeName + std::to_string(Attempt++);
-  } while (declarationExists(IteratorName));
+  } while (declarationExists(IteratorName) ||
+   IteratorName == OldIndex->getName());
 
   return IteratorName;
 }


Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -325,6 +325,23 @@
   // CHECK-FIXES-NEXT: (void)NumsI;
 }
 
+void oldIndexConflict() {
+  for (int Num = 0; Num < N; ++Num) {
+printf("Num: %d\n", Nums[Num]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Num : Nums)
+  // CHECK-FIXES-NEXT: printf("Num: %d\n", Num);
+
+  S Things;
+  for (S::iterator Thing = Things.begin(), End = Things.end(); Thing != End; ++Thing) {
+printf("Thing: %d %d\n", Thing->X, (*Thing).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Thing : Things)
+  // CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X);
+}
+
 void macroConflict() {
   S MAXs;
   for (S::iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -820,14 +820,14 @@
   if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) {
 IteratorName = ContainerName.substr(0, Len - 1);
 // E.g.: (auto thing : things)
-if (!declarationExists(IteratorName))
+if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName())
   return IteratorName;
   }
 
   if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) {
 IteratorName = ContainerName.substr(0, Len - 2);
 // E.g.: (auto thing : things_)
-if (!declarationExists(IteratorN

Re: [PATCH] D14378: Fix another case where loop-convert wasn't handling correctly data members.

2015-11-05 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 39350.
angelgarcia added a comment.

Update the method comment.


http://reviews.llvm.org/D14378

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -240,6 +240,7 @@
 struct MemberNaming {
   const static int N = 10;
   int Ints[N], Ints_[N];
+  dependent DInts;
   void loops() {
 for (int I = 0; I < N; ++I) {
   printf("%d\n", Ints[I]);
@@ -254,8 +255,32 @@
 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop 
instead
 // CHECK-FIXES: for (int Int : Ints_)
 // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+for (int I = 0; I < DInts.size(); ++I) {
+  printf("%d\n", DInts[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop 
instead
+// CHECK-FIXES: for (int DInt : DInts)
+// CHECK-FIXES-NEXT: printf("%d\n", DInt);
   }
+
+  void outOfLine();
 };
+void MemberNaming::outOfLine() {
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints_)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+}
 
 } // namespace NamingAlias
 
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -352,12 +352,12 @@
   LangOpts);
 }
 
-/// \brief If the given expression is actually a DeclRefExpr, find and return
-/// the underlying ValueDecl; otherwise, return NULL.
+/// \brief If the given expression is actually a DeclRefExpr or a MemberExpr,
+/// find and return the underlying ValueDecl; otherwise, return NULL.
 static const ValueDecl *getReferencedVariable(const Expr *E) {
   if (const DeclRefExpr *DRE = getDeclRef(E))
 return dyn_cast(DRE->getDecl());
-  if (const auto *Mem = dyn_cast(E))
+  if (const auto *Mem = dyn_cast(E->IgnoreParenImpCasts()))
 return dyn_cast(Mem->getMemberDecl());
   return nullptr;
 }


Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -240,6 +240,7 @@
 struct MemberNaming {
   const static int N = 10;
   int Ints[N], Ints_[N];
+  dependent DInts;
   void loops() {
 for (int I = 0; I < N; ++I) {
   printf("%d\n", Ints[I]);
@@ -254,8 +255,32 @@
 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
 // CHECK-FIXES: for (int Int : Ints_)
 // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+for (int I = 0; I < DInts.size(); ++I) {
+  printf("%d\n", DInts[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int DInt : DInts)
+// CHECK-FIXES-NEXT: printf("%d\n", DInt);
   }
+
+  void outOfLine();
 };
+void MemberNaming::outOfLine() {
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints_)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+}
 
 } // namespace NamingAlias
 
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -352,12 +352,12 @@
   LangOpts);
 }
 
-/// \brief If the given expression is actually a DeclRefExpr, find and return
-/// the underlying ValueDecl; otherwise, return NULL.
+/// \brief If the given expression is actually a DeclRefExpr or a MemberExpr,
+/// find and return the underlying ValueDecl; otherwise, return NULL.
 static const ValueDecl *getReferencedVariable(const Expr *E) {
   if (const DeclRefExpr *DRE = getDeclRef(E))
 return dyn_cast(DRE->getDecl());
-  if (const auto *Mem = dyn_cast(E))
+  if (const auto *Mem = dyn_cast(E->IgnoreParenImpCasts()))
 return dyn_cast(Mem->getMemberDecl());
   return nullptr;
 }
___
cfe-commits mailing list
cfe-commits

[PATCH] D14378: Fix another case where loop-convert wasn't handling correctly data members.

2015-11-05 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

If the container expression was obtained from the point where "size" (which 
usually is a const method) is invoked, then the topmost node in this expression 
may be an implicit cast to const.

When the container is a data member, the check was trying to obtain the member 
expression directly and was failing in the case mentioned above. This is solved 
by ignoring implicit casts.

http://reviews.llvm.org/D14378

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -240,6 +240,7 @@
 struct MemberNaming {
   const static int N = 10;
   int Ints[N], Ints_[N];
+  dependent DInts;
   void loops() {
 for (int I = 0; I < N; ++I) {
   printf("%d\n", Ints[I]);
@@ -254,8 +255,32 @@
 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop 
instead
 // CHECK-FIXES: for (int Int : Ints_)
 // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+for (int I = 0; I < DInts.size(); ++I) {
+  printf("%d\n", DInts[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop 
instead
+// CHECK-FIXES: for (int DInt : DInts)
+// CHECK-FIXES-NEXT: printf("%d\n", DInt);
   }
+
+  void outOfLine();
 };
+void MemberNaming::outOfLine() {
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints_)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+}
 
 } // namespace NamingAlias
 
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -357,7 +357,7 @@
 static const ValueDecl *getReferencedVariable(const Expr *E) {
   if (const DeclRefExpr *DRE = getDeclRef(E))
 return dyn_cast(DRE->getDecl());
-  if (const auto *Mem = dyn_cast(E))
+  if (const auto *Mem = dyn_cast(E->IgnoreParenImpCasts()))
 return dyn_cast(Mem->getMemberDecl());
   return nullptr;
 }


Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -240,6 +240,7 @@
 struct MemberNaming {
   const static int N = 10;
   int Ints[N], Ints_[N];
+  dependent DInts;
   void loops() {
 for (int I = 0; I < N; ++I) {
   printf("%d\n", Ints[I]);
@@ -254,8 +255,32 @@
 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
 // CHECK-FIXES: for (int Int : Ints_)
 // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+for (int I = 0; I < DInts.size(); ++I) {
+  printf("%d\n", DInts[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int DInt : DInts)
+// CHECK-FIXES-NEXT: printf("%d\n", DInt);
   }
+
+  void outOfLine();
 };
+void MemberNaming::outOfLine() {
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", Ints_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints_)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+}
 
 } // namespace NamingAlias
 
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -357,7 +357,7 @@
 static const ValueDecl *getReferencedVariable(const Expr *E) {
   if (const DeclRefExpr *DRE = getDeclRef(E))
 return dyn_cast(DRE->getDecl());
-  if (const auto *Mem = dyn_cast(E))
+  if (const auto *Mem = dyn_cast(E->IgnoreParenImpCasts()))
 return dyn_cast(Mem->getMemberDecl());
   return nullptr;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D14291: Improve modernize-make-unique matcher.

2015-11-03 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

"std::unique_ptr" is not the same type as "std::unique_ptr>", unless we insert a "hasCanonicalType" in the 
middle. Probably it also happens in other cases related to default template 
argument.

http://reviews.llvm.org/D14291

Files:
  clang-tidy/modernize/MakeUniqueCheck.cpp
  test/clang-tidy/modernize-make-unique.cpp

Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -195,3 +195,9 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_unique instead
   // CHECK-FIXES: auto Spaces = std::make_unique();
 }
+
+void nesting() {
+  auto Nest = std::unique_ptr>(new 
std::unique_ptr(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_unique instead
+  // CHECK-FIXES: auto Nest = std::make_unique>(new int);
+}
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -42,9 +42,10 @@
   qualType(equalsBoundNode(
   PointerType))),
 argumentCountIs(1),
-hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType(
-  equalsBoundNode(PointerType)
-   .bind(NewExpression)))
+hasArgument(
+0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
+  equalsBoundNode(PointerType))
+   .bind(NewExpression)))
 .bind(ConstructorCall))),
 this);
   }


Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -195,3 +195,9 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_unique instead
   // CHECK-FIXES: auto Spaces = std::make_unique();
 }
+
+void nesting() {
+  auto Nest = std::unique_ptr>(new std::unique_ptr(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_unique instead
+  // CHECK-FIXES: auto Nest = std::make_unique>(new int);
+}
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -42,9 +42,10 @@
   qualType(equalsBoundNode(
   PointerType))),
 argumentCountIs(1),
-hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType(
-  equalsBoundNode(PointerType)
-   .bind(NewExpression)))
+hasArgument(
+0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
+  equalsBoundNode(PointerType))
+   .bind(NewExpression)))
 .bind(ConstructorCall))),
 this);
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D14289: Handle correctly containers that are data members in modernize-loop-convert.

2015-11-03 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 39075.
angelgarcia added a comment.

Merge with the latest revision.


http://reviews.llvm.org/D14289

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/LoopConvertCheck.h
  clang-tidy/modernize/LoopConvertUtils.h
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-const.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-negative.cpp

Index: test/clang-tidy/modernize-loop-convert-negative.cpp
===
--- test/clang-tidy/modernize-loop-convert-negative.cpp
+++ test/clang-tidy/modernize-loop-convert-negative.cpp
@@ -92,33 +92,6 @@
   }
 }
 
-struct HasArr {
-  int Arr[N];
-  Val ValArr[N];
-};
-
-struct HasIndirectArr {
-  HasArr HA;
-  void implicitThis() {
-for (int I = 0; I < N; ++I) {
-  printf("%d", HA.Arr[I]);
-}
-
-for (int I = 0; I < N; ++I) {
-  printf("%d", HA.ValArr[I].X);
-}
-  }
-
-  void explicitThis() {
-for (int I = 0; I < N; ++I) {
-  printf("%d", this->HA.Arr[I]);
-}
-
-for (int I = 0; I < N; ++I) {
-  printf("%d", this->HA.ValArr[I].X);
-}
-  }
-};
 }
 
 namespace NegativeIterator {
Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -237,6 +237,26 @@
   }
 }
 
+struct MemberNaming {
+  const static int N = 10;
+  int Ints[N], Ints_[N];
+  void loops() {
+for (int I = 0; I < N; ++I) {
+  printf("%d\n", Ints[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Int : Ints)
+// CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+for (int I = 0; I < N; ++I) {
+  printf("%d\n", Ints_[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Int : Ints_)
+// CHECK-FIXES-NEXT: printf("%d\n", Int);
+  }
+};
+
 } // namespace NamingAlias
 
 namespace NamingConlict {
Index: test/clang-tidy/modernize-loop-convert-const.cpp
===
--- test/clang-tidy/modernize-loop-convert-const.cpp
+++ test/clang-tidy/modernize-loop-convert-const.cpp
@@ -341,7 +341,7 @@
 copyArg(Ints[I]);
 }
 // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
-// CHECK-FIXES: for (int Elem : Ints)
+// CHECK-FIXES: for (int Int : Ints)
 
 for (int I = 0; I < N; ++I) {
   Array[I].constMember(0);
Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -168,6 +168,41 @@
   }
 };
 
+struct HasIndirectArr {
+  HasArr HA;
+  void implicitThis() {
+for (int I = 0; I < N; ++I) {
+  printf("%d", HA.Arr[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Elem : HA.Arr)
+// CHECK-FIXES-NEXT: printf("%d", Elem);
+
+for (int I = 0; I < N; ++I) {
+  printf("%d", HA.ValArr[I].X);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (auto & Elem : HA.ValArr)
+// CHECK-FIXES-NEXT: printf("%d", Elem.X);
+  }
+
+  void explicitThis() {
+for (int I = 0; I < N; ++I) {
+  printf("%d", this->HA.Arr[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Elem : this->HA.Arr)
+// CHECK-FIXES-NEXT: printf("%d", Elem);
+
+for (int I = 0; I < N; ++I) {
+  printf("%d", this->HA.ValArr[I].X);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (auto & Elem : this->HA.ValArr)
+// CHECK-FIXES-NEXT: printf("%d", Elem.X);
+  }
+};
+
 // Loops whose bounds are value-dependent should not be converted.
 template 
 void dependentExprBound() {
Index: clang-tidy/modernize/LoopConvertUtils.h
===
--- clang-tidy/modernize/LoopConvertUtils.h
+++ clang-tidy/modernize/LoopConvertUtils.h
@@ -425,7 +425,7 @@
   VariableNamer(StmtGeneratedVarNameMap *GeneratedDecls,
 const StmtParentMap *ReverseAST, const clang::Stmt *SourceStmt,
 const clang::VarDecl *OldIndex,
-const clang::VarDecl *TheContainer,
+const clang::ValueDecl *TheContainer,
 const clang::ASTContext *Context, NamingStyle Style)
   : GeneratedDecls(GeneratedDecls), ReverseAST(ReverseAST),
 SourceStmt(SourceStmt), OldIndex(OldIndex), TheContainer(TheContainer),
@@ -443,7 +443,7 @@
   const StmtParentMa

Re: [PATCH] D14282: Improve more the const-detection in modernize-loop-convert.

2015-11-03 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL251940: Improve more the const-detection in 
modernize-loop-convert. (authored by angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D14282?vs=39052&id=39074#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D14282

Files:
  clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp

Index: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -372,6 +372,8 @@
 /// containter that we are iterating over, returns false when it can be
 /// guaranteed this element cannot be modified as a result of this usage.
 static bool canBeModified(ASTContext *Context, const Expr *E) {
+  if (E->getType().isConstQualified())
+return false;
   auto Parents = Context->getParents(*E);
   if (Parents.size() != 1)
 return true;
Index: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp
@@ -271,28 +271,91 @@
   // Aliases.
   for (int I = 0; I < N; ++I) {
 const Str &J = Array[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (auto J : Array)
   for (int I = 0; I < N; ++I) {
 Str &J = Array[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (auto & J : Array)
 
   for (int I = 0; I < N; ++I) {
 const int &J = Ints[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (int J : Ints)
 
   for (int I = 0; I < N; ++I) {
 int &J = Ints[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (int & J : Ints)
 }
+
+template 
+struct vector {
+  unsigned size() const;
+  const T &operator[](int) const;
+  T &operator[](int);
+  T *begin();
+  T *end();
+  const T *begin() const;
+  const T *end() const;
+};
+
+// If the elements are already constant, we won't do any ImplicitCast to const.
+void testContainerOfConstElements() {
+  const int Ints[N]{};
+  for (int I = 0; I < N; ++I) {
+OtherInt -= Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+
+  vector Strs;
+  for (int I = 0; I < Strs.size(); ++I) {
+Strs[I].constMember(0);
+constRefArg(Strs[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto Str : Strs)
+}
+
+// When we are inside a const-qualified member functions, all the data members
+// are implicitly set as const. As before, there won't be any ImplicitCast to
+// const in their usages.
+class TestInsideConstFunction {
+  const static int N = 10;
+  int Ints[N];
+  Str Array[N];
+  vector V;
+
+  void foo() const {
+for (int I = 0; I < N; ++I) {
+  if (Ints[I])
+copyArg(Ints[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+// CHECK-FIXES: for (int Elem : Ints)
+
+for (int I = 0; I < N; ++I) {
+  Array[I].constMember(0);
+  constRefArg(Array[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+// CHECK-FIXES: for (auto Elem : Array)
+
+for (int I = 0; I < V.size(); ++I) {
+  if (V[I])
+copyArg(V[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+// CHECK-FIXES: for (int Elem : V)
+
+  }
+};
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D14289: Handle correctly containers that are data members in modernize-loop-convert.

2015-11-03 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

I recently found that the variable naming wasn't working as expected with 
containers that are data members. The new index always received the name "Elem" 
(or equivalent) regardless of the container's name.
The check was assuming that the container's declaration was a VarDecl, which 
cannot be converted to a FieldDecl (a data member), and then it could never 
retrieve its name.

This also fixes some cases where the check failed to find the container at all 
(so it didn't do any fix) because of the same reason.

http://reviews.llvm.org/D14289

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/LoopConvertCheck.h
  clang-tidy/modernize/LoopConvertUtils.h
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-negative.cpp

Index: test/clang-tidy/modernize-loop-convert-negative.cpp
===
--- test/clang-tidy/modernize-loop-convert-negative.cpp
+++ test/clang-tidy/modernize-loop-convert-negative.cpp
@@ -92,33 +92,6 @@
   }
 }
 
-struct HasArr {
-  int Arr[N];
-  Val ValArr[N];
-};
-
-struct HasIndirectArr {
-  HasArr HA;
-  void implicitThis() {
-for (int I = 0; I < N; ++I) {
-  printf("%d", HA.Arr[I]);
-}
-
-for (int I = 0; I < N; ++I) {
-  printf("%d", HA.ValArr[I].X);
-}
-  }
-
-  void explicitThis() {
-for (int I = 0; I < N; ++I) {
-  printf("%d", this->HA.Arr[I]);
-}
-
-for (int I = 0; I < N; ++I) {
-  printf("%d", this->HA.ValArr[I].X);
-}
-  }
-};
 }
 
 namespace NegativeIterator {
Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -237,6 +237,26 @@
   }
 }
 
+struct MemberNaming {
+  const static int N = 10;
+  int Ints[N], Ints_[N];
+  void loops() {
+for (int I = 0; I < N; ++I) {
+  printf("%d\n", Ints[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Int : Ints)
+// CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+for (int I = 0; I < N; ++I) {
+  printf("%d\n", Ints_[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Int : Ints_)
+// CHECK-FIXES-NEXT: printf("%d\n", Int);
+  }
+};
+
 } // namespace NamingAlias
 
 namespace NamingConlict {
Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -168,6 +168,41 @@
   }
 };
 
+struct HasIndirectArr {
+  HasArr HA;
+  void implicitThis() {
+for (int I = 0; I < N; ++I) {
+  printf("%d", HA.Arr[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Elem : HA.Arr)
+// CHECK-FIXES-NEXT: printf("%d", Elem);
+
+for (int I = 0; I < N; ++I) {
+  printf("%d", HA.ValArr[I].X);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (auto & Elem : HA.ValArr)
+// CHECK-FIXES-NEXT: printf("%d", Elem.X);
+  }
+
+  void explicitThis() {
+for (int I = 0; I < N; ++I) {
+  printf("%d", this->HA.Arr[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (int Elem : this->HA.Arr)
+// CHECK-FIXES-NEXT: printf("%d", Elem);
+
+for (int I = 0; I < N; ++I) {
+  printf("%d", this->HA.ValArr[I].X);
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+// CHECK-FIXES: for (auto & Elem : this->HA.ValArr)
+// CHECK-FIXES-NEXT: printf("%d", Elem.X);
+  }
+};
+
 // Loops whose bounds are value-dependent should not be converted.
 template 
 void dependentExprBound() {
Index: clang-tidy/modernize/LoopConvertUtils.h
===
--- clang-tidy/modernize/LoopConvertUtils.h
+++ clang-tidy/modernize/LoopConvertUtils.h
@@ -425,7 +425,7 @@
   VariableNamer(StmtGeneratedVarNameMap *GeneratedDecls,
 const StmtParentMap *ReverseAST, const clang::Stmt *SourceStmt,
 const clang::VarDecl *OldIndex,
-const clang::VarDecl *TheContainer,
+const clang::ValueDecl *TheContainer,
 const clang::ASTContext *Context, NamingStyle Style)
   : GeneratedDecls(GeneratedDecls), ReverseAST(ReverseAST),
 SourceStmt(SourceStmt), OldIndex(OldIndex), TheContainer(TheContainer),
@@ -443,7 +443,7 @@
   const StmtParentMap *ReverseAST;
   const clang::S

[PATCH] D14282: Improve more the const-detection in modernize-loop-convert.

2015-11-03 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

The previous change was focused in detecting when a non-const object was used 
in a constant way. Looks like I forgot the most important and trivial case: 
when the object is already constant. Failing to detect this cases results in 
compile errors, due to trying to bind a constant object to a non-const 
reference in the range-for statement. This change should fix that.

http://reviews.llvm.org/D14282

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-const.cpp

Index: test/clang-tidy/modernize-loop-convert-const.cpp
===
--- test/clang-tidy/modernize-loop-convert-const.cpp
+++ test/clang-tidy/modernize-loop-convert-const.cpp
@@ -271,28 +271,91 @@
   // Aliases.
   for (int I = 0; I < N; ++I) {
 const Str &J = Array[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (auto J : Array)
   for (int I = 0; I < N; ++I) {
 Str &J = Array[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (auto & J : Array)
 
   for (int I = 0; I < N; ++I) {
 const int &J = Ints[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (int J : Ints)
 
   for (int I = 0; I < N; ++I) {
 int &J = Ints[I];
-(void) J;
+(void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (int & J : Ints)
 }
+
+template 
+struct vector {
+  unsigned size() const;
+  const T &operator[](int) const;
+  T &operator[](int);
+  T *begin();
+  T *end();
+  const T *begin() const;
+  const T *end() const;
+};
+
+// If the elements are already constant, we won't do any ImplicitCast to const.
+void testContainerOfConstElements() {
+  const int Ints[N]{};
+  for (int I = 0; I < N; ++I) {
+OtherInt -= Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+
+  vector Strs;
+  for (int I = 0; I < Strs.size(); ++I) {
+Strs[I].constMember(0);
+constRefArg(Strs[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto Str : Strs)
+}
+
+// When we are inside a const-qualified member functions, all the data members
+// are implicitly set as const. As before, there won't be any ImplicitCast to
+// const in their usages.
+class TestInsideConstFunction {
+  const static int N = 10;
+  int Ints[N];
+  Str Array[N];
+  vector V;
+
+  void foo() const {
+for (int I = 0; I < N; ++I) {
+  if (Ints[I])
+copyArg(Ints[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+// CHECK-FIXES: for (int Elem : Ints)
+
+for (int I = 0; I < N; ++I) {
+  Array[I].constMember(0);
+  constRefArg(Array[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+// CHECK-FIXES: for (auto Elem : Array)
+
+for (int I = 0; I < V.size(); ++I) {
+  if (V[I])
+copyArg(V[I]);
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+// CHECK-FIXES: for (int Elem : V)
+
+  }
+};
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -372,6 +372,8 @@
 /// containter that we are iterating over, returns false when it can be
 /// guaranteed this element cannot be modified as a result of this usage.
 static bool canBeModified(ASTContext *Context, const Expr *E) {
+  if (E->getType().isConstQualified())
+return false;
   auto Parents = Context->getParents(*E);
   if (Parents.size() != 1)
 return true;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D14198: Make the modernize-loop-convert's const-detection smarter.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38930.
angelgarcia added a comment.

OK, is it better now?


http://reviews.llvm.org/D14198

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-camelback.cpp
  test/clang-tidy/modernize-loop-convert-const.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", ARR[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int & ELEM : ARR)
+  // CHECK-FIXES: for (int ELEM : ARR)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUM : NUMS)
+  // CHECK-FIXES: for (int NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS_[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUM : NUMS_)
+  // CHECK-FIXES: for (int NUM : NUMS_)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & ELEM : NUMS)
+  // CHECK-FIXES: for (int ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM + NUM);
 
   int ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUMS_I : NUMS)
+  // CHECK-FIXES: for (int NUMS_I : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_I + NUM + ELEM);
 
   int NUMS_I = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUMS_ELEM : NUMS)
+  // CHECK-FIXES: for (int NUMS_ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_ELEM + NUM + ELEM + NUMS_I);
 
   int NUMS_ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + NUM + ELEM + NUMS_I + NUMS_ELEM);
 
   int GIVE_ME_NAME_0 = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
 
   int NUMS_J = 0;
@@ -79,7 +79,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_J + NUMS_ELEM);
 }
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", arr[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int & elem : arr)
+  // CHECK-FIXES: for (int elem : arr)
   // CHECK-FIXES-NEXT: printf("%d\n", elem);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & num : nums)
+  // CHECK-FIXES: for (int num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums_[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & num : nums_)
+  // CHECK-FIXES: for (int num : nums_)
  

[PATCH] D14238: Fix another crash in the redundant-void-arg check.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: alexfh.
angelgarcia added subscribers: cfe-commits, klimek.

The check was assuming that a definition of a function always has a body, but a 
declaration that explicitly defaults or deletes a function is a definition too.

http://reviews.llvm.org/D14238

Files:
  clang-tidy/modernize/RedundantVoidArgCheck.cpp
  test/clang-tidy/modernize-redundant-void-arg.cpp

Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -433,3 +433,9 @@
 F(Foo, Bar) {
 
 }
+
+struct DefinitionWithNoBody {
+  DefinitionWithNoBody(void) = delete;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in function definition
+  // CHECK-FIXES: DefinitionWithNoBody() = delete;
+};
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -116,9 +116,12 @@
 const MatchFinder::MatchResult &Result, const FunctionDecl *Function) {
   SourceLocation Start = Function->getLocStart();
   if (Function->isThisDeclarationADefinition()) {
-SourceLocation BeforeBody =
-Function->getBody()->getLocStart().getLocWithOffset(-1);
-removeVoidArgumentTokens(Result, SourceRange(Start, BeforeBody),
+SourceLocation End;
+if (Function->hasBody())
+  End = Function->getBody()->getLocStart().getLocWithOffset(-1);
+else
+  End = Function->getLocEnd();
+removeVoidArgumentTokens(Result, SourceRange(Start, End),
  "function definition");
   } else {
 removeVoidArgumentTokens(Result, Function->getSourceRange(),


Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -433,3 +433,9 @@
 F(Foo, Bar) {
 
 }
+
+struct DefinitionWithNoBody {
+  DefinitionWithNoBody(void) = delete;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in function definition
+  // CHECK-FIXES: DefinitionWithNoBody() = delete;
+};
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -116,9 +116,12 @@
 const MatchFinder::MatchResult &Result, const FunctionDecl *Function) {
   SourceLocation Start = Function->getLocStart();
   if (Function->isThisDeclarationADefinition()) {
-SourceLocation BeforeBody =
-Function->getBody()->getLocStart().getLocWithOffset(-1);
-removeVoidArgumentTokens(Result, SourceRange(Start, BeforeBody),
+SourceLocation End;
+if (Function->hasBody())
+  End = Function->getBody()->getLocStart().getLocWithOffset(-1);
+else
+  End = Function->getLocEnd();
+removeVoidArgumentTokens(Result, SourceRange(Start, End),
  "function definition");
   } else {
 removeVoidArgumentTokens(Result, Function->getSourceRange(),
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D14229: Remove unreachable that was reached in modernize-use-nullptr.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38918.
angelgarcia added a comment.

Merge lines.


http://reviews.llvm.org/D14229

Files:
  clang-tidy/modernize/UseNullptrCheck.cpp
  test/clang-tidy/modernize-use-nullptr.cpp

Index: test/clang-tidy/modernize-use-nullptr.cpp
===
--- test/clang-tidy/modernize-use-nullptr.cpp
+++ test/clang-tidy/modernize-use-nullptr.cpp
@@ -184,3 +184,14 @@
   // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
 #undef ENTRY
 }
+
+// One of the ancestor of the cast is a NestedNameSpecifierLoc.
+class NoDef;
+char function(NoDef *p);
+#define F(x) (sizeof(function(x)) == 1)
+template
+class C {};
+C c;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
+// CHECK-FIXES: C c;
+#undef F
Index: clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tidy/modernize/UseNullptrCheck.cpp
@@ -435,12 +435,14 @@
 Loc = D->getLocStart();
   else if (const auto *S = Parent.get())
 Loc = S->getLocStart();
-  else
-llvm_unreachable("Expected to find Decl or Stmt containing ancestor");
 
-  if (!expandsFrom(Loc, MacroLoc)) {
-Result = Parent;
-return true;
+  // TypeLoc and NestedNameSpecifierLoc are members of the parent map. Skip
+  // them and keep going up.
+  if (Loc.isValid()) {
+if (!expandsFrom(Loc, MacroLoc)) {
+  Result = Parent;
+  return true;
+}
   }
   Start = Parent;
 }


Index: test/clang-tidy/modernize-use-nullptr.cpp
===
--- test/clang-tidy/modernize-use-nullptr.cpp
+++ test/clang-tidy/modernize-use-nullptr.cpp
@@ -184,3 +184,14 @@
   // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
 #undef ENTRY
 }
+
+// One of the ancestor of the cast is a NestedNameSpecifierLoc.
+class NoDef;
+char function(NoDef *p);
+#define F(x) (sizeof(function(x)) == 1)
+template
+class C {};
+C c;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
+// CHECK-FIXES: C c;
+#undef F
Index: clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tidy/modernize/UseNullptrCheck.cpp
@@ -435,12 +435,14 @@
 Loc = D->getLocStart();
   else if (const auto *S = Parent.get())
 Loc = S->getLocStart();
-  else
-llvm_unreachable("Expected to find Decl or Stmt containing ancestor");
 
-  if (!expandsFrom(Loc, MacroLoc)) {
-Result = Parent;
-return true;
+  // TypeLoc and NestedNameSpecifierLoc are members of the parent map. Skip
+  // them and keep going up.
+  if (Loc.isValid()) {
+if (!expandsFrom(Loc, MacroLoc)) {
+  Result = Parent;
+  return true;
+}
   }
   Start = Parent;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D14229: Remove unreachable that was reached in modernize-use-nullptr.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: alexfh.
angelgarcia added subscribers: cfe-commits, klimek.

When traversing the parent map, the check assumed that all the nodes would be 
either Stmt or Decl. After r251101, this is no longer true: there can be 
TypeLoc and NestedNameSpecifierLoc nodes.

http://reviews.llvm.org/D14229

Files:
  clang-tidy/modernize/UseNullptrCheck.cpp
  test/clang-tidy/modernize-use-nullptr.cpp

Index: test/clang-tidy/modernize-use-nullptr.cpp
===
--- test/clang-tidy/modernize-use-nullptr.cpp
+++ test/clang-tidy/modernize-use-nullptr.cpp
@@ -184,3 +184,15 @@
   // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
 #undef ENTRY
 }
+
+// One of the ancestor of the cast is a NestedNameSpecifierLoc.
+class NoDef;
+char function(NoDef *p);
+#define F(x) \
+(sizeof(function(x)) == 1)
+template
+class C {};
+C c;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
+// CHECK-FIXES: C c;
+#undef F
Index: clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tidy/modernize/UseNullptrCheck.cpp
@@ -435,12 +435,14 @@
 Loc = D->getLocStart();
   else if (const auto *S = Parent.get())
 Loc = S->getLocStart();
-  else
-llvm_unreachable("Expected to find Decl or Stmt containing ancestor");
 
-  if (!expandsFrom(Loc, MacroLoc)) {
-Result = Parent;
-return true;
+  // TypeLoc and NestedNameSpecifierLoc are members of the parent map. Skip
+  // them and keep going up.
+  if (Loc.isValid()) {
+if (!expandsFrom(Loc, MacroLoc)) {
+  Result = Parent;
+  return true;
+}
   }
   Start = Parent;
 }


Index: test/clang-tidy/modernize-use-nullptr.cpp
===
--- test/clang-tidy/modernize-use-nullptr.cpp
+++ test/clang-tidy/modernize-use-nullptr.cpp
@@ -184,3 +184,15 @@
   // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
 #undef ENTRY
 }
+
+// One of the ancestor of the cast is a NestedNameSpecifierLoc.
+class NoDef;
+char function(NoDef *p);
+#define F(x) \
+(sizeof(function(x)) == 1)
+template
+class C {};
+C c;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
+// CHECK-FIXES: C c;
+#undef F
Index: clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tidy/modernize/UseNullptrCheck.cpp
@@ -435,12 +435,14 @@
 Loc = D->getLocStart();
   else if (const auto *S = Parent.get())
 Loc = S->getLocStart();
-  else
-llvm_unreachable("Expected to find Decl or Stmt containing ancestor");
 
-  if (!expandsFrom(Loc, MacroLoc)) {
-Result = Parent;
-return true;
+  // TypeLoc and NestedNameSpecifierLoc are members of the parent map. Skip
+  // them and keep going up.
+  if (Loc.isValid()) {
+if (!expandsFrom(Loc, MacroLoc)) {
+  Result = Parent;
+  return true;
+}
   }
   Start = Parent;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D14204: Fix crash in redundant-void-arg check.

2015-11-02 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL251792: Fix crash in redundant-void-arg check. (authored by 
angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D14204?vs=38889&id=38890#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D14204

Files:
  clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
  clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp

Index: clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -47,8 +47,8 @@
 
 void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0),
-  unless(isImplicit()),
-  unless(isExternC())).bind(FunctionId),
+  unless(isImplicit()), unless(isExternC()))
+ .bind(FunctionId),
  this);
   Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId),
  this);
@@ -77,9 +77,10 @@
   cxxReinterpretCastExpr(isExpansionInMainFile(), 
CastDestinationIsFunction)
   .bind(NamedCastId),
   this);
-  Finder->addMatcher(cxxConstCastExpr(isExpansionInMainFile(),
-   
CastDestinationIsFunction).bind(NamedCastId),
- this);
+  Finder->addMatcher(
+  cxxConstCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
+  .bind(NamedCastId),
+  this);
   Finder->addMatcher(lambdaExpr(isExpansionInMainFile()).bind(LambdaId), this);
 }
 
@@ -128,11 +129,14 @@
 void RedundantVoidArgCheck::removeVoidArgumentTokens(
 const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range,
 StringRef GrammarLocation) {
-  std::string DeclText =
-  Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
-   *Result.SourceManager,
-   Result.Context->getLangOpts()).str();
-  Lexer PrototypeLexer(Range.getBegin(), Result.Context->getLangOpts(),
+  CharSourceRange CharRange = Lexer::makeFileCharRange(
+  CharSourceRange::getTokenRange(Range), *Result.SourceManager,
+  Result.Context->getLangOpts());
+
+  std::string DeclText = Lexer::getSourceText(CharRange, *Result.SourceManager,
+  Result.Context->getLangOpts())
+ .str();
+  Lexer PrototypeLexer(CharRange.getBegin(), Result.Context->getLangOpts(),
DeclText.data(), DeclText.data(),
DeclText.data() + DeclText.size());
   enum TokenState {
Index: clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -417,3 +417,19 @@
   // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
   // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; 
};{{$}}
 }
+
+#define M(x) x
+
+M(void inmacro(void) {})
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: M(void inmacro() {})
+
+#define F(A, B)\
+  struct F_##A##_##B { \
+F_##A##_##B(void); \
+  };   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}


Index: clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -47,8 +47,8 @@
 
 void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0),
-  unless(isImplicit()),
-  unless(isExternC())).bind(FunctionId),
+  unless(isImplicit()), unless(isExternC()))
+ .bind(FunctionId),
  this);
   Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId),
  this);
@@ -77,9 +77,10 @@
   cxxReinterpretCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
   .bind(NamedCastId),
   this);
-  Finder->addMatcher(cxxConstCastExpr(isExpansionInMainFile(),
-   CastDestinationIsFunction).bind(NamedCastId),
- this);
+  Finder->addMatcher(
+  cxxConstCastExpr(isExpansionInMainFile(), CastDestinationIsFu

Re: [PATCH] D14204: Fix crash in redundant-void-arg check.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38889.
angelgarcia added a comment.

Sorry, I forgot. That case works just fine.


http://reviews.llvm.org/D14204

Files:
  clang-tidy/modernize/RedundantVoidArgCheck.cpp
  test/clang-tidy/modernize-redundant-void-arg.cpp

Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -417,3 +417,19 @@
   // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
   // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; 
};{{$}}
 }
+
+#define M(x) x
+
+M(void inmacro(void) {})
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: M(void inmacro() {})
+
+#define F(A, B)\
+  struct F_##A##_##B { \
+F_##A##_##B(void); \
+  };   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -47,8 +47,8 @@
 
 void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0),
-  unless(isImplicit()),
-  unless(isExternC())).bind(FunctionId),
+  unless(isImplicit()), unless(isExternC()))
+ .bind(FunctionId),
  this);
   Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId),
  this);
@@ -77,9 +77,10 @@
   cxxReinterpretCastExpr(isExpansionInMainFile(), 
CastDestinationIsFunction)
   .bind(NamedCastId),
   this);
-  Finder->addMatcher(cxxConstCastExpr(isExpansionInMainFile(),
-   
CastDestinationIsFunction).bind(NamedCastId),
- this);
+  Finder->addMatcher(
+  cxxConstCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
+  .bind(NamedCastId),
+  this);
   Finder->addMatcher(lambdaExpr(isExpansionInMainFile()).bind(LambdaId), this);
 }
 
@@ -128,11 +129,14 @@
 void RedundantVoidArgCheck::removeVoidArgumentTokens(
 const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range,
 StringRef GrammarLocation) {
-  std::string DeclText =
-  Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
-   *Result.SourceManager,
-   Result.Context->getLangOpts()).str();
-  Lexer PrototypeLexer(Range.getBegin(), Result.Context->getLangOpts(),
+  CharSourceRange CharRange = Lexer::makeFileCharRange(
+  CharSourceRange::getTokenRange(Range), *Result.SourceManager,
+  Result.Context->getLangOpts());
+
+  std::string DeclText = Lexer::getSourceText(CharRange, *Result.SourceManager,
+  Result.Context->getLangOpts())
+ .str();
+  Lexer PrototypeLexer(CharRange.getBegin(), Result.Context->getLangOpts(),
DeclText.data(), DeclText.data(),
DeclText.data() + DeclText.size());
   enum TokenState {


Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -417,3 +417,19 @@
   // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
   // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; };{{$}}
 }
+
+#define M(x) x
+
+M(void inmacro(void) {})
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: M(void inmacro() {})
+
+#define F(A, B)\
+  struct F_##A##_##B { \
+F_##A##_##B(void); \
+  };   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -47,8 +47,8 @@
 
 void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0),
-  unless(isImplicit()),
-  unless(isExternC())).bind(FunctionId),
+  unless(isImplicit()), unless(isExternC()))
+ .bind(FunctionId),
  this);
   Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId),
  this);
@@ -77,9 +77,10 @@
   cxxReinterpretCastExpr(isExpansionInMainFile(), CastDestinat

Re: [PATCH] D14204: Fix crash in redundant-void-arg check.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38887.
angelgarcia added a comment.

Use Lexer::makeFileCharRange (and a few changes due to clang-format).

It seems to work as well.


http://reviews.llvm.org/D14204

Files:
  clang-tidy/modernize/RedundantVoidArgCheck.cpp
  test/clang-tidy/modernize-redundant-void-arg.cpp

Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -417,3 +417,13 @@
   // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
   // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; 
};{{$}}
 }
+
+#define F(A, B)\
+  struct F_##A##_##B { \
+F_##A##_##B(void); \
+  };   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -47,8 +47,8 @@
 
 void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0),
-  unless(isImplicit()),
-  unless(isExternC())).bind(FunctionId),
+  unless(isImplicit()), unless(isExternC()))
+ .bind(FunctionId),
  this);
   Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId),
  this);
@@ -77,9 +77,10 @@
   cxxReinterpretCastExpr(isExpansionInMainFile(), 
CastDestinationIsFunction)
   .bind(NamedCastId),
   this);
-  Finder->addMatcher(cxxConstCastExpr(isExpansionInMainFile(),
-   
CastDestinationIsFunction).bind(NamedCastId),
- this);
+  Finder->addMatcher(
+  cxxConstCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
+  .bind(NamedCastId),
+  this);
   Finder->addMatcher(lambdaExpr(isExpansionInMainFile()).bind(LambdaId), this);
 }
 
@@ -128,11 +129,14 @@
 void RedundantVoidArgCheck::removeVoidArgumentTokens(
 const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range,
 StringRef GrammarLocation) {
-  std::string DeclText =
-  Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
-   *Result.SourceManager,
-   Result.Context->getLangOpts()).str();
-  Lexer PrototypeLexer(Range.getBegin(), Result.Context->getLangOpts(),
+  CharSourceRange CharRange = Lexer::makeFileCharRange(
+  CharSourceRange::getTokenRange(Range), *Result.SourceManager,
+  Result.Context->getLangOpts());
+
+  std::string DeclText = Lexer::getSourceText(CharRange, *Result.SourceManager,
+  Result.Context->getLangOpts())
+ .str();
+  Lexer PrototypeLexer(CharRange.getBegin(), Result.Context->getLangOpts(),
DeclText.data(), DeclText.data(),
DeclText.data() + DeclText.size());
   enum TokenState {


Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -417,3 +417,13 @@
   // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
   // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; };{{$}}
 }
+
+#define F(A, B)\
+  struct F_##A##_##B { \
+F_##A##_##B(void); \
+  };   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -47,8 +47,8 @@
 
 void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0),
-  unless(isImplicit()),
-  unless(isExternC())).bind(FunctionId),
+  unless(isImplicit()), unless(isExternC()))
+ .bind(FunctionId),
  this);
   Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId),
  this);
@@ -77,9 +77,10 @@
   cxxReinterpretCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
   .bind(NamedCastId),
   this);
-  Finder->addMatcher(cxxConstCastExpr(isExpansionInMainFile(),
-   CastDestinationIsFunction).bind(NamedCastId),
- this);
+  Finder->addMatcher(
+  cx

Re: [PATCH] D14225: Try to fix buildbots failure.

2015-11-02 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL251790: Try to fix buildbots failure. (authored by 
angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D14225?vs=38885&id=38886#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D14225

Files:
  clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp
  clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp

Index: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing -fexceptions
 
 // Out of line definition.
 struct OL {
Index: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing  -fexceptions
 
 // Out of line definition.
 class OL {


Index: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing -fexceptions
 
 // Out of line definition.
 struct OL {
Index: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing  -fexceptions
 
 // Out of line definition.
 class OL {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D14225: Try to fix buildbots failure.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a subscriber: cfe-commits.

Add -fexceptions flag to enable exceptions.

http://reviews.llvm.org/D14225

Files:
  test/clang-tidy/modernize-use-default-copy.cpp
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- test/clang-tidy/modernize-use-default.cpp
+++ test/clang-tidy/modernize-use-default.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing  -fexceptions
 
 // Out of line definition.
 class OL {
Index: test/clang-tidy/modernize-use-default-copy.cpp
===
--- test/clang-tidy/modernize-use-default-copy.cpp
+++ test/clang-tidy/modernize-use-default-copy.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 
-fno-delayed-template-parsing -fexceptions
 
 // Out of line definition.
 struct OL {


Index: test/clang-tidy/modernize-use-default.cpp
===
--- test/clang-tidy/modernize-use-default.cpp
+++ test/clang-tidy/modernize-use-default.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing  -fexceptions
 
 // Out of line definition.
 class OL {
Index: test/clang-tidy/modernize-use-default-copy.cpp
===
--- test/clang-tidy/modernize-use-default-copy.cpp
+++ test/clang-tidy/modernize-use-default-copy.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing -fexceptions
 
 // Out of line definition.
 struct OL {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D14198: Make the modernize-loop-convert's const-detection smarter.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

> Reading just this function, it is unclear what the 'container' is.


It should be clearer now.

> Can't CaptureBuRef be modified?


I added a comment with an explanation.

> But they are aliases. Shouldn't we then go into the const-ness of the


aliases?
I wanted to test that if we take a non-const reference, we recognize that
it is a non-const usage. But if we only do it once, the check handles it
differently because it moves that declaration to the loop's statement. I
added a few tests with this particular case as well (they don't harm).

In the case of const-references, we don't need to go through their usages
to know that they won't be modified. If the reference is non-const, even if
it is used in a const way, I don't think we should do anything about it.
That would only make things more complicated: first, we would need to
traverse the subtree again looking for usages of the reference; then, if we
decide that it is not modified and we take a const-reference of the
container's element, we should also change the declaration of the reference
to make it const.


http://reviews.llvm.org/D14198



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


Re: [PATCH] D14198: Make the modernize-loop-convert's const-detection smarter.

2015-11-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38881.
angelgarcia added a comment.

Improve comments and add more tests.


http://reviews.llvm.org/D14198

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-camelback.cpp
  test/clang-tidy/modernize-loop-convert-const.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", ARR[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int & ELEM : ARR)
+  // CHECK-FIXES: for (int ELEM : ARR)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUM : NUMS)
+  // CHECK-FIXES: for (int NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS_[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUM : NUMS_)
+  // CHECK-FIXES: for (int NUM : NUMS_)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & ELEM : NUMS)
+  // CHECK-FIXES: for (int ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM + NUM);
 
   int ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUMS_I : NUMS)
+  // CHECK-FIXES: for (int NUMS_I : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_I + NUM + ELEM);
 
   int NUMS_I = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUMS_ELEM : NUMS)
+  // CHECK-FIXES: for (int NUMS_ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_ELEM + NUM + ELEM + NUMS_I);
 
   int NUMS_ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + NUM + ELEM + NUMS_I + NUMS_ELEM);
 
   int GIVE_ME_NAME_0 = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
 
   int NUMS_J = 0;
@@ -79,7 +79,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_J + NUMS_ELEM);
 }
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", arr[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int & elem : arr)
+  // CHECK-FIXES: for (int elem : arr)
   // CHECK-FIXES-NEXT: printf("%d\n", elem);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & num : nums)
+  // CHECK-FIXES: for (int num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums_[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & num : nums_)
+  // CHECK-FIXES: for (int 

[PATCH] D14204: Fix crash in redundant-void-arg check.

2015-10-30 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added reviewers: klimek, LegalizeAdulthood.
angelgarcia added subscribers: alexfh, cfe-commits.

When applying this check to the unit tests, it would hit an assertion:
llvm/tools/clang/lib/Lex/Lexer.cpp:1056: clang::SourceLocation 
clang::Lexer::getSourceLocation(const char*, unsigned int) const: Assertion `PP 
&& "This doesn't work on raw lexers"' failed.

http://reviews.llvm.org/D14204

Files:
  clang-tidy/modernize/RedundantVoidArgCheck.cpp
  test/clang-tidy/modernize-redundant-void-arg.cpp

Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -417,3 +417,13 @@
   // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
   // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; 
};{{$}}
 }
+
+#define F(A, B)\
+  struct F_##A##_##B { \
+F_##A##_##B(void); \
+  };   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -128,6 +128,9 @@
 void RedundantVoidArgCheck::removeVoidArgumentTokens(
 const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range,
 StringRef GrammarLocation) {
+  if (Range.getBegin().isMacroID() || Range.getEnd().isMacroID())
+return;
+
   std::string DeclText =
   Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
*Result.SourceManager,


Index: test/clang-tidy/modernize-redundant-void-arg.cpp
===
--- test/clang-tidy/modernize-redundant-void-arg.cpp
+++ test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -417,3 +417,13 @@
   // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
   // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; };{{$}}
 }
+
+#define F(A, B)\
+  struct F_##A##_##B { \
+F_##A##_##B(void); \
+  };   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
Index: clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -128,6 +128,9 @@
 void RedundantVoidArgCheck::removeVoidArgumentTokens(
 const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range,
 StringRef GrammarLocation) {
+  if (Range.getBegin().isMacroID() || Range.getEnd().isMacroID())
+return;
+
   std::string DeclText =
   Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
*Result.SourceManager,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D14198: Make the modernize-loop-convert's const-detection smarter.

2015-10-30 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

Now, it detects that several kinds of usages are can't modify the elements. 
Examples:
-When an usage is a call to a const member function or operator of the element.
-If the element is used as an argument to a function or constructor that takes 
a const-reference or a value.
-LValue to RValue conversion, if the element is a fundamental type (which 
allows the use of most of the builtin operators).

http://reviews.llvm.org/D14198

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-camelback.cpp
  test/clang-tidy/modernize-loop-convert-const.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", ARR[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int & ELEM : ARR)
+  // CHECK-FIXES: for (int ELEM : ARR)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUM : NUMS)
+  // CHECK-FIXES: for (int NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS_[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUM : NUMS_)
+  // CHECK-FIXES: for (int NUM : NUMS_)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & ELEM : NUMS)
+  // CHECK-FIXES: for (int ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM + NUM);
 
   int ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUMS_I : NUMS)
+  // CHECK-FIXES: for (int NUMS_I : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_I + NUM + ELEM);
 
   int NUMS_I = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & NUMS_ELEM : NUMS)
+  // CHECK-FIXES: for (int NUMS_ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_ELEM + NUM + ELEM + NUMS_I);
 
   int NUMS_ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + NUM + ELEM + NUMS_I + NUMS_ELEM);
 
   int GIVE_ME_NAME_0 = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
 
   int NUMS_J = 0;
@@ -79,7 +79,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
-  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_J + NUMS_ELEM);
 }
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", arr[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (int & elem : arr)
+  // CHECK-FIXES: for (int elem : arr)
   // CHECK-FIXES-NEXT: printf("%d\n", elem);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i]);
   }
   // CHECK-MESSAG

Re: [PATCH] D14176: Only copy small types in modernize-loop-convert.

2015-10-30 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL251694: Only copy small types in modernize-loop-convert. 
(authored by angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D14176?vs=38736&id=38789#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D14176

Files:
  clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h
  clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
  
clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h
  clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp

Index: clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h
===
--- clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h
+++ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h
@@ -23,6 +23,11 @@
   int X;
 };
 
+struct TriviallyCopyableButBig {
+  int X;
+  char Array[16];
+};
+
 struct S {
   typedef MutableVal *iterator;
   typedef const MutableVal *const_iterator;
Index: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -113,6 +113,14 @@
   // CHECK-FIXES: for (const auto & Elem : NonCopy)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
 
+  const TriviallyCopyableButBig Big[N]{};
+  for (int I = 0; I < N; ++I) {
+printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : Big)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
+
   bool Something = false;
   for (int I = 0; I < N; ++I) {
 if (Something)
Index: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
===
--- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -47,6 +47,10 @@
   ClangTidyOptions getModuleOptions() override {
 ClangTidyOptions Options;
 auto &Opts = Options.CheckOptions;
+// For types whose size in bytes is above this threshold, we prefer taking a
+// const-reference than making a copy.
+Opts["modernize-loop-convert.MaxCopySize"] = "16";
+
 Opts["modernize-loop-convert.MinConfidence"] = "reasonable";
 Opts["modernize-loop-convert.NamingStyle"] = "CamelCase";
 Opts["modernize-pass-by-value.IncludeStyle"] = "llvm";// Also: "google".
Index: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h
===
--- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h
+++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h
@@ -66,6 +66,7 @@
  const ForStmt *Loop, LoopFixerKind FixerKind);
 
   std::unique_ptr TUInfo;
+  const unsigned long long MaxCopySize;
   const Confidence::Level MinConfidence;
   const VariableNamer::NamingStyle NamingStyle;
 };
Index: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -230,18 +230,18 @@
   // FIXME: Also, a record doesn't necessarily need begin() and end(). Free
   // functions called begin() and end() taking the container as an argument
   // are also allowed.
-  TypeMatcher RecordWithBeginEnd = qualType(
-  anyOf(qualType(isConstQualified(),
- hasDeclaration(cxxRecordDecl(
- hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
- hasMethod(cxxMethodDecl(hasName("end"),
- isConst() // hasDeclaration
- ),// qualType
-qualType(unless(isConstQualified()),
- hasDeclaration(
- cxxRecordDecl(hasMethod(hasName("begin")),
+  TypeMatcher RecordWithBeginEnd = qualType(anyOf(
+  qualType(isConstQualified(),
+   hasDeclaration(cxxRecordDecl(
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst() // hasDeclaration
+   ),// qualType
+  qualType(
+  unless(isConstQualified()),

[PATCH] D14176: Only copy small types in modernize-loop-convert.

2015-10-29 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

If the size of the type is above a certain bound, we'll take a const reference. 
This bound can be set as an option. For now, the default value is 16 bytes.

http://reviews.llvm.org/D14176

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/LoopConvertCheck.h
  clang-tidy/modernize/ModernizeTidyModule.cpp
  test/clang-tidy/Inputs/modernize-loop-convert/structures.h
  test/clang-tidy/modernize-loop-convert-basic.cpp

Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -113,6 +113,14 @@
   // CHECK-FIXES: for (const auto & Elem : NonCopy)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
 
+  const TriviallyCopyableButBig Big[N]{};
+  for (int I = 0; I < N; ++I) {
+printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : Big)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
+
   bool Something = false;
   for (int I = 0; I < N; ++I) {
 if (Something)
Index: test/clang-tidy/Inputs/modernize-loop-convert/structures.h
===
--- test/clang-tidy/Inputs/modernize-loop-convert/structures.h
+++ test/clang-tidy/Inputs/modernize-loop-convert/structures.h
@@ -23,6 +23,11 @@
   int X;
 };
 
+struct TriviallyCopyableButBig {
+  int X;
+  char Array[16];
+};
+
 struct S {
   typedef MutableVal *iterator;
   typedef const MutableVal *const_iterator;
Index: clang-tidy/modernize/ModernizeTidyModule.cpp
===
--- clang-tidy/modernize/ModernizeTidyModule.cpp
+++ clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -47,6 +47,10 @@
   ClangTidyOptions getModuleOptions() override {
 ClangTidyOptions Options;
 auto &Opts = Options.CheckOptions;
+// For types whose size in bytes is above this threshold, we prefer taking a
+// const-reference than making a copy.
+Opts["modernize-loop-convert.MaxCopySize"] = "16";
+
 Opts["modernize-loop-convert.MinConfidence"] = "reasonable";
 Opts["modernize-loop-convert.NamingStyle"] = "CamelCase";
 Opts["modernize-pass-by-value.IncludeStyle"] = "llvm";// Also: "google".
Index: clang-tidy/modernize/LoopConvertCheck.h
===
--- clang-tidy/modernize/LoopConvertCheck.h
+++ clang-tidy/modernize/LoopConvertCheck.h
@@ -66,6 +66,7 @@
  const ForStmt *Loop, LoopFixerKind FixerKind);
 
   std::unique_ptr TUInfo;
+  const unsigned long long MaxCopySize;
   const Confidence::Level MinConfidence;
   const VariableNamer::NamingStyle NamingStyle;
 };
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -230,18 +230,18 @@
   // FIXME: Also, a record doesn't necessarily need begin() and end(). Free
   // functions called begin() and end() taking the container as an argument
   // are also allowed.
-  TypeMatcher RecordWithBeginEnd = qualType(
-  anyOf(qualType(isConstQualified(),
- hasDeclaration(cxxRecordDecl(
- hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
- hasMethod(cxxMethodDecl(hasName("end"),
- isConst() // hasDeclaration
- ),// qualType
-qualType(unless(isConstQualified()),
- hasDeclaration(
- cxxRecordDecl(hasMethod(hasName("begin")),
+  TypeMatcher RecordWithBeginEnd = qualType(anyOf(
+  qualType(isConstQualified(),
+   hasDeclaration(cxxRecordDecl(
+   hasMethod(cxxMethodDecl(hasName("begin"), isConst())),
+   hasMethod(cxxMethodDecl(hasName("end"),
+   isConst() // hasDeclaration
+   ),// qualType
+  qualType(
+  unless(isConstQualified()),
+  hasDeclaration(cxxRecordDecl(hasMethod(hasName("begin")),
hasMethod(hasName("end") // qualType
-));
+  ));
 
   StatementMatcher SizeCallMatcher = cxxMemberCallExpr(
   argumentCountIs(0),
@@ -409,6 +409,7 @@
 
 LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo),
+  MaxCopySize(std::stoull(Options.get("MaxC

Re: [PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-29 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38730.
angelgarcia marked an inline comment as done.
angelgarcia added a comment.

Remove debugging code.


http://reviews.llvm.org/D14145

Files:
  clang-tidy/modernize/UseDefaultCheck.cpp
  test/clang-tidy/modernize-use-default-copy.cpp
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- test/clang-tidy/modernize-use-default.cpp
+++ test/clang-tidy/modernize-use-default.cpp
@@ -1,137 +1,159 @@
 // RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
 
-class A {
+// Out of line definition.
+class OL {
 public:
-  A();
-  ~A();
+  OL();
+  ~OL();
 };
 
-A::A() {}
+OL::OL() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial default constructor [modernize-use-default]
-// CHECK-FIXES: A::A() = default;
-A::~A() {}
+// CHECK-FIXES: OL::OL() = default;
+OL::~OL() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial destructor [modernize-use-default]
-// CHECK-FIXES: A::~A() = default;
+// CHECK-FIXES: OL::~OL() = default;
 
 // Inline definitions.
-class B {
+class IL {
 public:
-  B() {}
+  IL() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: B() = default;
-  ~B() {}
+  // CHECK-FIXES: IL() = default;
+  ~IL() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~B() = default;
+  // CHECK-FIXES: ~IL() = default;
 };
 
+// Non-empty body.
 void f();
-
-class C {
+class NE {
 public:
-  // Non-empty constructor body.
-  C() { f(); }
-  // Non-empty destructor body.
-  ~C() { f(); }
+  NE() { f(); }
+  ~NE() { f(); }
 };
 
-class D {
+// Initializer or arguments.
+class IA {
 public:
   // Constructor with initializer.
-  D() : Field(5) {}
+  IA() : Field(5) {}
   // Constructor with arguments.
-  D(int Arg1, int Arg2) {}
+  IA(int Arg1, int Arg2) {}
   int Field;
 };
 
 // Private constructor/destructor.
-class E {
-  E() {}
+class Priv {
+  Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: E() = default;
-  ~E() {}
+  // CHECK-FIXES: Priv() = default;
+  ~Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~E() = default;
+  // CHECK-FIXES: ~Priv() = default;
 };
 
 // struct.
-struct F {
-  F() {}
+struct ST {
+  ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: F() = default;
-  ~F() {}
+  // CHECK-FIXES: ST() = default;
+  ~ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: F() = default;
+  // CHECK-FIXES: ST() = default;
 };
 
 // Deleted constructor/destructor.
-class G {
+class Del {
 public:
-  G() = delete;
-  ~G() = delete;
+  Del() = delete;
+  ~Del() = delete;
 };
 
 // Do not remove other keywords.
-class H {
+class KW {
 public:
-  explicit H() {}
+  explicit KW() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: explicit H() = default;
-  virtual ~H() {}
+  // CHECK-FIXES: explicit KW() = default;
+  virtual ~KW() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: virtual ~H() = default;
+  // CHECK-FIXES: virtual ~KW() = default;
 };
 
 // Nested class.
-struct I {
-  struct II {
-II() {}
+struct N {
+  struct NN {
+NN() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
-// CHECK-FIXES: II() = default;
-~II() {}
+// CHECK-FIXES: NN() = default;
+~NN() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
-// CHECK-FIXES: ~II() = default;
+// CHECK-FIXES: ~NN() = default;
   };
   int Int;
 };
 
 // Class template.
 template 
-class J {
+class Temp {
 public:
-  J() {}
+  Temp() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: J() = default;
-  ~J() {}
+  // CHECK-FIXES: Temp() = default;
+  ~Temp() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~J() = default;
+  // CHECK-FIXES: ~Temp() = default;
 };
 
 // Non user-provided constructor/destructor.
-struct K {
+struct Imp {
   int Int;
 };
 void g() {
-  K *PtrK = new K();
-  PtrK->~K();
-  delete PtrK;
+  Imp *PtrImp = new Imp();
+  PtrImp->~Imp();
+  delete PtrImp;
 }
 
 // Already using default.
-struct L {
-  L() = default;
-  ~L() = default;
-};
-struct M {
-  M();
-  ~M();
+struct IDef {
+  IDef() = default;
+  ~IDef() = default;
+};
+struct ODef {
+  ODef();
+  ~ODef();
 };
-M::M() = default;
-M::~M() = default;
+ODef::ODef() = default;
+ODef::~ODef() = default;
 
 // Delegating constructor and overriden destructor.
-struct N : H {
-  N() : H() {}
-  ~N() override {}
+struct DC : KW {
+  DC() : KW() {}
+  ~DC() override {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~N() override = default;
+  // CHECK-FIXES:

Re: [PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-29 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38728.
angelgarcia added a comment.

Put more logic into the matchers.

Btw, do you know how can I get the exception specification of a function?


http://reviews.llvm.org/D14145

Files:
  clang-tidy/modernize/UseDefaultCheck.cpp
  test/clang-tidy/modernize-use-default-copy.cpp
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- test/clang-tidy/modernize-use-default.cpp
+++ test/clang-tidy/modernize-use-default.cpp
@@ -1,137 +1,159 @@
 // RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
 
-class A {
+// Out of line definition.
+class OL {
 public:
-  A();
-  ~A();
+  OL();
+  ~OL();
 };
 
-A::A() {}
+OL::OL() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial default constructor [modernize-use-default]
-// CHECK-FIXES: A::A() = default;
-A::~A() {}
+// CHECK-FIXES: OL::OL() = default;
+OL::~OL() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial destructor [modernize-use-default]
-// CHECK-FIXES: A::~A() = default;
+// CHECK-FIXES: OL::~OL() = default;
 
 // Inline definitions.
-class B {
+class IL {
 public:
-  B() {}
+  IL() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: B() = default;
-  ~B() {}
+  // CHECK-FIXES: IL() = default;
+  ~IL() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~B() = default;
+  // CHECK-FIXES: ~IL() = default;
 };
 
+// Non-empty body.
 void f();
-
-class C {
+class NE {
 public:
-  // Non-empty constructor body.
-  C() { f(); }
-  // Non-empty destructor body.
-  ~C() { f(); }
+  NE() { f(); }
+  ~NE() { f(); }
 };
 
-class D {
+// Initializer or arguments.
+class IA {
 public:
   // Constructor with initializer.
-  D() : Field(5) {}
+  IA() : Field(5) {}
   // Constructor with arguments.
-  D(int Arg1, int Arg2) {}
+  IA(int Arg1, int Arg2) {}
   int Field;
 };
 
 // Private constructor/destructor.
-class E {
-  E() {}
+class Priv {
+  Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: E() = default;
-  ~E() {}
+  // CHECK-FIXES: Priv() = default;
+  ~Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~E() = default;
+  // CHECK-FIXES: ~Priv() = default;
 };
 
 // struct.
-struct F {
-  F() {}
+struct ST {
+  ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: F() = default;
-  ~F() {}
+  // CHECK-FIXES: ST() = default;
+  ~ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: F() = default;
+  // CHECK-FIXES: ST() = default;
 };
 
 // Deleted constructor/destructor.
-class G {
+class Del {
 public:
-  G() = delete;
-  ~G() = delete;
+  Del() = delete;
+  ~Del() = delete;
 };
 
 // Do not remove other keywords.
-class H {
+class KW {
 public:
-  explicit H() {}
+  explicit KW() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: explicit H() = default;
-  virtual ~H() {}
+  // CHECK-FIXES: explicit KW() = default;
+  virtual ~KW() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: virtual ~H() = default;
+  // CHECK-FIXES: virtual ~KW() = default;
 };
 
 // Nested class.
-struct I {
-  struct II {
-II() {}
+struct N {
+  struct NN {
+NN() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
-// CHECK-FIXES: II() = default;
-~II() {}
+// CHECK-FIXES: NN() = default;
+~NN() {}
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
-// CHECK-FIXES: ~II() = default;
+// CHECK-FIXES: ~NN() = default;
   };
   int Int;
 };
 
 // Class template.
 template 
-class J {
+class Temp {
 public:
-  J() {}
+  Temp() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: J() = default;
-  ~J() {}
+  // CHECK-FIXES: Temp() = default;
+  ~Temp() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~J() = default;
+  // CHECK-FIXES: ~Temp() = default;
 };
 
 // Non user-provided constructor/destructor.
-struct K {
+struct Imp {
   int Int;
 };
 void g() {
-  K *PtrK = new K();
-  PtrK->~K();
-  delete PtrK;
+  Imp *PtrImp = new Imp();
+  PtrImp->~Imp();
+  delete PtrImp;
 }
 
 // Already using default.
-struct L {
-  L() = default;
-  ~L() = default;
-};
-struct M {
-  M();
-  ~M();
+struct IDef {
+  IDef() = default;
+  ~IDef() = default;
+};
+struct ODef {
+  ODef();
+  ~ODef();
 };
-M::M() = default;
-M::~M() = default;
+ODef::ODef() = default;
+ODef::~ODef() = default;
 
 // Delegating constructor and overriden destructor.
-struct N : H {
-  N() : H() {}
-  ~N() override {}
+struct DC : KW {
+  DC() : KW() {}
+  ~DC() override {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~N(

Re: [PATCH] D14152: Add "equalsNode" for types and "isCopyAssignmentOperator" matchers.

2015-10-29 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38727.
angelgarcia added a comment.

Add tests.


http://reviews.llvm.org/D14152

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1890,6 +1890,21 @@
   EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure(;
 }
 
+TEST(Matcher, MatchesCopyAssignmentOperator) {
+  EXPECT_TRUE(matches("class X { X &operator=(X); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+}
+
 TEST(Matcher, MatchesConstMethod) {
   EXPECT_TRUE(
   matches("struct A { void foo() const; };", cxxMethodDecl(isConst(;
@@ -4671,6 +4686,16 @@
  decl(has(decl(equalsNode(TypedNode.bind(""))),
  *Node, Context)) != nullptr;
   }
+  bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
+// Use the original typed pointer to verify we can pass pointers to 
subtypes
+// to equalsNode.
+const T *TypedNode = cast(Node);
+const auto *Dec = Nodes.getNodeAs("decl");
+return selectFirst(
+   "", match(fieldDecl(hasParent(decl(has(fieldDecl(
+ 
hasType(type(equalsNode(TypedNode)).bind(""))),
+ *Dec, Context)) != nullptr;
+  }
 };
 
 TEST(IsEqualTo, MatchesNodesByIdentity) {
@@ -4680,6 +4705,10 @@
   EXPECT_TRUE(matchAndVerifyResultTrue(
   "void f() { if (true) if(true) {} }", ifStmt().bind(""),
   new VerifyAncestorHasChildIsEqual()));
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+  "class X { class Y {} y; };",
+  fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
+  new VerifyAncestorHasChildIsEqual()));
 }
 
 TEST(MatchFinder, CheckProfiling) {
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3385,6 +3385,23 @@
   return Node.isConst();
 }
 
+/// \brief Matches if the given method declaration declares a copy assignment
+/// operator.
+///
+/// Given
+/// \code
+/// struct A {
+///   A &operator=(const A &);
+///   A &operator=(A &&);
+/// };
+/// \endcode
+///
+/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
+/// the second one.
+AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) {
+  return Node.isCopyAssignmentOperator();
+}
+
 /// \brief Matches if the given method declaration overrides another method.
 ///
 /// Given
@@ -4307,10 +4324,15 @@
 /// \brief Matches if a node equals another node.
 ///
 /// \c Stmt has pointer identity in the AST.
-///
 AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
   return &Node == Other;
 }
+/// \brief Matches if a node equals another node.
+///
+/// \c Type has pointer identity in the AST.
+AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
+return &Node == Other;
+}
 
 /// @}
 


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1890,6 +1890,21 @@
   EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure(;
 }
 
+TEST(Matcher, MatchesCopyAssignmentOperator) {
+  EXPECT_TRUE(matches("class X { X &operator=(X); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
+  cxxMethodDecl(isCopyAssignmentOperator(;
+  EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
+  cxxMethodDecl(isCopyAssignmentOperator

Re: [PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-28 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

You can initialize an indirect base if it's virtual.


http://reviews.llvm.org/D14145



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


Re: [PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-28 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

> In which cases can this be false? (I assume if not all are copied?)


This can be false is there is we do anything else than initializing the
bases and members. So the previous code is there to ensure that we do that
and this is here to ensure that we *only* do that.


http://reviews.llvm.org/D14145



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


Re: [PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-28 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38664.
angelgarcia added a comment.

Refactor most of the code to use AST matchers.

Note that now this change requires http://reviews.llvm.org/D14152 to be applied 
first.


http://reviews.llvm.org/D14145

Files:
  clang-tidy/modernize/UseDefaultCheck.cpp
  test/clang-tidy/modernize-use-default-copy.cpp
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- test/clang-tidy/modernize-use-default.cpp
+++ test/clang-tidy/modernize-use-default.cpp
@@ -135,3 +135,13 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~N() override = default;
 };
+
+struct O {
+  O() {
+// Don't erase comments inside the body.
+  }
+  ~O() {
+// Don't erase comments inside the body.
+  }
+};
+
Index: test/clang-tidy/modernize-use-default-copy.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-use-default-copy.cpp
@@ -0,0 +1,422 @@
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
+
+// Out of line definition.
+struct OL {
+  OL(const OL &);
+  OL &operator=(const OL &);
+  int Field;
+};
+OL::OL(const OL &Other) : Field(Other.Field) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy constructor [modernize-use-default]
+// CHECK-FIXES: OL::OL(const OL &Other) = default;
+OL &OL::operator=(const OL &Other) {
+  Field = Other.Field;
+  return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:1: warning: use '= default' to define a trivial copy-assignment operator [modernize-use-default]
+// CHECK-FIXES: OL &OL::operator=(const OL &Other) = default;
+
+// Inline.
+struct IL {
+  IL(const IL &Other) : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: IL(const IL &Other) = default;
+  IL &operator=(const IL &Other) {
+Field = Other.Field;
+return *this;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use '= default'
+  // CHECK-FIXES: IL &operator=(const IL &Other) = default;
+  int Field;
+};
+
+// Wrong type.
+struct WT {
+  WT(const IL &Other) {}
+  WT &operator=(const IL &);
+};
+WT &WT::operator=(const IL &Other) { return *this; }
+
+// Qualifiers.
+struct Qual {
+  Qual(const Qual &Other) : Field(Other.Field), Volatile(Other.Volatile),
+Mutable(Other.Mutable), Reference(Other.Reference),
+Const(Other.Const) {}
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
+  // CHECK-FIXES: Qual(const Qual &Other) = default;
+
+  int Field;
+  volatile char Volatile;
+  mutable bool Mutable;
+  const OL &Reference; // This makes this class non-assignable.
+  const IL Const;  // This also makes this class non-assignable.
+  static int Static;
+};
+
+// Wrong init arguments.
+struct WI {
+  WI(const WI &Other) : Field1(Other.Field1), Field2(Other.Field1) {}
+  WI &operator=(const WI &);
+  int Field1, Field2;
+};
+WI &WI::operator=(const WI &Other) {
+  Field1 = Other.Field1;
+  Field2 = Other.Field1;
+  return *this;
+}
+
+// Missing field.
+struct MF {
+  MF(const MF &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
+  MF &operator=(const MF &);
+  int Field1, Field2, Field3;
+};
+MF &MF::operator=(const MF &Other) {
+  Field1 = Other.Field1;
+  Field2 = Other.Field2;
+  return *this;
+}
+
+struct Comments {
+  Comments(const Comments &Other)
+  /* don't delete */ : /* this comment */ Field(Other.Field) {}
+  int Field;
+};
+
+struct MoreComments {
+  MoreComments(const MoreComments &Other) /* this comment is OK */
+  : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+  // CHECK-FIXES: MoreComments(const MoreComments &Other) /* this comment is OK */
+  // CHECK-FIXES-NEXT: = default;
+  int Field;
+};
+
+struct ColonInComment {
+  ColonInComment(const ColonInComment &Other) /* : */ : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ColonInComment(const ColonInComment &Other) /* : */ = default;
+  int Field;
+};
+
+// No members or bases (in particular, no colon).
+struct Empty {
+  Empty(const Empty &Other) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Empty(const Empty &Other) = default;
+  Empty &operator=(const Empty &);
+};
+Empty &Empty::operator=(const Empty &Other) { return *this; }
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default'
+// CHECK-FIXES: Empty &Empty::operator=(const Empty &Other) = default;
+
+// Bit fields.
+struct BF {
+  BF() = default;
+  BF(const BF &Other) : Field1(Other.Field1), Field2(Other.Field2), Field3(Other.Field3),
+Field4(Other.Field4) {}
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+  // CHECK-FIXES: BF(const BF &Other) = default;
+  BF &op

[PATCH] D14152: Add "equalsNode" for types and "isCopyAssignmentOperator" matchers.

2015-10-28 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.
Herald added a subscriber: klimek.

This matchers are going to be used in modernize-use-default, but are generic 
enough to be placed in ASTMatchers.h.

http://reviews.llvm.org/D14152

Files:
  include/clang/ASTMatchers/ASTMatchers.h

Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3385,6 +3385,23 @@
   return Node.isConst();
 }
 
+/// \brief Matches if the given method declaration declares a copy assignment
+/// operator.
+///
+/// Given
+/// \code
+/// struct A {
+///   A &operator=(const A &);
+///   A &operator=(A &&);
+/// };
+/// \endcode
+///
+/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
+/// the second one.
+AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) {
+  return Node.isCopyAssignmentOperator();
+}
+
 /// \brief Matches if the given method declaration overrides another method.
 ///
 /// Given
@@ -4307,10 +4324,15 @@
 /// \brief Matches if a node equals another node.
 ///
 /// \c Stmt has pointer identity in the AST.
-///
 AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
   return &Node == Other;
 }
+/// \brief Matches if a node equals another node.
+///
+/// \c Type has pointer identity in the AST.
+AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
+return &Node == Other;
+}
 
 /// @}
 


Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3385,6 +3385,23 @@
   return Node.isConst();
 }
 
+/// \brief Matches if the given method declaration declares a copy assignment
+/// operator.
+///
+/// Given
+/// \code
+/// struct A {
+///   A &operator=(const A &);
+///   A &operator=(A &&);
+/// };
+/// \endcode
+///
+/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
+/// the second one.
+AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) {
+  return Node.isCopyAssignmentOperator();
+}
+
 /// \brief Matches if the given method declaration overrides another method.
 ///
 /// Given
@@ -4307,10 +4324,15 @@
 /// \brief Matches if a node equals another node.
 ///
 /// \c Stmt has pointer identity in the AST.
-///
 AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
   return &Node == Other;
 }
+/// \brief Matches if a node equals another node.
+///
+/// \c Type has pointer identity in the AST.
+AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
+return &Node == Other;
+}
 
 /// @}
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-28 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

OK, thanks! I will try to refactor some of the parts into AST matchers
then. It will probably take some time, though.


http://reviews.llvm.org/D14145



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


Re: [PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-28 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38648.
angelgarcia added a comment.

Small tweak.


http://reviews.llvm.org/D14145

Files:
  clang-tidy/modernize/UseDefaultCheck.cpp
  test/clang-tidy/modernize-use-default-copy.cpp
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- test/clang-tidy/modernize-use-default.cpp
+++ test/clang-tidy/modernize-use-default.cpp
@@ -135,3 +135,13 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~N() override = default;
 };
+
+struct O {
+  O() {
+// Don't erase comments inside the body.
+  }
+  ~O() {
+// Don't erase comments inside the body.
+  }
+};
+
Index: test/clang-tidy/modernize-use-default-copy.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-use-default-copy.cpp
@@ -0,0 +1,422 @@
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
+
+// Out of line definition.
+struct OL {
+  OL(const OL &);
+  OL &operator=(const OL &);
+  int Field;
+};
+OL::OL(const OL &Other) : Field(Other.Field) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy constructor [modernize-use-default]
+// CHECK-FIXES: OL::OL(const OL &Other) = default;
+OL &OL::operator=(const OL &Other) {
+  Field = Other.Field;
+  return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:1: warning: use '= default' to define a trivial copy-assignment operator [modernize-use-default]
+// CHECK-FIXES: OL &OL::operator=(const OL &Other) = default;
+
+// Inline.
+struct IL {
+  IL(const IL &Other) : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: IL(const IL &Other) = default;
+  IL &operator=(const IL &Other) {
+Field = Other.Field;
+return *this;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use '= default'
+  // CHECK-FIXES: IL &operator=(const IL &Other) = default;
+  int Field;
+};
+
+// Wrong type.
+struct WT {
+  WT(const IL &Other) {}
+  WT &operator=(const IL &);
+};
+WT &WT::operator=(const IL &Other) { return *this; }
+
+// Qualifiers.
+struct Qual {
+  Qual(const Qual &Other) : Field(Other.Field), Volatile(Other.Volatile),
+Mutable(Other.Mutable), Reference(Other.Reference),
+Const(Other.Const) {}
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
+  // CHECK-FIXES: Qual(const Qual &Other) = default;
+
+  int Field;
+  volatile char Volatile;
+  mutable bool Mutable;
+  const OL &Reference; // This makes this class non-assignable.
+  const IL Const;  // This also makes this class non-assignable.
+  static int Static;
+};
+
+// Wrong init arguments.
+struct WI {
+  WI(const WI &Other) : Field1(Other.Field1), Field2(Other.Field1) {}
+  WI &operator=(const WI &);
+  int Field1, Field2;
+};
+WI &WI::operator=(const WI &Other) {
+  Field1 = Other.Field1;
+  Field2 = Other.Field1;
+  return *this;
+}
+
+// Missing field.
+struct MF {
+  MF(const MF &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
+  MF &operator=(const MF &);
+  int Field1, Field2, Field3;
+};
+MF &MF::operator=(const MF &Other) {
+  Field1 = Other.Field1;
+  Field2 = Other.Field2;
+  return *this;
+}
+
+struct Comments {
+  Comments(const Comments &Other)
+  /* don't delete */ : /* this comment */ Field(Other.Field) {}
+  int Field;
+};
+
+struct MoreComments {
+  MoreComments(const MoreComments &Other) /* this comment is OK */
+  : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+  // CHECK-FIXES: MoreComments(const MoreComments &Other) /* this comment is OK */
+  // CHECK-FIXES-NEXT: = default;
+  int Field;
+};
+
+struct ColonInComment {
+  ColonInComment(const ColonInComment &Other) /* : */ : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ColonInComment(const ColonInComment &Other) /* : */ = default;
+  int Field;
+};
+
+// No members or bases (in particular, no colon).
+struct Empty {
+  Empty(const Empty &Other) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Empty(const Empty &Other) = default;
+  Empty &operator=(const Empty &);
+};
+Empty &Empty::operator=(const Empty &Other) { return *this; }
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default'
+// CHECK-FIXES: Empty &Empty::operator=(const Empty &Other) = default;
+
+// Bit fields.
+struct BF {
+  BF() = default;
+  BF(const BF &Other) : Field1(Other.Field1), Field2(Other.Field2), Field3(Other.Field3),
+Field4(Other.Field4) {}
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+  // CHECK-FIXES: BF(const BF &Other) = default;
+  BF &operator=(const BF &);
+
+  unsigned Field1 : 3;
+  int : 7;
+  char Field2 : 6;
+  int : 0;
+  int Field3 : 24;
+  unsigned 

[PATCH] D14145: modernize-use-default supports copy constructor and copy-assignment operator.

2015-10-28 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

the check will now warn when the user provided definitions of this functions is 
equivalent to the explicitly defaulted ones.

http://reviews.llvm.org/D14145

Files:
  clang-tidy/modernize/UseDefaultCheck.cpp
  test/clang-tidy/modernize-use-default-copy.cpp
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- test/clang-tidy/modernize-use-default.cpp
+++ test/clang-tidy/modernize-use-default.cpp
@@ -135,3 +135,13 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~N() override = default;
 };
+
+struct O {
+  O() {
+// Don't erase comments inside the body.
+  }
+  ~O() {
+// Don't erase comments inside the body.
+  }
+};
+
Index: test/clang-tidy/modernize-use-default-copy.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-use-default-copy.cpp
@@ -0,0 +1,424 @@
+// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing
+
+// Out of line definition.
+struct OL {
+  OL(const OL &);
+  OL &operator=(const OL &);
+  int Field;
+};
+OL::OL(const OL &Other) : Field(Other.Field) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy constructor [modernize-use-default]
+// CHECK-FIXES: OL::OL(const OL &Other) = default;
+OL &OL::operator=(const OL &Other) {
+  Field = Other.Field;
+  return *this;
+}
+// CHECK-MESSAGES: :[[@LINE-4]]:1: warning: use '= default' to define a trivial copy-assignment operator [modernize-use-default]
+// CHECK-FIXES: OL &OL::operator=(const OL &Other) = default;
+
+// Inline.
+struct IL {
+  IL(const IL &Other) : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: IL(const IL &Other) = default;
+  IL &operator=(const IL &Other) {
+Field = Other.Field;
+return *this;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use '= default'
+  // CHECK-FIXES: IL &operator=(const IL &Other) = default;
+  int Field;
+};
+
+// Wrong type.
+struct WT {
+  WT(const IL &Other) {}
+  WT &operator=(const IL &);
+};
+WT &WT::operator=(const IL &Other) { return *this; }
+
+// Qualifiers.
+struct Qual {
+  Qual(const Qual &Other) : Field(Other.Field), Volatile(Other.Volatile),
+Mutable(Other.Mutable), Reference(Other.Reference),
+Const(Other.Const) {}
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
+  // CHECK-FIXES: Qual(const Qual &Other) = default;
+
+  int Field;
+  volatile char Volatile;
+  mutable bool Mutable;
+  const OL &Reference; // This makes this class non-assignable.
+  const IL Const;  // This also makes this class non-assignable.
+  static int Static;
+};
+
+// Wrong init arguments.
+struct WI {
+  WI(const WI &Other) : Field1(Other.Field1), Field2(Other.Field1) {}
+  WI &operator=(const WI &);
+  int Field1, Field2;
+};
+WI &WI::operator=(const WI &Other) {
+  Field1 = Other.Field1;
+  Field2 = Other.Field1;
+  return *this;
+}
+
+// Missing field.
+struct MF {
+  MF(const MF &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
+  MF &operator=(const MF &);
+  int Field1, Field2, Field3;
+};
+MF &MF::operator=(const MF &Other) {
+  Field1 = Other.Field1;
+  Field2 = Other.Field2;
+  return *this;
+}
+
+struct Comments {
+  Comments(const Comments &Other)
+  /* don't delete */ : /* this comment */ Field(Other.Field) {}
+  int Field;
+};
+
+struct MoreComments {
+  MoreComments(const MoreComments &Other) /* this comment is OK */
+  : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+  // CHECK-FIXES: MoreComments(const MoreComments &Other) /* this comment is OK */
+  // CHECK-FIXES-NEXT: = default;
+  int Field;
+};
+
+struct ColonInComment {
+  ColonInComment(const ColonInComment &Other) /* : */ : Field(Other.Field) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ColonInComment(const ColonInComment &Other) /* : */ = default;
+  int Field;
+};
+
+// No members or bases (in particular, no colon).
+struct Empty {
+  Empty(const Empty &Other) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Empty(const Empty &Other) = default;
+  Empty &operator=(const Empty &);
+};
+Empty &Empty::operator=(const Empty &Other) { return *this; }
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default'
+// CHECK-FIXES: Empty &Empty::operator=(const Empty &Other) = default;
+
+// Bit fields.
+struct BF {
+  BF() = default;
+  BF(const BF &Other) : Field1(Other.Field1), Field2(Other.Field2), Field3(Other.Field3),
+Field4(Other.Field4) {}
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+  // CHECK-FIXES: BF(c

[PATCH] D13983: Correctly print the type in modernize-make-unique.

2015-10-22 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Take into account the current LangOptions the check has to add back the 
template argument.

http://reviews.llvm.org/D13983

Files:
  clang-tidy/modernize/MakeUniqueCheck.cpp
  test/clang-tidy/modernize-make-unique.cpp

Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -163,6 +163,18 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_unique instead
   // CHECK-FIXES: IntPtr Typedef = std::make_unique();
 
+  // We use 'bool' instead of '_Bool'.
+  typedef std::unique_ptr BoolPtr;
+  BoolPtr BoolType = BoolPtr(new bool);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_unique instead
+  // CHECK-FIXES: BoolPtr BoolType = std::make_unique();
+
+  // We use 'Base' instead of 'struct Base'.
+  typedef std::unique_ptr BasePtr;
+  BasePtr StructType = BasePtr(new Base);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+  // CHECK-FIXES: BasePtr StructType = std::make_unique();
+
 #define PTR unique_ptr
   std::unique_ptr Macro = std::PTR(new int);
   // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -79,8 +79,8 @@
 // If the template argument is missing (because it is part of the alias)
 // we have to add it back.
 ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size());
-Diag << FixItHint::CreateInsertion(ConstructCallEnd,
-   "<" + Type->getAsString() + ">");
+Diag << FixItHint::CreateInsertion(
+ConstructCallEnd, "<" + Type->getAsString(getLangOpts()) + ">");
   } else {
 ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle);
   }


Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -163,6 +163,18 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_unique instead
   // CHECK-FIXES: IntPtr Typedef = std::make_unique();
 
+  // We use 'bool' instead of '_Bool'.
+  typedef std::unique_ptr BoolPtr;
+  BoolPtr BoolType = BoolPtr(new bool);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_unique instead
+  // CHECK-FIXES: BoolPtr BoolType = std::make_unique();
+
+  // We use 'Base' instead of 'struct Base'.
+  typedef std::unique_ptr BasePtr;
+  BasePtr StructType = BasePtr(new Base);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+  // CHECK-FIXES: BasePtr StructType = std::make_unique();
+
 #define PTR unique_ptr
   std::unique_ptr Macro = std::PTR(new int);
   // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -79,8 +79,8 @@
 // If the template argument is missing (because it is part of the alias)
 // we have to add it back.
 ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size());
-Diag << FixItHint::CreateInsertion(ConstructCallEnd,
-   "<" + Type->getAsString() + ">");
+Diag << FixItHint::CreateInsertion(
+ConstructCallEnd, "<" + Type->getAsString(getLangOpts()) + ">");
   } else {
 ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle);
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13982: Don't use "auto" on loops over fundamental types in modernize-loop-convert.

2015-10-22 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 38119.
angelgarcia added a comment.

Add a guard to check that ElemType is not null.


http://reviews.llvm.org/D13982

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/LoopConvertCheck.h
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-camelback.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", ARR[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (auto & ELEM : ARR)
+  // CHECK-FIXES: for (int & ELEM : ARR)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUM : NUMS)
+  // CHECK-FIXES: for (int & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS_[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES: for (int & NUM : NUMS_)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & ELEM : NUMS)
+  // CHECK-FIXES: for (int & ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM + NUM);
 
   int ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUMS_I : NUMS)
+  // CHECK-FIXES: for (int & NUMS_I : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_I + NUM + ELEM);
 
   int NUMS_I = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUMS_ELEM : NUMS)
+  // CHECK-FIXES: for (int & NUMS_ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_ELEM + NUM + ELEM + NUMS_I);
 
   int NUMS_ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + NUM + ELEM + NUMS_I + NUMS_ELEM);
 
   int GIVE_ME_NAME_0 = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
 
   int NUMS_J = 0;
@@ -79,7 +79,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_0 : NUMS)
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_J + NUMS_ELEM);
 }
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", arr[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (auto & elem : arr)
+  // CHECK-FIXES: for (int & elem : arr)
   // CHECK-FIXES-NEXT: printf("%d\n", elem);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & num : nums)
+  // CHECK-FIXES: for (int & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums_[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & nu

[PATCH] D13982: Don't use "auto" on loops over fundamental types in modernize-loop-convert.

2015-10-22 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

using "auto" on a loop that iterates over ints is kind of an overkill. Use the 
real type name instead.

http://reviews.llvm.org/D13982

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/LoopConvertCheck.h
  test/clang-tidy/modernize-loop-convert-basic.cpp
  test/clang-tidy/modernize-loop-convert-camelback.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", ARR[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (auto & ELEM : ARR)
+  // CHECK-FIXES: for (int & ELEM : ARR)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUM : NUMS)
+  // CHECK-FIXES: for (int & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS_[I]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES: for (int & NUM : NUMS_)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & ELEM : NUMS)
+  // CHECK-FIXES: for (int & ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", ELEM + NUM);
 
   int ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUMS_I : NUMS)
+  // CHECK-FIXES: for (int & NUMS_I : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_I + NUM + ELEM);
 
   int NUMS_I = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & NUMS_ELEM : NUMS)
+  // CHECK-FIXES: for (int & NUMS_ELEM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUMS_ELEM + NUM + ELEM + NUMS_I);
 
   int NUMS_ELEM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + NUM + ELEM + NUMS_I + NUMS_ELEM);
 
   int GIVE_ME_NAME_0 = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_ELEM + GIVE_ME_NAME_0);
 
   int NUMS_J = 0;
@@ -79,7 +79,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_0 : NUMS)
-  // CHECK-FIXES: for (auto & GIVE_ME_NAME_1 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_0 : NUMS)
+  // CHECK-FIXES: for (int & GIVE_ME_NAME_1 : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", GIVE_ME_NAME_0 + GIVE_ME_NAME_1 + NUM + ELEM + NUMS_I + NUMS_J + NUMS_ELEM);
 }
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -14,61 +14,61 @@
 printf("%d\n", arr[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
-  // CHECK-FIXES: for (auto & elem : arr)
+  // CHECK-FIXES: for (int & elem : arr)
   // CHECK-FIXES-NEXT: printf("%d\n", elem);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i]);
   }
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto & num : nums)
+  // CHECK-FIXES: for (int & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums_[i]);
   }
   // CHECK

[PATCH] D13975: Make string constants in the modernize module static.

2015-10-22 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added a subscriber: cfe-commits.

Add static to global variables, if they are not in an anonymous namespace.

http://reviews.llvm.org/D13975

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/MakeUniqueCheck.cpp
  clang-tidy/modernize/ReplaceAutoPtrCheck.cpp

Index: clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
===
--- clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
+++ clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
@@ -21,8 +21,8 @@
 namespace tidy {
 namespace modernize {
 
-const char AutoPtrTokenId[] = "AutoPrTokenId";
-const char AutoPtrOwnershipTransferId[] = "AutoPtrOwnershipTransferId";
+static const char AutoPtrTokenId[] = "AutoPrTokenId";
+static const char AutoPtrOwnershipTransferId[] = "AutoPtrOwnershipTransferId";
 
 /// \brief Matches expressions that are lvalues.
 ///
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -18,9 +18,9 @@
 namespace tidy {
 namespace modernize {
 
-const char PointerType[] = "pointerType";
-const char ConstructorCall[] = "constructorCall";
-const char NewExpression[] = "newExpression";
+static const char PointerType[] = "pointerType";
+static const char ConstructorCall[] = "constructorCall";
+static const char NewExpression[] = "newExpression";
 
 void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) {
   if (getLangOpts().CPlusPlus11) {
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -19,19 +19,19 @@
 namespace tidy {
 namespace modernize {
 
-const char LoopNameArray[] = "forLoopArray";
-const char LoopNameIterator[] = "forLoopIterator";
-const char LoopNamePseudoArray[] = "forLoopPseudoArray";
-const char ConditionBoundName[] = "conditionBound";
-const char ConditionVarName[] = "conditionVar";
-const char IncrementVarName[] = "incrementVar";
-const char InitVarName[] = "initVar";
-const char BeginCallName[] = "beginCall";
-const char EndCallName[] = "endCall";
-const char ConditionEndVarName[] = "conditionEndVar";
-const char EndVarName[] = "endVar";
-const char DerefByValueResultName[] = "derefByValueResult";
-const char DerefByRefResultName[] = "derefByRefResult";
+static const char LoopNameArray[] = "forLoopArray";
+static const char LoopNameIterator[] = "forLoopIterator";
+static const char LoopNamePseudoArray[] = "forLoopPseudoArray";
+static const char ConditionBoundName[] = "conditionBound";
+static const char ConditionVarName[] = "conditionVar";
+static const char IncrementVarName[] = "incrementVar";
+static const char InitVarName[] = "initVar";
+static const char BeginCallName[] = "beginCall";
+static const char EndCallName[] = "endCall";
+static const char ConditionEndVarName[] = "conditionEndVar";
+static const char EndVarName[] = "endVar";
+static const char DerefByValueResultName[] = "derefByValueResult";
+static const char DerefByRefResultName[] = "derefByRefResult";
 
 // shared matchers
 static const TypeMatcher AnyType = anything();


Index: clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
===
--- clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
+++ clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
@@ -21,8 +21,8 @@
 namespace tidy {
 namespace modernize {
 
-const char AutoPtrTokenId[] = "AutoPrTokenId";
-const char AutoPtrOwnershipTransferId[] = "AutoPtrOwnershipTransferId";
+static const char AutoPtrTokenId[] = "AutoPrTokenId";
+static const char AutoPtrOwnershipTransferId[] = "AutoPtrOwnershipTransferId";
 
 /// \brief Matches expressions that are lvalues.
 ///
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -18,9 +18,9 @@
 namespace tidy {
 namespace modernize {
 
-const char PointerType[] = "pointerType";
-const char ConstructorCall[] = "constructorCall";
-const char NewExpression[] = "newExpression";
+static const char PointerType[] = "pointerType";
+static const char ConstructorCall[] = "constructorCall";
+static const char NewExpression[] = "newExpression";
 
 void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) {
   if (getLangOpts().CPlusPlus11) {
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -19,19 +19,19 @@
 namespace tidy {
 namespace modernize {
 
-const char LoopNameArray[] = "forLoopArray";
-const char LoopNameIterator[] = "forLoopIterator";
-const char LoopNamePse

Re: [clang-tools-extra] r250824 - Apply modernize-use-default to clang-tools-extra.

2015-10-20 Thread Angel Garcia via cfe-commits
Sorry, I have just seen all this. Thank you for reverting it, David.

On Tue, Oct 20, 2015 at 11:48 PM, David Blaikie  wrote:

> Reverted in r250862
>
> On Tue, Oct 20, 2015 at 2:39 PM, Tobias Grosser  wrote:
>
>> On 10/20/2015 11:37 PM, David Blaikie wrote:
>>
>>>
>>>
>>> On Tue, Oct 20, 2015 at 2:24 PM, Tobias Grosser via cfe-commits
>>> mailto:cfe-commits@lists.llvm.org>> wrote:
>>>
>>> On 10/20/2015 02:56 PM, Angel Garcia Gomez via cfe-commits wrote:
>>>
>>> Author: angelgarcia
>>> Date: Tue Oct 20 07:56:27 2015
>>> New Revision: 250824
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=250824&view=rev
>>> Log:
>>> Apply modernize-use-default to clang-tools-extra.
>>>
>>> Summary: Replace empty bodies of default constructors and
>>> destructors with '= default'.
>>>
>>>
>>> Hi Angel,
>>>
>>> this breaks http://lab.llvm.org:8011/builders/perf-x86_64-penryn-O3.
>>> The builder runs gcc 4.7.2.
>>>
>>>
>>> Ah, I was/am seeing this on the GDB 7.5 buildbot too - but figured it
>>> might be GCC 4.6, because I couldn't reproduce similar behavior in small
>>> samples on GCC 4.7, but it might be that I have GCC 4.7.3 locally, not
>>> 4.7.2...
>>>
>>> I think I have some ideas on how to fix this while keeping the change,
>>> but probably best to revert first, then try some things once we've got a
>>> reproduction locally to experiment with. (I think maybe Optional and
>>> possibly some other types are missing noexcept on their user-defined
>>> dtors, and GCC 4.old is assuming user defined dtors are noexcept(false),
>>> which is incorrect in C++11)
>>>
>>
>> This seems to be the same issue (or at least a similar issue) to what we
>> had seen in the Polly source. It would be interesting to understand what is
>> going on.
>>
>> Best,
>> Tobias
>>
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13893: Roll-back r250822.

2015-10-20 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL250827: Roll-back r250822. (authored by angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D13893?vs=37875&id=37878#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D13893

Files:
  cfe/trunk/include/clang/AST/ASTConsumer.h
  cfe/trunk/include/clang/AST/CanonicalType.h
  cfe/trunk/include/clang/AST/DeclFriend.h
  cfe/trunk/include/clang/AST/DeclTemplate.h
  cfe/trunk/include/clang/AST/Expr.h
  cfe/trunk/include/clang/AST/ExprCXX.h
  cfe/trunk/include/clang/AST/Mangle.h
  cfe/trunk/include/clang/AST/MangleNumberingContext.h
  cfe/trunk/include/clang/AST/Redeclarable.h
  cfe/trunk/include/clang/AST/StmtIterator.h
  cfe/trunk/include/clang/AST/UnresolvedSet.h
  cfe/trunk/include/clang/AST/VTableBuilder.h
  cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
  cfe/trunk/include/clang/Analysis/Analyses/FormatString.h
  cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
  cfe/trunk/include/clang/Analysis/Analyses/ReachableCode.h
  cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
  cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h
  cfe/trunk/include/clang/Analysis/AnalysisContext.h
  cfe/trunk/include/clang/Analysis/CFG.h
  cfe/trunk/include/clang/Basic/FileSystemStatCache.h
  cfe/trunk/include/clang/Basic/IdentifierTable.h
  cfe/trunk/include/clang/Driver/Job.h
  cfe/trunk/include/clang/Edit/EditsReceiver.h
  cfe/trunk/include/clang/Frontend/SerializedDiagnosticReader.h
  cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h
  cfe/trunk/include/clang/Lex/ModuleMap.h
  cfe/trunk/include/clang/Lex/PTHLexer.h
  cfe/trunk/include/clang/Lex/PreprocessorLexer.h
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/include/clang/Sema/TypoCorrection.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
  cfe/trunk/include/clang/Tooling/FileMatchTrie.h
  cfe/trunk/include/clang/Tooling/Tooling.h
  cfe/trunk/lib/ARCMigrate/ARCMT.cpp
  cfe/trunk/lib/ARCMigrate/TransformActions.cpp
  cfe/trunk/lib/ARCMigrate/Transforms.cpp
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/AST/ASTImporter.cpp
  cfe/trunk/lib/AST/DeclBase.cpp
  cfe/trunk/lib/AST/ExternalASTSource.cpp
  cfe/trunk/lib/AST/StmtPrinter.cpp
  cfe/trunk/lib/AST/VTableBuilder.cpp
  cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp
  cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
  cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
  cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp
  cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
  cfe/trunk/lib/Analysis/CFG.cpp
  cfe/trunk/lib/Analysis/CodeInjector.cpp
  cfe/trunk/lib/Analysis/Consumed.cpp
  cfe/trunk/lib/Analysis/FormatString.cpp
  cfe/trunk/lib/Analysis/ProgramPoint.cpp
  cfe/trunk/lib/Analysis/ThreadSafety.cpp
  cfe/trunk/lib/Analysis/UninitializedValues.cpp
  cfe/trunk/lib/Basic/Diagnostic.cpp
  cfe/trunk/lib/Basic/FileManager.cpp
  cfe/trunk/lib/Basic/IdentifierTable.cpp
  cfe/trunk/lib/Basic/SourceManager.cpp
  cfe/trunk/lib/Basic/TargetInfo.cpp
  cfe/trunk/lib/Basic/VirtualFileSystem.cpp
  cfe/trunk/lib/CodeGen/CGBlocks.cpp
  cfe/trunk/lib/CodeGen/CGCUDARuntime.cpp
  cfe/trunk/lib/CodeGen/CGCXXABI.cpp
  cfe/trunk/lib/CodeGen/CGCall.cpp
  cfe/trunk/lib/CodeGen/CGObjC.cpp
  cfe/trunk/lib/CodeGen/CGOpenCLRuntime.cpp
  cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h
  cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
  cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
  cfe/trunk/lib/CodeGen/TargetInfo.cpp
  cfe/trunk/lib/Driver/Tool.cpp
  cfe/trunk/lib/Driver/ToolChain.cpp
  cfe/trunk/lib/Driver/ToolChains.cpp
  cfe/trunk/lib/Format/BreakableToken.h
  cfe/trunk/lib/Format/FormatToken.cpp
  cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
  cfe/trunk/lib/Format/UnwrappedLineParser.cpp
  cfe/trunk/lib/Format/UnwrappedLineParser.h
  cfe/trunk/lib/Frontend/ASTUnit.cpp
  cfe/trunk/lib/Frontend/CacheTokens.cpp
  cfe/trunk/lib/Frontend/CompilerInvocation.cpp
  cfe/trunk/lib/Frontend/DependencyFile.cpp
  cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
  cfe/trunk/lib/Frontend/FrontendAction.cpp
  cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
  cfe/trunk/lib/Frontend/Rewrite/FixItRewriter.cpp
  cfe/trunk/lib/Frontend/Rewrite/FrontendActions.cpp
  cfe/trunk/lib/Frontend/Rewrit

[PATCH] D13893: Roll-back r250822.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

It breaks the build for the ASTMatchers

http://reviews.llvm.org/D13893

Files:
  include/clang/AST/ASTConsumer.h
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclFriend.h
  include/clang/AST/DeclTemplate.h
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/Mangle.h
  include/clang/AST/MangleNumberingContext.h
  include/clang/AST/Redeclarable.h
  include/clang/AST/StmtIterator.h
  include/clang/AST/UnresolvedSet.h
  include/clang/AST/VTableBuilder.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  include/clang/Analysis/Analyses/FormatString.h
  include/clang/Analysis/Analyses/LiveVariables.h
  include/clang/Analysis/Analyses/ReachableCode.h
  include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
  include/clang/Analysis/Analyses/UninitializedValues.h
  include/clang/Analysis/AnalysisContext.h
  include/clang/Analysis/CFG.h
  include/clang/Basic/FileSystemStatCache.h
  include/clang/Basic/IdentifierTable.h
  include/clang/Driver/Job.h
  include/clang/Edit/EditsReceiver.h
  include/clang/Frontend/SerializedDiagnosticReader.h
  include/clang/Frontend/VerifyDiagnosticConsumer.h
  include/clang/Lex/ModuleMap.h
  include/clang/Lex/PTHLexer.h
  include/clang/Lex/PreprocessorLexer.h
  include/clang/Sema/Sema.h
  include/clang/Sema/TypoCorrection.h
  include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
  include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
  include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
  include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
  include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
  include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
  include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
  include/clang/Tooling/FileMatchTrie.h
  include/clang/Tooling/Tooling.h
  lib/ARCMigrate/ARCMT.cpp
  lib/ARCMigrate/TransformActions.cpp
  lib/ARCMigrate/Transforms.cpp
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/DeclBase.cpp
  lib/AST/ExternalASTSource.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/VTableBuilder.cpp
  lib/ASTMatchers/ASTMatchFinder.cpp
  lib/ASTMatchers/Dynamic/Marshallers.h
  lib/ASTMatchers/Dynamic/Parser.cpp
  lib/ASTMatchers/Dynamic/VariantValue.cpp
  lib/Analysis/AnalysisDeclContext.cpp
  lib/Analysis/CFG.cpp
  lib/Analysis/CodeInjector.cpp
  lib/Analysis/Consumed.cpp
  lib/Analysis/FormatString.cpp
  lib/Analysis/ProgramPoint.cpp
  lib/Analysis/ThreadSafety.cpp
  lib/Analysis/UninitializedValues.cpp
  lib/Basic/Diagnostic.cpp
  lib/Basic/FileManager.cpp
  lib/Basic/IdentifierTable.cpp
  lib/Basic/SourceManager.cpp
  lib/Basic/TargetInfo.cpp
  lib/Basic/VirtualFileSystem.cpp
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGCUDARuntime.cpp
  lib/CodeGen/CGCXXABI.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGObjC.cpp
  lib/CodeGen/CGOpenCLRuntime.cpp
  lib/CodeGen/CGOpenMPRuntime.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenTBAA.cpp
  lib/CodeGen/TargetInfo.cpp
  lib/Driver/Tool.cpp
  lib/Driver/ToolChain.cpp
  lib/Driver/ToolChains.cpp
  lib/Format/BreakableToken.h
  lib/Format/FormatToken.cpp
  lib/Format/UnwrappedLineFormatter.cpp
  lib/Format/UnwrappedLineParser.cpp
  lib/Format/UnwrappedLineParser.h
  lib/Frontend/ASTUnit.cpp
  lib/Frontend/CacheTokens.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Frontend/DependencyFile.cpp
  lib/Frontend/DiagnosticRenderer.cpp
  lib/Frontend/FrontendAction.cpp
  lib/Frontend/MultiplexConsumer.cpp
  lib/Frontend/Rewrite/FixItRewriter.cpp
  lib/Frontend/Rewrite/FrontendActions.cpp
  lib/Frontend/Rewrite/RewriteModernObjC.cpp
  lib/Frontend/Rewrite/RewriteObjC.cpp
  lib/Frontend/SerializedDiagnosticPrinter.cpp
  lib/Frontend/TextDiagnostic.cpp
  lib/Index/CommentToXML.cpp
  lib/Lex/HeaderSearch.cpp
  lib/Lex/PPLexerChange.cpp
  lib/Lex/PTHLexer.cpp
  lib/Lex/Pragma.cpp
  lib/Lex/PreprocessingRecord.cpp
  lib/Lex/Preprocessor.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Rewrite/TokenRewriter.cpp
  lib/Sema/AttributeList.cpp
  lib/Sema/CodeCompleteConsumer.cpp
  lib/Sema/MultiplexExternalSemaSource.cpp
  lib/Sema/ScopeInfo.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaOpenMP.cpp
  lib/Sema/SemaPseudoObject.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/GeneratePCH.cpp
  lib/Serialization/MultiOnDiskHashTable.h
  lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  lib/StaticAnalyzer/Core/BugReporter.cpp
  lib/StaticAnalyzer/Core/ConstraintManager.cpp
  lib/StaticAnalyzer/Core/CoreEngine.cpp
  lib/StaticAnalyzer/Core/ExplodedGraph.cpp
  lib/StaticAnaly

Re: [PATCH] D13892: Apply modernize-use-default to compiler-rt.

2015-10-20 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL250823: Apply modernize-use-default to compiler-rt. 
(authored by angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D13892?vs=37868&id=37869#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D13892

Files:
  compiler-rt/trunk/lib/asan/asan_fake_stack.h
  compiler-rt/trunk/lib/msan/msan_allocator.h
  compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h
  compiler-rt/trunk/lib/tsan/rtl/tsan_clock.h
  compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc
  compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
  compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
  compiler-rt/trunk/lib/ubsan/ubsan_diag.h

Index: compiler-rt/trunk/lib/asan/asan_fake_stack.h
===
--- compiler-rt/trunk/lib/asan/asan_fake_stack.h
+++ compiler-rt/trunk/lib/asan/asan_fake_stack.h
@@ -155,7 +155,7 @@
   void ForEachFakeFrame(RangeIteratorCallback callback, void *arg);
 
  private:
-  FakeStack() { }
+  FakeStack() = default;
   static const uptr kFlagsOffset = 4096;  // This is were the flags begin.
   // Must match the number of uses of DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID
   COMPILER_CHECK(kNumberOfSizeClasses == 11);
Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h
===
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h
@@ -87,7 +87,7 @@
   // }
   class Iterator {
public:
-Iterator() { }
+Iterator() = default;
 explicit Iterator(const BasicBitVector &bv) : bv_(bv) {}
 bool hasNext() const { return !bv_.empty(); }
 uptr next() { return bv_.getAndClearFirstOne(); }
@@ -273,7 +273,7 @@
   // }
   class Iterator {
public:
-Iterator() { }
+Iterator() = default;
 explicit Iterator(const TwoLevelBitVector &bv) : bv_(bv), i0_(0), i1_(0) {
   it1_.clear();
   it2_.clear();
Index: compiler-rt/trunk/lib/msan/msan_allocator.h
===
--- compiler-rt/trunk/lib/msan/msan_allocator.h
+++ compiler-rt/trunk/lib/msan/msan_allocator.h
@@ -26,7 +26,7 @@
 
  private:
   // These objects are allocated via mmap() and are zero-initialized.
-  MsanThreadLocalMallocStorage() {}
+  MsanThreadLocalMallocStorage() = default;
 };
 
 } // namespace __msan
Index: compiler-rt/trunk/lib/ubsan/ubsan_diag.h
===
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.h
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.h
@@ -150,7 +150,7 @@
 
   /// An individual diagnostic message argument.
   struct Arg {
-Arg() {}
+Arg() = default;
 Arg(const char *String) : Kind(AK_String), String(String) {}
 Arg(TypeName TN) : Kind(AK_TypeName), String(TN.getName()) {}
 Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}
Index: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
===
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
@@ -67,9 +67,8 @@
 : mset(MBlockReportMutex) {
 }
 
-ReportDesc::~ReportDesc() {
-  // FIXME(dvyukov): it must be leaking a lot of memory.
-}
+// FIXME(dvyukov): it must be leaking a lot of memory.
+ReportDesc::~ReportDesc() = default;
 
 #ifndef SANITIZER_GO
 
Index: compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc
===
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc
@@ -126,9 +126,8 @@
 #endif
 }
 
-InternalDeadlockDetector::InternalDeadlockDetector() {
-  // Rely on zero initialization because some mutexes can be locked before ctor.
-}
+// Rely on zero initialization because some mutexes can be locked before ctor.
+InternalDeadlockDetector::InternalDeadlockDetector() = default;
 
 #if SANITIZER_DEBUG && !SANITIZER_GO
 void InternalDeadlockDetector::Lock(MutexType t) {
Index: compiler-rt/trunk/lib/tsan/rtl/tsan_clock.h
===
--- compiler-rt/trunk/lib/tsan/rtl/tsan_clock.h
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_clock.h
@@ -33,8 +33,7 @@
 ClockElem clock[kClockCount];
   };
 
-  ClockBlock() {
-  }
+  ClockBlock() = default;
 };
 
 typedef DenseSlabAlloc ClockAlloc;
Index: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
===
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
@@ -31,8 +31,7 @@
 }
 
 #ifndef SANITIZER_GO
-ThreadContext::~ThreadContext() {
-}
+ThreadContext::~ThreadContext() = default;
 #endif
 
 void ThreadContext::OnDead() {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cg

Re: [PATCH] D13892: Apply modernize-use-default to compiler-rt.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37868.
angelgarcia added a comment.

Put comments back.


http://reviews.llvm.org/D13892

Files:
  lib/asan/asan_fake_stack.h
  lib/msan/msan_allocator.h
  lib/sanitizer_common/sanitizer_bitvector.h
  lib/tsan/rtl/tsan_clock.h
  lib/tsan/rtl/tsan_mutex.cc
  lib/tsan/rtl/tsan_report.cc
  lib/tsan/rtl/tsan_rtl_thread.cc
  lib/ubsan/ubsan_diag.h

Index: lib/ubsan/ubsan_diag.h
===
--- lib/ubsan/ubsan_diag.h
+++ lib/ubsan/ubsan_diag.h
@@ -150,7 +150,7 @@
 
   /// An individual diagnostic message argument.
   struct Arg {
-Arg() {}
+Arg() = default;
 Arg(const char *String) : Kind(AK_String), String(String) {}
 Arg(TypeName TN) : Kind(AK_TypeName), String(TN.getName()) {}
 Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}
Index: lib/tsan/rtl/tsan_rtl_thread.cc
===
--- lib/tsan/rtl/tsan_rtl_thread.cc
+++ lib/tsan/rtl/tsan_rtl_thread.cc
@@ -31,8 +31,7 @@
 }
 
 #ifndef SANITIZER_GO
-ThreadContext::~ThreadContext() {
-}
+ThreadContext::~ThreadContext() = default;
 #endif
 
 void ThreadContext::OnDead() {
Index: lib/tsan/rtl/tsan_report.cc
===
--- lib/tsan/rtl/tsan_report.cc
+++ lib/tsan/rtl/tsan_report.cc
@@ -67,9 +67,8 @@
 : mset(MBlockReportMutex) {
 }
 
-ReportDesc::~ReportDesc() {
-  // FIXME(dvyukov): it must be leaking a lot of memory.
-}
+// FIXME(dvyukov): it must be leaking a lot of memory.
+ReportDesc::~ReportDesc() = default;
 
 #ifndef SANITIZER_GO
 
Index: lib/tsan/rtl/tsan_mutex.cc
===
--- lib/tsan/rtl/tsan_mutex.cc
+++ lib/tsan/rtl/tsan_mutex.cc
@@ -126,9 +126,8 @@
 #endif
 }
 
-InternalDeadlockDetector::InternalDeadlockDetector() {
-  // Rely on zero initialization because some mutexes can be locked before ctor.
-}
+// Rely on zero initialization because some mutexes can be locked before ctor.
+InternalDeadlockDetector::InternalDeadlockDetector() = default;
 
 #if SANITIZER_DEBUG && !SANITIZER_GO
 void InternalDeadlockDetector::Lock(MutexType t) {
Index: lib/tsan/rtl/tsan_clock.h
===
--- lib/tsan/rtl/tsan_clock.h
+++ lib/tsan/rtl/tsan_clock.h
@@ -33,8 +33,7 @@
 ClockElem clock[kClockCount];
   };
 
-  ClockBlock() {
-  }
+  ClockBlock() = default;
 };
 
 typedef DenseSlabAlloc ClockAlloc;
Index: lib/sanitizer_common/sanitizer_bitvector.h
===
--- lib/sanitizer_common/sanitizer_bitvector.h
+++ lib/sanitizer_common/sanitizer_bitvector.h
@@ -87,7 +87,7 @@
   // }
   class Iterator {
public:
-Iterator() { }
+Iterator() = default;
 explicit Iterator(const BasicBitVector &bv) : bv_(bv) {}
 bool hasNext() const { return !bv_.empty(); }
 uptr next() { return bv_.getAndClearFirstOne(); }
@@ -273,7 +273,7 @@
   // }
   class Iterator {
public:
-Iterator() { }
+Iterator() = default;
 explicit Iterator(const TwoLevelBitVector &bv) : bv_(bv), i0_(0), i1_(0) {
   it1_.clear();
   it2_.clear();
Index: lib/msan/msan_allocator.h
===
--- lib/msan/msan_allocator.h
+++ lib/msan/msan_allocator.h
@@ -26,7 +26,7 @@
 
  private:
   // These objects are allocated via mmap() and are zero-initialized.
-  MsanThreadLocalMallocStorage() {}
+  MsanThreadLocalMallocStorage() = default;
 };
 
 } // namespace __msan
Index: lib/asan/asan_fake_stack.h
===
--- lib/asan/asan_fake_stack.h
+++ lib/asan/asan_fake_stack.h
@@ -155,7 +155,7 @@
   void ForEachFakeFrame(RangeIteratorCallback callback, void *arg);
 
  private:
-  FakeStack() { }
+  FakeStack() = default;
   static const uptr kFlagsOffset = 4096;  // This is were the flags begin.
   // Must match the number of uses of DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID
   COMPILER_CHECK(kNumberOfSizeClasses == 11);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13890: Apply modernize-use-default to clang.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37867.
angelgarcia added a comment.

Put comment back.


http://reviews.llvm.org/D13890

Files:
  include/clang/AST/ASTConsumer.h
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclFriend.h
  include/clang/AST/DeclTemplate.h
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/Mangle.h
  include/clang/AST/MangleNumberingContext.h
  include/clang/AST/Redeclarable.h
  include/clang/AST/StmtIterator.h
  include/clang/AST/UnresolvedSet.h
  include/clang/AST/VTableBuilder.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  include/clang/Analysis/Analyses/FormatString.h
  include/clang/Analysis/Analyses/LiveVariables.h
  include/clang/Analysis/Analyses/ReachableCode.h
  include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
  include/clang/Analysis/Analyses/UninitializedValues.h
  include/clang/Analysis/AnalysisContext.h
  include/clang/Analysis/CFG.h
  include/clang/Basic/FileSystemStatCache.h
  include/clang/Basic/IdentifierTable.h
  include/clang/Driver/Job.h
  include/clang/Edit/EditsReceiver.h
  include/clang/Frontend/SerializedDiagnosticReader.h
  include/clang/Frontend/VerifyDiagnosticConsumer.h
  include/clang/Lex/ModuleMap.h
  include/clang/Lex/PTHLexer.h
  include/clang/Lex/PreprocessorLexer.h
  include/clang/Sema/Sema.h
  include/clang/Sema/TypoCorrection.h
  include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
  include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
  include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
  include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
  include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
  include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
  include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
  include/clang/Tooling/FileMatchTrie.h
  include/clang/Tooling/Tooling.h
  lib/ARCMigrate/ARCMT.cpp
  lib/ARCMigrate/TransformActions.cpp
  lib/ARCMigrate/Transforms.cpp
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/DeclBase.cpp
  lib/AST/ExternalASTSource.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/VTableBuilder.cpp
  lib/ASTMatchers/ASTMatchFinder.cpp
  lib/ASTMatchers/Dynamic/Marshallers.h
  lib/ASTMatchers/Dynamic/Parser.cpp
  lib/ASTMatchers/Dynamic/VariantValue.cpp
  lib/Analysis/AnalysisDeclContext.cpp
  lib/Analysis/CFG.cpp
  lib/Analysis/CodeInjector.cpp
  lib/Analysis/Consumed.cpp
  lib/Analysis/FormatString.cpp
  lib/Analysis/ProgramPoint.cpp
  lib/Analysis/ThreadSafety.cpp
  lib/Analysis/UninitializedValues.cpp
  lib/Basic/Diagnostic.cpp
  lib/Basic/FileManager.cpp
  lib/Basic/IdentifierTable.cpp
  lib/Basic/SourceManager.cpp
  lib/Basic/TargetInfo.cpp
  lib/Basic/VirtualFileSystem.cpp
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGCUDARuntime.cpp
  lib/CodeGen/CGCXXABI.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGObjC.cpp
  lib/CodeGen/CGOpenCLRuntime.cpp
  lib/CodeGen/CGOpenMPRuntime.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenTBAA.cpp
  lib/CodeGen/TargetInfo.cpp
  lib/Driver/Tool.cpp
  lib/Driver/ToolChain.cpp
  lib/Driver/ToolChains.cpp
  lib/Format/BreakableToken.h
  lib/Format/FormatToken.cpp
  lib/Format/UnwrappedLineFormatter.cpp
  lib/Format/UnwrappedLineParser.cpp
  lib/Format/UnwrappedLineParser.h
  lib/Frontend/ASTUnit.cpp
  lib/Frontend/CacheTokens.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Frontend/DependencyFile.cpp
  lib/Frontend/DiagnosticRenderer.cpp
  lib/Frontend/FrontendAction.cpp
  lib/Frontend/MultiplexConsumer.cpp
  lib/Frontend/Rewrite/FixItRewriter.cpp
  lib/Frontend/Rewrite/FrontendActions.cpp
  lib/Frontend/Rewrite/RewriteModernObjC.cpp
  lib/Frontend/Rewrite/RewriteObjC.cpp
  lib/Frontend/SerializedDiagnosticPrinter.cpp
  lib/Frontend/TextDiagnostic.cpp
  lib/Index/CommentToXML.cpp
  lib/Lex/HeaderSearch.cpp
  lib/Lex/PPLexerChange.cpp
  lib/Lex/PTHLexer.cpp
  lib/Lex/Pragma.cpp
  lib/Lex/PreprocessingRecord.cpp
  lib/Lex/Preprocessor.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Rewrite/TokenRewriter.cpp
  lib/Sema/AttributeList.cpp
  lib/Sema/CodeCompleteConsumer.cpp
  lib/Sema/MultiplexExternalSemaSource.cpp
  lib/Sema/ScopeInfo.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaOpenMP.cpp
  lib/Sema/SemaPseudoObject.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/GeneratePCH.cpp
  lib/Serialization/MultiOnDiskHashTable.h
  lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  lib/StaticAnalyzer/Core/BugReporter.cpp
  lib/StaticAnalyzer/Core/ConstraintManager.cpp
  lib/StaticAnalyzer/Core/CoreEngine.cpp
  lib/StaticAnalyzer/Core/ExplodedGraph.cpp
  lib/StaticAnalyzer/Core/MemRegion.cpp
  lib/StaticAnalyzer/Core/PathDiagn

[PATCH] D13892: Apply modernize-use-default to compiler-rt.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Replace empty bodies of default constructors and destructors with '= default'.

http://reviews.llvm.org/D13892

Files:
  lib/asan/asan_fake_stack.h
  lib/msan/msan_allocator.h
  lib/sanitizer_common/sanitizer_bitvector.h
  lib/tsan/rtl/tsan_clock.h
  lib/tsan/rtl/tsan_mutex.cc
  lib/tsan/rtl/tsan_report.cc
  lib/tsan/rtl/tsan_rtl_thread.cc
  lib/ubsan/ubsan_diag.h

Index: lib/ubsan/ubsan_diag.h
===
--- lib/ubsan/ubsan_diag.h
+++ lib/ubsan/ubsan_diag.h
@@ -150,7 +150,7 @@
 
   /// An individual diagnostic message argument.
   struct Arg {
-Arg() {}
+Arg() = default;
 Arg(const char *String) : Kind(AK_String), String(String) {}
 Arg(TypeName TN) : Kind(AK_TypeName), String(TN.getName()) {}
 Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}
Index: lib/tsan/rtl/tsan_rtl_thread.cc
===
--- lib/tsan/rtl/tsan_rtl_thread.cc
+++ lib/tsan/rtl/tsan_rtl_thread.cc
@@ -31,8 +31,7 @@
 }
 
 #ifndef SANITIZER_GO
-ThreadContext::~ThreadContext() {
-}
+ThreadContext::~ThreadContext() = default;
 #endif
 
 void ThreadContext::OnDead() {
Index: lib/tsan/rtl/tsan_report.cc
===
--- lib/tsan/rtl/tsan_report.cc
+++ lib/tsan/rtl/tsan_report.cc
@@ -67,9 +67,7 @@
 : mset(MBlockReportMutex) {
 }
 
-ReportDesc::~ReportDesc() {
-  // FIXME(dvyukov): it must be leaking a lot of memory.
-}
+ReportDesc::~ReportDesc() = default;
 
 #ifndef SANITIZER_GO
 
Index: lib/tsan/rtl/tsan_mutex.cc
===
--- lib/tsan/rtl/tsan_mutex.cc
+++ lib/tsan/rtl/tsan_mutex.cc
@@ -126,9 +126,7 @@
 #endif
 }
 
-InternalDeadlockDetector::InternalDeadlockDetector() {
-  // Rely on zero initialization because some mutexes can be locked before ctor.
-}
+InternalDeadlockDetector::InternalDeadlockDetector() = default;
 
 #if SANITIZER_DEBUG && !SANITIZER_GO
 void InternalDeadlockDetector::Lock(MutexType t) {
Index: lib/tsan/rtl/tsan_clock.h
===
--- lib/tsan/rtl/tsan_clock.h
+++ lib/tsan/rtl/tsan_clock.h
@@ -33,8 +33,7 @@
 ClockElem clock[kClockCount];
   };
 
-  ClockBlock() {
-  }
+  ClockBlock() = default;
 };
 
 typedef DenseSlabAlloc ClockAlloc;
Index: lib/sanitizer_common/sanitizer_bitvector.h
===
--- lib/sanitizer_common/sanitizer_bitvector.h
+++ lib/sanitizer_common/sanitizer_bitvector.h
@@ -87,7 +87,7 @@
   // }
   class Iterator {
public:
-Iterator() { }
+Iterator() = default;
 explicit Iterator(const BasicBitVector &bv) : bv_(bv) {}
 bool hasNext() const { return !bv_.empty(); }
 uptr next() { return bv_.getAndClearFirstOne(); }
@@ -273,7 +273,7 @@
   // }
   class Iterator {
public:
-Iterator() { }
+Iterator() = default;
 explicit Iterator(const TwoLevelBitVector &bv) : bv_(bv), i0_(0), i1_(0) {
   it1_.clear();
   it2_.clear();
Index: lib/msan/msan_allocator.h
===
--- lib/msan/msan_allocator.h
+++ lib/msan/msan_allocator.h
@@ -26,7 +26,7 @@
 
  private:
   // These objects are allocated via mmap() and are zero-initialized.
-  MsanThreadLocalMallocStorage() {}
+  MsanThreadLocalMallocStorage() = default;
 };
 
 } // namespace __msan
Index: lib/asan/asan_fake_stack.h
===
--- lib/asan/asan_fake_stack.h
+++ lib/asan/asan_fake_stack.h
@@ -155,7 +155,7 @@
   void ForEachFakeFrame(RangeIteratorCallback callback, void *arg);
 
  private:
-  FakeStack() { }
+  FakeStack() = default;
   static const uptr kFlagsOffset = 4096;  // This is were the flags begin.
   // Must match the number of uses of DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID
   COMPILER_CHECK(kNumberOfSizeClasses == 11);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D13890: Apply modernize-use-default to clang.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.
Herald added a subscriber: klimek.

Replace empty bodies of default constructors and destructors with '= default'.

http://reviews.llvm.org/D13890

Files:
  include/clang/AST/ASTConsumer.h
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclFriend.h
  include/clang/AST/DeclTemplate.h
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/Mangle.h
  include/clang/AST/MangleNumberingContext.h
  include/clang/AST/Redeclarable.h
  include/clang/AST/StmtIterator.h
  include/clang/AST/UnresolvedSet.h
  include/clang/AST/VTableBuilder.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  include/clang/Analysis/Analyses/FormatString.h
  include/clang/Analysis/Analyses/LiveVariables.h
  include/clang/Analysis/Analyses/ReachableCode.h
  include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
  include/clang/Analysis/Analyses/UninitializedValues.h
  include/clang/Analysis/AnalysisContext.h
  include/clang/Analysis/CFG.h
  include/clang/Basic/FileSystemStatCache.h
  include/clang/Basic/IdentifierTable.h
  include/clang/Driver/Job.h
  include/clang/Edit/EditsReceiver.h
  include/clang/Frontend/SerializedDiagnosticReader.h
  include/clang/Frontend/VerifyDiagnosticConsumer.h
  include/clang/Lex/ModuleMap.h
  include/clang/Lex/PTHLexer.h
  include/clang/Lex/PreprocessorLexer.h
  include/clang/Sema/Sema.h
  include/clang/Sema/TypoCorrection.h
  include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
  include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
  include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
  include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
  include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
  include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
  include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
  include/clang/Tooling/FileMatchTrie.h
  include/clang/Tooling/Tooling.h
  lib/ARCMigrate/ARCMT.cpp
  lib/ARCMigrate/TransformActions.cpp
  lib/ARCMigrate/Transforms.cpp
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/DeclBase.cpp
  lib/AST/ExternalASTSource.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/VTableBuilder.cpp
  lib/ASTMatchers/ASTMatchFinder.cpp
  lib/ASTMatchers/Dynamic/Marshallers.h
  lib/ASTMatchers/Dynamic/Parser.cpp
  lib/ASTMatchers/Dynamic/VariantValue.cpp
  lib/Analysis/AnalysisDeclContext.cpp
  lib/Analysis/CFG.cpp
  lib/Analysis/CodeInjector.cpp
  lib/Analysis/Consumed.cpp
  lib/Analysis/FormatString.cpp
  lib/Analysis/ProgramPoint.cpp
  lib/Analysis/ThreadSafety.cpp
  lib/Analysis/UninitializedValues.cpp
  lib/Basic/Diagnostic.cpp
  lib/Basic/FileManager.cpp
  lib/Basic/IdentifierTable.cpp
  lib/Basic/SourceManager.cpp
  lib/Basic/TargetInfo.cpp
  lib/Basic/VirtualFileSystem.cpp
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGCUDARuntime.cpp
  lib/CodeGen/CGCXXABI.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGObjC.cpp
  lib/CodeGen/CGOpenCLRuntime.cpp
  lib/CodeGen/CGOpenMPRuntime.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenTBAA.cpp
  lib/CodeGen/TargetInfo.cpp
  lib/Driver/Tool.cpp
  lib/Driver/ToolChain.cpp
  lib/Driver/ToolChains.cpp
  lib/Format/BreakableToken.h
  lib/Format/FormatToken.cpp
  lib/Format/UnwrappedLineFormatter.cpp
  lib/Format/UnwrappedLineParser.cpp
  lib/Format/UnwrappedLineParser.h
  lib/Frontend/ASTUnit.cpp
  lib/Frontend/CacheTokens.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Frontend/DependencyFile.cpp
  lib/Frontend/DiagnosticRenderer.cpp
  lib/Frontend/FrontendAction.cpp
  lib/Frontend/MultiplexConsumer.cpp
  lib/Frontend/Rewrite/FixItRewriter.cpp
  lib/Frontend/Rewrite/FrontendActions.cpp
  lib/Frontend/Rewrite/RewriteModernObjC.cpp
  lib/Frontend/Rewrite/RewriteObjC.cpp
  lib/Frontend/SerializedDiagnosticPrinter.cpp
  lib/Frontend/TextDiagnostic.cpp
  lib/Index/CommentToXML.cpp
  lib/Lex/HeaderSearch.cpp
  lib/Lex/PPLexerChange.cpp
  lib/Lex/PTHLexer.cpp
  lib/Lex/Pragma.cpp
  lib/Lex/PreprocessingRecord.cpp
  lib/Lex/Preprocessor.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Rewrite/TokenRewriter.cpp
  lib/Sema/AttributeList.cpp
  lib/Sema/CodeCompleteConsumer.cpp
  lib/Sema/MultiplexExternalSemaSource.cpp
  lib/Sema/ScopeInfo.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaOpenMP.cpp
  lib/Sema/SemaPseudoObject.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/GeneratePCH.cpp
  lib/Serialization/MultiOnDiskHashTable.h
  lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  lib/StaticAnalyzer/Core/BugReporter.cpp
  lib/StaticAnalyzer/Core/ConstraintManager.cpp
  lib/StaticAnalyz

[PATCH] D13889: Apply modernize-use-default to clang-tools-extra.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Replace empty bodies of default constructors and destructors with '= default'.

http://reviews.llvm.org/D13889

Files:
  clang-modernize/Core/IncludeDirectives.cpp
  clang-modernize/Core/Transform.cpp
  clang-query/Query.cpp
  clang-tidy/ClangTidyModule.h
  clang-tidy/ClangTidyOptions.h
  clang-tidy/utils/IncludeInserter.cpp
  modularize/CoverageChecker.cpp
  modularize/PreprocessorTracker.cpp
  pp-trace/PPCallbacksTracker.cpp
  unittests/clang-tidy/IncludeInserterTest.cpp

Index: unittests/clang-tidy/IncludeInserterTest.cpp
===
--- unittests/clang-tidy/IncludeInserterTest.cpp
+++ unittests/clang-tidy/IncludeInserterTest.cpp
@@ -98,7 +98,7 @@
 public:
   CXXSystemIncludeInserterCheck(StringRef CheckName, ClangTidyContext *Context)
   : IncludeInserterCheckBase(CheckName, Context) {}
-  virtual ~CXXSystemIncludeInserterCheck() {}
+  virtual ~CXXSystemIncludeInserterCheck() = default;
 
   std::vector HeadersToInclude() const override { return {"set"}; }
   bool IsAngledInclude() const override { return true; }
Index: pp-trace/PPCallbacksTracker.cpp
===
--- pp-trace/PPCallbacksTracker.cpp
+++ pp-trace/PPCallbacksTracker.cpp
@@ -93,7 +93,7 @@
clang::Preprocessor &PP)
 : CallbackCalls(CallbackCalls), Ignore(Ignore), PP(PP) {}
 
-PPCallbacksTracker::~PPCallbacksTracker() {}
+PPCallbacksTracker::~PPCallbacksTracker() = default;
 
 // Callback functions.
 
Index: modularize/PreprocessorTracker.cpp
===
--- modularize/PreprocessorTracker.cpp
+++ modularize/PreprocessorTracker.cpp
@@ -746,7 +746,7 @@
   PreprocessorCallbacks(PreprocessorTrackerImpl &ppTracker,
 clang::Preprocessor &PP, llvm::StringRef rootHeaderFile)
   : PPTracker(ppTracker), PP(PP), RootHeaderFile(rootHeaderFile) {}
-  ~PreprocessorCallbacks() override {}
+  ~PreprocessorCallbacks() override = default;
 
   // Overridden handlers.
   void InclusionDirective(clang::SourceLocation HashLoc,
@@ -812,7 +812,7 @@
 }
   }
 
-  ~PreprocessorTrackerImpl() override {}
+  ~PreprocessorTrackerImpl() override = default;
 
   // Handle entering a preprocessing session.
   void handlePreprocessorEntry(clang::Preprocessor &PP,
@@ -1288,7 +1288,7 @@
 // PreprocessorTracker functions.
 
 // PreprocessorTracker desctructor.
-PreprocessorTracker::~PreprocessorTracker() {}
+PreprocessorTracker::~PreprocessorTracker() = default;
 
 // Create instance of PreprocessorTracker.
 PreprocessorTracker *PreprocessorTracker::create(
Index: modularize/CoverageChecker.cpp
===
--- modularize/CoverageChecker.cpp
+++ modularize/CoverageChecker.cpp
@@ -83,7 +83,7 @@
 class CoverageCheckerCallbacks : public PPCallbacks {
 public:
   CoverageCheckerCallbacks(CoverageChecker &Checker) : Checker(Checker) {}
-  ~CoverageCheckerCallbacks() override {}
+  ~CoverageCheckerCallbacks() override = default;
 
   // Include directive callback.
   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
Index: clang-tidy/utils/IncludeInserter.cpp
===
--- clang-tidy/utils/IncludeInserter.cpp
+++ clang-tidy/utils/IncludeInserter.cpp
@@ -38,7 +38,7 @@
  IncludeSorter::IncludeStyle Style)
 : SourceMgr(SourceMgr), LangOpts(LangOpts), Style(Style) {}
 
-IncludeInserter::~IncludeInserter() {}
+IncludeInserter::~IncludeInserter() = default;
 
 std::unique_ptr IncludeInserter::CreatePPCallbacks() {
   return llvm::make_unique(this);
Index: clang-tidy/ClangTidyOptions.h
===
--- clang-tidy/ClangTidyOptions.h
+++ clang-tidy/ClangTidyOptions.h
@@ -88,7 +88,7 @@
 /// \brief Abstract interface for retrieving various ClangTidy options.
 class ClangTidyOptionsProvider {
 public:
-  virtual ~ClangTidyOptionsProvider() {}
+  virtual ~ClangTidyOptionsProvider() = default;
 
   /// \brief Returns global options, which are independent of the file.
   virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0;
Index: clang-tidy/ClangTidyModule.h
===
--- clang-tidy/ClangTidyModule.h
+++ clang-tidy/ClangTidyModule.h
@@ -82,7 +82,7 @@
 /// them a prefixed name.
 class ClangTidyModule {
 public:
-  virtual ~ClangTidyModule() {}
+  virtual ~ClangTidyModule() = default;
 
   /// \brief Implement this function in order to register all \c CheckFactories
   /// belonging to this module.
Index: clang-query/Query.cpp
===
--- clang-query/Query.cpp
+++ clang-query/Query.cpp
@

Re: [PATCH] D13871: Add modernize-use-default check to clang-tidy.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37859.
angelgarcia added a comment.

Remove the fixme.


http://reviews.llvm.org/D13871

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tidy/modernize/UseDefaultCheck.cpp
  clang-tidy/modernize/UseDefaultCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-use-default.rst
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-use-default.cpp
@@ -0,0 +1,137 @@
+// RUN: %python %S/check_clang_tidy.py %s modernize-use-default %t
+
+class A {
+public:
+  A();
+  ~A();
+};
+
+A::A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial default constructor [modernize-use-default]
+// CHECK-FIXES: A::A() = default;
+A::~A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial destructor [modernize-use-default]
+// CHECK-FIXES: A::~A() = default;
+
+// Inline definitions.
+class B {
+public:
+  B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: B() = default;
+  ~B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~B() = default;
+};
+
+void f();
+
+class C {
+public:
+  // Non-empty constructor body.
+  C() { f(); }
+  // Non-empty destructor body.
+  ~C() { f(); }
+};
+
+class D {
+public:
+  // Constructor with initializer.
+  D() : Field(5) {}
+  // Constructor with arguments.
+  D(int Arg1, int Arg2) {}
+  int Field;
+};
+
+// Private constructor/destructor.
+class E {
+  E() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: E() = default;
+  ~E() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~E() = default;
+};
+
+// struct.
+struct F {
+  F() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: F() = default;
+  ~F() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: F() = default;
+};
+
+// Deleted constructor/destructor.
+class G {
+public:
+  G() = delete;
+  ~G() = delete;
+};
+
+// Do not remove other keywords.
+class H {
+public:
+  explicit H() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: explicit H() = default;
+  virtual ~H() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: virtual ~H() = default;
+};
+
+// Nested class.
+struct I {
+  struct II {
+II() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+// CHECK-FIXES: II() = default;
+~II() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+// CHECK-FIXES: ~II() = default;
+  };
+  int Int;
+};
+
+// Class template.
+template 
+class J {
+public:
+  J() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: J() = default;
+  ~J() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~J() = default;
+};
+
+// Non user-provided constructor/destructor.
+struct K {
+  int Int;
+};
+void g() {
+  K *PtrK = new K();
+  PtrK->~K();
+  delete PtrK;
+}
+
+// Already using default.
+struct L {
+  L() = default;
+  ~L() = default;
+};
+struct M {
+  M();
+  ~M();
+};
+M::M() = default;
+M::~M() = default;
+
+// Delegating constructor and overriden destructor.
+struct N : H {
+  N() : H() {}
+  ~N() override {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~N() override = default;
+};
Index: docs/clang-tidy/checks/modernize-use-default.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-use-default.rst
@@ -0,0 +1,27 @@
+modernize-use-default
+=
+
+This check replaces default bodies of special member functions with ``=
+default;``.  The explicitly defaulted function declarations enable more
+opportunities in optimization, because the compiler might treat explicitly
+defaulted functions as trivial.
+
+.. code-block:: c++
+
+  struct A {
+A() {}
+~A();
+  };
+  A::~A() {}
+
+  // becomes
+
+  struct A {
+A() = default;
+~A();
+  };
+  A::~A() = default;
+
+.. note::
+  Copy-constructor, copy-assignment operator, move-constructor and
+  move-assignment operator are not supported yet.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -54,6 +54,7 @@
modernize-replace-auto-ptr
modernize-shrink-to-fit
modernize-use-auto
+   modernize-use-default
modernize-use-nullptr
modernize-use-override
readability-braces-around-statements
Index: clang-tidy/modernize/UseDefaultCheck.h
===
--- /dev/null
+

Re: [PATCH] D13871: Add modernize-use-default check to clang-tidy.

2015-10-20 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37833.
angelgarcia added a comment.

Global variable -> static, and a few other additions.

> Will be good idea to add handling of cases where default constructor is empty 
> and only call base class(es) default constructor/members default constructors


I agree, but checking all members and base classes is the main difficulty of 
the copy-constructor/copy-assignment operator. When I implement those I will 
probably update this.


http://reviews.llvm.org/D13871

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tidy/modernize/UseDefaultCheck.cpp
  clang-tidy/modernize/UseDefaultCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-use-default.rst
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-use-default.cpp
@@ -0,0 +1,137 @@
+// RUN: %python %S/check_clang_tidy.py %s modernize-use-default %t
+
+class A {
+public:
+  A();
+  ~A();
+};
+
+A::A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial default constructor [modernize-use-default]
+// CHECK-FIXES: A::A() = default;
+A::~A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial destructor [modernize-use-default]
+// CHECK-FIXES: A::~A() = default;
+
+// Inline definitions.
+class B {
+public:
+  B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: B() = default;
+  ~B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~B() = default;
+};
+
+void f();
+
+class C {
+public:
+  // Non-empty constructor body.
+  C() { f(); }
+  // Non-empty destructor body.
+  ~C() { f(); }
+};
+
+class D {
+public:
+  // Constructor with initializer.
+  D() : Field(5) {}
+  // Constructor with arguments.
+  D(int Arg1, int Arg2) {}
+  int Field;
+};
+
+// Private constructor/destructor.
+class E {
+  E() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: E() = default;
+  ~E() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~E() = default;
+};
+
+// struct.
+struct F {
+  F() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: F() = default;
+  ~F() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: F() = default;
+};
+
+// Deleted constructor/destructor.
+class G {
+public:
+  G() = delete;
+  ~G() = delete;
+};
+
+// Do not remove other keywords.
+class H {
+public:
+  explicit H() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: explicit H() = default;
+  virtual ~H() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: virtual ~H() = default;
+};
+
+// Nested class.
+struct I {
+  struct II {
+II() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+// CHECK-FIXES: II() = default;
+~II() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+// CHECK-FIXES: ~II() = default;
+  };
+  int Int;
+};
+
+// Class template.
+template 
+class J {
+public:
+  J() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: J() = default;
+  ~J() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~J() = default;
+};
+
+// Non user-provided constructor/destructor.
+struct K {
+  int Int;
+};
+void g() {
+  K *PtrK = new K();
+  PtrK->~K();
+  delete PtrK;
+}
+
+// Already using default.
+struct L {
+  L() = default;
+  ~L() = default;
+};
+struct M {
+  M();
+  ~M();
+};
+M::M() = default;
+M::~M() = default;
+
+// Delegating constructor and overriden destructor.
+struct N : H {
+  N() : H() {}
+  ~N() override {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~N() override = default;
+};
Index: docs/clang-tidy/checks/modernize-use-default.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-use-default.rst
@@ -0,0 +1,27 @@
+modernize-use-default
+=
+
+This check replaces default bodies of special member functions with ``=
+default;``.  The explicitly defaulted function declarations enable more
+opportunities in optimization, because the compiler might treat explicitly
+defaulted functions as trivial.
+
+.. code-block:: c++
+
+  struct A {
+A() {}
+~A();
+  };
+  A::~A() {}
+
+  // becomes
+
+  struct A {
+A() = default;
+~A();
+  };
+  A::~A() = default;
+
+.. note::
+  Copy-constructor, copy-assignment operator, move-constructor and
+  move-assignment operator are not supported yet.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ doc

[PATCH] D13871: Add modernize-use-default check to clang-tidy.

2015-10-19 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Add a check that replaces empty bodies of special member functions with '= 
default;'.
For now, it is only implemented for the default constructor and the destructor, 
which are the easier cases.
The copy-constructor and the copy-assignment operator cases will be implemented 
later.

I applied this check to the llvm code base and found 627 warnings (385 in llvm, 
9 in compiler-rt, 220 in clang and 13 in clang-tools-extra).
Applying the fixes didn't break any build or test, it only caused a -Wpedantic 
warning in lib/Target/Mips/MipsOptionRecord.h:33 becaused it replaced
virtual ~MipsOptionRecord(){}; to virtual ~MipsOptionRecord()= default;;

http://reviews.llvm.org/D13871

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tidy/modernize/UseDefaultCheck.cpp
  clang-tidy/modernize/UseDefaultCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-use-default.rst
  test/clang-tidy/modernize-use-default.cpp

Index: test/clang-tidy/modernize-use-default.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-use-default.cpp
@@ -0,0 +1,137 @@
+// RUN: %python %S/check_clang_tidy.py %s modernize-use-default %t
+
+class A {
+public:
+  A();
+  ~A();
+};
+
+A::A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a default constructor/destructor [modernize-use-default]
+// CHECK-FIXES: A::A() = default;
+A::~A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default'
+// CHECK-FIXES: A::~A() = default;
+
+// Inline definitions.
+class B {
+public:
+  B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: B() = default;
+  ~B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~B() = default;
+};
+
+void f();
+
+class C {
+public:
+  // Non-empty constructor body.
+  C() { f(); }
+  // Non-empty destructor body.
+  ~C() { f(); }
+};
+
+class D {
+public:
+  // Constructor with initializer.
+  D() : Field(5) {}
+  // Constructor with arguments.
+  D(int Arg1, int Arg2) {}
+  int Field;
+};
+
+// Private constructor/destructor.
+class E {
+  E() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: E() = default;
+  ~E() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~E() = default;
+};
+
+// struct.
+struct F {
+  F() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: F() = default;
+  ~F() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: F() = default;
+};
+
+// Deleted constructor/destructor.
+class G {
+public:
+  G() = delete;
+  ~G() = delete;
+};
+
+// Do not remove other keywords.
+class H {
+public:
+  explicit H() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: explicit H() = default;
+  virtual ~H() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: virtual ~H() = default;
+};
+
+// Nested class.
+struct I {
+  struct II {
+II() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+// CHECK-FIXES: II() = default;
+~II() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
+// CHECK-FIXES: ~II() = default;
+  };
+  int Int;
+};
+
+// Class template.
+template 
+class J {
+public:
+  J() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: J() = default;
+  ~J() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~J() = default;
+};
+
+// Non user-provided constructor/destructor.
+struct K {
+  int Int;
+};
+void g() {
+  K *PtrK = new K();
+  PtrK->~K();
+  delete PtrK;
+}
+
+// Already using default.
+struct L {
+  L() = default;
+  ~L() = default;
+};
+struct M {
+  M();
+  ~M();
+};
+M::M() = default;
+M::~M() = default;
+
+// Delegating constructor and overriden destructor.
+struct N : H {
+  N() : H() {}
+  ~N() override {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~N() override = default;
+};
Index: docs/clang-tidy/checks/modernize-use-default.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-use-default.rst
@@ -0,0 +1,27 @@
+modernize-use-default
+=
+
+This check replaces default bodies of special member functions with ``=
+default;``.  The explicitly defaulted function declarations enable more
+opportunities in optimization, because the compiler might treat explicitly
+defaulted functions as trivial.
+
+.. code-block:: c++
+
+  struct A {
+A() {}
+~A();
+  };
+  A::~A() {}
+
+  // becomes
+
+  struct A {
+A() = default;
+~A();
+  };
+  A::~A() = default;
+
+.. note::
+  Copy-constructor, 

Re: [clang-tools-extra] r250509 - Fix overlapping replacements in clang-tidy.

2015-10-19 Thread Angel Garcia via cfe-commits
Using these as the default comparison operators might not make much sense,
as they don't take into account all the fields (they only look at
ClangTidyError::Message). But here I just wanted to mimic existing
behavior, so honestly I don't know.

I implemented equality with !<&&!< to improve maintainability. If someone
ever wants to modify LessClangTidyError, EqualClangTidyError will still be
consistent with the new definition without any additional work. Moreover,
LessClangTidyError is used to sort, while EqualClangTidyError is used by
std::unique (a linear amount of times), so the extra work shouldn't be too
bad for the performance.

On Fri, Oct 16, 2015 at 10:50 PM, David Blaikie  wrote:

>
>
> On Fri, Oct 16, 2015 at 4:43 AM, Angel Garcia Gomez via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> Author: angelgarcia
>> Date: Fri Oct 16 06:43:49 2015
>> New Revision: 250509
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=250509&view=rev
>> Log:
>> Fix overlapping replacements in clang-tidy.
>>
>> Summary: Prevent clang-tidy from applying fixes to errors that overlap
>> with other errors' fixes, with one exception: if one fix is completely
>> contained inside another one, then we can apply the big one.
>>
>> Reviewers: bkramer, klimek
>>
>> Subscribers: djasper, cfe-commits, alexfh
>>
>> Differential Revision: http://reviews.llvm.org/D13516
>>
>> Modified:
>> clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
>> clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
>>
>> clang-tools-extra/trunk/unittests/clang-tidy/OverlappingReplacementsTest.cpp
>>
>> Modified:
>> clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=250509&r1=250508&r2=250509&view=diff
>>
>> ==
>> --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
>> (original)
>> +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
>> Fri Oct 16 06:43:49 2015
>> @@ -22,8 +22,8 @@
>>  #include "clang/Basic/DiagnosticOptions.h"
>>  #include "clang/Frontend/DiagnosticRenderer.h"
>>  #include "llvm/ADT/SmallString.h"
>> -#include 
>>  #include 
>> +#include 
>>  using namespace clang;
>>  using namespace tidy;
>>
>> @@ -146,8 +146,7 @@ static llvm::Regex ConsumeGlob(StringRef
>>  }
>>
>>  GlobList::GlobList(StringRef Globs)
>> -: Positive(!ConsumeNegativeIndicator(Globs)),
>> -  Regex(ConsumeGlob(Globs)),
>> +: Positive(!ConsumeNegativeIndicator(Globs)),
>> Regex(ConsumeGlob(Globs)),
>>NextGlob(Globs.empty() ? nullptr : new GlobList(Globs)) {}
>>
>>  bool GlobList::contains(StringRef S, bool Contains) {
>> @@ -222,9 +221,7 @@ const ClangTidyOptions &ClangTidyContext
>>return CurrentOptions;
>>  }
>>
>> -void ClangTidyContext::setCheckProfileData(ProfileData *P) {
>> -  Profile = P;
>> -}
>> +void ClangTidyContext::setCheckProfileData(ProfileData *P) { Profile =
>> P; }
>>
>>  GlobList &ClangTidyContext::getChecksFilter() {
>>assert(CheckFilter != nullptr);
>> @@ -296,16 +293,16 @@ void ClangTidyDiagnosticConsumer::Handle
>>// This is a compiler diagnostic without a warning option. Assign
>> check
>>// name based on its level.
>>switch (DiagLevel) {
>> -case DiagnosticsEngine::Error:
>> -case DiagnosticsEngine::Fatal:
>> -  CheckName = "clang-diagnostic-error";
>> -  break;
>> -case DiagnosticsEngine::Warning:
>> -  CheckName = "clang-diagnostic-warning";
>> -  break;
>> -default:
>> -  CheckName = "clang-diagnostic-unknown";
>> -  break;
>> +  case DiagnosticsEngine::Error:
>> +  case DiagnosticsEngine::Fatal:
>> +CheckName = "clang-diagnostic-error";
>> +break;
>> +  case DiagnosticsEngine::Warning:
>> +CheckName = "clang-diagnostic-warning";
>> +break;
>> +  default:
>> +CheckName = "clang-diagnostic-unknown";
>> +break;
>>}
>>  }
>>
>> @@ -340,7 +337,7 @@ bool ClangTidyDiagnosticConsumer::passes
>> unsigned LineNumber)
>> const {
>>if (Context.getGlobalOptions().LineFilter.empty())
>>  return true;
>> -  for (const FileFilter& Filter : Context.getGlobalOptions().LineFilter)
>> {
>> +  for (const FileFilter &Filter : Context.getGlobalOptions().LineFilter)
>> {
>>  if (FileName.endswith(Filter.Name)) {
>>if (Filter.LineRanges.empty())
>>  return true;
>> @@ -398,26 +395,147 @@ llvm::Regex *ClangTidyDiagnosticConsumer
>>return HeaderFilter.get();
>>  }
>>
>> +void ClangTidyDiagnosticConsumer::removeIncompatibleErrors(
>> +SmallVectorImpl &Errors) const {
>> +  // Each error is modelled as the set of intervals in which it applies
>> +  // replacements. To detect overlapping replaceme

Re: [PATCH] D13810: Replacements in different files do not overlap.

2015-10-16 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37603.
angelgarcia added a comment.

In both files.


http://reviews.llvm.org/D13810

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  test/clang-tidy/Inputs/overlapping/
  test/clang-tidy/Inputs/overlapping/o.h
  test/clang-tidy/overlapping.cpp

Index: test/clang-tidy/overlapping.cpp
===
--- /dev/null
+++ test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN:   not grep "note: this fix will not be applied because it overlaps 
with another fix"
+
+#include 
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.
Index: test/clang-tidy/Inputs/overlapping/o.h
===
--- /dev/null
+++ test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run:   not grep "note: this fix will not be applied because it overlaps 
with another fix"
+
+#include "b.h"
+#include "a.h"
+
+// The comments above are there to match the offset of the #include with the
+// offset of the #includes in the .cpp file.
Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -469,34 +469,40 @@
   }
 
   // Build events from error intervals.
-  std::vector Events;
+  std::map> FileEvents;
   for (unsigned I = 0; I < Errors.size(); ++I) {
 for (const auto &Replace : Errors[I].Fix) {
   unsigned Begin = Replace.getOffset();
   unsigned End = Begin + Replace.getLength();
+  const std::string &FilePath = Replace.getFilePath();
   // FIXME: Handle empty intervals, such as those from insertions.
   if (Begin == End)
 continue;
-  Events.push_back(Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
-  Events.push_back(Event(Begin, End, Event::ET_End, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_End, I, Sizes[I]));
 }
   }
-  std::sort(Events.begin(), Events.end());
 
-  // Sweep.
   std::vector Apply(Errors.size(), true);
-  int OpenIntervals = 0;
-  for (const auto &Event : Events) {
-if (Event.Type == Event::ET_End)
-  --OpenIntervals;
-// This has to be checked after removing the interval from the count if it
-// is an end event, or before adding it if it is a begin event.
-if (OpenIntervals != 0)
-  Apply[Event.ErrorId] = false;
-if (Event.Type == Event::ET_Begin)
-  ++OpenIntervals;
+  for (auto &FileAndEvents : FileEvents) {
+std::vector &Events = FileAndEvents.second;
+// Sweep.
+std::sort(Events.begin(), Events.end());
+int OpenIntervals = 0;
+for (const auto &Event : Events) {
+  if (Event.Type == Event::ET_End)
+--OpenIntervals;
+  // This has to be checked after removing the interval from the count if 
it
+  // is an end event, or before adding it if it is a begin event.
+  if (OpenIntervals != 0)
+Apply[Event.ErrorId] = false;
+  if (Event.Type == Event::ET_Begin)
+++OpenIntervals;
+}
+assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
   }
-  assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
 
   for (unsigned I = 0; I < Errors.size(); ++I) {
 if (!Apply[I]) {


Index: test/clang-tidy/overlapping.cpp
===
--- /dev/null
+++ test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN:   not grep "note: this fix will not be applied because it overlaps with another fix"
+
+#include 
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.
Index: test/clang-tidy/Inputs/overlapping/o.h
===
--- /dev/null
+++ test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run:   not grep "note: this fix will not be applied because i

Re: [PATCH] D13810: Replacements in different files do not overlap.

2015-10-16 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL250523: Replacements in different files do not overlap. 
(authored by angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D13810?vs=37603&id=37604#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D13810

Files:
  clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h
  clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp

Index: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -469,34 +469,40 @@
   }
 
   // Build events from error intervals.
-  std::vector Events;
+  std::map> FileEvents;
   for (unsigned I = 0; I < Errors.size(); ++I) {
 for (const auto &Replace : Errors[I].Fix) {
   unsigned Begin = Replace.getOffset();
   unsigned End = Begin + Replace.getLength();
+  const std::string &FilePath = Replace.getFilePath();
   // FIXME: Handle empty intervals, such as those from insertions.
   if (Begin == End)
 continue;
-  Events.push_back(Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
-  Events.push_back(Event(Begin, End, Event::ET_End, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_End, I, Sizes[I]));
 }
   }
-  std::sort(Events.begin(), Events.end());
 
-  // Sweep.
   std::vector Apply(Errors.size(), true);
-  int OpenIntervals = 0;
-  for (const auto &Event : Events) {
-if (Event.Type == Event::ET_End)
-  --OpenIntervals;
-// This has to be checked after removing the interval from the count if it
-// is an end event, or before adding it if it is a begin event.
-if (OpenIntervals != 0)
-  Apply[Event.ErrorId] = false;
-if (Event.Type == Event::ET_Begin)
-  ++OpenIntervals;
+  for (auto &FileAndEvents : FileEvents) {
+std::vector &Events = FileAndEvents.second;
+// Sweep.
+std::sort(Events.begin(), Events.end());
+int OpenIntervals = 0;
+for (const auto &Event : Events) {
+  if (Event.Type == Event::ET_End)
+--OpenIntervals;
+  // This has to be checked after removing the interval from the count if 
it
+  // is an end event, or before adding it if it is a begin event.
+  if (OpenIntervals != 0)
+Apply[Event.ErrorId] = false;
+  if (Event.Type == Event::ET_Begin)
+++OpenIntervals;
+}
+assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
   }
-  assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
 
   for (unsigned I = 0; I < Errors.size(); ++I) {
 if (!Apply[I]) {
Index: clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h
===
--- clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h
+++ clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run:   not grep "note: this fix will not be applied because it overlaps 
with another fix"
+
+#include "b.h"
+#include "a.h"
+
+// The comments above are there to match the offset of the #include with the
+// offset of the #includes in the .cpp file.
Index: clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN:   not grep "note: this fix will not be applied because it overlaps 
with another fix"
+
+#include 
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.


Index: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -469,34 +469,40 @@
   }
 
   // Build events from error intervals.
-  std::vector Events;
+  std::map> FileEvents;
   for (unsigned I = 0; I < Errors.size(); ++I) {
 for (const auto &Replace : Errors[I].Fix) {
   unsigned Begin = Replace.getOffset();
   unsigned End = Begin + 

Re: [PATCH] D13810: Replacements in different files do not overlap.

2015-10-16 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37602.
angelgarcia added a comment.

Use "not" instead of "!".


http://reviews.llvm.org/D13810

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  test/clang-tidy/Inputs/overlapping/
  test/clang-tidy/Inputs/overlapping/o.h
  test/clang-tidy/overlapping.cpp

Index: test/clang-tidy/overlapping.cpp
===
--- /dev/null
+++ test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN:   not grep "note: this fix will not be applied because it overlaps 
with another fix"
+
+#include 
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.
Index: test/clang-tidy/Inputs/overlapping/o.h
===
--- /dev/null
+++ test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: not clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run:   grep "note: this fix will not be applied because it overlaps with 
another fix"
+
+#include "b.h"
+#include "a.h"
+
+// The comments above are there to match the offset of the #include with the
+// offset of the #includes in the .cpp file.
Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -469,34 +469,40 @@
   }
 
   // Build events from error intervals.
-  std::vector Events;
+  std::map> FileEvents;
   for (unsigned I = 0; I < Errors.size(); ++I) {
 for (const auto &Replace : Errors[I].Fix) {
   unsigned Begin = Replace.getOffset();
   unsigned End = Begin + Replace.getLength();
+  const std::string &FilePath = Replace.getFilePath();
   // FIXME: Handle empty intervals, such as those from insertions.
   if (Begin == End)
 continue;
-  Events.push_back(Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
-  Events.push_back(Event(Begin, End, Event::ET_End, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_End, I, Sizes[I]));
 }
   }
-  std::sort(Events.begin(), Events.end());
 
-  // Sweep.
   std::vector Apply(Errors.size(), true);
-  int OpenIntervals = 0;
-  for (const auto &Event : Events) {
-if (Event.Type == Event::ET_End)
-  --OpenIntervals;
-// This has to be checked after removing the interval from the count if it
-// is an end event, or before adding it if it is a begin event.
-if (OpenIntervals != 0)
-  Apply[Event.ErrorId] = false;
-if (Event.Type == Event::ET_Begin)
-  ++OpenIntervals;
+  for (auto &FileAndEvents : FileEvents) {
+std::vector &Events = FileAndEvents.second;
+// Sweep.
+std::sort(Events.begin(), Events.end());
+int OpenIntervals = 0;
+for (const auto &Event : Events) {
+  if (Event.Type == Event::ET_End)
+--OpenIntervals;
+  // This has to be checked after removing the interval from the count if 
it
+  // is an end event, or before adding it if it is a begin event.
+  if (OpenIntervals != 0)
+Apply[Event.ErrorId] = false;
+  if (Event.Type == Event::ET_Begin)
+++OpenIntervals;
+}
+assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
   }
-  assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
 
   for (unsigned I = 0; I < Errors.size(); ++I) {
 if (!Apply[I]) {


Index: test/clang-tidy/overlapping.cpp
===
--- /dev/null
+++ test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN:   not grep "note: this fix will not be applied because it overlaps with another fix"
+
+#include 
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.
Index: test/clang-tidy/Inputs/overlapping/o.h
===
--- /dev/null
+++ test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: not clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run:   grep "note: this fix will not be applie

Re: [PATCH] D13810: Replacements in different files do not overlap.

2015-10-16 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37600.
angelgarcia added a comment.

Add a test.


http://reviews.llvm.org/D13810

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  test/clang-tidy/Inputs/overlapping/
  test/clang-tidy/Inputs/overlapping/o.h
  test/clang-tidy/overlapping.cpp

Index: test/clang-tidy/overlapping.cpp
===
--- /dev/null
+++ test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: ! clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN:   grep "note: this fix will not be applied because it overlaps with 
another fix"
+
+#include 
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.
Index: test/clang-tidy/Inputs/overlapping/o.h
===
--- /dev/null
+++ test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: ! clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run:   grep "note: this fix will not be applied because it overlaps with 
another fix"
+
+#include "b.h"
+#include "a.h"
+
+// The comments above are there to match the offset of the #include with the
+// offset of the #includes in the .cpp file.
Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -469,34 +469,40 @@
   }
 
   // Build events from error intervals.
-  std::vector Events;
+  std::map> FileEvents;
   for (unsigned I = 0; I < Errors.size(); ++I) {
 for (const auto &Replace : Errors[I].Fix) {
   unsigned Begin = Replace.getOffset();
   unsigned End = Begin + Replace.getLength();
+  const std::string &FilePath = Replace.getFilePath();
   // FIXME: Handle empty intervals, such as those from insertions.
   if (Begin == End)
 continue;
-  Events.push_back(Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
-  Events.push_back(Event(Begin, End, Event::ET_End, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_End, I, Sizes[I]));
 }
   }
-  std::sort(Events.begin(), Events.end());
 
-  // Sweep.
   std::vector Apply(Errors.size(), true);
-  int OpenIntervals = 0;
-  for (const auto &Event : Events) {
-if (Event.Type == Event::ET_End)
-  --OpenIntervals;
-// This has to be checked after removing the interval from the count if it
-// is an end event, or before adding it if it is a begin event.
-if (OpenIntervals != 0)
-  Apply[Event.ErrorId] = false;
-if (Event.Type == Event::ET_Begin)
-  ++OpenIntervals;
+  for (auto &FileAndEvents : FileEvents) {
+std::vector &Events = FileAndEvents.second;
+// Sweep.
+std::sort(Events.begin(), Events.end());
+int OpenIntervals = 0;
+for (const auto &Event : Events) {
+  if (Event.Type == Event::ET_End)
+--OpenIntervals;
+  // This has to be checked after removing the interval from the count if 
it
+  // is an end event, or before adding it if it is a begin event.
+  if (OpenIntervals != 0)
+Apply[Event.ErrorId] = false;
+  if (Event.Type == Event::ET_Begin)
+++OpenIntervals;
+}
+assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
   }
-  assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
 
   for (unsigned I = 0; I < Errors.size(); ++I) {
 if (!Apply[I]) {


Index: test/clang-tidy/overlapping.cpp
===
--- /dev/null
+++ test/clang-tidy/overlapping.cpp
@@ -0,0 +1,10 @@
+// RUN: ! clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// RUN:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// RUN:   grep "note: this fix will not be applied because it overlaps with another fix"
+
+#include 
+#include "o.h"
+
+// Test that clang-tidy takes into account in which file we are doing the
+// replacements to determine if they overlap or not. In the file "o.h" there is
+// a similar error at the same file offset, but they do not overlap.
Index: test/clang-tidy/Inputs/overlapping/o.h
===
--- /dev/null
+++ test/clang-tidy/Inputs/overlapping/o.h
@@ -0,0 +1,9 @@
+// run: ! clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \
+// run:   -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \
+// run:   grep "note: this fix will not be applied because it overlaps 

[PATCH] D13810: Replacements in different files do not overlap.

2015-10-16 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Prevent clang-tidy from discarding fixes that are in different files but happen 
to have the same file offset.

http://reviews.llvm.org/D13810

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp

Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -469,34 +469,40 @@
   }
 
   // Build events from error intervals.
-  std::vector Events;
+  std::map> FileEvents;
   for (unsigned I = 0; I < Errors.size(); ++I) {
 for (const auto &Replace : Errors[I].Fix) {
   unsigned Begin = Replace.getOffset();
   unsigned End = Begin + Replace.getLength();
+  const std::string &FilePath = Replace.getFilePath();
   // FIXME: Handle empty intervals, such as those from insertions.
   if (Begin == End)
 continue;
-  Events.push_back(Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
-  Events.push_back(Event(Begin, End, Event::ET_End, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_End, I, Sizes[I]));
 }
   }
-  std::sort(Events.begin(), Events.end());
 
-  // Sweep.
   std::vector Apply(Errors.size(), true);
-  int OpenIntervals = 0;
-  for (const auto &Event : Events) {
-if (Event.Type == Event::ET_End)
-  --OpenIntervals;
-// This has to be checked after removing the interval from the count if it
-// is an end event, or before adding it if it is a begin event.
-if (OpenIntervals != 0)
-  Apply[Event.ErrorId] = false;
-if (Event.Type == Event::ET_Begin)
-  ++OpenIntervals;
+  for (auto &FileAndEvents : FileEvents) {
+std::vector &Events = FileAndEvents.second;
+// Sweep.
+std::sort(Events.begin(), Events.end());
+int OpenIntervals = 0;
+for (const auto &Event : Events) {
+  if (Event.Type == Event::ET_End)
+--OpenIntervals;
+  // This has to be checked after removing the interval from the count if 
it
+  // is an end event, or before adding it if it is a begin event.
+  if (OpenIntervals != 0)
+Apply[Event.ErrorId] = false;
+  if (Event.Type == Event::ET_Begin)
+++OpenIntervals;
+}
+assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
   }
-  assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
 
   for (unsigned I = 0; I < Errors.size(); ++I) {
 if (!Apply[I]) {


Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -469,34 +469,40 @@
   }
 
   // Build events from error intervals.
-  std::vector Events;
+  std::map> FileEvents;
   for (unsigned I = 0; I < Errors.size(); ++I) {
 for (const auto &Replace : Errors[I].Fix) {
   unsigned Begin = Replace.getOffset();
   unsigned End = Begin + Replace.getLength();
+  const std::string &FilePath = Replace.getFilePath();
   // FIXME: Handle empty intervals, such as those from insertions.
   if (Begin == End)
 continue;
-  Events.push_back(Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
-  Events.push_back(Event(Begin, End, Event::ET_End, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
+  FileEvents[FilePath].push_back(
+  Event(Begin, End, Event::ET_End, I, Sizes[I]));
 }
   }
-  std::sort(Events.begin(), Events.end());
 
-  // Sweep.
   std::vector Apply(Errors.size(), true);
-  int OpenIntervals = 0;
-  for (const auto &Event : Events) {
-if (Event.Type == Event::ET_End)
-  --OpenIntervals;
-// This has to be checked after removing the interval from the count if it
-// is an end event, or before adding it if it is a begin event.
-if (OpenIntervals != 0)
-  Apply[Event.ErrorId] = false;
-if (Event.Type == Event::ET_Begin)
-  ++OpenIntervals;
+  for (auto &FileAndEvents : FileEvents) {
+std::vector &Events = FileAndEvents.second;
+// Sweep.
+std::sort(Events.begin(), Events.end());
+int OpenIntervals = 0;
+for (const auto &Event : Events) {
+  if (Event.Type == Event::ET_End)
+--OpenIntervals;
+  // This has to be checked after removing the interval from the count if it
+  // is an end event, or before adding it if it is a begin event.
+  if (OpenIntervals != 0)
+Apply[Event.ErrorId] = false;
+  if (Event.Type == Event::ET_Begin)
+++OpenIntervals;
+}
+assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
   }
-  assert(OpenIntervals == 0 && "Amount of begin/end p

Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-16 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37569.
angelgarcia added a comment.

Remove unused include, fix typo and rename Count to OpenIntervals.


http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,18 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +321,87 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   std::string Res;
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest,
+ ApplyAtMostOneOfTheChangesWhenPartialOverlapping) {
+  std::string Res;
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // ~~ -> false
+  //   int a = potato;
+  //   ^^ -> tomato
+  //
+  // The 'StartsWithPotaCheck' fix has endpoints inside the 'IfFalseCheck' fix,
+  // so it is going to be set as

Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-16 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37568.
angelgarcia added a comment.

New algorithm :)


http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,18 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +321,87 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   std::string Res;
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest,
+ ApplyAtMostOneOfTheChangesWhenPartialOverlapping) {
+  std::string Res;
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // ~~ -> false
+  //   int a = potato;
+  //   ^^ -> tomato
+  //
+  // The 'StartsWithPotaCheck' fix has endpoints inside the 'IfFalseCheck' fix,
+  // so it is going to be set as inapplicable. The 'if' fix will be applied.
   co

Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-15 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

I implemented this, with the following addition: if several errors share
the same interval, I can still apply the biggest one that was not discarded
during the sweep. This way, the first example would work and in the two
other examples it would just apply a random one, as you suggested. But I
found a different case that also fails:
A: [a, b)[c,d)
B: [e, f) such that e < a, b < f < c.

In this case it just discards A. This is not incorrect (as long as we don't
apply both, everything is OK), but it gets away from the idea of "if two
fixes overlap, discard both", which is what Manuel said when I started
this. I don't think that changing that idea is a problem, but right now the
behavior of the tool is so diffuse that maintaining and testing it would be
a bit painful. Also, if we want to allow applying one of the fixes when
they overlap, we have a different problem, it might be better just to start
from scratch and think about how to solve that problem.


http://reviews.llvm.org/D13516



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


Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-15 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

I cannot find a way to make Daniel's idea work with equal intervals:

In this case, fix A can be applied because B is completely contained inside
it.
A: [a, b)[c, d)
B: [a, b)

This time, we should not apply anyone:
A: [a, b)
B: [a, b)

And here they both have to be discarded again, but for a different reason:
A:[a, b)[c, d)
B: [e, f)[a, b)

The problem is that we have three completely different situations that are
the same from the point of view of interval "[a, b)". The local situation
of individual intervals doesn't provide enough information.


http://reviews.llvm.org/D13516



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


Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-15 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37465.
angelgarcia added a comment.

I did several mutations and the only case were a test didn't break was when I 
removed the sort, but it turned out that we don't need it. I changed the tests 
to apply the checks in both orders to ensure that a test will break if the 
errors are not sorted.

I am still thinking about how to complete Daniel's idea.


http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,18 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +321,80 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   std::string Res;
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+  Res = runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest, DiscardBothChangesWhenPartialOverlapping) {
+std::string Res;
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
-  const char IfFix[] =
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other. Both of them 

Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

That works pretty well (well, identical end points have to be sorted
decreasingly, if I understand correctly). I see a couple of problems
though, like equal intervals, or consecutive. But the algorithm is way more
efficient than what we currently have, I will try to make it work.


http://reviews.llvm.org/D13516



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


Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

I've done a couple of runs for each version, and these are the results (I
have clang-tidy compiled with the option "RelWithDebInfo"):

$ time clang-tidy -checks=* test.cpp -- -std=c++11

Without looking for overlaps.

Suppressed 23463 warnings (23463 in non-user code).
Use -header-filter=.* to display errors from all non-system headers.

real2m14.572s
user2m13.136s
sys 0m0.483s

real2m15.103s
user2m13.361s
sys 0m0.687s

Bounding boxes

Suppressed 23463 warnings (23463 in non-user code).
Use -header-filter=.* to display errors from all non-system headers.

real2m14.208s
user2m13.051s
sys 0m0.643s

real2m16.368s
user2m14.286s
sys 0m0.986s

Quadratic

Suppressed 23463 warnings (23463 in non-user code).
Use -header-filter=.* to display errors from all non-system headers.

real2m15.130s
user2m13.627s
sys 0m0.499s

real2m15.322s
user2m13.660s
sys 0m0.683s

The time is about the same for all three versions. Note that the first
version doesn't do any sweep at all, and the last version invariably does
(23463 choose 2) = 275244453 sweeps. The amount of time required to do this
seems to be too low compared to the time that clang-tidy takes to output
these diagnostics.
Also, the fact that all three versions take about the same time is a bit
suspicious, but I double-checked that I was doing it right (I did a small
file with would cause overlapping and I checked if the message "note: this
fix will not be applied because it overlaps with another fix" was there
before each run).

I intended to implement Daniel's idea to check out which one was more
efficient, but with these results in sight I don't think it is worth it.


http://reviews.llvm.org/D13516



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


Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37344.
angelgarcia added a comment.

Use bounding boxes to reduce complexity.


http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,16 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +319,73 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
-  std::string Res;
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  std::string Res =
+  runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest, DiscardBothChangesWhenPartialOverlapping) {
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
-  const char IfFix[] =
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other. Both of them are discarded.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // ~~ -> false
+  //   int a = potato;
+  //   ^^ -> tomato
+  std::string Res = runCheckOnCode(Code);
+  EXPECT_EQ(Code, Res);
+}
+
+TEST(OverlappingReplacementsTest, TwoErrorsHavePerfectOverlapping) {
+  std::string Res;
+  const char Code[] =
   R"(void f() {
   int potato = 0;
   potato += potato * potato;
-  if (true) potato;
+  if (char

Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37336.
angelgarcia added a comment.

Done.


http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,16 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +319,73 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
-  std::string Res;
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  std::string Res =
+  runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest, DiscardBothChangesWhenPartialOverlapping) {
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
-  const char IfFix[] =
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other. Both of them are discarded.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // ~~ -> false
+  //   int a = potato;
+  //   ^^ -> tomato
+  std::string Res = runCheckOnCode(Code);
+  EXPECT_EQ(Code, Res);
+}
+
+TEST(OverlappingReplacementsTest, TwoErrorsHavePerfectOverlapping) {
+  std::string Res;
+  const char Code[] =
   R"(void f() {
   int potato = 0;
   potato += potato * potato;
-  if (true) potato;
+  if (char a = potato) potato;
 })";
-  Res =

Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37334.
angelgarcia added a comment.

Add an enum and rename "Sit" to "Coverage" to improve readability.


http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,16 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +319,73 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
-  std::string Res;
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  std::string Res =
+  runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest, DiscardBothChangesWhenPartialOverlapping) {
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
-  const char IfFix[] =
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other. Both of them are discarded.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // ~~ -> false
+  //   int a = potato;
+  //   ^^ -> tomato
+  std::string Res = runCheckOnCode(Code);
+  EXPECT_EQ(Code, Res);
+}
+
+TEST(OverlappingReplacementsTest, TwoErrorsHavePerfectOverlapping) {
+  std::string Res;
+  const char Code[] =
   R"(void f() {
   int potato = 0;
   potato += potato * potato;
-  if 

[PATCH] D13720: Use __SIZE_TYPE__ to fix buildbot failures.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added a subscriber: cfe-commits.

Use __SIZE_TYPE__ to fix buildbot failures.

http://reviews.llvm.org/D13720

Files:
  test/clang-tidy/modernize-make-unique.cpp

Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -48,7 +48,7 @@
 
 template using unique_ptr_ = std::unique_ptr;
 
-void *operator new(unsigned long Count, void *Ptr);
+void *operator new(__SIZE_TYPE__ Count, void *Ptr);
 
 int g(std::unique_ptr P);
 


Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -48,7 +48,7 @@
 
 template using unique_ptr_ = std::unique_ptr;
 
-void *operator new(unsigned long Count, void *Ptr);
+void *operator new(__SIZE_TYPE__ Count, void *Ptr);
 
 int g(std::unique_ptr P);
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13504: Prevent modernize-use-auto from emitting a warning when 'auto' was already being used.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

Ping


http://reviews.llvm.org/D13504



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


Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

> These need to be documented.


Done.

> I'd name this Queue instead (reading later I had no idea what this was).


Done.

> Why are you calling this "Sit"?


I didn't even know how to describe this variable without using examples,
and naming it is harder. More or less, it keeps track of the different
overlapping situations that have been spotted during the process, so "Sit"
stands for that. But I know it is a really poor name and I'd like to change
it, any ideas?

Why do we need to sort?

> 


It's a remnant of a different approach that I tried before. Removed.


http://reviews.llvm.org/D13516



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


Re: [PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37323.
angelgarcia added a comment.

Fix comments.


http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,16 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +319,73 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
-  std::string Res;
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  std::string Res =
+  runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest, DiscardBothChangesWhenPartialOverlapping) {
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
-  const char IfFix[] =
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other. Both of them are discarded.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // ~~ -> false
+  //   int a = potato;
+  //   ^^ -> tomato
+  std::string Res = runCheckOnCode(Code);
+  EXPECT_EQ(Code, Res);
+}
+
+TEST(OverlappingReplacementsTest, TwoErrorsHavePerfectOverlapping) {
+  std::string Res;
+  const char Code[] =
   R"(void f() {
   int potato = 0;
   potato += potato * potato;
-  if (true) potato;
+  if (char a = potato) potato;
 })";

Re: [PATCH] D13590: Support every kind of initialization.

2015-10-14 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 37322.
angelgarcia added a comment.

Remove \code and \endcode.


http://reviews.llvm.org/D13590

Files:
  clang-tidy/modernize/MakeUniqueCheck.cpp
  test/clang-tidy/modernize-make-unique.cpp

Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -34,21 +34,31 @@
   Derived(int, int);
 };
 
-struct Pair {
+struct APair {
   int a, b;
 };
 
+struct DPair {
+  DPair() : a(0), b(0) {}
+  DPair(int x, int y) : a(y), b(x) {}
+  int a, b;
+};
+
+struct Empty {};
+
 template using unique_ptr_ = std::unique_ptr;
 
+void *operator new(unsigned long Count, void *Ptr);
+
 int g(std::unique_ptr P);
 
 std::unique_ptr getPointer() {
   return std::unique_ptr(new Base);
   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_unique instead
   // CHECK-FIXES: return std::make_unique();
 }
 
-void f() {
+void basic() {
   std::unique_ptr P1 = std::unique_ptr(new int());
   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
   // CHECK-FIXES: std::unique_ptr P1 = std::make_unique();
@@ -78,24 +88,76 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
   // CHECK-FIXES: int T = g(std::make_unique());
 
-  // Arguments are correctly handled.
-  std::unique_ptr Pbase = std::unique_ptr(new Base(5, T));
-  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use std::make_unique instead
-  // CHECK-FIXES: std::unique_ptr Pbase = std::make_unique(5, T);
-
-  // Works with init lists.
-  std::unique_ptr Ppair = std::unique_ptr(new Pair{T, 1});
-  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use std::make_unique instead
-  // CHECK-FIXES: std::unique_ptr Ppair = std::make_unique({T, 1});
-
   // Only replace if the type in the template is the same than the type returned
   // by the new operator.
   auto Pderived = std::unique_ptr(new Derived());
 
   // The pointer is returned by the function, nothing to do.
   std::unique_ptr RetPtr = getPointer();
 
-  // Aliases.
+  // This emulates std::move.
+  std::unique_ptr Move = static_cast&&>(P1);
+
+  // Placemenet arguments should not be removed.
+  int *PInt = new int;
+  std::unique_ptr Placement = std::unique_ptr(new (PInt) int{3});
+}
+
+void initialization(int T, Base b) {
+  // Test different kinds of initialization of the pointee.
+
+  // Direct initialization with parenthesis.
+  std::unique_ptr PDir1 = std::unique_ptr(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir1 = std::make_unique(1, T);
+
+  // Direct initialization with braces.
+  std::unique_ptr PDir2 = std::unique_ptr(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir2 = std::make_unique(2, T);
+
+  // Aggregate initialization.
+  std::unique_ptr PAggr = std::unique_ptr(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PAggr = std::make_unique(APair{T, 1});
+
+
+  // Test different kinds of initialization of the pointee, when the unique_ptr
+  // is initialized with braces.
+
+  // Direct initialization with parenthesis.
+  std::unique_ptr PDir3 = std::unique_ptr{new DPair(3, T)};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir3 = std::make_unique(3, T);
+
+  // Direct initialization with braces.
+  std::unique_ptr PDir4 = std::unique_ptr{new DPair{4, T}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir4 = std::make_unique(4, T);
+
+  // Aggregate initialization.
+  std::unique_ptr PAggr2 = std::unique_ptr{new APair{T, 2}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PAggr2 = std::make_unique(APair{T, 2});
+
+
+  // Direct initialization with parenthesis, without arguments.
+  std::unique_ptr PDir5 = std::unique_ptr(new DPair());
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir5 = std::make_unique();
+
+  // Direct initialization with braces, without arguments.
+  std::unique_ptr PDir6 = std::unique_ptr(new DPair{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir6 = std::make_unique();
+
+  // Aggregate initialization without arguments.
+  std::unique_ptr PEmpty = std::unique_ptr(new Empty{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PEmpty = std::make_unique(Empty{});
+}
+
+void aliases() {
   typedef std::unique_ptr IntPtr;
   IntPtr Typedef = IntPtr(new int);
   // CHECK-MESSAGES: :[[@LINE-1]]

[PATCH] D13590: Support every kind of initialization.

2015-10-09 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

modernize-make-unique now correctly supports the different kinds of list 
initialization.

http://reviews.llvm.org/D13590

Files:
  clang-tidy/modernize/MakeUniqueCheck.cpp
  test/clang-tidy/modernize-make-unique.cpp

Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -34,21 +34,31 @@
   Derived(int, int);
 };
 
-struct Pair {
+struct APair {
   int a, b;
 };
 
+struct DPair {
+  DPair() : a(0), b(0) {}
+  DPair(int x, int y) : a(y), b(x) {}
+  int a, b;
+};
+
+struct Empty {};
+
 template using unique_ptr_ = std::unique_ptr;
 
+void *operator new(unsigned long Count, void *Ptr);
+
 int g(std::unique_ptr P);
 
 std::unique_ptr getPointer() {
   return std::unique_ptr(new Base);
   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_unique instead
   // CHECK-FIXES: return std::make_unique();
 }
 
-void f() {
+void basic() {
   std::unique_ptr P1 = std::unique_ptr(new int());
   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
   // CHECK-FIXES: std::unique_ptr P1 = std::make_unique();
@@ -78,24 +88,76 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
   // CHECK-FIXES: int T = g(std::make_unique());
 
-  // Arguments are correctly handled.
-  std::unique_ptr Pbase = std::unique_ptr(new Base(5, T));
-  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use std::make_unique instead
-  // CHECK-FIXES: std::unique_ptr Pbase = std::make_unique(5, T);
-
-  // Works with init lists.
-  std::unique_ptr Ppair = std::unique_ptr(new Pair{T, 1});
-  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use std::make_unique instead
-  // CHECK-FIXES: std::unique_ptr Ppair = std::make_unique({T, 1});
-
   // Only replace if the type in the template is the same than the type returned
   // by the new operator.
   auto Pderived = std::unique_ptr(new Derived());
 
   // The pointer is returned by the function, nothing to do.
   std::unique_ptr RetPtr = getPointer();
 
-  // Aliases.
+  // This emulates std::move.
+  std::unique_ptr Move = static_cast&&>(P1);
+
+  // Placemenet arguments should not be removed.
+  int *PInt = new int;
+  std::unique_ptr Placement = std::unique_ptr(new (PInt) int{3});
+}
+
+void initialization(int T, Base b) {
+  // Test different kinds of initialization of the pointee.
+
+  // Direct initialization with parenthesis.
+  std::unique_ptr PDir1 = std::unique_ptr(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir1 = std::make_unique(1, T);
+
+  // Direct initialization with braces.
+  std::unique_ptr PDir2 = std::unique_ptr(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir2 = std::make_unique(2, T);
+
+  // Aggregate initialization.
+  std::unique_ptr PAggr = std::unique_ptr(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PAggr = std::make_unique(APair{T, 1});
+
+
+  // Test different kinds of initialization of the pointee, when the unique_ptr
+  // is initialized with braces.
+
+  // Direct initialization with parenthesis.
+  std::unique_ptr PDir3 = std::unique_ptr{new DPair(3, T)};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir3 = std::make_unique(3, T);
+
+  // Direct initialization with braces.
+  std::unique_ptr PDir4 = std::unique_ptr{new DPair{4, T}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir4 = std::make_unique(4, T);
+
+  // Aggregate initialization.
+  std::unique_ptr PAggr2 = std::unique_ptr{new APair{T, 2}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PAggr2 = std::make_unique(APair{T, 2});
+
+
+  // Direct initialization with parenthesis, without arguments.
+  std::unique_ptr PDir5 = std::unique_ptr(new DPair());
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir5 = std::make_unique();
+
+  // Direct initialization with braces, without arguments.
+  std::unique_ptr PDir6 = std::unique_ptr(new DPair{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PDir6 = std::make_unique();
+
+  // Aggregate initialization without arguments.
+  std::unique_ptr PEmpty = std::unique_ptr(new Empty{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr PEmpty = std::make_unique(Empty{});
+}
+
+void aliases()

[PATCH] D13516: Fix overlapping replacements in clang-tidy.

2015-10-07 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added reviewers: klimek, bkramer.
angelgarcia added subscribers: alexfh, cfe-commits.

Prevent clang-tidy from applying fixes to errors that overlap with other 
errors' fixes, with one exception: if one fix is completely contained inside 
another one, then we can apply the big one.

http://reviews.llvm.org/D13516

Files:
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp

Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -77,11 +77,12 @@
 auto *VD = Result.Nodes.getNodeAs(BoundDecl);
 std::string NewName = newName(VD->getName());
 
-auto Diag = diag(VD->getLocation(), "refactor")
+auto Diag = diag(VD->getLocation(), "refactor %0 into %1")
+<< VD->getName() << NewName
 << FixItHint::CreateReplacement(
-CharSourceRange::getTokenRange(VD->getLocation(),
-   VD->getLocation()),
-NewName);
+   CharSourceRange::getTokenRange(VD->getLocation(),
+  VD->getLocation()),
+   NewName);
 
 class UsageVisitor : public RecursiveASTVisitor {
 public:
@@ -281,7 +282,7 @@
 
   // Apply the UseCharCheck together with the IfFalseCheck.
   //
-  // The 'If' fix is bigger, so that is the one that has to be applied.
+  // The 'If' fix contains the other, so that is the one that has to be applied.
   // } else if (int a = 0) {
   //^^^ -> char
   //~ -> false
@@ -294,16 +295,16 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(CharIfFix, Res);
+  EXPECT_EQ(CharIfFix, Res);
 
   // Apply the IfFalseCheck with the StartsWithPotaCheck.
   //
   // The 'If' replacement is bigger here.
   // if (char potato = 0) {
   //  ^^ -> tomato
   // ~~~ -> false
   //
-  // But the refactoring is bigger here:
+  // But the refactoring is the one that contains the other here:
   // char potato = 0;
   //  ^^ -> tomato
   // if (potato) potato;
@@ -318,60 +319,73 @@
   }
 })";
   Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_EQ(IfStartsFix, Res);
-
-  // Silence warnings.
-  (void)CharIfFix;
-  (void)IfStartsFix;
+  EXPECT_EQ(IfStartsFix, Res);
 }
 
-TEST(OverlappingReplacementsTest, ApplyFullErrorOrNothingWhenOverlapping) {
-  std::string Res;
+TEST(OverlappingReplacements, TwoReplacementsInsideOne) {
   const char Code[] =
   R"(void f() {
-  int potato = 0;
-  potato += potato * potato;
-  if (char this_name_make_this_if_really_long = potato) potato;
+  if (int potato = 0) {
+int a = 0;
+  }
 })";
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato',
-  // and EndsWithTatoCheck will try to use 'pomelo'. We have to apply
-  // either all conversions from one check, or all from the other.
-  const char StartsFix[] =
+  // The two smallest replacements should not be applied.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // *** -> char
+  // ~~ -> false
+  // But other errors from the same checks should not be affected.
+  //   int a = 0;
+  //   *** -> char
+  const char Fix[] =
   R"(void f() {
-  int tomato = 0;
-  tomato += tomato * tomato;
-  if (char this_name_make_this_if_really_long = tomato) tomato;
+  if (false) {
+char a = 0;
+  }
 })";
-  const char EndsFix[] =
+  std::string Res =
+  runCheckOnCode(Code);
+  EXPECT_EQ(Fix, Res);
+}
+
+TEST(OverlappingReplacementsTest, DiscardBothChangesWhenPartialOverlapping) {
+  const char Code[] =
   R"(void f() {
-  int pomelo = 0;
-  pomelo += pomelo * pomelo;
-  if (char this_name_make_this_if_really_long = pomelo) pomelo;
+  if (int potato = 0) {
+int a = potato;
+  }
 })";
-  // In case of overlapping, we will prioritize the biggest fix. However, these
-  // two fixes have the same size and position, so we don't know yet which one
-  // will have preference.
-  Res = runCheckOnCode(Code);
-  // FIXME: EXPECT_TRUE(Res == StartsFix || Res == EndsFix);
 
-  // StartsWithPotaCheck will try to refactor 'potato' into 'tomato', but
-  // replacing the 'if' condition is a bigger change than all the refactoring
-  // changes together (48 vs 36), so this is the one that is going to be
-  // applied.
-  const char IfFix[] =
+  // These two replacements overlap, but none of them is completely contained
+  // inside the other. Both of them are discarded.
+  // if (int potato = 0) {
+  // ^^ -> tomato
+  // ~~ -> false
+  //   int a = potato;
+  //   ^^ -> tomato
+  std::string Res = runCheckOnCode(Code);
+  EXPECT_EQ(Code, Res);
+}
+
+TEST(

Re: [PATCH] D13504: Prevent modernize-use-auto from emitting a warning when 'auto' was already being used.

2015-10-07 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36724.
angelgarcia added a comment.

Good point. Solved.


http://reviews.llvm.org/D13504

Files:
  clang-tidy/modernize/UseAutoCheck.cpp
  test/clang-tidy/modernize-use-auto-new.cpp

Index: test/clang-tidy/modernize-use-auto-new.cpp
===
--- test/clang-tidy/modernize-use-auto-new.cpp
+++ test/clang-tidy/modernize-use-auto-new.cpp
@@ -95,4 +95,9 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing 
with new
 // CHECK-FIXES: auto g = new int*, h = new int_p;
   }
+
+  // Don't warn when 'auto' is already being used.
+  auto aut = new MyType();
+  auto *paut = new MyType();
+  const auto *pcaut = new MyType();
 }
Index: clang-tidy/modernize/UseAutoCheck.cpp
===
--- clang-tidy/modernize/UseAutoCheck.cpp
+++ clang-tidy/modernize/UseAutoCheck.cpp
@@ -222,6 +222,9 @@
  has(varDecl()),
  unless(has(varDecl(anyOf(
  unless(hasInitializer(ignoringParenImpCasts(cxxNewExpr(,
+ // Skip declarations that are already using auto.
+ anyOf(hasType(autoType()),
+   hasType(pointerType(pointee(autoType(),
  // FIXME: TypeLoc information is not reliable where CV
  // qualifiers are concerned so these types can't be
  // handled for now.


Index: test/clang-tidy/modernize-use-auto-new.cpp
===
--- test/clang-tidy/modernize-use-auto-new.cpp
+++ test/clang-tidy/modernize-use-auto-new.cpp
@@ -95,4 +95,9 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
 // CHECK-FIXES: auto g = new int*, h = new int_p;
   }
+
+  // Don't warn when 'auto' is already being used.
+  auto aut = new MyType();
+  auto *paut = new MyType();
+  const auto *pcaut = new MyType();
 }
Index: clang-tidy/modernize/UseAutoCheck.cpp
===
--- clang-tidy/modernize/UseAutoCheck.cpp
+++ clang-tidy/modernize/UseAutoCheck.cpp
@@ -222,6 +222,9 @@
  has(varDecl()),
  unless(has(varDecl(anyOf(
  unless(hasInitializer(ignoringParenImpCasts(cxxNewExpr(,
+ // Skip declarations that are already using auto.
+ anyOf(hasType(autoType()),
+   hasType(pointerType(pointee(autoType(),
  // FIXME: TypeLoc information is not reliable where CV
  // qualifiers are concerned so these types can't be
  // handled for now.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D13504: Prevent modernize-use-auto from emitting a warning when 'auto' was already being used.

2015-10-07 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added reviewers: klimek, bkramer.
angelgarcia added subscribers: alexfh, cfe-commits.

This fixes https://llvm.org/bugs/show_bug.cgi?id=25082 .

http://reviews.llvm.org/D13504

Files:
  clang-tidy/modernize/UseAutoCheck.cpp
  test/clang-tidy/modernize-use-auto-new.cpp

Index: test/clang-tidy/modernize-use-auto-new.cpp
===
--- test/clang-tidy/modernize-use-auto-new.cpp
+++ test/clang-tidy/modernize-use-auto-new.cpp
@@ -95,4 +95,7 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing 
with new
 // CHECK-FIXES: auto g = new int*, h = new int_p;
   }
+
+  // Don't warn when 'auto' is already being used.
+  auto aut = new MyType();
 }
Index: clang-tidy/modernize/UseAutoCheck.cpp
===
--- clang-tidy/modernize/UseAutoCheck.cpp
+++ clang-tidy/modernize/UseAutoCheck.cpp
@@ -222,6 +222,8 @@
  has(varDecl()),
  unless(has(varDecl(anyOf(
  unless(hasInitializer(ignoringParenImpCasts(cxxNewExpr(,
+ // Skip declarations that are already using auto.
+ hasType(autoType()),
  // FIXME: TypeLoc information is not reliable where CV
  // qualifiers are concerned so these types can't be
  // handled for now.


Index: test/clang-tidy/modernize-use-auto-new.cpp
===
--- test/clang-tidy/modernize-use-auto-new.cpp
+++ test/clang-tidy/modernize-use-auto-new.cpp
@@ -95,4 +95,7 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
 // CHECK-FIXES: auto g = new int*, h = new int_p;
   }
+
+  // Don't warn when 'auto' is already being used.
+  auto aut = new MyType();
 }
Index: clang-tidy/modernize/UseAutoCheck.cpp
===
--- clang-tidy/modernize/UseAutoCheck.cpp
+++ clang-tidy/modernize/UseAutoCheck.cpp
@@ -222,6 +222,8 @@
  has(varDecl()),
  unless(has(varDecl(anyOf(
  unless(hasInitializer(ignoringParenImpCasts(cxxNewExpr(,
+ // Skip declarations that are already using auto.
+ hasType(autoType()),
  // FIXME: TypeLoc information is not reliable where CV
  // qualifiers are concerned so these types can't be
  // handled for now.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13469: Create interfaces and tests for the overlapping replacements fix in clang-tidy.

2015-10-06 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36620.
angelgarcia added a comment.

Explain why we have defined these mocks.


http://reviews.llvm.org/D13469

Files:
  unittests/clang-tidy/CMakeLists.txt
  unittests/clang-tidy/ClangTidyTest.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp
  unittests/clang-tidy/ReadabilityModuleTest.cpp

Index: unittests/clang-tidy/ReadabilityModuleTest.cpp
===
--- unittests/clang-tidy/ReadabilityModuleTest.cpp
+++ unittests/clang-tidy/ReadabilityModuleTest.cpp
@@ -237,7 +237,7 @@
 
 TEST(BracesAroundStatementsCheck, IfElseWithShortStatements) {
   ClangTidyOptions Options;
-  Options.CheckOptions["test-check.ShortStatementLines"] = "1";
+  Options.CheckOptions["test-check-0.ShortStatementLines"] = "1";
 
   EXPECT_EQ("int main() {\n"
 "  if (true) return 1;\n"
Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- /dev/null
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -0,0 +1,379 @@
+//=== OverlappingReplacementsTest.cpp - clang-tidy ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangTidyTest.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace tidy {
+namespace test {
+namespace {
+
+const char BoundDecl[] = "decl";
+const char BoundIf[] = "if";
+
+// We define a reduced set of very small checks that allow to test different
+// overlapping situations (no overlapping, replacements partially overlap, etc),
+// as well as different kinds of diagnostics (one check produces several errors,
+// several replacement ranges in an error, etc).
+class UseCharCheck : public ClangTidyCheck {
+public:
+  UseCharCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
+using namespace ast_matchers;
+Finder->addMatcher(varDecl(hasType(isInteger())).bind(BoundDecl), this);
+  }
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
+auto *VD = Result.Nodes.getNodeAs(BoundDecl);
+diag(VD->getLocStart(), "use char") << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(VD->getLocStart(), VD->getLocStart()),
+"char");
+  }
+};
+
+class IfFalseCheck : public ClangTidyCheck {
+public:
+  IfFalseCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
+using namespace ast_matchers;
+Finder->addMatcher(ifStmt().bind(BoundIf), this);
+  }
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
+auto *If = Result.Nodes.getNodeAs(BoundIf);
+auto *Cond = If->getCond();
+SourceRange Range = Cond->getSourceRange();
+if (auto *D = If->getConditionVariable()) {
+  Range = SourceRange(D->getLocStart(), D->getLocEnd());
+}
+diag(Range.getBegin(), "the cake is a lie") << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(Range), "false");
+  }
+};
+
+class RefactorCheck : public ClangTidyCheck {
+public:
+  RefactorCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context), NamePattern("::$") {}
+  RefactorCheck(StringRef CheckName, ClangTidyContext *Context,
+StringRef NamePattern)
+  : ClangTidyCheck(CheckName, Context), NamePattern(NamePattern) {}
+  virtual std::string newName(StringRef OldName) = 0;
+
+  void registerMatchers(ast_matchers::MatchFinder *Finder) final {
+using namespace ast_matchers;
+Finder->addMatcher(varDecl(matchesName(NamePattern)).bind(BoundDecl), this);
+  }
+
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) final {
+auto *VD = Result.Nodes.getNodeAs(BoundDecl);
+std::string NewName = newName(VD->getName());
+
+auto Diag = diag(VD->getLocation(), "refactor")
+<< FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(VD->getLocation(),
+   VD->getLocation()),
+NewName);
+
+class UsageVisitor : public RecursiveASTVisitor {
+public:
+  UsageVisitor(const ValueDecl *VD, StringRef NewName,
+   DiagnosticBuilder &Diag)
+  : VD(VD), NewName(NewName), Diag(Diag) {}
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+if (const ValueDecl *D = E->getDecl()) {
+  if (VD->getCanonicalDecl() == D->getCanonicalDecl()) {
+Diag << FixItHint::CreateReplacement(
+CharSourc

Re: [PATCH] D13469: Create interfaces and tests for the overlapping replacements fix in clang-tidy.

2015-10-06 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36615.
angelgarcia added a comment.

This test was intended to ensure that we don't have a bug in the mock checks. 
I've split it up into one test for each mock check, I hope it is more 
descriptive now.


http://reviews.llvm.org/D13469

Files:
  unittests/clang-tidy/CMakeLists.txt
  unittests/clang-tidy/ClangTidyTest.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp
  unittests/clang-tidy/ReadabilityModuleTest.cpp

Index: unittests/clang-tidy/ReadabilityModuleTest.cpp
===
--- unittests/clang-tidy/ReadabilityModuleTest.cpp
+++ unittests/clang-tidy/ReadabilityModuleTest.cpp
@@ -237,7 +237,7 @@
 
 TEST(BracesAroundStatementsCheck, IfElseWithShortStatements) {
   ClangTidyOptions Options;
-  Options.CheckOptions["test-check.ShortStatementLines"] = "1";
+  Options.CheckOptions["test-check-0.ShortStatementLines"] = "1";
 
   EXPECT_EQ("int main() {\n"
 "  if (true) return 1;\n"
Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- /dev/null
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -0,0 +1,375 @@
+//=== OverlappingReplacementsTest.cpp - clang-tidy ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangTidyTest.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace tidy {
+namespace test {
+namespace {
+
+const char BoundDecl[] = "decl";
+const char BoundIf[] = "if";
+
+class UseCharCheck : public ClangTidyCheck {
+public:
+  UseCharCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
+using namespace ast_matchers;
+Finder->addMatcher(varDecl(hasType(isInteger())).bind(BoundDecl), this);
+  }
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
+auto *VD = Result.Nodes.getNodeAs(BoundDecl);
+diag(VD->getLocStart(), "use char") << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(VD->getLocStart(), VD->getLocStart()),
+"char");
+  }
+};
+
+class IfFalseCheck : public ClangTidyCheck {
+public:
+  IfFalseCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
+using namespace ast_matchers;
+Finder->addMatcher(ifStmt().bind(BoundIf), this);
+  }
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
+auto *If = Result.Nodes.getNodeAs(BoundIf);
+auto *Cond = If->getCond();
+SourceRange Range = Cond->getSourceRange();
+if (auto *D = If->getConditionVariable()) {
+  Range = SourceRange(D->getLocStart(), D->getLocEnd());
+}
+diag(Range.getBegin(), "the cake is a lie") << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(Range), "false");
+  }
+};
+
+class RefactorCheck : public ClangTidyCheck {
+public:
+  RefactorCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context), NamePattern("::$") {}
+  RefactorCheck(StringRef CheckName, ClangTidyContext *Context,
+StringRef NamePattern)
+  : ClangTidyCheck(CheckName, Context), NamePattern(NamePattern) {}
+  virtual std::string newName(StringRef OldName) = 0;
+
+  void registerMatchers(ast_matchers::MatchFinder *Finder) final {
+using namespace ast_matchers;
+Finder->addMatcher(varDecl(matchesName(NamePattern)).bind(BoundDecl), this);
+  }
+
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) final {
+auto *VD = Result.Nodes.getNodeAs(BoundDecl);
+std::string NewName = newName(VD->getName());
+
+auto Diag = diag(VD->getLocation(), "refactor")
+<< FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(VD->getLocation(),
+   VD->getLocation()),
+NewName);
+
+class UsageVisitor : public RecursiveASTVisitor {
+public:
+  UsageVisitor(const ValueDecl *VD, StringRef NewName,
+   DiagnosticBuilder &Diag)
+  : VD(VD), NewName(NewName), Diag(Diag) {}
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+if (const ValueDecl *D = E->getDecl()) {
+  if (VD->getCanonicalDecl() == D->getCanonicalDecl()) {
+Diag << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(E->getSourceRange()), NewName);
+  }
+}
+return RecursiveASTVisitor::VisitDeclRefExpr(E);
+  }
+
+private:
+

[PATCH] D13469: Create interfaces and tests for the overlapping replacements fix in clang-tidy.

2015-10-06 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

No changes in clang-tidy yet.

http://reviews.llvm.org/D13469

Files:
  unittests/clang-tidy/CMakeLists.txt
  unittests/clang-tidy/ClangTidyTest.h
  unittests/clang-tidy/OverlappingReplacementsTest.cpp
  unittests/clang-tidy/ReadabilityModuleTest.cpp

Index: unittests/clang-tidy/ReadabilityModuleTest.cpp
===
--- unittests/clang-tidy/ReadabilityModuleTest.cpp
+++ unittests/clang-tidy/ReadabilityModuleTest.cpp
@@ -237,7 +237,7 @@
 
 TEST(BracesAroundStatementsCheck, IfElseWithShortStatements) {
   ClangTidyOptions Options;
-  Options.CheckOptions["test-check.ShortStatementLines"] = "1";
+  Options.CheckOptions["test-check-0.ShortStatementLines"] = "1";
 
   EXPECT_EQ("int main() {\n"
 "  if (true) return 1;\n"
Index: unittests/clang-tidy/OverlappingReplacementsTest.cpp
===
--- /dev/null
+++ unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -0,0 +1,344 @@
+//=== OverlappingReplacementsTest.cpp - clang-tidy ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangTidyTest.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace tidy {
+namespace test {
+namespace {
+
+const char BoundDecl[] = "decl";
+const char BoundIf[] = "if";
+
+class UseCharCheck : public ClangTidyCheck {
+public:
+  UseCharCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
+using namespace ast_matchers;
+Finder->addMatcher(varDecl(hasType(isInteger())).bind(BoundDecl), this);
+  }
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
+auto *VD = Result.Nodes.getNodeAs(BoundDecl);
+diag(VD->getLocStart(), "use char") << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(VD->getLocStart(), VD->getLocStart()),
+"char");
+  }
+};
+
+class IfFalseCheck : public ClangTidyCheck {
+public:
+  IfFalseCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
+using namespace ast_matchers;
+Finder->addMatcher(ifStmt().bind(BoundIf), this);
+  }
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
+auto *If = Result.Nodes.getNodeAs(BoundIf);
+auto *Cond = If->getCond();
+SourceRange Range = Cond->getSourceRange();
+if (auto *D = If->getConditionVariable()) {
+  Range = SourceRange(D->getLocStart(), D->getLocEnd());
+}
+diag(Range.getBegin(), "the cake is a lie") << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(Range), "false");
+  }
+};
+
+class RefactorCheck : public ClangTidyCheck {
+public:
+  RefactorCheck(StringRef CheckName, ClangTidyContext *Context)
+  : ClangTidyCheck(CheckName, Context), NamePattern("::$") {}
+  RefactorCheck(StringRef CheckName, ClangTidyContext *Context,
+StringRef NamePattern)
+  : ClangTidyCheck(CheckName, Context), NamePattern(NamePattern) {}
+  virtual std::string newName(StringRef OldName) = 0;
+
+  void registerMatchers(ast_matchers::MatchFinder *Finder) final {
+using namespace ast_matchers;
+Finder->addMatcher(varDecl(matchesName(NamePattern)).bind(BoundDecl), this);
+  }
+
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) final {
+auto *VD = Result.Nodes.getNodeAs(BoundDecl);
+std::string NewName = newName(VD->getName());
+
+auto Diag = diag(VD->getLocation(), "refactor")
+<< FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(VD->getLocation(),
+   VD->getLocation()),
+NewName);
+
+class UsageVisitor : public RecursiveASTVisitor {
+public:
+  UsageVisitor(const ValueDecl *VD, StringRef NewName,
+   DiagnosticBuilder &Diag)
+  : VD(VD), NewName(NewName), Diag(Diag) {}
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+if (const ValueDecl *D = E->getDecl()) {
+  if (VD->getCanonicalDecl() == D->getCanonicalDecl()) {
+Diag << FixItHint::CreateReplacement(
+CharSourceRange::getTokenRange(E->getSourceRange()), NewName);
+  }
+}
+return RecursiveASTVisitor::VisitDeclRefExpr(E);
+  }
+
+private:
+  const ValueDecl *VD;
+  StringRef NewName;
+  DiagnosticBuilder &Diag;
+};
+

[PATCH] D13433: Use better mocks in modernize-make-unique, and fix matcher.

2015-10-05 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Add the second template argument to the unique_ptr mock, and update the matcher 
so that it only matches against cases where the second argument is the default.

http://reviews.llvm.org/D13433

Files:
  clang-tidy/modernize/MakeUniqueCheck.cpp
  test/clang-tidy/modernize-make-unique.cpp

Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -2,7 +2,10 @@
 
 namespace std {
 
-template 
+template 
+class default_delete {};
+
+template >
 class unique_ptr {
 public:
   unique_ptr(type *ptr);
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -29,10 +29,18 @@
 cxxConstructExpr(
 
hasType(qualType(hasDeclaration(classTemplateSpecializationDecl(
 matchesName("::std::unique_ptr"),
-templateArgumentCountIs(1),
+templateArgumentCountIs(2),
+hasTemplateArgument(0, templateArgument(refersToType(
+   qualType().bind(PointerType,
 hasTemplateArgument(
-0, templateArgument(
-   
refersToType(qualType().bind(PointerType,
+1, templateArgument(refersToType(qualType(
+   hasDeclaration(classTemplateSpecializationDecl(
+   matchesName("::std::default_delete"),
+   templateArgumentCountIs(1),
+   hasTemplateArgument(
+   0, templateArgument(refersToType(
+  qualType(equalsBoundNode(
+  PointerType))),
 argumentCountIs(1),
 hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType(
   equalsBoundNode(PointerType)


Index: test/clang-tidy/modernize-make-unique.cpp
===
--- test/clang-tidy/modernize-make-unique.cpp
+++ test/clang-tidy/modernize-make-unique.cpp
@@ -2,7 +2,10 @@
 
 namespace std {
 
-template 
+template 
+class default_delete {};
+
+template >
 class unique_ptr {
 public:
   unique_ptr(type *ptr);
Index: clang-tidy/modernize/MakeUniqueCheck.cpp
===
--- clang-tidy/modernize/MakeUniqueCheck.cpp
+++ clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -29,10 +29,18 @@
 cxxConstructExpr(
 hasType(qualType(hasDeclaration(classTemplateSpecializationDecl(
 matchesName("::std::unique_ptr"),
-templateArgumentCountIs(1),
+templateArgumentCountIs(2),
+hasTemplateArgument(0, templateArgument(refersToType(
+   qualType().bind(PointerType,
 hasTemplateArgument(
-0, templateArgument(
-   refersToType(qualType().bind(PointerType,
+1, templateArgument(refersToType(qualType(
+   hasDeclaration(classTemplateSpecializationDecl(
+   matchesName("::std::default_delete"),
+   templateArgumentCountIs(1),
+   hasTemplateArgument(
+   0, templateArgument(refersToType(
+  qualType(equalsBoundNode(
+  PointerType))),
 argumentCountIs(1),
 hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType(
   equalsBoundNode(PointerType)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13431: Document a bug in loop-convert and fix one of its subcases.

2015-10-05 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL249300: Document a bug in loop-convert and fix one of its 
subcases. (authored by angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D13431?vs=36500&id=36501#toc

http://reviews.llvm.org/D13431

Files:
  clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp

Index: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -477,6 +477,7 @@
   std::string VarName;
   bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl;
   bool AliasVarIsRef = false;
+  bool CanCopy = true;
 
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
@@ -525,6 +526,16 @@
 // and parenthesis around a simple DeclRefExpr can always be
 // removed.
 Range = Paren->getSourceRange();
+  } else if (const auto *UOP = Parents[0].get()) {
+// If we are taking the address of the loop variable, then we must
+// not use a copy, as it would mean taking the address of the 
loop's
+// local index instead.
+// FIXME: This won't catch cases where the address is taken outside
+// of the loop's body (for instance, in a function that got the
+// loop's index as a const reference parameter), or where we take
+// the address of a member (like "&Arr[i].A.B.C").
+if (UOP->getOpcode() == UO_AddrOf)
+  CanCopy = false;
   }
 }
   } else {
@@ -548,8 +559,10 @@
   // If the new variable name is from the aliased variable, then the reference
   // type for the new variable should only be used if the aliased variable was
   // declared as a reference.
-  bool UseCopy = (VarNameFromAlias && !AliasVarIsRef) ||
- (Descriptor.DerefByConstRef && 
Descriptor.IsTriviallyCopyable);
+  bool UseCopy =
+  CanCopy &&
+  ((VarNameFromAlias && !AliasVarIsRef) ||
+   (Descriptor.DerefByConstRef && Descriptor.IsTriviallyCopyable));
 
   if (!UseCopy) {
 if (Descriptor.DerefByConstRef) {
Index: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -97,7 +97,7 @@
   // CHECK-FIXES-NEXT: Tea.g();
 }
 
-void constArray() {
+const int *constArray() {
   for (int I = 0; I < N; ++I) {
 printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
   }
@@ -112,6 +112,16 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (const auto & Elem : NonCopy)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
+
+  bool Something = false;
+  for (int I = 0; I < N; ++I) {
+if (Something)
+  return &ConstArr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : ConstArr)
+  // CHECK-FIXES-NEXT: if (Something)
+  // CHECK-FIXES-NEXT: return &Elem;
 }
 
 struct HasArr {


Index: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -477,6 +477,7 @@
   std::string VarName;
   bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl;
   bool AliasVarIsRef = false;
+  bool CanCopy = true;
 
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
@@ -525,6 +526,16 @@
 // and parenthesis around a simple DeclRefExpr can always be
 // removed.
 Range = Paren->getSourceRange();
+  } else if (const auto *UOP = Parents[0].get()) {
+// If we are taking the address of the loop variable, then we must
+// not use a copy, as it would mean taking the address of the loop's
+// local index instead.
+// FIXME: This won't catch cases where the address is taken outside
+// of the loop's body (for instance, in a function that got the
+// loop's index as a const reference parameter), or where we take
+// the address of a member (like "&Arr[i].A.B.C").
+if (UOP->getOpcode() == UO_AddrOf)
+  CanCopy = false;
   }
 }
   } else {
@@ -548,8 +559,10 @@
   // If the new variable name is from the aliased variable, then the reference
   // type for the new 

Re: [PATCH] D13431: Document a bug in loop-convert and fix one of its subcases.

2015-10-05 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36500.
angelgarcia added a comment.

Use "UOP".


http://reviews.llvm.org/D13431

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-basic.cpp

Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -97,7 +97,7 @@
   // CHECK-FIXES-NEXT: Tea.g();
 }
 
-void constArray() {
+const int *constArray() {
   for (int I = 0; I < N; ++I) {
 printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
   }
@@ -112,6 +112,16 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (const auto & Elem : NonCopy)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
+
+  bool Something = false;
+  for (int I = 0; I < N; ++I) {
+if (Something)
+  return &ConstArr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : ConstArr)
+  // CHECK-FIXES-NEXT: if (Something)
+  // CHECK-FIXES-NEXT: return &Elem;
 }
 
 struct HasArr {
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -477,6 +477,7 @@
   std::string VarName;
   bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl;
   bool AliasVarIsRef = false;
+  bool CanCopy = true;
 
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
@@ -525,6 +526,16 @@
 // and parenthesis around a simple DeclRefExpr can always be
 // removed.
 Range = Paren->getSourceRange();
+  } else if (const auto *UOP = Parents[0].get()) {
+// If we are taking the address of the loop variable, then we must
+// not use a copy, as it would mean taking the address of the 
loop's
+// local index instead.
+// FIXME: This won't catch cases where the address is taken outside
+// of the loop's body (for instance, in a function that got the
+// loop's index as a const reference parameter), or where we take
+// the address of a member (like "&Arr[i].A.B.C").
+if (UOP->getOpcode() == UO_AddrOf)
+  CanCopy = false;
   }
 }
   } else {
@@ -548,8 +559,10 @@
   // If the new variable name is from the aliased variable, then the reference
   // type for the new variable should only be used if the aliased variable was
   // declared as a reference.
-  bool UseCopy = (VarNameFromAlias && !AliasVarIsRef) ||
- (Descriptor.DerefByConstRef && 
Descriptor.IsTriviallyCopyable);
+  bool UseCopy =
+  CanCopy &&
+  ((VarNameFromAlias && !AliasVarIsRef) ||
+   (Descriptor.DerefByConstRef && Descriptor.IsTriviallyCopyable));
 
   if (!UseCopy) {
 if (Descriptor.DerefByConstRef) {


Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -97,7 +97,7 @@
   // CHECK-FIXES-NEXT: Tea.g();
 }
 
-void constArray() {
+const int *constArray() {
   for (int I = 0; I < N; ++I) {
 printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
   }
@@ -112,6 +112,16 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (const auto & Elem : NonCopy)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
+
+  bool Something = false;
+  for (int I = 0; I < N; ++I) {
+if (Something)
+  return &ConstArr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : ConstArr)
+  // CHECK-FIXES-NEXT: if (Something)
+  // CHECK-FIXES-NEXT: return &Elem;
 }
 
 struct HasArr {
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -477,6 +477,7 @@
   std::string VarName;
   bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl;
   bool AliasVarIsRef = false;
+  bool CanCopy = true;
 
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
@@ -525,6 +526,16 @@
 // and parenthesis around a simple DeclRefExpr can always be
 // removed.
 Range = Paren->getSourceRange();
+  } else if (const auto *UOP = Parents[0].get()) {
+// If we are taking the address of the loop variable, then we must
+// not use a copy, as it would mean taking the address of the loop's
+  

[PATCH] D13431: Document a bug in loop-convert and fix one of its subcases.

2015-10-05 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

Now that we prioritize copying trivial types over using const-references where 
possible, I found some cases where, after the transformation, the loop was 
using the address of the local copy instead of the original object.

http://reviews.llvm.org/D13431

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-basic.cpp

Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -97,7 +97,7 @@
   // CHECK-FIXES-NEXT: Tea.g();
 }
 
-void constArray() {
+const int *constArray() {
   for (int I = 0; I < N; ++I) {
 printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
   }
@@ -112,6 +112,16 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (const auto & Elem : NonCopy)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
+
+  bool Something = false;
+  for (int I = 0; I < N; ++I) {
+if (Something)
+  return &ConstArr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : ConstArr)
+  // CHECK-FIXES-NEXT: if (Something)
+  // CHECK-FIXES-NEXT: return &Elem;
 }
 
 struct HasArr {
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -477,6 +477,7 @@
   std::string VarName;
   bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl;
   bool AliasVarIsRef = false;
+  bool CanCopy = true;
 
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
@@ -525,6 +526,16 @@
 // and parenthesis around a simple DeclRefExpr can always be
 // removed.
 Range = Paren->getSourceRange();
+  } else if (const auto *Uop = Parents[0].get()) {
+// If we are taking the address of the loop variable, then we must
+// not use a copy, as it would mean taking the address of the 
loop's
+// local index instead.
+// FIXME: This won't catch cases where the address is taken outside
+// of the loop's body (for instance, in a function that got the
+// loop's index as a const reference parameter), or where we take
+// the address of a member (like "&Arr[i].A.B.C").
+if (Uop->getOpcode() == UO_AddrOf)
+  CanCopy = false;
   }
 }
   } else {
@@ -548,8 +559,10 @@
   // If the new variable name is from the aliased variable, then the reference
   // type for the new variable should only be used if the aliased variable was
   // declared as a reference.
-  bool UseCopy = (VarNameFromAlias && !AliasVarIsRef) ||
- (Descriptor.DerefByConstRef && 
Descriptor.IsTriviallyCopyable);
+  bool UseCopy =
+  CanCopy &&
+  ((VarNameFromAlias && !AliasVarIsRef) ||
+   (Descriptor.DerefByConstRef && Descriptor.IsTriviallyCopyable));
 
   if (!UseCopy) {
 if (Descriptor.DerefByConstRef) {


Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -97,7 +97,7 @@
   // CHECK-FIXES-NEXT: Tea.g();
 }
 
-void constArray() {
+const int *constArray() {
   for (int I = 0; I < N; ++I) {
 printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
   }
@@ -112,6 +112,16 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (const auto & Elem : NonCopy)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
+
+  bool Something = false;
+  for (int I = 0; I < N; ++I) {
+if (Something)
+  return &ConstArr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : ConstArr)
+  // CHECK-FIXES-NEXT: if (Something)
+  // CHECK-FIXES-NEXT: return &Elem;
 }
 
 struct HasArr {
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -477,6 +477,7 @@
   std::string VarName;
   bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl;
   bool AliasVarIsRef = false;
+  bool CanCopy = true;
 
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
@@ -525,6 +526,16 @@
 // and parenthesis around a simple DeclRefExpr can always be
 // removed.
 Ran

Re: [PATCH] D13246: Fix bug in modernize-use-nullptr.

2015-10-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36359.
angelgarcia added a comment.

Update this patch to the change in RecursiveASTVisitor.


http://reviews.llvm.org/D13246

Files:
  clang-tidy/modernize/UseNullptrCheck.cpp
  test/clang-tidy/modernize-use-nullptr.cpp

Index: test/clang-tidy/modernize-use-nullptr.cpp
===
--- test/clang-tidy/modernize-use-nullptr.cpp
+++ test/clang-tidy/modernize-use-nullptr.cpp
@@ -174,4 +174,13 @@
 #define CALL(X) X
   OPTIONAL_CODE(NOT_NULL);
   CALL(NOT_NULL);
+
+#define ENTRY(X) {X}
+  struct A {
+int *Ptr;
+  } a[2] = {ENTRY(0), {0}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+  // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr
+  // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
+#undef ENTRY
 }
Index: clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tidy/modernize/UseNullptrCheck.cpp
@@ -150,6 +150,16 @@
 return true;
   }
 
+  bool TraverseInitListExpr(InitListExpr *S) {
+// Only go through the semantic form of the InitListExpr, because
+// ImplicitCast might not appear in the syntactic form, and this results in
+// finding usages of the macro argument that don't have a ImplicitCast as 
an
+// ancestor (thus invalidating the replacement) when they actually have.
+return RecursiveASTVisitor::
+TraverseSynOrSemInitListExpr(
+S->isSemanticForm() ? S : S->getSemanticForm());
+  }
+
   bool foundInvalid() const { return InvalidFound; }
 
 private:
@@ -273,7 +283,7 @@
 // Visit children of this containing parent looking for the least-descended
 // nodes of the containing parent which are macro arg expansions that 
expand
 // from the given arg location.
-// Visitor needs: arg loc
+// Visitor needs: arg loc.
 MacroArgUsageVisitor ArgUsageVisitor(SM.getFileLoc(CastLoc), SM);
 if (const auto *D = ContainingAncestor.get())
   ArgUsageVisitor.TraverseDecl(const_cast(D));
@@ -345,8 +355,8 @@
   /// also handled.
   ///
   /// False means either:
-  /// - TestLoc is not from a macro expansion
-  /// - TestLoc is from a different macro expansion
+  /// - TestLoc is not from a macro expansion.
+  /// - TestLoc is from a different macro expansion.
   bool expandsFrom(SourceLocation TestLoc, SourceLocation TestMacroLoc) {
 if (TestLoc.isFileID()) {
   return false;
@@ -399,17 +409,24 @@
   ast_type_traits::DynTypedNode &Result) {
 // Below we're only following the first parent back up the AST. This should
 // be fine since for the statements we care about there should only be one
-// parent as far up as we care. If this assumption doesn't hold, need to
-// revisit what to do here.
+// parent, except for the case specified below.
 
 assert(MacroLoc.isFileID());
 
 while (true) {
   const auto &Parents = Context.getParents(Start);
   if (Parents.empty())
 return false;
-  assert(Parents.size() == 1 &&
- "Found an ancestor with more than one parent!");
+  if (Parents.size() > 1) {
+// If there are more than one parents, don't do the replacement unless
+// they are InitListsExpr (semantic and syntactic form). In this case 
we
+// can choose any one here, and the ASTVisitor will take care of
+// traversing the right one.
+for (const auto &Parent : Parents) {
+  if (!Parent.get())
+return false;
+}
+  }
 
   const ast_type_traits::DynTypedNode &Parent = Parents[0];
 


Index: test/clang-tidy/modernize-use-nullptr.cpp
===
--- test/clang-tidy/modernize-use-nullptr.cpp
+++ test/clang-tidy/modernize-use-nullptr.cpp
@@ -174,4 +174,13 @@
 #define CALL(X) X
   OPTIONAL_CODE(NOT_NULL);
   CALL(NOT_NULL);
+
+#define ENTRY(X) {X}
+  struct A {
+int *Ptr;
+  } a[2] = {ENTRY(0), {0}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
+  // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr
+  // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
+#undef ENTRY
 }
Index: clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tidy/modernize/UseNullptrCheck.cpp
@@ -150,6 +150,16 @@
 return true;
   }
 
+  bool TraverseInitListExpr(InitListExpr *S) {
+// Only go through the semantic form of the InitListExpr, because
+// ImplicitCast might not appear in the syntactic form, and this results in
+// finding usages of the macro argument that don't have a ImplicitCast as an
+// ancestor (thus invalidating the replacement) when they actually have.
+return RecursiveASTVisitor::
+TraverseSynOrSemInitListExpr(
+S->isSemanticForm() ? S : S-

Re: [PATCH] D13381: Handle trailing underscores on modernize-loop-convert variable namer.

2015-10-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36357.
angelgarcia added a comment.

Yes! Sorry.


http://reviews.llvm.org/D13381

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -7,6 +7,7 @@
 const int N = 10;
 int ARR[N];
 int NUMS[N];
+int NUMS_[N];
 
 void naming() {
   for (int I = 0; I < N; ++I) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", NUMS_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -7,6 +7,7 @@
 const int n = 10;
 int arr[n];
 int nums[n];
+int nums_[n];
 
 void naming() {
   for (int i = 0; i < n; ++i) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
+  for (int i = 0; i < n; ++i) {
+printf("%d\n", nums_[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & num : nums_)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
   int num = 0;
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i] + num);
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -819,6 +819,14 @@
   size_t Len = ContainerName.size();
   if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) {
 IteratorName = ContainerName.substr(0, Len - 1);
+// Ej: (auto thing : things)
+if (!declarationExists(IteratorName))
+  return IteratorName;
+  }
+
+  if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) {
+IteratorName = ContainerName.substr(0, Len - 2);
+// E.g.: (auto thing : things_)
 if (!declarationExists(IteratorName))
   return IteratorName;
   }
@@ -835,14 +843,17 @@
   case NS_UpperCase:
 Elem = "ELEM";
   }
+  // E.g.: (auto elem : container)
   if (!declarationExists(Elem))
 return Elem;
 
   IteratorName = AppendWithStyle(ContainerName, OldIndex->getName());
+  // E.g.: (auto container_i : container)
   if (!declarationExists(IteratorName))
 return IteratorName;
 
   IteratorName = AppendWithStyle(ContainerName, Elem);
+  // E.g.: (auto container_elem : container)
   if (!declarationExists(IteratorName))
 return IteratorName;
 


Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -7,6 +7,7 @@
 const int N = 10;
 int ARR[N];
 int NUMS[N];
+int NUMS_[N];
 
 void naming() {
   for (int I = 0; I < N; ++I) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", NUMS_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -7,6 +7,7 @@
 const int n = 10;
 int arr[n];
 int nums[n];
+int nums_[n];
 
 void naming() {
   for (int i = 0; i < n; ++i) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
+  for (int i = 0; i < n; ++i) {
+printf("%d\n", nums_[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & num : nums_)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
   int num = 0;
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i] + num);
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -819,

Re: [PATCH] D13381: Handle trailing underscores on modernize-loop-convert variable namer.

2015-10-02 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36358.
angelgarcia added a comment.

I forgot one.


http://reviews.llvm.org/D13381

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -7,6 +7,7 @@
 const int N = 10;
 int ARR[N];
 int NUMS[N];
+int NUMS_[N];
 
 void naming() {
   for (int I = 0; I < N; ++I) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", NUMS_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -7,6 +7,7 @@
 const int n = 10;
 int arr[n];
 int nums[n];
+int nums_[n];
 
 void naming() {
   for (int i = 0; i < n; ++i) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
+  for (int i = 0; i < n; ++i) {
+printf("%d\n", nums_[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & num : nums_)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
   int num = 0;
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i] + num);
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -819,6 +819,14 @@
   size_t Len = ContainerName.size();
   if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) {
 IteratorName = ContainerName.substr(0, Len - 1);
+// E.g.: (auto thing : things)
+if (!declarationExists(IteratorName))
+  return IteratorName;
+  }
+
+  if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) {
+IteratorName = ContainerName.substr(0, Len - 2);
+// E.g.: (auto thing : things_)
 if (!declarationExists(IteratorName))
   return IteratorName;
   }
@@ -835,14 +843,17 @@
   case NS_UpperCase:
 Elem = "ELEM";
   }
+  // E.g.: (auto elem : container)
   if (!declarationExists(Elem))
 return Elem;
 
   IteratorName = AppendWithStyle(ContainerName, OldIndex->getName());
+  // E.g.: (auto container_i : container)
   if (!declarationExists(IteratorName))
 return IteratorName;
 
   IteratorName = AppendWithStyle(ContainerName, Elem);
+  // E.g.: (auto container_elem : container)
   if (!declarationExists(IteratorName))
 return IteratorName;
 


Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -7,6 +7,7 @@
 const int N = 10;
 int ARR[N];
 int NUMS[N];
+int NUMS_[N];
 
 void naming() {
   for (int I = 0; I < N; ++I) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", NUMS_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -7,6 +7,7 @@
 const int n = 10;
 int arr[n];
 int nums[n];
+int nums_[n];
 
 void naming() {
   for (int i = 0; i < n; ++i) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
+  for (int i = 0; i < n; ++i) {
+printf("%d\n", nums_[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & num : nums_)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
   int num = 0;
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i] + num);
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -

[PATCH] D13381: Handle trailing underscores on modernize-loop-convert variable namer.

2015-10-02 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

https://llvm.org/bugs/show_bug.cgi?id=24961.

http://reviews.llvm.org/D13381

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-lowercase.cpp
  test/clang-tidy/modernize-loop-convert-uppercase.cpp

Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -7,6 +7,7 @@
 const int N = 10;
 int ARR[N];
 int NUMS[N];
+int NUMS_[N];
 
 void naming() {
   for (int I = 0; I < N; ++I) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", NUMS_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -7,6 +7,7 @@
 const int n = 10;
 int arr[n];
 int nums[n];
+int nums_[n];
 
 void naming() {
   for (int i = 0; i < n; ++i) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
+  for (int i = 0; i < n; ++i) {
+printf("%d\n", nums_[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & num : nums_)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
   int num = 0;
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i] + num);
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -819,6 +819,14 @@
   size_t Len = ContainerName.size();
   if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) {
 IteratorName = ContainerName.substr(0, Len - 1);
+// Ej: (auto thing : things)
+if (!declarationExists(IteratorName))
+  return IteratorName;
+  }
+
+  if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) {
+IteratorName = ContainerName.substr(0, Len - 2);
+// Ej: (auto thing : things_)
 if (!declarationExists(IteratorName))
   return IteratorName;
   }
@@ -835,14 +843,17 @@
   case NS_UpperCase:
 Elem = "ELEM";
   }
+  // Ej: (auto elem : container)
   if (!declarationExists(Elem))
 return Elem;
 
   IteratorName = AppendWithStyle(ContainerName, OldIndex->getName());
+  // Ej: (auto container_i : container)
   if (!declarationExists(IteratorName))
 return IteratorName;
 
   IteratorName = AppendWithStyle(ContainerName, Elem);
+  // Ej: (auto container_elem : container)
   if (!declarationExists(IteratorName))
 return IteratorName;
 


Index: test/clang-tidy/modernize-loop-convert-uppercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-uppercase.cpp
+++ test/clang-tidy/modernize-loop-convert-uppercase.cpp
@@ -7,6 +7,7 @@
 const int N = 10;
 int ARR[N];
 int NUMS[N];
+int NUMS_[N];
 
 void naming() {
   for (int I = 0; I < N; ++I) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & NUM : NUMS)
   // CHECK-FIXES-NEXT: printf("%d\n", NUM);
 
+  for (int I = 0; I < N; ++I) {
+printf("%d\n", NUMS_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & NUM : NUMS_)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
   int NUM = 0;
   for (int I = 0; I < N; ++I) {
 printf("%d\n", NUMS[I] + NUM);
Index: test/clang-tidy/modernize-loop-convert-lowercase.cpp
===
--- test/clang-tidy/modernize-loop-convert-lowercase.cpp
+++ test/clang-tidy/modernize-loop-convert-lowercase.cpp
@@ -7,6 +7,7 @@
 const int n = 10;
 int arr[n];
 int nums[n];
+int nums_[n];
 
 void naming() {
   for (int i = 0; i < n; ++i) {
@@ -23,6 +24,13 @@
   // CHECK-FIXES: for (auto & num : nums)
   // CHECK-FIXES-NEXT: printf("%d\n", num);
 
+  for (int i = 0; i < n; ++i) {
+printf("%d\n", nums_[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & num : nums_)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
   int num = 0;
   for (int i = 0; i < n; ++i) {
 printf("%d\n", nums[i] + num);
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===
--- clang-tidy/modernize/Loop

[PATCH] D13346: Update clang-tidy documentation.

2015-10-01 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

Improve modernize-use-auto documentation 
(https://llvm.org/bugs/show_bug.cgi?id=24962).
Add documentation for modernize-make-unique.

http://reviews.llvm.org/D13346

Files:
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-make-unique.rst
  docs/clang-tidy/checks/modernize-use-auto.rst

Index: docs/clang-tidy/checks/modernize-use-auto.rst
===
--- docs/clang-tidy/checks/modernize-use-auto.rst
+++ docs/clang-tidy/checks/modernize-use-auto.rst
@@ -108,6 +108,39 @@
   list. Otherwise, use of ``auto`` would cause the type of the variable to be
   deduced as``std::initializer_list``.
 
+New expressions
+---
+
+Frequently, when a pointer is declared and initialized with ``new``, the
+pointee type has to be written twice: in the declaration type and in the
+``new`` expression. In this cases, the declaration type can be replaced with
+``auto`` improving readability and maintainability.
+
+.. code-block:: c++
+
+  TypeName *my_pointer = new TypeName(my_param);
+
+  // becomes
+
+  auto my_pointer = new TypeName(my_param);
+
+The check will also replace the declaration type in multiple declarations, if
+the following conditions are satisfied:
+
+* All declared variables have the same type (i.e. all of them are pointers to
+  the same type).
+* All declared variables are initialized with a ``new`` expression.
+* The types of all the new expressions are the same than the pointee of the
+  declaration type.
+
+.. code-block:: c++
+
+  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
+
+  // becomes
+
+  auto my_first_pointer = new TypeName, my_second_pointer = new TypeName;
+
 Known Limitations
 -
 * If the initializer is an explicit conversion constructor, the check will not
Index: docs/clang-tidy/checks/modernize-make-unique.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-make-unique.rst
@@ -0,0 +1,15 @@
+modernize-make-unique
+=
+
+This check finds the creation of ``std::unique_ptr`` objects by explicitly
+calling the constructor and a ``new`` expression, and replaces it with a call
+to ``std::make_unique``, introduced in C++14.
+
+.. code-block:: c++
+
+  auto my_ptr = std::unique_ptr(new MyPair(1, 2));
+
+  // becomes
+
+  auto my_ptr = std::make_unique(1, 2);
+
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -42,6 +42,7 @@
misc-unused-parameters
misc-unused-raii
modernize-loop-convert
+   modernize-make-unique
modernize-pass-by-value
modernize-replace-auto-ptr
modernize-shrink-to-fit


Index: docs/clang-tidy/checks/modernize-use-auto.rst
===
--- docs/clang-tidy/checks/modernize-use-auto.rst
+++ docs/clang-tidy/checks/modernize-use-auto.rst
@@ -108,6 +108,39 @@
   list. Otherwise, use of ``auto`` would cause the type of the variable to be
   deduced as``std::initializer_list``.
 
+New expressions
+---
+
+Frequently, when a pointer is declared and initialized with ``new``, the
+pointee type has to be written twice: in the declaration type and in the
+``new`` expression. In this cases, the declaration type can be replaced with
+``auto`` improving readability and maintainability.
+
+.. code-block:: c++
+
+  TypeName *my_pointer = new TypeName(my_param);
+
+  // becomes
+
+  auto my_pointer = new TypeName(my_param);
+
+The check will also replace the declaration type in multiple declarations, if
+the following conditions are satisfied:
+
+* All declared variables have the same type (i.e. all of them are pointers to
+  the same type).
+* All declared variables are initialized with a ``new`` expression.
+* The types of all the new expressions are the same than the pointee of the
+  declaration type.
+
+.. code-block:: c++
+
+  TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
+
+  // becomes
+
+  auto my_first_pointer = new TypeName, my_second_pointer = new TypeName;
+
 Known Limitations
 -
 * If the initializer is an explicit conversion constructor, the check will not
Index: docs/clang-tidy/checks/modernize-make-unique.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-make-unique.rst
@@ -0,0 +1,15 @@
+modernize-make-unique
+=
+
+This check finds the creation of ``std::unique_ptr`` objects by explicitly
+calling the constructor and a ``new`` expression, and replaces it with a call
+to ``std::make_unique``, introduced in C++14.
+
+.. code-block:: c++
+
+  auto my_ptr = std::unique_ptr(new MyPair(1, 2));

Re: [PATCH] D13342: Prevent loop-convert from leaving empty lines after removing an alias declaration.

2015-10-01 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36234.
angelgarcia added a comment.

Change a comment.


http://reviews.llvm.org/D13342

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/LoopConvertCheck.h
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -53,7 +53,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & T : Arr)
   // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: int Y = T.X;
 
   // The container was not only used to initialize a temporary loop variable for
@@ -89,7 +89,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & T : V)
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: int Y = T.X;
 
   // The same with a call to at()
@@ -100,7 +100,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & T : *Pv)
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: int Y = T.X;
 
   for (int I = 0; I < N; ++I) {
@@ -166,8 +166,17 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & Elem : IntArr)
   // CHECK-FIXES-NEXT: IntRef Int(Elem);
-}
 
+  // Ensure that removing the alias doesn't leave empty lines behind.
+  for (int I = 0; I < N; ++I) {
+auto &X = IntArr[I];
+X = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & X : IntArr) {
+  // CHECK-FIXES-NEXT: {{^X = 0;$}}
+  // CHECK-FIXES-NEXT: {{^  }$}}
+}
 
 void refs_and_vals() {
   // The following tests check that the transform correctly preserves the
@@ -186,7 +195,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto Alias : S_const)
   // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: Alias.X = 0;
 
   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
@@ -197,7 +206,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto Alias : Ss)
   // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: Alias.X = 0;
 
   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
@@ -208,7 +217,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & Alias : Ss)
   // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: Alias.X = 0;
 
   dependent Dep, Other;
@@ -863,7 +872,7 @@
   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto R5 : Arr)
   // CHECK-FIXES-NEXT: auto G5 = [&]()
-  // CHECK-FIXES: int J5 = 8 + R5;
+  // CHECK-FIXES-NEXT: int J5 = 8 + R5;
 
   // Alias by reference.
   for (int I = 0; I < N; ++I) {
@@ -875,7 +884,7 @@
   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & R6 : Arr)
   // CHECK-FIXES-NEXT: auto G6 = [&]()
-  // CHECK-FIXES: int J6 = -1 + R6;
+  // CHECK-FIXES-NEXT: int J6 = -1 + R6;
 }
 
 void iterators() {
@@ -953,7 +962,8 @@
 E Ee{ { { g( { Array[I] } ) } } };
   }
   // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: int A{ Elem };
+  // CHECK-FIXES: for (auto & Elem : Array)
+  // CHECK-FIXES-NEXT: int A{ Elem };
   // CHECK-FIXES-NEXT: int B{ g(Elem) };
   // CHECK-FIXES-NEXT: int C{ g( { Elem } ) };
   // CHECK-FIXES-NEXT: D Dd{ { g( { Elem } ) } };
Index: clang-tidy/modernize/LoopConvertCheck.h
===
--- clang-tidy/modernize/LoopConvertCheck.h
+++ clang-tidy/modernize/LoopConvertCheck.h
@@ -34,6 +34,8 @@
 std::string ContainerString;
   };
 
+  void getAliasRange(SourceManager &SM, SourceRange &DeclRange);
+
   void doConversion(ASTContext *Context, const VarDecl *IndexVar,
 const VarDecl *MaybeContainer, const UsageResult &Usages,
 const DeclStmt *AliasDecl, bool AliasUseRequired,
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -442,6 +442,30 @@
   Finder->addMatcher(makePseudoArrayLoopMatcher(), this);
 }
 
+/// \brief Given the range of a single declaration, such as:
+/// \code
+///   unsigned &ThisIsADeclarationThatCanSpanS

[PATCH] D13342: Prevent loop-convert from leaving empty lines after removing an alias declaration.

2015-10-01 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

This fixes https://llvm.org/bugs/show_bug.cgi?id=17716.

http://reviews.llvm.org/D13342

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tidy/modernize/LoopConvertCheck.h
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -53,7 +53,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & T : Arr)
   // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: int Y = T.X;
 
   // The container was not only used to initialize a temporary loop variable for
@@ -89,7 +89,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & T : V)
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: int Y = T.X;
 
   // The same with a call to at()
@@ -100,7 +100,7 @@
   }
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & T : *Pv)
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: int Y = T.X;
 
   for (int I = 0; I < N; ++I) {
@@ -166,8 +166,17 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & Elem : IntArr)
   // CHECK-FIXES-NEXT: IntRef Int(Elem);
-}
 
+  // Ensure that removing the alias doesn't leave empty lines behind.
+  for (int I = 0; I < N; ++I) {
+auto &X = IntArr[I];
+X = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & X : IntArr) {
+  // CHECK-FIXES-NEXT: {{^X = 0;$}}
+  // CHECK-FIXES-NEXT: {{^  }$}}
+}
 
 void refs_and_vals() {
   // The following tests check that the transform correctly preserves the
@@ -186,7 +195,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto Alias : S_const)
   // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: Alias.X = 0;
 
   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
@@ -197,7 +206,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto Alias : Ss)
   // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: Alias.X = 0;
 
   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
@@ -208,7 +217,7 @@
   // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & Alias : Ss)
   // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} =
-  // CHECK-FIXES: {}
+  // CHECK-FIXES-NEXT: {}
   // CHECK-FIXES-NEXT: Alias.X = 0;
 
   dependent Dep, Other;
@@ -863,7 +872,7 @@
   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto R5 : Arr)
   // CHECK-FIXES-NEXT: auto G5 = [&]()
-  // CHECK-FIXES: int J5 = 8 + R5;
+  // CHECK-FIXES-NEXT: int J5 = 8 + R5;
 
   // Alias by reference.
   for (int I = 0; I < N; ++I) {
@@ -875,7 +884,7 @@
   // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & R6 : Arr)
   // CHECK-FIXES-NEXT: auto G6 = [&]()
-  // CHECK-FIXES: int J6 = -1 + R6;
+  // CHECK-FIXES-NEXT: int J6 = -1 + R6;
 }
 
 void iterators() {
@@ -953,7 +962,8 @@
 E Ee{ { { g( { Array[I] } ) } } };
   }
   // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: int A{ Elem };
+  // CHECK-FIXES: for (auto & Elem : Array)
+  // CHECK-FIXES-NEXT: int A{ Elem };
   // CHECK-FIXES-NEXT: int B{ g(Elem) };
   // CHECK-FIXES-NEXT: int C{ g( { Elem } ) };
   // CHECK-FIXES-NEXT: D Dd{ { g( { Elem } ) } };
Index: clang-tidy/modernize/LoopConvertCheck.h
===
--- clang-tidy/modernize/LoopConvertCheck.h
+++ clang-tidy/modernize/LoopConvertCheck.h
@@ -34,6 +34,8 @@
 std::string ContainerString;
   };
 
+  void getAliasRange(SourceManager &SM, SourceRange &DeclRange);
+
   void doConversion(ASTContext *Context, const VarDecl *IndexVar,
 const VarDecl *MaybeContainer, const UsageResult &Usages,
 const DeclStmt *AliasDecl, bool AliasUseRequired,
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -442,6 +442,30 @@
   Finder->addMatcher(makePseudoArrayLoopMatcher(), this);
 }
 
+/// \brief Given the range of a sin

Re: [PATCH] D13292: Add support for 'cbegin()' and 'cend()' on modernize-loop-convert.

2015-10-01 Thread Angel Garcia via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL248994: Add support for 'cbegin()' and 'cend()' on 
modernize-loop-convert. (authored by angelgarcia).

Changed prior to commit:
  http://reviews.llvm.org/D13292?vs=36198&id=36200#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D13292

Files:
  clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
  
clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h
  clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp

Index: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -104,6 +104,14 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto Elem : ConstArr)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem, Elem + Elem);
+
+  const NonTriviallyCopyable NonCopy[N]{};
+  for (int I = 0; I < N; ++I) {
+printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : NonCopy)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
 }
 
 struct HasArr {
@@ -209,6 +217,13 @@
   // CHECK-FIXES: for (auto & P : *Ps)
   // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
 
+  for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto Elem : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);
+
   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
 printf("s has value %d\n", It->X);
   }
@@ -459,8 +474,8 @@
 const int N = 6;
 dependent V;
 dependent *Pv;
-const dependent Constv;
-const dependent *Pconstv;
+const dependent Constv;
+const dependent *Pconstv;
 
 transparent> Cv;
 
@@ -516,50 +531,51 @@
   // CHECK-FIXES-NEXT: Sum += Elem + 2;
 }
 
+// Ensure that 'const auto &' is used with containers of non-trivial types.
 void constness() {
   int Sum = 0;
   for (int I = 0, E = Constv.size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Constv[I]);
-Sum += Constv[I] + 2;
+printf("Fibonacci number is %d\n", Constv[I].X);
+Sum += Constv[I].X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : Constv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   for (int I = 0, E = Constv.size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Constv.at(I));
-Sum += Constv.at(I) + 2;
+printf("Fibonacci number is %d\n", Constv.at(I).X);
+Sum += Constv.at(I).X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : Constv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   for (int I = 0, E = Pconstv->size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Pconstv->at(I));
-Sum += Pconstv->at(I) + 2;
+printf("Fibonacci number is %d\n", Pconstv->at(I).X);
+Sum += Pconstv->at(I).X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : *Pconstv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : *Pconstv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   // This test will fail if size() isn't called repeatedly, since it
   // returns unsigned int, and 0 is deduced to be signed int.
   // FIXME: Insert the necessary explicit conversion, or write out the types
   // explicitly.
   for (int I = 0; I < Pconstv->size(); ++I) {
-printf("Fibonacci number is %d\n", (*Pconstv).at(I));
-Sum += (*Pconstv)[I] + 2;
+printf("Fibonacci number is %d\n", (*Pconstv).at(I).X);
+Sum += (*Pconstv)[I].X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : *Pconstv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const au

Re: [PATCH] D13292: Add support for 'cbegin()' and 'cend()' on modernize-loop-convert.

2015-10-01 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36198.
angelgarcia added a comment.

Yes, right now it is pretty hard to figure out what some of the tests are for, 
they are a bit messy. I plan to do something about it, but for now I added a 
comment on that test.


http://reviews.llvm.org/D13292

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/Inputs/modernize-loop-convert/structures.h
  test/clang-tidy/modernize-loop-convert-basic.cpp

Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -104,6 +104,14 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto Elem : ConstArr)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem, Elem + Elem);
+
+  const NonTriviallyCopyable NonCopy[N]{};
+  for (int I = 0; I < N; ++I) {
+printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : NonCopy)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
 }
 
 struct HasArr {
@@ -209,6 +217,13 @@
   // CHECK-FIXES: for (auto & P : *Ps)
   // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
 
+  for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto Elem : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);
+
   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
 printf("s has value %d\n", It->X);
   }
@@ -459,8 +474,8 @@
 const int N = 6;
 dependent V;
 dependent *Pv;
-const dependent Constv;
-const dependent *Pconstv;
+const dependent Constv;
+const dependent *Pconstv;
 
 transparent> Cv;
 
@@ -516,50 +531,51 @@
   // CHECK-FIXES-NEXT: Sum += Elem + 2;
 }
 
+// Ensure that 'const auto &' is used with containers of non-trivial types.
 void constness() {
   int Sum = 0;
   for (int I = 0, E = Constv.size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Constv[I]);
-Sum += Constv[I] + 2;
+printf("Fibonacci number is %d\n", Constv[I].X);
+Sum += Constv[I].X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : Constv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   for (int I = 0, E = Constv.size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Constv.at(I));
-Sum += Constv.at(I) + 2;
+printf("Fibonacci number is %d\n", Constv.at(I).X);
+Sum += Constv.at(I).X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : Constv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   for (int I = 0, E = Pconstv->size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Pconstv->at(I));
-Sum += Pconstv->at(I) + 2;
+printf("Fibonacci number is %d\n", Pconstv->at(I).X);
+Sum += Pconstv->at(I).X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : *Pconstv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : *Pconstv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   // This test will fail if size() isn't called repeatedly, since it
   // returns unsigned int, and 0 is deduced to be signed int.
   // FIXME: Insert the necessary explicit conversion, or write out the types
   // explicitly.
   for (int I = 0; I < Pconstv->size(); ++I) {
-printf("Fibonacci number is %d\n", (*Pconstv).at(I));
-Sum += (*Pconstv)[I] + 2;
+printf("Fibonacci number is %d\n", (*Pconstv).at(I).X);
+Sum += (*Pconstv)[I].X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : *Pconstv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : *Pconstv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 }
 
-void ConstRef(const dependent& ConstVRef) {
+v

[PATCH] D13292: Add support for 'cbegin()' and 'cend()' on modernize-loop-convert.

2015-09-30 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: cfe-commits, alexfh.

This fixes https://llvm.org/bugs/show_bug.cgi?id=22196 .

Also add a non-trivially copyable type to fix some tests that were meant to be 
about using const-refs, but were changed in r248438.

http://reviews.llvm.org/D13292

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/Inputs/modernize-loop-convert/structures.h
  test/clang-tidy/modernize-loop-convert-basic.cpp

Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -104,6 +104,14 @@
   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto Elem : ConstArr)
   // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem, Elem + Elem);
+
+  const NonTriviallyCopyable NonCopy[N]{};
+  for (int I = 0; I < N; ++I) {
+printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & Elem : NonCopy)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X);
 }
 
 struct HasArr {
@@ -209,6 +217,13 @@
   // CHECK-FIXES: for (auto & P : *Ps)
   // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
 
+  for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {
+printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto Elem : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);
+
   for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
 printf("s has value %d\n", It->X);
   }
@@ -459,8 +474,8 @@
 const int N = 6;
 dependent V;
 dependent *Pv;
-const dependent Constv;
-const dependent *Pconstv;
+const dependent Constv;
+const dependent *Pconstv;
 
 transparent> Cv;
 
@@ -519,47 +534,47 @@
 void constness() {
   int Sum = 0;
   for (int I = 0, E = Constv.size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Constv[I]);
-Sum += Constv[I] + 2;
+printf("Fibonacci number is %d\n", Constv[I].X);
+Sum += Constv[I].X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : Constv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   for (int I = 0, E = Constv.size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Constv.at(I));
-Sum += Constv.at(I) + 2;
+printf("Fibonacci number is %d\n", Constv.at(I).X);
+Sum += Constv.at(I).X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : Constv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   for (int I = 0, E = Pconstv->size(); I < E; ++I) {
-printf("Fibonacci number is %d\n", Pconstv->at(I));
-Sum += Pconstv->at(I) + 2;
+printf("Fibonacci number is %d\n", Pconstv->at(I).X);
+Sum += Pconstv->at(I).X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : *Pconstv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : *Pconstv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 
   // This test will fail if size() isn't called repeatedly, since it
   // returns unsigned int, and 0 is deduced to be signed int.
   // FIXME: Insert the necessary explicit conversion, or write out the types
   // explicitly.
   for (int I = 0; I < Pconstv->size(); ++I) {
-printf("Fibonacci number is %d\n", (*Pconstv).at(I));
-Sum += (*Pconstv)[I] + 2;
+printf("Fibonacci number is %d\n", (*Pconstv).at(I).X);
+Sum += (*Pconstv)[I].X + 2;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
-  // CHECK-FIXES: for (auto Elem : *Pconstv)
-  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);
-  // CHECK-FIXES-NEXT: Sum += Elem + 2;
+  // CHECK-FIXES: for (const auto & Elem : *Pconstv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem.X);
+  // CHECK-FIXES-NEXT: Sum += Elem.X + 2;
 }
 
-void ConstRef(const dependent& ConstVRef) {
+void constRef(const dependent& ConstVRef) {
   int sum = 0;
   // F

Re: [PATCH] D13249: Divide TraverseInitListExpr to a different function for each form.

2015-09-30 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36106.
angelgarcia added a comment.

Use only one function.

I find somewhat frustating that getSemanticForm() returns nullptr if the object 
is already in its semantic form (and the same for isSyntacticForm()). Something 
like QualType::getNonReferenceType(), that returns the object itself if it is 
already a non-reference type, would be more intuitive.


http://reviews.llvm.org/D13249

Files:
  include/clang/AST/RecursiveASTVisitor.h

Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -255,6 +255,12 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
+  /// \brief Recursively visit the syntactic or semantic form of an
+  /// initialization list.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseSynOrSemInitListExpr(InitListExpr *S);
+
   //  Methods on Attrs 
 
   // \brief Visit an attribute.
@@ -2056,31 +2062,33 @@
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
 
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
 template 
-bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
-  InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S;
-  if (Syn) {
-TRY_TO(WalkUpFromInitListExpr(Syn));
+bool RecursiveASTVisitor::TraverseSynOrSemInitListExpr(InitListExpr 
*S) {
+  if (S) {
+TRY_TO(WalkUpFromInitListExpr(S));
 // All we need are the default actions.  FIXME: use a helper function.
-for (Stmt *SubStmt : Syn->children()) {
-  TRY_TO(TraverseStmt(SubStmt));
-}
-  }
-  InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm();
-  if (Sem) {
-TRY_TO(WalkUpFromInitListExpr(Sem));
-for (Stmt *SubStmt : Sem->children()) {
+for (Stmt *SubStmt : S->children()) {
   TRY_TO(TraverseStmt(SubStmt));
 }
   }
   return true;
 }
 
+// This method is called once for each pair of syntactic and semantic
+// InitListExpr, and it traverses the subtrees defined by the two forms. This
+// may cause some of the children to be visited twice, if they appear both in
+// the syntactic and the semantic form.
+//
+// There is no guarantee about which form \p S takes when this method is 
called.
+template 
+bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
+  TRY_TO(TraverseSynOrSemInitListExpr(
+  S->isSemanticForm() ? S->getSyntacticForm() : S));
+  TRY_TO(TraverseSynOrSemInitListExpr(
+  S->isSemanticForm() ? S : S->getSemanticForm()));
+  return true;
+}
+
 // GenericSelectionExpr is a special case because the types and expressions
 // are interleaved.  We also need to watch out for null types (default
 // generic associations).


Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -255,6 +255,12 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
+  /// \brief Recursively visit the syntactic or semantic form of an
+  /// initialization list.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseSynOrSemInitListExpr(InitListExpr *S);
+
   //  Methods on Attrs 
 
   // \brief Visit an attribute.
@@ -2056,31 +2062,33 @@
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
 
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
 template 
-bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
-  InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S;
-  if (Syn) {
-TRY_TO(WalkUpFromInitListExpr(Syn));
+bool RecursiveASTVisitor::TraverseSynOrSemInitListExpr(InitListExpr *S) {
+  if (S) {
+TRY_TO(WalkUpFromInitListExpr(S));
 // All we need are the default actions.  FIXME: use a helper function.
-for (Stmt *SubStmt : Syn->children()) {
-  TRY_TO(TraverseStmt(SubStmt));
-}
-  }
-  InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm();
-  if (Sem) {
-TRY_TO(WalkUpFromInitListExpr(Sem));
-for (Stmt *SubStmt : Sem->children()) {
+for (Stmt *SubStmt : S->children()) {
   TRY_TO(TraverseStmt(SubStmt));
 }
   }
   re

Re: [PATCH] D13249: Divide TraverseInitListExpr to a different function for each form.

2015-09-30 Thread Angel Garcia via cfe-commits
angelgarcia updated this revision to Diff 36099.
angelgarcia added a comment.

Add some comments.


http://reviews.llvm.org/D13249

Files:
  include/clang/AST/RecursiveASTVisitor.h

Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -255,6 +255,13 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
+  /// \brief Recursively visit the syntactic and semantic forms of a
+  /// initialization list.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseSyntacticInitListExpr(InitListExpr *S);
+  bool TraverseSemanticInitListExpr(InitListExpr *S);
+
   //  Methods on Attrs 
 
   // \brief Visit an attribute.
@@ -2056,21 +2063,21 @@
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
 
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
 template 
-bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
+bool RecursiveASTVisitor::TraverseSyntacticInitListExpr(InitListExpr 
*S) {
   InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S;
   if (Syn) {
 TRY_TO(WalkUpFromInitListExpr(Syn));
 // All we need are the default actions.  FIXME: use a helper function.
 for (Stmt *SubStmt : Syn->children()) {
   TRY_TO(TraverseStmt(SubStmt));
 }
   }
+  return true;
+}
+
+template 
+bool RecursiveASTVisitor::TraverseSemanticInitListExpr(InitListExpr 
*S) {
   InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm();
   if (Sem) {
 TRY_TO(WalkUpFromInitListExpr(Sem));
@@ -2081,6 +2088,25 @@
   return true;
 }
 
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default.  We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+//
+// This method is called once for each pair of syntactic and semantic
+// InitListExpr, and it traverses the subtrees defined by the two forms. This
+// may cause some of the children to be visited twice, if they appear both in
+// the syntactic and the semantic form.
+//
+// There is no guarantee about which form \p S takes when this method is 
called.
+template 
+bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
+  TRY_TO(TraverseSyntacticInitListExpr(S));
+  TRY_TO(TraverseSemanticInitListExpr(S));
+  return true;
+}
+
 // GenericSelectionExpr is a special case because the types and expressions
 // are interleaved.  We also need to watch out for null types (default
 // generic associations).


Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -255,6 +255,13 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
+  /// \brief Recursively visit the syntactic and semantic forms of a
+  /// initialization list.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseSyntacticInitListExpr(InitListExpr *S);
+  bool TraverseSemanticInitListExpr(InitListExpr *S);
+
   //  Methods on Attrs 
 
   // \brief Visit an attribute.
@@ -2056,21 +2063,21 @@
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
 
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
 template 
-bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
+bool RecursiveASTVisitor::TraverseSyntacticInitListExpr(InitListExpr *S) {
   InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S;
   if (Syn) {
 TRY_TO(WalkUpFromInitListExpr(Syn));
 // All we need are the default actions.  FIXME: use a helper function.
 for (Stmt *SubStmt : Syn->children()) {
   TRY_TO(TraverseStmt(SubStmt));
 }
   }
+  return true;
+}
+
+template 
+bool RecursiveASTVisitor::TraverseSemanticInitListExpr(InitListExpr *S) {
   InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm();
   if (Sem) {
 TRY_TO(WalkUpFromInitListExpr(Sem));
@@ -2081,6 +2088,25 @@
   return true;
 }
 
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syn

Re: [PATCH] D13249: Divide TraverseInitListExpr to a different function for each form.

2015-09-29 Thread Angel Garcia via cfe-commits
angelgarcia added a comment.

Yes, it breaks a few tests:

FAIL: Clang :: Analysis/operator-calls.cpp (598 of 8596)

FAIL: Clang :: Analysis/misc-ps-region-store.cpp (599 of 8596)

FAIL: Clang :: Analysis/array-struct-region.c (602 of 8596)


http://reviews.llvm.org/D13249



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


[PATCH] D13249: Divide TraverseInitListExpr to a different function for each form.

2015-09-29 Thread Angel Garcia via cfe-commits
angelgarcia created this revision.
angelgarcia added a reviewer: klimek.
angelgarcia added subscribers: alexfh, cfe-commits.

create TraverseSyntacticInitListExpr and TraverseSemanticInitListExpr.

http://reviews.llvm.org/D13249

Files:
  include/clang/AST/RecursiveASTVisitor.h

Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -255,6 +255,13 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
+  /// \brief Recursively visit the syntactic and semantic forms of a
+  /// initialization list.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseSyntacticInitListExpr(InitListExpr *S);
+  bool TraverseSemanticInitListExpr(InitListExpr *S);
+
   //  Methods on Attrs 
 
   // \brief Visit an attribute.
@@ -2056,21 +2063,21 @@
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
 
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
 template 
-bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
+bool RecursiveASTVisitor::TraverseSyntacticInitListExpr(InitListExpr 
*S) {
   InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S;
   if (Syn) {
 TRY_TO(WalkUpFromInitListExpr(Syn));
 // All we need are the default actions.  FIXME: use a helper function.
 for (Stmt *SubStmt : Syn->children()) {
   TRY_TO(TraverseStmt(SubStmt));
 }
   }
+  return true;
+}
+
+template 
+bool RecursiveASTVisitor::TraverseSemanticInitListExpr(InitListExpr 
*S) {
   InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm();
   if (Sem) {
 TRY_TO(WalkUpFromInitListExpr(Sem));
@@ -2081,6 +2088,18 @@
   return true;
 }
 
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default.  We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template 
+bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
+  TRY_TO(TraverseSyntacticInitListExpr(S));
+  TRY_TO(TraverseSemanticInitListExpr(S));
+  return true;
+}
+
 // GenericSelectionExpr is a special case because the types and expressions
 // are interleaved.  We also need to watch out for null types (default
 // generic associations).


Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -255,6 +255,13 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
+  /// \brief Recursively visit the syntactic and semantic forms of a
+  /// initialization list.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseSyntacticInitListExpr(InitListExpr *S);
+  bool TraverseSemanticInitListExpr(InitListExpr *S);
+
   //  Methods on Attrs 
 
   // \brief Visit an attribute.
@@ -2056,21 +2063,21 @@
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
 
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
 template 
-bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) {
+bool RecursiveASTVisitor::TraverseSyntacticInitListExpr(InitListExpr *S) {
   InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S;
   if (Syn) {
 TRY_TO(WalkUpFromInitListExpr(Syn));
 // All we need are the default actions.  FIXME: use a helper function.
 for (Stmt *SubStmt : Syn->children()) {
   TRY_TO(TraverseStmt(SubStmt));
 }
   }
+  return true;
+}
+
+template 
+bool RecursiveASTVisitor::TraverseSemanticInitListExpr(InitListExpr *S) {
   InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm();
   if (Sem) {
 TRY_TO(WalkUpFromInitListExpr(Sem));
@@ -2081,6 +2088,18 @@
   return true;
 }
 
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default.  We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template 
+bool RecursiveASTVisitor::T

  1   2   >