Applied clang-format only to the changes concerning to this patch.

Hi revane,

http://llvm-reviews.chandlerc.com/D759

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D759?vs=1884&id=1891#toc

Files:
  cpp11-migrate/LoopConvert/LoopActions.cpp
  cpp11-migrate/LoopConvert/LoopActions.h
  cpp11-migrate/LoopConvert/LoopMatchers.cpp
  cpp11-migrate/LoopConvert/LoopMatchers.h
  cpp11-migrate/UseAuto/UseAutoActions.cpp
  test/cpp11-migrate/LoopConvert/Inputs/structures.h
  test/cpp11-migrate/LoopConvert/iterator.cpp
  test/cpp11-migrate/LoopConvert/naming-conflict.cpp
  test/cpp11-migrate/LoopConvert/nesting.cpp
  test/cpp11-migrate/LoopConvert/single-iterator.cpp
Index: cpp11-migrate/LoopConvert/LoopActions.cpp
===================================================================
--- cpp11-migrate/LoopConvert/LoopActions.cpp
+++ cpp11-migrate/LoopConvert/LoopActions.cpp
@@ -791,7 +791,8 @@
                              bool AliasFromForInit,
                              const ForStmt *TheLoop,
                              bool ContainerNeedsDereference,
-                             bool DerefByValue) {
+                             bool DerefByValue,
+                             bool DerefByConstRef) {
   std::string VarName;
   bool VarNameFromAlias = Usages.size() == 1 && AliasDecl;
   bool AliasVarIsRef = false;
@@ -849,8 +850,11 @@
     // to 'T&&'.
     if (DerefByValue)
       AutoRefType = Context->getRValueReferenceType(AutoRefType);
-    else
+    else {
+      if (DerefByConstRef)
+        AutoRefType = Context->getConstType(AutoRefType);
       AutoRefType = Context->getLValueReferenceType(AutoRefType);
+    }
   }
 
   std::string MaybeDereference = ContainerNeedsDereference ? "*" : "";
@@ -979,6 +983,7 @@
                                     const Expr *BoundExpr,
                                     bool ContainerNeedsDereference,
                                     bool DerefByValue,
+                                    bool DerefByConstRef,
                                     const ForStmt *TheLoop,
                                     Confidence ConfidenceLevel) {
   ForLoopIndexUseVisitor Finder(Context, LoopVar, EndVar, ContainerExpr,
@@ -1013,7 +1018,7 @@
   doConversion(Context, LoopVar, getReferencedVariable(ContainerExpr),
                ContainerString, Finder.getUsages(), Finder.getAliasDecl(),
                Finder.aliasUseRequired(), Finder.aliasFromForInit(), TheLoop,
-               ContainerNeedsDereference, DerefByValue);
+               ContainerNeedsDereference, DerefByValue, DerefByConstRef);
   ++*AcceptedChanges;
 }
 
@@ -1051,14 +1056,64 @@
     ConfidenceLevel.lowerTo(RL_Reasonable);
 
   const Expr *ContainerExpr = NULL;
+  bool DerefByValue = false;
+  bool DerefByConstRef = false;
   bool ContainerNeedsDereference = false;
   // FIXME: Try to put most of this logic inside a matcher. Currently, matchers
   // don't allow the right-recursive checks in digThroughConstructors.
-  if (FixerKind == LFK_Iterator)
+  if (FixerKind == LFK_Iterator) {
     ContainerExpr = findContainer(Context, LoopVar->getInit(),
                                   EndVar ? EndVar->getInit() : EndCall,
                                   &ContainerNeedsDereference);
-  else if (FixerKind == LFK_PseudoArray) {
+
+    QualType InitVarType = InitVar->getType();
+    QualType CanonicalInitVarType = InitVarType.getCanonicalType();
+
+    const CXXMemberCallExpr *BeginCall =
+        Nodes.getNodeAs<CXXMemberCallExpr>(BeginCallName);
+    assert(BeginCall != 0 && "Bad Callback. No begin call expression.");
+    QualType CanonicalBeginType =
+        BeginCall->getMethodDecl()->getResultType().getCanonicalType();
+
+    if (CanonicalBeginType->isPointerType() &&
+        CanonicalInitVarType->isPointerType()) {
+      QualType BeginPointeeType = CanonicalBeginType->getPointeeType();
+      QualType InitPointeeType = CanonicalInitVarType->getPointeeType();
+      // If the initializer and the variable are both pointers check if the
+      // un-qualified pointee types match otherwise we don't use auto.
+      if (!Context->hasSameUnqualifiedType(InitPointeeType, BeginPointeeType))
+        return;
+    } else {
+      // Check for qualified types to avoid conversions from non-const to const
+      // iterator types.
+      if (!Context->hasSameType(CanonicalInitVarType, CanonicalBeginType))
+        return;
+    }
+
+    DerefByValue = Nodes.getNodeAs<QualType>(DerefByValueResultName) != 0;
+    if (!DerefByValue) {
+      if (const QualType *DerefType =
+              Nodes.getNodeAs<QualType>(DerefByRefResultName)) {
+        // A node will only be bound with DerefByRefResultName if we're dealing
+        // with a user-defined iterator type. Test the const qualification of
+        // the reference type.
+        DerefByConstRef = (*DerefType)->getAs<ReferenceType>()->getPointeeType()
+            .isConstQualified();
+      } else {
+        // By nature of the matcher this case is triggered only for built-in
+        // iterator types (i.e. pointers). Test for const qualification of the
+        // pointed-at type.
+        QualType InitPointeeType = CanonicalInitVarType->getPointeeType();
+        assert(isa<PointerType>(CanonicalInitVarType) &&
+               "Non-class iterator type is not a pointer type");
+        DerefByConstRef = InitPointeeType.isConstQualified();
+      }
+    } else {
+      // If the de-referece operator return by value then test for the canonical
+      // const qualification of the init variable type.
+      DerefByConstRef = CanonicalInitVarType.isConstQualified();
+    }
+  } else if (FixerKind == LFK_PseudoArray) {
     if (!EndCall)
       return;
     ContainerExpr = EndCall->getImplicitObjectArgument();
@@ -1071,9 +1126,7 @@
   if (!ContainerExpr && !BoundExpr)
     return;
 
-  bool DerefByValue = Nodes.getNodeAs<QualType>(DerefByValueResultName) != 0;
-
   findAndVerifyUsages(Context, LoopVar, EndVar, ContainerExpr, BoundExpr,
-                      ContainerNeedsDereference, DerefByValue, TheLoop,
-                      ConfidenceLevel);
+                      ContainerNeedsDereference, DerefByValue, DerefByConstRef,
+                      TheLoop, ConfidenceLevel);
 }
Index: cpp11-migrate/LoopConvert/LoopActions.h
===================================================================
--- cpp11-migrate/LoopConvert/LoopActions.h
+++ cpp11-migrate/LoopConvert/LoopActions.h
@@ -77,7 +77,8 @@
                     bool AliasFromForInit,
                     const clang::ForStmt *TheLoop,
                     bool ContainerNeedsDereference,
-                    bool DerefByValue);
+                    bool DerefByValue,
+                    bool DerefByConstRef);
 
   /// \brief Given a loop header that would be convertible, discover all usages
   /// of the index variable and convert the loop if possible.
@@ -88,6 +89,7 @@
                            const clang::Expr *BoundExpr,
                            bool ContainerNeedsDereference,
                            bool DerefByValue,
+                           bool DerefByConstRef,
                            const clang::ForStmt *TheLoop,
                            Confidence ConfidenceLevel);
 
Index: cpp11-migrate/LoopConvert/LoopMatchers.cpp
===================================================================
--- cpp11-migrate/LoopConvert/LoopMatchers.cpp
+++ cpp11-migrate/LoopConvert/LoopMatchers.cpp
@@ -22,10 +22,12 @@
 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";
 
 // shared matchers
 static const TypeMatcher AnyType = anything();
@@ -109,10 +111,23 @@
 ///   - If the end iterator variable 'g' is defined, it is the same as 'f'
 StatementMatcher makeIteratorLoopMatcher() {
   StatementMatcher BeginCallMatcher =
-      memberCallExpr(argumentCountIs(0), callee(methodDecl(hasName("begin"))));
+      memberCallExpr(
+        argumentCountIs(0),
+        callee(
+          methodDecl(hasName("begin"))
+        )
+      ).bind(BeginCallName);
 
   DeclarationMatcher InitDeclMatcher =
-      varDecl(hasInitializer(anything())).bind(InitVarName);
+      varDecl(
+        hasInitializer(
+          anyOf(
+            ignoringParenImpCasts(BeginCallMatcher),
+            materializeTemporaryExpr(ignoringParenImpCasts(BeginCallMatcher)),
+            hasDescendant(BeginCallMatcher)
+          )
+        )
+      ).bind(InitVarName);
 
   DeclarationMatcher EndDeclMatcher =
       varDecl(hasInitializer(anything())).bind(EndVarName);
@@ -157,14 +172,19 @@
                 returns(
                   // Skip loops where the iterator's operator* returns an
                   // rvalue reference. This is just weird.
-                  qualType(unless(hasCanonicalType(rValueReferenceType())))
+                  qualType(
+                    unless(
+                      hasCanonicalType(rValueReferenceType())
+                    )
+                  ).bind(DerefByRefResultName)
                 )
               )
             )
           )
         )
       );
 
+
   return
     forStmt(
       hasLoopInit(anyOf(
Index: cpp11-migrate/LoopConvert/LoopMatchers.h
===================================================================
--- cpp11-migrate/LoopConvert/LoopMatchers.h
+++ cpp11-migrate/LoopConvert/LoopMatchers.h
@@ -27,10 +27,12 @@
 extern const char ConditionEndVarName[];
 extern const char IncrementVarName[];
 extern const char InitVarName[];
+extern const char BeginCallName[];
 extern const char EndExprName[];
 extern const char EndCallName[];
 extern const char EndVarName[];
 extern const char DerefByValueResultName[];
+extern const char DerefByRefResultName[];
 
 clang::ast_matchers::StatementMatcher makeArrayLoopMatcher();
 clang::ast_matchers::StatementMatcher makeIteratorLoopMatcher();
Index: cpp11-migrate/UseAuto/UseAutoActions.cpp
===================================================================
--- cpp11-migrate/UseAuto/UseAutoActions.cpp
+++ cpp11-migrate/UseAuto/UseAutoActions.cpp
@@ -77,7 +77,7 @@
   SourceManager &SM = *Result.SourceManager;
   if (!SM.isFromMainFile(D->getLocStart()))
     return;
-  
+
   const CXXNewExpr *NewExpr = Result.Nodes.getNodeAs<CXXNewExpr>(NewExprId);
   assert(NewExpr && "Bad Callback. No CXXNewExpr bound");
 
Index: test/cpp11-migrate/LoopConvert/Inputs/structures.h
===================================================================
--- test/cpp11-migrate/LoopConvert/Inputs/structures.h
+++ test/cpp11-migrate/LoopConvert/Inputs/structures.h
@@ -131,10 +131,13 @@
 template<typename IteratorType>
 struct Nested {
   typedef IteratorType* iterator;
+  typedef const IteratorType* const_iterator;
   IteratorType *operator->();
   IteratorType operator*();
   iterator begin();
   iterator end();
+  const_iterator begin() const;
+  const_iterator end() const;
 };
 
 // Like llvm::SmallPtrSet, the iterator has a dereference operator that returns
Index: test/cpp11-migrate/LoopConvert/iterator.cpp
===================================================================
--- test/cpp11-migrate/LoopConvert/iterator.cpp
+++ test/cpp11-migrate/LoopConvert/iterator.cpp
@@ -26,20 +26,20 @@
   for (S::const_iterator it = s.begin(), e = s.end(); it != e; ++it) {
     printf("s has value %d\n", (*it).x);
   }
-  // CHECK: for (auto & elem : s)
+  // CHECK: for (auto const & elem : s)
   // CHECK-NEXT: printf("s has value %d\n", (elem).x);
 
   S *ps;
   for (S::const_iterator it = ps->begin(), e = ps->end(); it != e; ++it) {
     printf("s has value %d\n", (*it).x);
   }
-  // CHECK: for (auto & p : *ps)
+  // CHECK: for (auto const & p : *ps)
   // CHECK-NEXT: printf("s has value %d\n", (p).x);
 
   for (S::const_iterator it = s.begin(), e = s.end(); it != e; ++it) {
     printf("s has value %d\n", it->x);
   }
-  // CHECK: for (auto & elem : s)
+  // CHECK: for (auto const & elem : s)
   // CHECK-NEXT: printf("s has value %d\n", elem.x);
 
   for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
@@ -84,15 +84,17 @@
        it != e; ++it) {
     printf("Fibonacci number is %d\n", *it);
   }
-  // CHECK: for (auto & elem : v)
-  // CHECK-NEXT: printf("Fibonacci number is %d\n", elem);
+  // CHECK: for (dependent<int>::const_iterator it = v.begin(), e = v.end();
+  // CHECK-NEXT: it != e; ++it) {
+  // CHECK-NEXT: printf("Fibonacci number is %d\n", *it);
 
   for (dependent<int>::const_iterator it(v.begin()), e = v.end();
        it != e; ++it) {
     printf("Fibonacci number is %d\n", *it);
   }
-  // CHECK: for (auto & elem : v)
-  // CHECK-NEXT: printf("Fibonacci number is %d\n", elem);
+  // CHECK: for (dependent<int>::const_iterator it(v.begin()), e = v.end();
+  // CHECK-NEXT: it != e; ++it) {
+  // CHECK-NEXT: printf("Fibonacci number is %d\n", *it);
 
   doublyDependent<int,int> intmap;
   for (doublyDependent<int,int>::iterator it = intmap.begin(), e = intmap.end();
@@ -174,14 +176,14 @@
 
   void doLoop() const {
     for (const_iterator I = begin(), E = end(); I != E; ++I) {
-      // CHECK: for (auto & elem : *this) {
+      // CHECK: for (auto const & elem : *this) {
     }
     for (const_iterator I = C::begin(), E = C::end(); I != E; ++I) {
-      // CHECK: for (auto & elem : *this) {
+      // CHECK: for (auto const & elem : *this) {
     }
     for (const_iterator I = begin(), E = end(); I != E; ++I) {
       // CHECK: for (const_iterator I = begin(), E = end(); I != E; ++I) {
-      // RISKY: for (auto & elem : *this) {
+      // RISKY: for (auto const & elem : *this) {
       doSomething();
     }
   }
@@ -201,4 +203,4 @@
       // CHECK: for (auto & elem : *this) {
     }
   }
-};
+};
\ No newline at end of file
Index: test/cpp11-migrate/LoopConvert/naming-conflict.cpp
===================================================================
--- test/cpp11-migrate/LoopConvert/naming-conflict.cpp
+++ test/cpp11-migrate/LoopConvert/naming-conflict.cpp
@@ -36,7 +36,7 @@
     printf("s has value %d\n", (*it).x);
     printf("Max of 3 and 5: %d\n", MAX(3,5));
   }
-  // CHECK: for (auto & MAXs_it : MAXs)
+  // CHECK: for (auto const & MAXs_it : MAXs)
   // CHECK-NEXT: printf("s has value %d\n", (MAXs_it).x);
   // CHECK-NEXT: printf("Max of 3 and 5: %d\n", MAX(3,5));
 
Index: test/cpp11-migrate/LoopConvert/nesting.cpp
===================================================================
--- test/cpp11-migrate/LoopConvert/nesting.cpp
+++ test/cpp11-migrate/LoopConvert/nesting.cpp
@@ -54,4 +54,16 @@
   // CHECK: for (auto & elem : NestT) {
   // CHECK-NEXT: for (T::iterator TI = (elem).begin(), TE = (elem).end(); TI != TE; ++TI) {
   // CHECK-NEXT: printf("%d", *TI);
+
+  Nested<S> NestS;
+  for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+    for (S::const_iterator SI = (*I).begin(), SE = (*I).end(); SI != SE; ++SI) {
+      printf("%d", *SI);
+    }
+  }
+  // The inner loop is also convertible, but doesn't need to be converted
+  // immediately. Update this test when that changes!
+  // CHECK: for (auto const & elem : NestS) {
+  // CHECK-NEXT: for (S::const_iterator SI = (elem).begin(), SE = (elem).end(); SI != SE; ++SI) {
+  // CHECK-NEXT: printf("%d", *SI);
 }
Index: test/cpp11-migrate/LoopConvert/single-iterator.cpp
===================================================================
--- test/cpp11-migrate/LoopConvert/single-iterator.cpp
+++ test/cpp11-migrate/LoopConvert/single-iterator.cpp
@@ -37,20 +37,20 @@
   for (S::const_iterator it = s.begin(); it != s.end(); ++it) {
     printf("s has value %d\n", (*it).x);
   }
-  // CHECK: for (auto & elem : s)
+  // CHECK: for (auto const & elem : s)
   // CHECK-NEXT: printf("s has value %d\n", (elem).x);
 
   S *ps;
   for (S::const_iterator it = ps->begin(); it != ps->end(); ++it) {
     printf("s has value %d\n", (*it).x);
   }
-  // CHECK: for (auto & p : *ps)
+  // CHECK: for (auto const & p : *ps)
   // CHECK-NEXT: printf("s has value %d\n", (p).x);
 
   for (S::const_iterator it = s.begin(); it != s.end(); ++it) {
     printf("s has value %d\n", it->x);
   }
-  // CHECK: for (auto & elem : s)
+  // CHECK: for (auto const & elem : s)
   // CHECK-NEXT: printf("s has value %d\n", elem.x);
 
   for (S::iterator it = s.begin(); it != s.end(); ++it) {
@@ -95,21 +95,23 @@
        it != v.end(); ++it) {
     printf("Fibonacci number is %d\n", *it);
   }
-  // CHECK: for (auto & elem : v)
-  // CHECK-NEXT: printf("Fibonacci number is %d\n", elem);
+  // CHECK: for (dependent<int>::const_iterator it = v.begin();
+  // CHECK-NEXT: it != v.end(); ++it) {
+  // CHECK-NEXT: printf("Fibonacci number is %d\n", *it);
 
   for (dependent<int>::const_iterator it(v.begin());
        it != v.end(); ++it) {
     printf("Fibonacci number is %d\n", *it);
   }
-  // CHECK: for (auto & elem : v)
-  // CHECK-NEXT: printf("Fibonacci number is %d\n", elem);
+  // CHECK: for (dependent<int>::const_iterator it(v.begin());
+  // CHECK-NEXT: it != v.end(); ++it) {
+  // CHECK-NEXT: printf("Fibonacci number is %d\n", *it);
 
   doublyDependent<int,int> intmap;
   for (doublyDependent<int,int>::iterator it = intmap.begin();
        it != intmap.end(); ++it) {
     printf("intmap[%d] = %d", it->first, it->second);
   }
   // CHECK: for (auto & elem : intmap)
   // CHECK-NEXT: printf("intmap[%d] = %d", elem.first, elem.second);
-}
+}
\ No newline at end of file
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to