diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp | 267 | 
1 files changed, 184 insertions, 83 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp index 69baf79ad0fe..5c6ddd2cb97d 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp @@ -35,17 +35,14 @@ enum AttributeDeclKind {    ExpectedVariableOrFunction,    ExpectedFunctionOrMethod,    ExpectedParameter, -  ExpectedParameterOrMethod,    ExpectedFunctionMethodOrBlock, -  ExpectedClassOrVirtualMethod,    ExpectedFunctionMethodOrParameter,    ExpectedClass, -  ExpectedVirtualMethod, -  ExpectedClassMember,    ExpectedVariable,    ExpectedMethod,    ExpectedVariableFunctionOrLabel, -  ExpectedFieldOrGlobalVar +  ExpectedFieldOrGlobalVar, +  ExpectedStruct  };  //===----------------------------------------------------------------------===// @@ -275,21 +272,25 @@ static const RecordType *getRecordType(QualType QT) {  /// \brief Thread Safety Analysis: Checks that the passed in RecordType  /// resolves to a lockable object. May flag an error. -static bool checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, -                                   const RecordType *RT) { -  // Flag error if could not get record type for this argument. +static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, +                                   QualType Ty) { +  const RecordType *RT = getRecordType(Ty); +                                    +  // Warn if could not get record type for this argument.    if (!RT) { -    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_class) -      << Attr.getName(); -    return false; +    S.Diag(Attr.getLoc(), diag::warn_attribute_argument_not_class) +      << Attr.getName() << Ty.getAsString(); +    return;    } -  // Flag error if the type is not lockable. +  // Don't check for lockable if the class hasn't been defined yet.  +  if (RT->isIncompleteType()) +    return; +  // Warn if the type is not lockable.    if (!RT->getDecl()->getAttr<LockableAttr>()) { -    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable) -      << Attr.getName(); -    return false; +    S.Diag(Attr.getLoc(), diag::warn_attribute_argument_not_lockable) +      << Attr.getName() << Ty.getAsString(); +    return;    } -  return true;  }  /// \brief Thread Safety Analysis: Checks that all attribute arguments, starting @@ -331,12 +332,10 @@ static bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D,            return false;          }          ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); -        RT = getRecordType(ArgTy);        }      } -    if (!checkForLockableRecord(S, D, Attr, RT)) -      return false; +    checkForLockableRecord(S, D, Attr, ArgTy);      Args.push_back(ArgExp);    } @@ -393,13 +392,9 @@ static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr,    if (pointer && !checkIsPointer(S, D, Attr))      return; -  if (Arg->isTypeDependent()) -    // FIXME: handle attributes with dependent types -    return; - -  // check that the argument is lockable object -  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) -    return; +  if (!Arg->isTypeDependent()) { +    checkForLockableRecord(S, D, Attr, Arg->getType()); +  }    if (pointer)      D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), @@ -446,6 +441,23 @@ static void handleNoThreadSafetyAttr(Sema &S, Decl *D,                                                            S.Context));  } +static void handleNoAddressSafetyAttr(Sema &S, Decl *D, +                                     const AttributeList &Attr) { +  assert(!Attr.isInvalid()); + +  if (!checkAttributeNumArgs(S, Attr, 0)) +    return; + +  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { +    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) +      << Attr.getName() << ExpectedFunctionOrMethod; +    return; +  } + +  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(), +                                                          S.Context)); +} +  static void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,                                     bool before) {    assert(!Attr.isInvalid()); @@ -466,7 +478,7 @@ static void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr,    if (!QT->isDependentType()) {      const RecordType *RT = getRecordType(QT);      if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { -      S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable) +      S.Diag(Attr.getLoc(), diag::warn_attribute_decl_not_lockable)                << Attr.getName();        return;      } @@ -636,8 +648,7 @@ static void handleLockReturnedAttr(Sema &S, Decl *D,      return;    // check that the argument is lockable object -  if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) -    return; +  checkForLockableRecord(S, D, Attr, Arg->getType());    D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg));  } @@ -684,10 +695,12 @@ static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,    // Special case where the argument is a template id.    if (Attr.getParameterName()) {      CXXScopeSpec SS; +    SourceLocation TemplateKWLoc;      UnqualifiedId id;      id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); -    ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false); +    ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id, +                                          false, false);      if (Size.isInvalid())        return; @@ -760,14 +773,14 @@ static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {    // have an object reference type.    if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {      if (!VD->getType()->getAs<ObjCObjectPointerType>()) { -      S.Diag(Attr.getLoc(), diag::err_iboutlet_object_type) +      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)          << Attr.getName() << VD->getType() << 0;        return false;      }    }    else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {      if (!PD->getType()->getAs<ObjCObjectPointerType>()) { -      S.Diag(Attr.getLoc(), diag::err_iboutlet_object_type)  +      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)          << Attr.getName() << PD->getType() << 1;        return false;      } @@ -776,7 +789,7 @@ static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {      S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();      return false;    } -   +    return true;  } @@ -805,7 +818,7 @@ static void handleIBOutletCollection(Sema &S, Decl *D,    IdentifierInfo *II = Attr.getParameterName();    if (!II) -    II = &S.Context.Idents.get("id"); +    II = &S.Context.Idents.get("NSObject");    ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),                           S.getScopeForContext(D->getDeclContext()->getParent())); @@ -818,8 +831,7 @@ static void handleIBOutletCollection(Sema &S, Decl *D,    // FIXME. Gnu attribute extension ignores use of builtin types in    // attributes. So, __attribute__((iboutletcollection(char))) will be    // treated as __attribute__((iboutletcollection())). -  if (!QT->isObjCIdType() && !QT->isObjCClassType() && -      !QT->isObjCObjectType()) { +  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;      return;    } @@ -1056,8 +1068,6 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {        }        break;      } -    default: -      llvm_unreachable("Unknown ownership attribute");      } // switch      // Check we don't have a conflict with another ownership attribute. @@ -1108,7 +1118,6 @@ static bool hasEffectivelyInternalLinkage(NamedDecl *D) {      return false;    }    llvm_unreachable("unknown linkage kind!"); -  return false;  }  static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { @@ -1580,6 +1589,39 @@ static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,                                            Attr.getRange(), S.Context));  } +static void handleObjCRootClassAttr(Sema &S, Decl *D,  +                                    const AttributeList &Attr) { +  if (!isa<ObjCInterfaceDecl>(D)) { +    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); +    return; +  } +   +  unsigned NumArgs = Attr.getNumArgs(); +  if (NumArgs > 0) { +    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; +    return; +  } +   +  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context)); +} + +static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,  +                                            const AttributeList &Attr) { +  if (!isa<ObjCInterfaceDecl>(D)) { +    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis); +    return; +  } +   +  unsigned NumArgs = Attr.getNumArgs(); +  if (NumArgs > 0) { +    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; +    return; +  } +   +  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr( +                                 Attr.getRange(), S.Context)); +} +  static void handleAvailabilityAttr(Sema &S, Decl *D,                                     const AttributeList &Attr) {    IdentifierInfo *Platform = Attr.getParameterName(); @@ -1625,12 +1667,19 @@ static void handleAvailabilityAttr(Sema &S, Decl *D,      return;    } +  StringRef Str; +  const StringLiteral *SE =  +    dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr()); +  if (SE) +    Str = SE->getString(); +      D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context,                                                  Platform,                                                  Introduced.Version,                                                  Deprecated.Version,                                                  Obsoleted.Version, -                                                IsUnavailable)); +                                                IsUnavailable,  +                                                Str));  }  static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { @@ -1657,9 +1706,16 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {      type = VisibilityAttr::Hidden;    else if (TypeStr == "internal")      type = VisibilityAttr::Hidden; // FIXME -  else if (TypeStr == "protected") -    type = VisibilityAttr::Protected; -  else { +  else if (TypeStr == "protected") { +    // Complain about attempts to use protected visibility on targets +    // (like Darwin) that don't support it. +    if (!S.Context.getTargetInfo().hasProtectedVisibility()) { +      S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); +      type = VisibilityAttr::Default; +    } else { +      type = VisibilityAttr::Protected; +    } +  } else {      S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;      return;    } @@ -1747,6 +1803,15 @@ static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {        return;      }    } +  else if (!isa<ObjCPropertyDecl>(D)) { +    // It is okay to include this attribute on properties, e.g.: +    // +    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); +    // +    // In this case it follows tradition and suppresses an error in the above +    // case.     +    S.Diag(D->getLocation(), diag::warn_nsobject_attribute); +  }    D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));  } @@ -1853,10 +1918,11 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {        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. -    ; +  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { +    if (!BD->isVariadic()) { +      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; +      return; +    }    } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {      QualType Ty = V->getType();      if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { @@ -1915,6 +1981,10 @@ static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {    }    if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { +    if (isa<CXXRecordDecl>(D)) { +      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); +      return; +    }      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)        << Attr.getName() << ExpectedVariableOrFunction;      return; @@ -1946,7 +2016,7 @@ static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {          << "weak_import" << 2 /*variable and function*/;      else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||               (S.Context.getTargetInfo().getTriple().isOSDarwin() && -              isa<ObjCInterfaceDecl>(D))) { +              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {        // Nothing to warn about here.      } else        S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) @@ -2109,7 +2179,7 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {    }    D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); -  S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); +  S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);  }  /// Handle __attribute__((format_arg((idx)))) attribute based on @@ -2209,8 +2279,7 @@ static FormatAttrKind getFormatAttrKind(StringRef Format) {    // Otherwise, check for supported formats.    if (Format == "scanf" || Format == "printf" || Format == "printf0" || -      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || -      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || +      Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" ||        Format == "zcmn_err" ||        Format == "kprintf")  // OpenBSD.      return SupportedFormat; @@ -2226,7 +2295,7 @@ static FormatAttrKind getFormatAttrKind(StringRef Format) {  /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html  static void handleInitPriorityAttr(Sema &S, Decl *D,                                     const AttributeList &Attr) { -  if (!S.getLangOptions().CPlusPlus) { +  if (!S.getLangOpts().CPlusPlus) {      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();      return;    } @@ -2541,6 +2610,10 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {  }  void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { +  // FIXME: Handle pack-expansions here. +  if (DiagnoseUnexpandedParameterPack(E)) +    return; +    if (E->isTypeDependent() || E->isValueDependent()) {      // Save dependent expressions in the AST to be instantiated.      D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); @@ -2550,18 +2623,19 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {    SourceLocation AttrLoc = AttrRange.getBegin();    // FIXME: Cache the number on the Attr object?    llvm::APSInt Alignment(32); -  if (!E->isIntegerConstantExpr(Alignment, Context)) { -    Diag(AttrLoc, diag::err_attribute_argument_not_int) -      << "aligned" << E->getSourceRange(); +  ExprResult ICE = +    VerifyIntegerConstantExpression(E, &Alignment, +      PDiag(diag::err_attribute_argument_not_int) << "aligned", +      /*AllowFold*/ false); +  if (ICE.isInvalid())      return; -  }    if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {      Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)        << E->getSourceRange();      return;    } -  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); +  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));  }  void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { @@ -2975,7 +3049,6 @@ static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {    }    default:      llvm_unreachable("unexpected attribute kind"); -    return;    }  } @@ -3024,7 +3097,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {      }      // FALLS THROUGH    } -  default: llvm_unreachable("unexpected attribute kind"); return true; +  default: llvm_unreachable("unexpected attribute kind");    }    return false; @@ -3195,7 +3268,7 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,      returnType = MD->getResultType();    else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))      returnType = PD->getType(); -  else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) && +  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&             (Attr.getKind() == AttributeList::AT_ns_returns_retained))      return; // ignore: was handled as a type attribute    else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) @@ -3210,7 +3283,7 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,    bool typeOK;    bool cf;    switch (Attr.getKind()) { -  default: llvm_unreachable("invalid ownership attribute"); return; +  default: llvm_unreachable("invalid ownership attribute");    case AttributeList::AT_ns_returns_autoreleased:    case AttributeList::AT_ns_returns_retained:    case AttributeList::AT_ns_returns_not_retained: @@ -3265,7 +3338,7 @@ static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,    if (!isa<ObjCMethodDecl>(method)) {      S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type) -      << SourceRange(loc, loc) << attr.getName() << 13 /* methods */; +      << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;      return;    } @@ -3290,7 +3363,7 @@ static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,  static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {    if (!isa<FunctionDecl>(D)) {      S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) -      << A.getRange() << A.getName() << 0 /*function*/; +      << A.getRange() << A.getName() << ExpectedFunction;      return;    } @@ -3326,7 +3399,7 @@ static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,    RecordDecl *RD = dyn_cast<RecordDecl>(D);    if (!RD || RD->isUnion()) {      S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) -      << Attr.getRange() << Attr.getName() << 14 /*struct */; +      << Attr.getRange() << Attr.getName() << ExpectedStruct;    }    IdentifierInfo *ParmName = Attr.getParameterName(); @@ -3334,7 +3407,7 @@ static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,    // In Objective-C, verify that the type names an Objective-C type.    // We don't want to check this outside of ObjC because people sometimes    // do crazy C declarations of Objective-C types. -  if (ParmName && S.getLangOptions().ObjC1) { +  if (ParmName && S.getLangOpts().ObjC1) {      // Check for an existing type with this name.      LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),                     Sema::LookupOrdinaryName); @@ -3356,14 +3429,14 @@ static void handleObjCOwnershipAttr(Sema &S, Decl *D,    if (hasDeclarator(D)) return;    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) -    << Attr.getRange() << Attr.getName() << 12 /* variable */; +    << Attr.getRange() << Attr.getName() << ExpectedVariable;  }  static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,                                            const AttributeList &Attr) {    if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {      S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) -      << Attr.getRange() << Attr.getName() << 12 /* variable */; +      << Attr.getRange() << Attr.getName() << ExpectedVariable;      return;    } @@ -3406,9 +3479,19 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,  }  static bool isKnownDeclSpecAttr(const AttributeList &Attr) { -  return Attr.getKind() == AttributeList::AT_dllimport || -         Attr.getKind() == AttributeList::AT_dllexport || -         Attr.getKind() == AttributeList::AT_uuid; +  switch (Attr.getKind()) { +  default: +    return false; +  case AttributeList::AT_dllimport: +  case AttributeList::AT_dllexport: +  case AttributeList::AT_uuid: +  case AttributeList::AT_deprecated: +  case AttributeList::AT_noreturn: +  case AttributeList::AT_nothrow: +  case AttributeList::AT_naked: +  case AttributeList::AT_noinline: +    return true; +  }  }  //===----------------------------------------------------------------------===// @@ -3433,7 +3516,7 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {      bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&                     StrRef.back() == '}'; -     +      // Validate GUID length.      if (IsCurly && StrRef.size() != 38) {        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); @@ -3444,7 +3527,7 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {        return;      } -    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or  +    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or      // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"      StringRef::iterator I = StrRef.begin();      if (IsCurly) // Skip the optional '{' @@ -3487,9 +3570,9 @@ static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,  static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,                                         const AttributeList &Attr) {    switch (Attr.getKind()) { -  case AttributeList::AT_IBAction:            handleIBAction(S, D, Attr); break; -    case AttributeList::AT_IBOutlet:          handleIBOutlet(S, D, Attr); break; -  case AttributeList::AT_IBOutletCollection: +    case AttributeList::AT_ibaction:            handleIBAction(S, D, Attr); break; +    case AttributeList::AT_iboutlet:          handleIBOutlet(S, D, Attr); break; +    case AttributeList::AT_iboutletcollection:        handleIBOutletCollection(S, D, Attr); break;    case AttributeList::AT_address_space:    case AttributeList::AT_opencl_image_access: @@ -3574,19 +3657,25 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_cf_returns_retained:      handleNSReturnsRetainedAttr(S, D, Attr); break; -  case AttributeList::AT_reqd_wg_size: +  case AttributeList::AT_reqd_work_group_size:      handleReqdWorkGroupSize(S, D, Attr); break;    case AttributeList::AT_init_priority:         handleInitPriorityAttr(S, D, Attr); break;    case AttributeList::AT_packed:      handlePackedAttr      (S, D, Attr); break; -  case AttributeList::AT_MsStruct:    handleMsStructAttr    (S, D, Attr); break; +  case AttributeList::AT_ms_struct:    handleMsStructAttr    (S, D, Attr); break;    case AttributeList::AT_section:     handleSectionAttr     (S, D, Attr); break;    case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; -  case AttributeList::AT_arc_weakref_unavailable:  +  case AttributeList::AT_objc_arc_weak_reference_unavailable:       handleArcWeakrefUnavailableAttr (S, D, Attr);       break; +  case AttributeList::AT_objc_root_class: +    handleObjCRootClassAttr(S, D, Attr); +    break; +  case AttributeList::AT_objc_requires_property_definitions:  +    handleObjCRequiresPropertyDefsAttr (S, D, Attr);  +    break;    case AttributeList::AT_unused:      handleUnusedAttr      (S, D, Attr); break;    case AttributeList::AT_returns_twice:      handleReturnsTwiceAttr(S, D, Attr); @@ -3607,7 +3696,7 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_objc_method_family:      handleObjCMethodFamilyAttr(S, D, Attr);      break; -  case AttributeList::AT_nsobject:    handleObjCNSObject    (S, D, Attr); break; +  case AttributeList::AT_NSObject:    handleObjCNSObject    (S, D, Attr); break;    case AttributeList::AT_blocks:      handleBlocksAttr      (S, D, Attr); break;    case AttributeList::AT_sentinel:    handleSentinelAttr    (S, D, Attr); break;    case AttributeList::AT_const:       handleConstAttr       (S, D, Attr); break; @@ -3647,6 +3736,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,    case AttributeList::AT_scoped_lockable:      handleLockableAttr(S, D, Attr, /*scoped = */true);      break; +  case AttributeList::AT_no_address_safety_analysis: +    handleNoAddressSafetyAttr(S, D, Attr); +    break;    case AttributeList::AT_no_thread_safety_analysis:      handleNoThreadSafetyAttr(S, D, Attr);      break; @@ -3924,7 +4016,7 @@ static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,                          "this system declaration uses an unsupported type"));      return;    } -  if (S.getLangOptions().ObjCAutoRefCount) +  if (S.getLangOpts().ObjCAutoRefCount)      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {        // FIXME. we may want to supress diagnostics for all        // kind of forbidden type messages on unavailable functions.  @@ -3982,7 +4074,7 @@ void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,    // We only want to actually emit delayed diagnostics when we    // successfully parsed a decl. -  if (decl && !decl->isInvalidDecl()) { +  if (decl) {      // We emit all the active diagnostics, not just those starting      // from the saved state.  The idea is this:  we get one push for a      // decl spec and another for each declarator;  in a decl group like: @@ -3997,7 +4089,9 @@ void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,        switch (diag.Kind) {        case DelayedDiagnostic::Deprecation: -        S.HandleDelayedDeprecationCheck(diag, decl); +        // Don't bother giving deprecation diagnostics if the decl is invalid. +        if (!decl->isInvalidDecl()) +          S.HandleDelayedDeprecationCheck(diag, decl);          break;        case DelayedDiagnostic::Access: @@ -4039,6 +4133,11 @@ void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,      Diag(DD.Loc, diag::warn_deprecated_message)        << DD.getDeprecationDecl()->getDeclName()        << DD.getDeprecationMessage(); +  else if (DD.getUnknownObjCClass()) { +    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)  +      << DD.getDeprecationDecl()->getDeclName(); +    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class); +  }    else      Diag(DD.Loc, diag::warn_deprecated)        << DD.getDeprecationDecl()->getDeclName(); @@ -4049,7 +4148,9 @@ void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,                                    const ObjCInterfaceDecl *UnknownObjCClass) {    // Delay if we're currently parsing a declaration.    if (DelayedDiagnostics.shouldDelayDiagnostics()) { -    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message)); +    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,  +                                                              UnknownObjCClass, +                                                              Message));      return;    }  | 
