Author: angelgarcia Date: Thu Oct 1 03:57:11 2015 New Revision: 248994 URL: http://llvm.org/viewvc/llvm-project?rev=248994&view=rev Log: Add support for 'cbegin()' and 'cend()' on modernize-loop-convert.
Summary: 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. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13292 Modified: 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 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=248994&r1=248993&r2=248994&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Thu Oct 1 03:57:11 2015 @@ -112,8 +112,9 @@ StatementMatcher makeArrayLoopMatcher() /// - If the end iterator variable 'g' is defined, it is the same as 'f'. StatementMatcher makeIteratorLoopMatcher() { StatementMatcher BeginCallMatcher = - cxxMemberCallExpr(argumentCountIs(0), - callee(cxxMethodDecl(hasName("begin")))) + cxxMemberCallExpr( + argumentCountIs(0), + callee(cxxMethodDecl(anyOf(hasName("begin"), hasName("cbegin"))))) .bind(BeginCallName); DeclarationMatcher InitDeclMatcher = @@ -127,7 +128,8 @@ StatementMatcher makeIteratorLoopMatcher varDecl(hasInitializer(anything())).bind(EndVarName); StatementMatcher EndCallMatcher = cxxMemberCallExpr( - argumentCountIs(0), callee(cxxMethodDecl(hasName("end")))); + argumentCountIs(0), + callee(cxxMethodDecl(anyOf(hasName("end"), hasName("cend"))))); StatementMatcher IteratorBoundMatcher = expr(anyOf(ignoringParenImpCasts( @@ -296,7 +298,8 @@ static const Expr *getContainerFromBegin return nullptr; StringRef Name = Member->getMemberDecl()->getName(); StringRef TargetName = IsBegin ? "begin" : "end"; - if (Name != TargetName) + StringRef ConstTargetName = IsBegin ? "cbegin" : "cend"; + if (Name != TargetName && Name != ConstTargetName) return nullptr; const Expr *SourceExpr = Member->getBase(); @@ -423,7 +426,7 @@ void LoopConvertCheck::storeOptions(Clan Options.store(Opts, "MinConfidence", Confs[static_cast<int>(MinConfidence)]); SmallVector<std::string, 4> Styles{"camelBack", "CamelCase", "lower_case", - "UPPER_CASE"}; + "UPPER_CASE"}; Options.store(Opts, "NamingStyle", Styles[static_cast<int>(NamingStyle)]); } Modified: clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h?rev=248994&r1=248993&r2=248994&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h (original) +++ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h Thu Oct 1 03:57:11 2015 @@ -16,11 +16,20 @@ struct MutableVal { int X; }; +struct NonTriviallyCopyable { + NonTriviallyCopyable() = default; + // Define this constructor to make this class non-trivially copyable. + NonTriviallyCopyable(const NonTriviallyCopyable& Ntc); + int X; +}; + struct S { typedef MutableVal *iterator; typedef const MutableVal *const_iterator; const_iterator begin() const; const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; iterator begin(); iterator end(); }; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp?rev=248994&r1=248993&r2=248994&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Thu Oct 1 03:57:11 2015 @@ -104,6 +104,14 @@ void constArray() { // 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 @@ void f() { // 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 @@ namespace PseudoArray { const int N = 6; dependent<int> V; dependent<int> *Pv; -const dependent<int> Constv; -const dependent<int> *Pconstv; +const dependent<NonTriviallyCopyable> Constv; +const dependent<NonTriviallyCopyable> *Pconstv; transparent<dependent<int>> Cv; @@ -516,50 +531,51 @@ void f() { // 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<int>& ConstVRef) { +void constRef(const dependent<int>& ConstVRef) { int sum = 0; // FIXME: This does not work with size_t (probably due to the implementation // of dependent); make dependent work exactly like a std container type. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits