Index: clang-tidy/modernize/LoopConvertCheck.h =================================================================== --- clang-tidy/modernize/LoopConvertCheck.h +++ clang-tidy/modernize/LoopConvertCheck.h @@ -37,7 +37,7 @@ void getAliasRange(SourceManager &SM, SourceRange &DeclRange); void doConversion(ASTContext *Context, const VarDecl *IndexVar, - const VarDecl *MaybeContainer, const UsageResult &Usages, + const ValueDecl *MaybeContainer, const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, const ForStmt *Loop, RangeDescriptor Descriptor); Index: clang-tidy/modernize/LoopConvertCheck.cpp =================================================================== --- clang-tidy/modernize/LoopConvertCheck.cpp +++ clang-tidy/modernize/LoopConvertCheck.cpp @@ -353,10 +353,12 @@ } /// \brief If the given expression is actually a DeclRefExpr, find and return -/// the underlying VarDecl; otherwise, return NULL. -static const VarDecl *getReferencedVariable(const Expr *E) { +/// 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)) + return dyn_cast(Mem->getMemberDecl()); return nullptr; } @@ -500,9 +502,10 @@ /// \brief Computes the changes needed to convert a given for loop, and /// applies them. void LoopConvertCheck::doConversion( - ASTContext *Context, const VarDecl *IndexVar, const VarDecl *MaybeContainer, - const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, - bool AliasFromForInit, const ForStmt *Loop, RangeDescriptor Descriptor) { + ASTContext *Context, const VarDecl *IndexVar, + const ValueDecl *MaybeContainer, const UsageResult &Usages, + const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, + const ForStmt *Loop, RangeDescriptor Descriptor) { auto Diag = diag(Loop->getForLoc(), "use range-based for loop instead"); std::string VarName; 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::Stmt *SourceStmt; const clang::VarDecl *OldIndex; - const clang::VarDecl *TheContainer; + const clang::ValueDecl *TheContainer; const clang::ASTContext *Context; const NamingStyle Style; 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: 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-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-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 {