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 69baf79..5c6ddd2 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; } |