Index: clang/include/clang/AST/StmtObjC.h =================================================================== --- clang/include/clang/AST/StmtObjC.h +++ clang/include/clang/AST/StmtObjC.h @@ -268,6 +268,27 @@ const_child_range children() const { return const_child_range(const_cast(this)->children()); } + + using catch_stmt_iterator = CastIterator; + using const_catch_stmt_iterator = ConstCastIterator; + using catch_range = llvm::iterator_range; + using catch_const_range = llvm::iterator_range; + + catch_stmt_iterator catch_stmts_begin() { return getStmts() + 1; } + catch_stmt_iterator catch_stmts_end() { + return getStmts() + 1 + NumCatchStmts; + } + catch_range catch_stmts() { + return catch_range(catch_stmts_begin(), catch_stmts_end()); + } + + const_catch_stmt_iterator catch_stmts_begin() const { return getStmts() + 1; } + const_catch_stmt_iterator catch_stmts_end() const { + return getStmts() + 1 + NumCatchStmts; + } + catch_const_range catch_stmts() const { + return catch_const_range(catch_stmts_begin(), catch_stmts_end()); + } }; /// Represents Objective-C's \@synchronized statement. Index: clang/lib/AST/StmtPrinter.cpp =================================================================== --- clang/lib/AST/StmtPrinter.cpp +++ clang/lib/AST/StmtPrinter.cpp @@ -521,13 +521,10 @@ OS << NL; } - for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) { - ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I); + for (ObjCAtCatchStmt *catchStmt : Node->catch_stmts()) { Indent() << "@catch("; - if (catchStmt->getCatchParamDecl()) { - if (Decl *DS = catchStmt->getCatchParamDecl()) - PrintRawDecl(DS); - } + if (Decl *DS = catchStmt->getCatchParamDecl()) + PrintRawDecl(DS); OS << ")"; if (auto *CS = dyn_cast(catchStmt->getCatchBody())) { PrintRawCompoundStmt(CS); Index: clang/lib/Analysis/CFG.cpp =================================================================== --- clang/lib/Analysis/CFG.cpp +++ clang/lib/Analysis/CFG.cpp @@ -3935,10 +3935,9 @@ NewTryTerminatedBlock->setTerminator(Terminator); bool HasCatchAll = false; - for (unsigned I = 0, E = Terminator->getNumCatchStmts(); I != E; ++I) { + for (ObjCAtCatchStmt *CS : Terminator->catch_stmts()) { // The code after the try is the implicit successor. Succ = TrySuccessor; - ObjCAtCatchStmt *CS = Terminator->getCatchStmt(I); if (CS->hasEllipsis()) { HasCatchAll = true; } Index: clang/lib/CodeGen/CGObjCMac.cpp =================================================================== --- clang/lib/CodeGen/CGObjCMac.cpp +++ clang/lib/CodeGen/CGObjCMac.cpp @@ -4721,9 +4721,7 @@ // matched and avoid generating code for falling off the end if // so. bool AllMatched = false; - for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) { - const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I); - + for (const ObjCAtCatchStmt *CatchStmt : AtTryStmt->catch_stmts()) { const VarDecl *CatchParam = CatchStmt->getCatchParamDecl(); const ObjCObjectPointerType *OPT = nullptr; Index: clang/lib/CodeGen/CGObjCRuntime.cpp =================================================================== --- clang/lib/CodeGen/CGObjCRuntime.cpp +++ clang/lib/CodeGen/CGObjCRuntime.cpp @@ -163,8 +163,7 @@ // Enter the catch, if there is one. if (S.getNumCatchStmts()) { - for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) { - const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I); + for (const ObjCAtCatchStmt *CatchStmt : S.catch_stmts()) { const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl(); Handlers.push_back(CatchHandler()); Index: clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp =================================================================== --- clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -1957,15 +1957,15 @@ // @try -> try ReplaceText(startLoc, 1, ""); - for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { - ObjCAtCatchStmt *Catch = S->getCatchStmt(I); + for (ObjCAtCatchStmt *Catch : S->catch_stmts()) { VarDecl *catchDecl = Catch->getCatchParamDecl(); startLoc = Catch->getBeginLoc(); bool AtRemoved = false; if (catchDecl) { QualType t = catchDecl->getType(); - if (const ObjCObjectPointerType *Ptr = t->getAs()) { + if (const ObjCObjectPointerType *Ptr = + t->getAs()) { // Should be a pointer to a class. ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); if (IDecl) { Index: clang/lib/Sema/JumpDiagnostics.cpp =================================================================== --- clang/lib/Sema/JumpDiagnostics.cpp +++ clang/lib/Sema/JumpDiagnostics.cpp @@ -493,8 +493,7 @@ } // Jump from the catch to the finally or try is not valid. - for (unsigned I = 0, N = AT->getNumCatchStmts(); I != N; ++I) { - ObjCAtCatchStmt *AC = AT->getCatchStmt(I); + for (ObjCAtCatchStmt *AC : AT->catch_stmts()) { unsigned NewParentScope = Scopes.size(); Scopes.push_back(GotoScope(ParentScope, diag::note_protected_by_objc_catch, Index: clang/lib/Serialization/ASTWriterStmt.cpp =================================================================== --- clang/lib/Serialization/ASTWriterStmt.cpp +++ clang/lib/Serialization/ASTWriterStmt.cpp @@ -1482,8 +1482,8 @@ Record.push_back(S->getNumCatchStmts()); Record.push_back(S->getFinallyStmt() != nullptr); Record.AddStmt(S->getTryBody()); - for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) - Record.AddStmt(S->getCatchStmt(I)); + for (ObjCAtCatchStmt *C : S->catch_stmts()) + Record.AddStmt(C); if (S->getFinallyStmt()) Record.AddStmt(S->getFinallyStmt()); Record.AddSourceLocation(S->getAtTryLoc());