diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 09cb96b..dbe5e09 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -34,7 +34,7 @@
     Ty = decl->getUnderlyingType();
   else
     return 0;
-  
+
   if (Ty->isFunctionPointerType())
     Ty = Ty->getAsPointerType()->getPointeeType();
   else if (blocksToo && Ty->isBlockPointerType())
@@ -95,7 +95,7 @@
     return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
   if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
     return BD->getParamDecl(Idx)->getType();
-  
+
   return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
 }
 
@@ -120,13 +120,13 @@
   const ObjCObjectPointerType *PT = T->getAsObjCObjectPointerType();
   if (!PT)
     return false;
-  
+
   const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
   if (!ClsT)
     return false;
-  
+
   IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
-  
+
   // FIXME: Should we walk the chain of classes?
   return ClsName == &Ctx.Idents.get("NSString") ||
          ClsName == &Ctx.Idents.get("NSMutableString");
@@ -140,7 +140,7 @@
   const RecordType *RT = PT->getPointeeType()->getAsRecordType();
   if (!RT)
     return false;
-  
+
   const RecordDecl *RD = RT->getDecl();
   if (RD->getTagKind() != TagDecl::TK_struct)
     return false;
@@ -156,14 +156,14 @@
 // least add some helper functions to check most argument patterns (#
 // and types of args).
 
-static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 
+static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
                                     const AttributeList &Attr, Sema &S) {
   TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
   if (tDecl == 0) {
     S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
     return;
   }
-  
+
   QualType curType = tDecl->getUnderlyingType();
 
   Expr *sizeExpr;
@@ -187,21 +187,20 @@
   QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
   if (!T.isNull()) {
     tDecl->setUnderlyingType(T);
-    
+
     // Remember this typedef decl, we will need it later for diagnostics.
     S.ExtVectorDecls.push_back(tDecl);
   }
 }
 
 
-/// HandleVectorSizeAttribute - this attribute is only applicable to 
-/// integral and float scalars, although arrays, pointers, and function
-/// return values are allowed in conjunction with this construct. Aggregates
-/// with this attribute are invalid, even if they are of the same size as a
-/// corresponding scalar.
-/// The raw attribute should contain precisely 1 argument, the vector size 
-/// for the variable, measured in bytes. If curType and rawAttr are well
-/// formed, this routine will return a new vector type.
+/// HandleVectorSizeAttribute - this attribute is only applicable to integral
+/// and float scalars, although arrays, pointers, and function return values are
+/// allowed in conjunction with this construct. Aggregates with this attribute
+/// are invalid, even if they are of the same size as a corresponding scalar.
+/// The raw attribute should contain precisely 1 argument, the vector size for
+/// the variable, measured in bytes. If curType and rawAttr are well formed,
+/// this routine will return a new vector type.
 static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
   QualType CurType;
   if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
@@ -213,7 +212,7 @@
       << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
     return;
   }
-    
+
   // Check the attribute arugments.
   if (Attr.getNumArgs() != 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
@@ -226,8 +225,8 @@
       << "vector_size" << sizeExpr->getSourceRange();
     return;
   }
-  // navigate to the base type - we need to provide for vector pointers, 
-  // vector arrays, and functions returning vectors.
+  // navigate to the base type - we need to provide for vector pointers, vector
+  // arrays, and functions returning vectors.
   if (CurType->isPointerType() || CurType->isArrayType() ||
       CurType->isFunctionType()) {
     S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType;
@@ -252,8 +251,8 @@
   }
   unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
   // vecSize is specified in bytes - convert to bits.
-  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 
-  
+  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
+
   // the vector size needs to be an integral multiple of the type size.
   if (vectorSize % typeSize) {
     S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
@@ -265,14 +264,14 @@
       << sizeExpr->getSourceRange();
     return;
   }
-  
+
   // Success! Instantiate the vector type, the number of elements is > 0, and
   // not required to be a power of 2, unlike GCC.
   CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
-  
+
   if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
     VD->setType(CurType);
-  else 
+  else
     cast<TypedefDecl>(D)->setUnderlyingType(CurType);
 }
 
@@ -282,7 +281,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   if (TagDecl *TD = dyn_cast<TagDecl>(d))
     TD->addAttr(::new (S.Context) PackedAttr(1));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
@@ -304,7 +303,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   // The IBOutlet attribute only applies to instance variables of Objective-C
   // classes.
   if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
@@ -314,23 +313,23 @@
 }
 
 static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
-  // GCC ignores the nonnull attribute on K&R style function
-  // prototypes, so we ignore it as well
+  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
+  // ignore it as well
   if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << 0 /*function*/;
     return;
   }
-  
+
   unsigned NumArgs = getFunctionOrMethodNumArgs(d);
 
   // The nonnull attribute only applies to pointers.
   llvm::SmallVector<unsigned, 10> NonNullArgs;
-  
+
   for (AttributeList::arg_iterator I=Attr.arg_begin(),
                                    E=Attr.arg_end(); I!=E; ++I) {
-    
-    
+
+
     // The argument must be an integer constant expression.
     Expr *Ex = static_cast<Expr *>(*I);
     llvm::APSInt ArgNum(32);
@@ -339,38 +338,38 @@
         << "nonnull" << Ex->getSourceRange();
       return;
     }
-    
+
     unsigned x = (unsigned) ArgNum.getZExtValue();
-        
+
     if (x < 1 || x > NumArgs) {
       S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
        << "nonnull" << I.getArgNum() << Ex->getSourceRange();
       return;
     }
-    
+
     --x;
 
     // Is the function argument a pointer type?
-    QualType T = getFunctionOrMethodArgType(d, x);    
+    QualType T = getFunctionOrMethodArgType(d, x);
     if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
       // FIXME: Should also highlight argument in decl.
       S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
         << "nonnull" << Ex->getSourceRange();
       continue;
     }
-    
+
     NonNullArgs.push_back(x);
   }
-  
-  // If no arguments were specified to __attribute__((nonnull)) then all
-  // pointer arguments have a nonnull attribute.
+
+  // If no arguments were specified to __attribute__((nonnull)) then all pointer
+  // arguments have a nonnull attribute.
   if (NonNullArgs.empty()) {
     for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
       QualType T = getFunctionOrMethodArgType(d, I);
       if (T->isAnyPointerType() || T->isBlockPointerType())
         NonNullArgs.push_back(I);
     }
-    
+
     if (NonNullArgs.empty()) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
       return;
@@ -389,26 +388,26 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
   }
-  
+
   Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
   Arg = Arg->IgnoreParenCasts();
   StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-  
+
   if (Str == 0 || Str->isWide()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
       << "alias" << 1;
     return;
   }
-  
+
   const char *Alias = Str->getStrData();
   unsigned AliasLen = Str->getByteLength();
-  
+
   // FIXME: check if target symbol exists in current file
-  
+
   d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
 }
 
-static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 
+static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
                                    Sema &S) {
   // check the attribute arguments.
   if (Attr.getNumArgs() != 0) {
@@ -421,7 +420,7 @@
     << Attr.getName() << 0 /*function*/;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) AlwaysInlineAttr());
 }
 
@@ -441,18 +440,18 @@
       return false;
     }
   }
-  
+
   return true;
 }
 
 static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
-  if (HandleCommonNoReturnAttr(d, Attr, S))  
+  if (HandleCommonNoReturnAttr(d, Attr, S))
     d->addAttr(::new (S.Context) NoReturnAttr());
 }
 
 static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
                                        Sema &S) {
-  if (HandleCommonNoReturnAttr(d, Attr, S))  
+  if (HandleCommonNoReturnAttr(d, Attr, S))
     d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
 }
 
@@ -462,13 +461,13 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << 2 /*variable and function*/;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) UnusedAttr());
 }
 
@@ -478,7 +477,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
     if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
@@ -489,7 +488,7 @@
       << Attr.getName() << 2 /*variable and function*/;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) UsedAttr());
 }
 
@@ -499,7 +498,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << "0 or 1";
     return;
-  } 
+  }
 
   int priority = 65535; // FIXME: Do not hardcode such constants.
   if (Attr.getNumArgs() > 0) {
@@ -512,7 +511,7 @@
     }
     priority = Idx.getZExtValue();
   }
-  
+
   if (!isa<FunctionDecl>(d)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << 0 /*function*/;
@@ -528,7 +527,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
        << "0 or 1";
     return;
-  } 
+  }
 
   int priority = 65535; // FIXME: Do not hardcode such constants.
   if (Attr.getNumArgs() > 0) {
@@ -541,7 +540,7 @@
     }
     priority = Idx.getZExtValue();
   }
-  
+
   if (!isa<FunctionDecl>(d)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << 0 /*function*/;
@@ -557,7 +556,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) DeprecatedAttr());
 }
 
@@ -567,7 +566,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) UnavailableAttr());
 }
 
@@ -577,21 +576,21 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
   }
-  
+
   Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
   Arg = Arg->IgnoreParenCasts();
   StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-  
+
   if (Str == 0 || Str->isWide()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
       << "visibility" << 1;
     return;
   }
-  
+
   const char *TypeStr = Str->getStrData();
   unsigned TypeLen = Str->getByteLength();
   VisibilityAttr::VisibilityTypes type;
-  
+
   if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
     type = VisibilityAttr::DefaultVisibility;
   else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
@@ -604,7 +603,7 @@
     S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) VisibilityAttr(type));
 }
 
@@ -614,13 +613,13 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
   if (OCI == 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
     return;
   }
-  
+
   D->addAttr(::new (S.Context) ObjCExceptionAttr());
 }
 
@@ -640,7 +639,7 @@
   D->addAttr(::new (S.Context) ObjCNSObjectAttr());
 }
 
-static void 
+static void
 HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
@@ -656,17 +655,17 @@
 }
 
 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
-  if (!Attr.getParameterName()) {    
+  if (!Attr.getParameterName()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
       << "blocks" << 1;
     return;
   }
-  
+
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
   }
-  
+
   BlocksAttr::BlocksAttrTypes type;
   if (Attr.getParameterName()->isStr("byref"))
     type = BlocksAttr::ByRef;
@@ -675,7 +674,7 @@
       << "blocks" << Attr.getParameterName();
     return;
   }
-  
+
   d->addAttr(::new (S.Context) BlocksAttr(type));
 }
 
@@ -685,8 +684,8 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << "0, 1 or 2";
     return;
-  } 
-  
+  }
+
   int sentinel = 0;
   if (Attr.getNumArgs() > 0) {
     Expr *E = static_cast<Expr *>(Attr.getArg(0));
@@ -697,7 +696,7 @@
       return;
     }
     sentinel = Idx.getZExtValue();
-    
+
     if (sentinel < 0) {
       S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
         << E->getSourceRange();
@@ -715,7 +714,7 @@
       return;
     }
     nullPos = Idx.getZExtValue();
-    
+
     if (nullPos > 1 || nullPos < 0) {
       // FIXME: This error message could be improved, it would be nice
       // to say what the bounds actually are.
@@ -728,29 +727,29 @@
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
     const FunctionType *FT = FD->getType()->getAsFunctionType();
     assert(FT && "FunctionDecl has non-function type?");
-    
+
     if (isa<FunctionNoProtoType>(FT)) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
       return;
     }
-    
+
     if (!cast<FunctionProtoType>(FT)->isVariadic()) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
       return;
-    }    
+    }
   } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
     if (!MD->isVariadic()) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
       return;
     }
   } else if (isa<BlockDecl>(d)) {
-    // Note! BlockDecl is typeless. Variadic diagnostics
-    // will be issued by the caller.
+    // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
+    // caller.
     ;
   } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
     QualType Ty = V->getType();
     if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
-      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 
+      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
         : Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType();
       if (!cast<FunctionProtoType>(FT)->isVariadic()) {
         int m = Ty->isFunctionPointerType() ? 0 : 1;
@@ -785,7 +784,7 @@
       << Attr.getName() << 0 /*function*/;
     return;
   }
-  
+
   Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
 }
 
@@ -815,7 +814,7 @@
       << Attr.getName() << 2 /*variable and function*/;
     return;
   }
-  
+
   D->addAttr(::new (S.Context) WeakAttr());
 }
 
@@ -824,7 +823,7 @@
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
-  }  
+  }
 
   // weak_import only applies to variable & function declarations.
   bool isDef = false;
@@ -843,7 +842,7 @@
 
   // Merge should handle any subsequent violations.
   if (isDef) {
-    S.Diag(Attr.getLoc(), 
+    S.Diag(Attr.getLoc(),
            diag::warn_attribute_weak_import_invalid_on_definition)
       << "weak_import" << 2 /*variable and function*/;
     return;
@@ -917,8 +916,8 @@
     return;
   }
 
-  // Currently, the dllexport attribute is ignored for inlined functions,
-  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
+  // Currently, the dllexport attribute is ignored for inlined functions, unless
+  // the -fkeep-inline-functions flag has been used. Warning is emitted;
   if (FD->isInline()) {
     // FIXME: ... unless the -fkeep-inline-functions flag has been used.
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
@@ -960,7 +959,7 @@
 
   // Make sure that there is a string literal as the sections's single
   // argument.
-  StringLiteral *SE = 
+  StringLiteral *SE =
     dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
   if (!SE) {
     // FIXME
@@ -1024,7 +1023,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) NoThrowAttr());
 }
 
@@ -1034,7 +1033,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) ConstAttr());
 }
 
@@ -1044,7 +1043,7 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) PureAttr());
 }
 
@@ -1052,24 +1051,24 @@
   // Match gcc which ignores cleanup attrs when compiling C++.
   if (S.getLangOptions().CPlusPlus)
     return;
-  
-  if (!Attr.getParameterName()) {    
+
+  if (!Attr.getParameterName()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
   }
-  
+
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
   }
-  
+
   VarDecl *VD = dyn_cast<VarDecl>(d);
-  
+
   if (!VD || !VD->hasLocalStorage()) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
     return;
   }
-  
+
   // Look up the function
   NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
                                         Sema::LookupOrdinaryName);
@@ -1078,7 +1077,7 @@
       Attr.getParameterName();
     return;
   }
-  
+
   FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
   if (!FD) {
     S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
@@ -1091,24 +1090,24 @@
       Attr.getParameterName();
     return;
   }
-  
+
   // We're currently more strict than GCC about what function types we accept.
   // If this ever proves to be a problem it should be easy to fix.
   QualType Ty = S.Context.getPointerType(VD->getType());
   QualType ParamTy = FD->getParamDecl(0)->getType();
   if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
-    S.Diag(Attr.getLoc(), 
+    S.Diag(Attr.getLoc(),
            diag::err_attribute_cleanup_func_arg_incompatible_type) <<
       Attr.getParameterName() << ParamTy << Ty;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) CleanupAttr(FD));
 }
 
-/// Handle __attribute__((format_arg((idx)))) attribute
-/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
-static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 
+/// Handle __attribute__((format_arg((idx)))) attribute based on
+/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   if (Attr.getNumArgs() != 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
@@ -1118,9 +1117,8 @@
     << Attr.getName() << 0 /*function*/;
     return;
   }
-  // FIXME: in C++ the implicit 'this' function parameter also counts.
-  // this is needed in order to be compatible with GCC
-  // the index must start with 1.
+  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
+  // needed in order to be compatible with GCC the index must start with 1.
   unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
   unsigned FirstIdx = 1;
   // checks for the 2nd argument
@@ -1131,18 +1129,18 @@
     << "format" << 2 << IdxExpr->getSourceRange();
     return;
   }
-  
+
   if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
     << "format" << 2 << IdxExpr->getSourceRange();
     return;
   }
-  
+
   unsigned ArgIdx = Idx.getZExtValue() - 1;
-  
+
   // make sure the format string is really a string
   QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
-  
+
   bool not_nsstring_type = !isNSStringType(Ty, S.Context);
   if (not_nsstring_type &&
       !isCFStringType(Ty, S.Context) &&
@@ -1150,10 +1148,10 @@
        !Ty->getAsPointerType()->getPointeeType()->isCharType())) {
     // FIXME: Should highlight the actual expression that has the wrong type.
     S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
-    << (not_nsstring_type ? "a string type" : "an NSString") 
+    << (not_nsstring_type ? "a string type" : "an NSString")
        << IdxExpr->getSourceRange();
     return;
-  }    
+  }
   Ty = getFunctionOrMethodResultType(d);
   if (!isNSStringType(Ty, S.Context) &&
       !isCFStringType(Ty, S.Context) &&
@@ -1161,16 +1159,16 @@
        !Ty->getAsPointerType()->getPointeeType()->isCharType())) {
     // FIXME: Should highlight the actual expression that has the wrong type.
     S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
-    << (not_nsstring_type ? "string type" : "NSString") 
+    << (not_nsstring_type ? "string type" : "NSString")
        << IdxExpr->getSourceRange();
     return;
-  }    
-  
+  }
+
   d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
 }
 
-/// Handle __attribute__((format(type,idx,firstarg))) attributes
-/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
+/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
 static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
 
   if (!Attr.getParameterName()) {
@@ -1190,9 +1188,9 @@
     return;
   }
 
-  // FIXME: in C++ the implicit 'this' function parameter also counts.
-  // this is needed in order to be compatible with GCC
-  // the index must start in 1 and the limit is numargs+1
+  // FIXME: in C++ the implicit 'this' function parameter also counts.  this is
+  // needed in order to be compatible with GCC the index must start in 1 and the
+  // limit is numargs+1
   unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
   unsigned FirstIdx = 1;
 
@@ -1210,7 +1208,7 @@
   bool is_NSString = false;
   bool is_strftime = false;
   bool is_CFString = false;
-  
+
   switch (FormatLen) {
   default: break;
   case 5: Supported = !memcmp(Format, "scanf", 5); break;
@@ -1222,7 +1220,7 @@
                 (is_CFString = !memcmp(Format, "CFString", 8));
     break;
   }
-      
+
   if (!Supported) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
       << "format" << Attr.getParameterName()->getName();
@@ -1246,7 +1244,7 @@
 
   // FIXME: Do we need to bounds check?
   unsigned ArgIdx = Idx.getZExtValue() - 1;
-  
+
   // make sure the format string is really a string
   QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
 
@@ -1264,7 +1262,7 @@
       S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
         << "an NSString" << IdxExpr->getSourceRange();
       return;
-    }    
+    }
   } else if (!Ty->isPointerType() ||
              !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
     // FIXME: Should highlight the actual expression that has the wrong type.
@@ -1334,7 +1332,7 @@
   }
 
   if (!RD->isDefinition()) {
-    S.Diag(Attr.getLoc(), 
+    S.Diag(Attr.getLoc(),
         diag::warn_transparent_union_attribute_not_definition);
     return;
   }
@@ -1349,7 +1347,7 @@
   FieldDecl *FirstField = *Field;
   QualType FirstType = FirstField->getType();
   if (FirstType->isFloatingType() || FirstType->isVectorType()) {
-    S.Diag(FirstField->getLocation(), 
+    S.Diag(FirstField->getLocation(),
            diag::warn_transparent_union_attribute_floating);
     return;
   }
@@ -1362,13 +1360,13 @@
         S.Context.getTypeAlign(FieldType) != FirstAlign) {
       // Warn if we drop the attribute.
       bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
-      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 
+      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
                                  : S.Context.getTypeAlign(FieldType);
-      S.Diag(Field->getLocation(), 
+      S.Diag(Field->getLocation(),
           diag::warn_transparent_union_attribute_field_size_align)
         << isSize << Field->getDeclName() << FieldBits;
       unsigned FirstBits = isSize? FirstSize : FirstAlign;
-      S.Diag(FirstField->getLocation(), 
+      S.Diag(FirstField->getLocation(),
              diag::note_transparent_union_first_field_size_align)
         << isSize << FirstBits;
       return;
@@ -1386,7 +1384,7 @@
   }
   Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
   StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
-  
+
   // Make sure that there is a string literal as the annotation's single
   // argument.
   if (!SE) {
@@ -1412,7 +1410,7 @@
     d->addAttr(::new (S.Context) AlignedAttr(Align));
     return;
   }
-  
+
   Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
   llvm::APSInt Alignment(32);
   if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
@@ -1421,7 +1419,7 @@
     return;
   }
   if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 
+    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
       << alignmentExpr->getSourceRange();
     return;
   }
@@ -1429,13 +1427,12 @@
   d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
 }
 
-/// HandleModeAttr - This attribute modifies the width of a decl with
-/// primitive type.
+/// HandleModeAttr - This attribute modifies the width of a decl with primitive
+/// type.
 ///
-/// Despite what would be logical, the mode attribute is a decl attribute,
-/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
-/// 'G' be HImode, not an intermediate pointer.
-///
+/// Despite what would be logical, the mode attribute is a decl attribute, not a
+/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
+/// HImode, not an intermediate pointer.
 static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
   // This attribute isn't documented, but glibc uses it.  It changes
   // the width of an int or unsigned int to the specified size.
@@ -1606,7 +1603,7 @@
       << Attr.getName() << 0 /*function*/;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) NodebugAttr());
 }
 
@@ -1616,13 +1613,13 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   if (!isa<FunctionDecl>(d)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
     << Attr.getName() << 0 /*function*/;
     return;
   }
-  
+
   d->addAttr(::new (S.Context) NoinlineAttr());
 }
 
@@ -1632,19 +1629,19 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
-  
+
   FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
   if (Fn == 0) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << 0 /*function*/;
     return;
   }
-  
+
   if (!Fn->isInline()) {
     S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
     return;
   }
-  
+
   d->addAttr(::new (S.Context) GNUInlineAttr());
 }
 
@@ -1692,7 +1689,7 @@
                                         Sema &S) {
 
   QualType RetTy;
-  
+
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
     RetTy = MD->getResultType();
   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
@@ -1702,14 +1699,14 @@
         << Attr.getName() << 3 /* function or method */;
     return;
   }
-  
+
   if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAsPointerType()
         || RetTy->getAsObjCObjectPointerType())) {
     S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
       << Attr.getName();
-    return;    
+    return;
   }
-  
+
   switch (Attr.getKind()) {
     default:
       assert(0 && "invalid ownership attribute");
@@ -1730,7 +1727,8 @@
 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
 /// the attribute applies to decls.  If the attribute is a type attribute, just
 /// silently ignore it.
-static void ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr, Sema &S) {
+static void ProcessDeclAttribute(Scope *scope, Decl *D,
+                                 const AttributeList &Attr, Sema &S) {
   if (Attr.isDeclspecAttribute())
     // FIXME: Try to deal with __declspec attributes!
     return;
@@ -1738,14 +1736,15 @@
   case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
   case AttributeList::AT_address_space:
   case AttributeList::AT_objc_gc:
-    // Ignore these, these are type attributes, handled by ProcessTypeAttributes.
+    // Ignore these, these are type attributes, handled by
+    // ProcessTypeAttributes.
     break;
   case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
   case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
-  case AttributeList::AT_always_inline: 
+  case AttributeList::AT_always_inline:
     HandleAlwaysInlineAttr  (D, Attr, S); break;
   case AttributeList::AT_analyzer_noreturn:
-    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;  
+    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
   case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
   case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
   case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
@@ -1800,7 +1799,7 @@
   case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
   case AttributeList::AT_noinline:    HandleNoinlineAttr  (D, Attr, S); break;
   case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
-  case AttributeList::IgnoredAttribute: 
+  case AttributeList::IgnoredAttribute:
   case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
     // Just ignore
     break;
@@ -1826,7 +1825,7 @@
   // Apply decl attributes from the DeclSpec if present.
   if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
     ProcessDeclAttributeList(S, D, Attrs);
-  
+
   // Walk the declarator structure, applying decl attributes that were in a type
   // position to the decl itself.  This handles cases like:
   //   int *__attr__(x)** D;
@@ -1834,7 +1833,7 @@
   for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
     if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
       ProcessDeclAttributeList(S, D, Attrs);
-  
+
   // Finally, apply any attributes on the decl itself.
   if (const AttributeList *Attrs = PD.getAttributes())
     ProcessDeclAttributeList(S, D, Attrs);
