]> granicus.if.org Git - clang/commitdiff
[C++11] Replacing DeclBase iterators specific_attr_begin() and specific_attr_end...
authorAaron Ballman <aaron@aaronballman.com>
Mon, 10 Mar 2014 17:08:28 +0000 (17:08 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Mon, 10 Mar 2014 17:08:28 +0000 (17:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203474 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/clang/AST/DeclBase.h
lib/AST/Decl.cpp
lib/Analysis/ThreadSafety.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/SemaCodeComplete.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
lib/StaticAnalyzer/Checkers/MallocChecker.cpp

index 49e0de11f42d4595e02e817435bbb6cff68d744e..cf027387cb87010048ec6d4d6b1cbc3bc084c7fd 100644 (file)
@@ -471,6 +471,12 @@ public:
       HasAttrs = false;
   }
 
+  template <typename T>
+  llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
+    return llvm::iterator_range<specific_attr_iterator<T>>(
+        specific_attr_begin<T>(), specific_attr_end<T>());
+  }
+
   template <typename T>
   specific_attr_iterator<T> specific_attr_begin() const {
     return specific_attr_iterator<T>(attr_begin());
index eaaf92775143e77753e3806e104907311d268eef..89f7291c4d08c5bb9fcab4c8c15165a3e217303b 100644 (file)
@@ -207,11 +207,8 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
   // If we're on Mac OS X, an 'availability' for Mac OS X attribute
   // implies visibility(default).
   if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) {
-    for (specific_attr_iterator<AvailabilityAttr> 
-              A = D->specific_attr_begin<AvailabilityAttr>(),
-           AEnd = D->specific_attr_end<AvailabilityAttr>();
-         A != AEnd; ++A)
-      if ((*A)->getPlatform()->getName().equals("macosx"))
+    for (const auto *A : D->specific_attrs<AvailabilityAttr>())
+      if (A->getPlatform()->getName().equals("macosx"))
         return DefaultVisibility;
   }
 
index 6e9845db34b0c19fe708f4cdf053961ed2a94b67..cf8b289207c646d34e19931bfd2298f7e3462fd0 100644 (file)
@@ -1878,10 +1878,8 @@ void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK) {
     Analyzer->Handler.handleNoMutexHeld(D, POK_VarAccess, AK,
                                         Exp->getExprLoc());
 
-  for (specific_attr_iterator<GuardedByAttr>
-         I = D->specific_attr_begin<GuardedByAttr>(),
-         E = D->specific_attr_end<GuardedByAttr>(); I != E; ++I)
-    warnIfMutexNotHeld(D, Exp, AK, (*I)->getArg(), POK_VarAccess);
+  for (const auto *I : D->specific_attrs<GuardedByAttr>())
+    warnIfMutexNotHeld(D, Exp, AK, I->getArg(), POK_VarAccess);
 }
 
 /// \brief Checks pt_guarded_by and pt_guarded_var attributes.
@@ -1916,10 +1914,8 @@ void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK) {
     Analyzer->Handler.handleNoMutexHeld(D, POK_VarDereference, AK,
                                         Exp->getExprLoc());
 
-  for (specific_attr_iterator<PtGuardedByAttr>
-          I = D->specific_attr_begin<PtGuardedByAttr>(),
-          E = D->specific_attr_end<PtGuardedByAttr>(); I != E; ++I)
-    warnIfMutexNotHeld(D, Exp, AK, (*I)->getArg(), POK_VarDereference);
+  for (auto const *I : D->specific_attrs<PtGuardedByAttr>())
+    warnIfMutexNotHeld(D, Exp, AK, I->getArg(), POK_VarDereference);
 }
 
 
index 5028d5ddecaa4aa8bfc2c5b088538fde7a048f20..2d8389f020e595bfb7e96a04463f575075318d3e 100644 (file)
@@ -1569,12 +1569,10 @@ void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) {
   assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
   // FIXME We create a new bitcast for every annotation because that's what
   // llvm-gcc was doing.
-  for (specific_attr_iterator<AnnotateAttr>
-       ai = D->specific_attr_begin<AnnotateAttr>(),
-       ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai)
+  for (const auto *I : D->specific_attrs<AnnotateAttr>())
     EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation),
                        Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()),
-                       (*ai)->getAnnotation(), D->getLocation());
+                       I->getAnnotation(), D->getLocation());
 }
 
 llvm::Value *CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
@@ -1584,15 +1582,13 @@ llvm::Value *CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
   llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
                                     CGM.Int8PtrTy);
 
-  for (specific_attr_iterator<AnnotateAttr>
-       ai = D->specific_attr_begin<AnnotateAttr>(),
-       ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai) {
+  for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
     // FIXME Always emit the cast inst so we can differentiate between
     // annotation on the first field of a struct and annotation on the struct
     // itself.
     if (VTy != CGM.Int8PtrTy)
       V = Builder.Insert(new llvm::BitCastInst(V, CGM.Int8PtrTy));
-    V = EmitAnnotationCall(F, V, (*ai)->getAnnotation(), D->getLocation());
+    V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation());
     V = Builder.CreateBitCast(V, VTy);
   }
 
index c8dd8136fd272525137385a8279f42c7368f7c8b..4f040e2780988b2cb8014722fd035d4c2d521d0b 100644 (file)
@@ -1051,10 +1051,8 @@ void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D,
                                          llvm::GlobalValue *GV) {
   assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
   // Get the struct elements for these annotations.
-  for (specific_attr_iterator<AnnotateAttr>
-       ai = D->specific_attr_begin<AnnotateAttr>(),
-       ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai)
-    Annotations.push_back(EmitAnnotateAttr(GV, *ai, D->getLocation()));
+  for (const auto *I : D->specific_attrs<AnnotateAttr>())
+    Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation()));
 }
 
 bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
index de82ea8bd18b36f78baea1b3768acb9f1d54e613..512916e9a8ea8470ca8917f26db8f1d76ce0dfb8 100644 (file)
@@ -730,11 +730,7 @@ static void CheckNonNullArguments(Sema &S,
                                   const Expr * const *ExprArgs,
                                   SourceLocation CallSiteLoc) {
   // Check the attributes attached to the method/function itself.
-  for (specific_attr_iterator<NonNullAttr>
-       I = FDecl->specific_attr_begin<NonNullAttr>(),
-       E = FDecl->specific_attr_end<NonNullAttr>(); I != E; ++I) {
-
-    const NonNullAttr *NonNull = *I;
+  for (const auto *NonNull : FDecl->specific_attrs<NonNullAttr>()) {
     for (NonNullAttr::args_iterator i = NonNull->args_begin(),
          e = NonNull->args_end();
          i != e; ++i) {
@@ -771,14 +767,11 @@ void Sema::checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
   // Printf and scanf checking.
   llvm::SmallBitVector CheckedVarArgs;
   if (FDecl) {
-    for (specific_attr_iterator<FormatAttr>
-             I = FDecl->specific_attr_begin<FormatAttr>(),
-             E = FDecl->specific_attr_end<FormatAttr>();
-         I != E; ++I) {
+    for (const auto *I : FDecl->specific_attrs<FormatAttr>()) {
       // Only create vector if there are format attributes.
       CheckedVarArgs.resize(Args.size());
 
-      CheckFormatArguments(*I, Args, IsMemberFunction, CallType, Loc, Range,
+      CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
                            CheckedVarArgs);
     }
   }
@@ -799,12 +792,8 @@ void Sema::checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
     CheckNonNullArguments(*this, FDecl, Args.data(), Loc);
 
     // Type safety checking.
-    for (specific_attr_iterator<ArgumentWithTypeTagAttr>
-           i = FDecl->specific_attr_begin<ArgumentWithTypeTagAttr>(),
-           e = FDecl->specific_attr_end<ArgumentWithTypeTagAttr>();
-         i != e; ++i) {
-      CheckArgumentWithTypeTag(*i, Args.data());
-    }
+    for (const auto *I : FDecl->specific_attrs<ArgumentWithTypeTagAttr>())
+      CheckArgumentWithTypeTag(I, Args.data());
   }
 }
 
@@ -2141,10 +2130,7 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,
         if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(VD)) {
           if (const NamedDecl *ND = dyn_cast<NamedDecl>(PV->getDeclContext())) {
             int PVIndex = PV->getFunctionScopeIndex() + 1;
-            for (specific_attr_iterator<FormatAttr>
-                 i = ND->specific_attr_begin<FormatAttr>(),
-                 e = ND->specific_attr_end<FormatAttr>(); i != e ; ++i) {
-              FormatAttr *PVFormat = *i;
+            for (const auto *PVFormat : ND->specific_attrs<FormatAttr>()) {
               // adjust for implicit parameter
               if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
                 if (MD->isInstance())
index 6a0c4c4d04ad73b2e33fff9d7580abaa02e7a8b0..2724c646be15494cabc431d8584d505fea98968b 100644 (file)
@@ -2638,12 +2638,8 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
     return Result.TakeString();
   }
 
-  for (specific_attr_iterator<AnnotateAttr>
-           i = ND->specific_attr_begin<AnnotateAttr>(),
-           e = ND->specific_attr_end<AnnotateAttr>();
-       i != e; ++i)
-    Result.AddAnnotation(
-        Result.getAllocator().CopyString((*i)->getAnnotation()));
+  for (const auto *I : ND->specific_attrs<AnnotateAttr>())
+    Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation()));
 
   AddResultTypeChunk(Ctx, Policy, ND, Result);
   
index 820f908e351d61ca3dbc9a3beff3abb44a054096..8e796e6be93ffc29a1653696a3dbc22f1fb1a072 100644 (file)
@@ -1825,9 +1825,7 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
   AlignedAttr *OldAlignasAttr = 0;
   AlignedAttr *OldStrictestAlignAttr = 0;
   unsigned OldAlign = 0;
-  for (specific_attr_iterator<AlignedAttr>
-         I = Old->specific_attr_begin<AlignedAttr>(),
-         E = Old->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+  for (auto *I : Old->specific_attrs<AlignedAttr>()) {
     // FIXME: We have no way of representing inherited dependent alignments
     // in a case like:
     //   template<int A, int B> struct alignas(A) X;
@@ -1838,26 +1836,24 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
       return false;
 
     if (I->isAlignas())
-      OldAlignasAttr = *I;
+      OldAlignasAttr = I;
 
     unsigned Align = I->getAlignment(S.Context);
     if (Align > OldAlign) {
       OldAlign = Align;
-      OldStrictestAlignAttr = *I;
+      OldStrictestAlignAttr = I;
     }
   }
 
   // Look for alignas attributes on New.
   AlignedAttr *NewAlignasAttr = 0;
   unsigned NewAlign = 0;
-  for (specific_attr_iterator<AlignedAttr>
-         I = New->specific_attr_begin<AlignedAttr>(),
-         E = New->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+  for (auto *I : New->specific_attrs<AlignedAttr>()) {
     if (I->isAlignmentDependent())
       return false;
 
     if (I->isAlignas())
-      NewAlignasAttr = *I;
+      NewAlignasAttr = I;
 
     unsigned Align = I->getAlignment(S.Context);
     if (Align > NewAlign)
@@ -2103,15 +2099,12 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
   // we process them.
   if (!foundAny) New->setAttrs(AttrVec());
 
-  for (specific_attr_iterator<InheritableAttr>
-         i = Old->specific_attr_begin<InheritableAttr>(),
-         e = Old->specific_attr_end<InheritableAttr>(); 
-       i != e; ++i) {
+  for (auto *I : Old->specific_attrs<InheritableAttr>()) {
     bool Override = false;
     // Ignore deprecated/unavailable/availability attributes if requested.
-    if (isa<DeprecatedAttr>(*i) ||
-        isa<UnavailableAttr>(*i) ||
-        isa<AvailabilityAttr>(*i)) {
+    if (isa<DeprecatedAttr>(I) ||
+        isa<UnavailableAttr>(I) ||
+        isa<AvailabilityAttr>(I)) {
       switch (AMK) {
       case AMK_None:
         continue;
@@ -2126,10 +2119,10 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
     }
 
     // Already handled.
-    if (isa<UsedAttr>(*i))
+    if (isa<UsedAttr>(I))
       continue;
 
-    if (mergeDeclAttribute(*this, New, *i, Override))
+    if (mergeDeclAttribute(*this, New, I, Override))
       foundAny = true;
   }
 
@@ -2171,12 +2164,10 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
   // done before we process them.
   if (!foundAny) newDecl->setAttrs(AttrVec());
 
-  for (specific_attr_iterator<InheritableParamAttr>
-       i = oldDecl->specific_attr_begin<InheritableParamAttr>(),
-       e = oldDecl->specific_attr_end<InheritableParamAttr>(); i != e; ++i) {
-    if (!DeclHasAttr(newDecl, *i)) {
+  for (const auto *I : oldDecl->specific_attrs<InheritableParamAttr>()) {
+    if (!DeclHasAttr(newDecl, I)) {
       InheritableAttr *newAttr =
-        cast<InheritableParamAttr>((*i)->clone(S.Context));
+        cast<InheritableParamAttr>(I->clone(S.Context));
       newAttr->setInherited(true);
       newDecl->addAttr(newAttr);
       foundAny = true;
@@ -8942,10 +8933,7 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
       !VD->getType()->isIntegralOrEnumerationType())
     return;
 
-  for (specific_attr_iterator<TypeTagForDatatypeAttr>
-         I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(),
-         E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>();
-       I != E; ++I) {
+  for (const auto *I : ThisDecl->specific_attrs<TypeTagForDatatypeAttr>()) {
     const Expr *MagicValueExpr = VD->getInit();
     if (!MagicValueExpr) {
       continue;
index 7817ca9efc5424d2841e86f348dee3cf248ccf41..26fa4cddd317313dca21fea8a72d0dbdd0034a98 100644 (file)
@@ -1284,15 +1284,13 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
     }
 
     // Check we don't have a conflict with another ownership attribute.
-    for (specific_attr_iterator<OwnershipAttr>
-         i = D->specific_attr_begin<OwnershipAttr>(),
-         e = D->specific_attr_end<OwnershipAttr>(); i != e; ++i) {
+    for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
       // FIXME: A returns attribute should conflict with any returns attribute
       // with a different index too.
-      if ((*i)->getOwnKind() != K && (*i)->args_end() !=
-          std::find((*i)->args_begin(), (*i)->args_end(), Idx)) {
+      if (I->getOwnKind() != K && I->args_end() !=
+          std::find(I->args_begin(), I->args_end(), Idx)) {
         S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
-          << AL.getName() << *i;
+          << AL.getName() << I;
         return;
       }
     }
@@ -2445,18 +2443,14 @@ FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range,
                                   int FirstArg,
                                   unsigned AttrSpellingListIndex) {
   // Check whether we already have an equivalent format attribute.
-  for (specific_attr_iterator<FormatAttr>
-         i = D->specific_attr_begin<FormatAttr>(),
-         e = D->specific_attr_end<FormatAttr>();
-       i != e ; ++i) {
-    FormatAttr *f = *i;
-    if (f->getType() == Format &&
-        f->getFormatIdx() == FormatIdx &&
-        f->getFirstArg() == FirstArg) {
+  for (auto *F : D->specific_attrs<FormatAttr>()) {
+    if (F->getType() == Format &&
+        F->getFormatIdx() == FormatIdx &&
+        F->getFirstArg() == FirstArg) {
       // If we don't have a valid location for this attribute, adopt the
       // location.
-      if (f->getLocation().isInvalid())
-        f->setRange(Range);
+      if (F->getLocation().isInvalid())
+        F->setRange(Range);
       return NULL;
     }
   }
@@ -2667,10 +2661,8 @@ static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     return;
 
   // Don't duplicate annotations that are already set.
-  for (specific_attr_iterator<AnnotateAttr>
-       i = D->specific_attr_begin<AnnotateAttr>(),
-       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
-    if ((*i)->getAnnotation() == Str)
+  for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
+    if (I->getAnnotation() == Str)
       return;
   }
   
@@ -2819,13 +2811,11 @@ void Sema::CheckAlignasUnderalignment(Decl *D) {
   //   would otherwise be required for the entity being declared.
   AlignedAttr *AlignasAttr = 0;
   unsigned Align = 0;
-  for (specific_attr_iterator<AlignedAttr>
-         I = D->specific_attr_begin<AlignedAttr>(),
-         E = D->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+  for (auto *I : D->specific_attrs<AlignedAttr>()) {
     if (I->isAlignmentDependent())
       return;
     if (I->isAlignas())
-      AlignasAttr = *I;
+      AlignasAttr = I;
     Align = std::max(Align, I->getAlignment(Context));
   }
 
index 4c2047a8ff15ba0b444cafe50f92ef53e58215bf..f200dac1c68dea2d1583fe920d5eda7fedeb18fe 100644 (file)
@@ -161,14 +161,10 @@ void DirectIvarAssignment::checkASTDecl(const ObjCImplementationDecl *D,
 }
 
 static bool isAnnotatedToAllowDirectAssignment(const Decl *D) {
-  for (specific_attr_iterator<AnnotateAttr>
-       AI = D->specific_attr_begin<AnnotateAttr>(),
-       AE = D->specific_attr_end<AnnotateAttr>(); AI != AE; ++AI) {
-    const AnnotateAttr *Ann = *AI;
+  for (const auto *Ann : D->specific_attrs<AnnotateAttr>())
     if (Ann->getAnnotation() ==
         "objc_allow_direct_instance_variable_assignment")
       return true;
-  }
   return false;
 }
 
@@ -226,14 +222,9 @@ void ento::registerDirectIvarAssignment(CheckerManager &mgr) {
 // Register the checker that checks for direct accesses in functions annotated
 // with __attribute__((annotate("objc_no_direct_instance_variable_assignment"))).
 static bool AttrFilter(const ObjCMethodDecl *M) {
-  for (specific_attr_iterator<AnnotateAttr>
-           AI = M->specific_attr_begin<AnnotateAttr>(),
-           AE = M->specific_attr_end<AnnotateAttr>();
-       AI != AE; ++AI) {
-    const AnnotateAttr *Ann = *AI;
+  for (const auto *Ann : M->specific_attrs<AnnotateAttr>())
     if (Ann->getAnnotation() == "objc_no_direct_instance_variable_assignment")
       return false;
-  }
   return true;
 }
 
index a55f8112d05f5f8774bcab7dd479a2cb6e7ff36e..4154d34438a02795b6757979cda4f689b6e5faff 100644 (file)
@@ -613,11 +613,7 @@ static bool getPrintfFormatArgumentNum(const CallExpr *CE,
   const FunctionDecl *FDecl = C.getCalleeDecl(CE);
   if (!FDecl)
     return false;
-  for (specific_attr_iterator<FormatAttr>
-         i = FDecl->specific_attr_begin<FormatAttr>(),
-         e = FDecl->specific_attr_end<FormatAttr>(); i != e ; ++i) {
-
-    const FormatAttr *Format = *i;
+  for (const auto *Format : FDecl->specific_attrs<FormatAttr>()) {
     ArgNum = Format->getFormatIdx() - 1;
     if ((Format->getType()->getName() == "printf") &&
          CE->getNumArgs() > ArgNum)
index c95654cb218371c07e30a439608927803321ab10..3b794f23256bd3a7cf768b9724970dd7528007ab 100644 (file)
@@ -227,10 +227,7 @@ public:
 };
 
 static bool isInvalidationMethod(const ObjCMethodDecl *M, bool LookForPartial) {
-  for (specific_attr_iterator<AnnotateAttr>
-       AI = M->specific_attr_begin<AnnotateAttr>(),
-       AE = M->specific_attr_end<AnnotateAttr>(); AI != AE; ++AI) {
-    const AnnotateAttr *Ann = *AI;
+  for (const auto *Ann : M->specific_attrs<AnnotateAttr>()) {
     if (!LookForPartial &&
         Ann->getAnnotation() == "objc_instance_variable_invalidator")
       return true;
index 51d26d8a648135bc3401340d2a33579d71570572..ca40bebc99ce049532da505f6dbbc57b071b3f5f 100644 (file)
@@ -512,11 +512,8 @@ bool MallocChecker::isAllocationFunction(const FunctionDecl *FD,
   }
 
   if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs())
-    for (specific_attr_iterator<OwnershipAttr>
-           i = FD->specific_attr_begin<OwnershipAttr>(),
-           e = FD->specific_attr_end<OwnershipAttr>();
-           i != e; ++i)
-      if ((*i)->getOwnKind() == OwnershipAttr::Returns)
+    for (const auto *I : FD->specific_attrs<OwnershipAttr>())
+      if (I->getOwnKind() == OwnershipAttr::Returns)
         return true;
   return false;
 }
@@ -534,12 +531,9 @@ bool MallocChecker::isFreeFunction(const FunctionDecl *FD, ASTContext &C) const
   }
 
   if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs())
-    for (specific_attr_iterator<OwnershipAttr>
-           i = FD->specific_attr_begin<OwnershipAttr>(),
-           e = FD->specific_attr_end<OwnershipAttr>();
-           i != e; ++i)
-      if ((*i)->getOwnKind() == OwnershipAttr::Takes ||
-          (*i)->getOwnKind() == OwnershipAttr::Holds)
+    for (const auto *I : FD->specific_attrs<OwnershipAttr>())
+      if (I->getOwnKind() == OwnershipAttr::Takes ||
+          I->getOwnKind() == OwnershipAttr::Holds)
         return true;
   return false;
 }
@@ -633,17 +627,14 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
     // Check all the attributes, if there are any.
     // There can be multiple of these attributes.
     if (FD->hasAttrs())
-      for (specific_attr_iterator<OwnershipAttr>
-          i = FD->specific_attr_begin<OwnershipAttr>(),
-          e = FD->specific_attr_end<OwnershipAttr>();
-          i != e; ++i) {
-        switch ((*i)->getOwnKind()) {
+      for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
+        switch (I->getOwnKind()) {
         case OwnershipAttr::Returns:
-          State = MallocMemReturnsAttr(C, CE, *i);
+          State = MallocMemReturnsAttr(C, CE, I);
           break;
         case OwnershipAttr::Takes:
         case OwnershipAttr::Holds:
-          State = FreeMemAttr(C, CE, *i);
+          State = FreeMemAttr(C, CE, I);
           break;
         }
       }