diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 18:11:16 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 18:11:16 +0000 |
commit | 6148c19c738a92f344008aa3f88f4e008bada0ee (patch) | |
tree | d4426858455f04d0d8c25a2f9eb9ea5582ffe1b6 /contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp | |
parent | 2c8643c6396b0a3db33430cf9380e70bbb9efce0 (diff) | |
parent | 173a4f43a911175643bda81ee675e8d9269056ea (diff) | |
download | FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.zip FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.tar.gz |
Merge clang 3.5.0 release from ^/vendor/clang/dist, resolve conflicts,
and preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp | 581 |
1 files changed, 318 insertions, 263 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp index d9d9cec..8eb806b 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp @@ -19,7 +19,6 @@ #include "clang/AST/ExprObjC.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" -#include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallString.h" @@ -132,11 +131,8 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, } // Check this property against any protocols we inherit. - for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), - PEnd = Proto->protocol_end(); - P != PEnd; ++P) { - CheckPropertyAgainstProtocol(S, Prop, *P, Known); - } + for (auto *P : Proto->protocols()) + CheckPropertyAgainstProtocol(S, Prop, P, Known); } Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, @@ -168,7 +164,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, // Proceed with constructing the ObjCPropertyDecls. ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext); - ObjCPropertyDecl *Res = 0; + ObjCPropertyDecl *Res = nullptr; if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { if (CDecl->IsClassExtension()) { Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc, @@ -179,7 +175,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, isOverridingProperty, TSI, MethodImplKind); if (!Res) - return 0; + return nullptr; } } @@ -204,7 +200,8 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { // For a class, compare the property against a property in our superclass. bool FoundInSuper = false; - if (ObjCInterfaceDecl *Super = IFace->getSuperClass()) { + ObjCInterfaceDecl *CurrentInterfaceDecl = IFace; + while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) { DeclContext::lookup_result R = Super->lookup(Res->getDeclName()); for (unsigned I = 0, N = R.size(); I != N; ++I) { if (ObjCPropertyDecl *SuperProp = dyn_cast<ObjCPropertyDecl>(R[I])) { @@ -213,37 +210,30 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, break; } } + if (FoundInSuper) + break; + else + CurrentInterfaceDecl = Super; } if (FoundInSuper) { // Also compare the property against a property in our protocols. - for (ObjCInterfaceDecl::protocol_iterator P = IFace->protocol_begin(), - PEnd = IFace->protocol_end(); - P != PEnd; ++P) { - CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos); + for (auto *P : CurrentInterfaceDecl->protocols()) { + CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); } } else { // Slower path: look in all protocols we referenced. - for (ObjCInterfaceDecl::all_protocol_iterator - P = IFace->all_referenced_protocol_begin(), - PEnd = IFace->all_referenced_protocol_end(); - P != PEnd; ++P) { - CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos); + for (auto *P : IFace->all_referenced_protocols()) { + CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); } } } else if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { - for (ObjCCategoryDecl::protocol_iterator P = Cat->protocol_begin(), - PEnd = Cat->protocol_end(); - P != PEnd; ++P) { - CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos); - } + for (auto *P : Cat->protocols()) + CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); } else { ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(ClassDecl); - for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), - PEnd = Proto->protocol_end(); - P != PEnd; ++P) { - CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos); - } + for (auto *P : Proto->protocols()) + CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); } ActOnDocumentableDecl(Res); @@ -302,8 +292,7 @@ static bool LocPropertyAttribute( ASTContext &Context, const char *attrName, Token Tok; do { lexer.LexFromRawLexer(Tok); - if (Tok.is(tok::raw_identifier) && - StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == attrName) { + if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) { Loc = Tok.getLocation(); return true; } @@ -321,21 +310,6 @@ static unsigned getOwnershipRule(unsigned attr) { ObjCPropertyDecl::OBJC_PR_unsafe_unretained); } -static const char *NameOfOwnershipAttribute(unsigned attr) { - if (attr & ObjCPropertyDecl::OBJC_PR_assign) - return "assign"; - if (attr & ObjCPropertyDecl::OBJC_PR_retain ) - return "retain"; - if (attr & ObjCPropertyDecl::OBJC_PR_copy) - return "copy"; - if (attr & ObjCPropertyDecl::OBJC_PR_weak) - return "weak"; - if (attr & ObjCPropertyDecl::OBJC_PR_strong) - return "strong"; - assert(attr & ObjCPropertyDecl::OBJC_PR_unsafe_unretained); - return "unsafe_unretained"; -} - ObjCPropertyDecl * Sema::HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, @@ -358,15 +332,12 @@ Sema::HandlePropertyInClassExtension(Scope *S, if (CCPrimary) { // Check for duplicate declaration of this property in current and // other class extensions. - for (ObjCInterfaceDecl::known_extensions_iterator - Ext = CCPrimary->known_extensions_begin(), - ExtEnd = CCPrimary->known_extensions_end(); - Ext != ExtEnd; ++Ext) { + for (const auto *Ext : CCPrimary->known_extensions()) { if (ObjCPropertyDecl *prevDecl - = ObjCPropertyDecl::findPropertyDecl(*Ext, PropertyId)) { + = ObjCPropertyDecl::findPropertyDecl(Ext, PropertyId)) { Diag(AtLoc, diag::err_duplicate_property); Diag(prevDecl->getLocation(), diag::note_property_declare); - return 0; + return nullptr; } } } @@ -398,7 +369,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, if (!CCPrimary) { Diag(CDecl->getLocation(), diag::err_continuation_class); *isOverridingProperty = true; - return 0; + return nullptr; } // Find the property in continuation class's primary class only. @@ -416,12 +387,14 @@ Sema::HandlePropertyInClassExtension(Scope *S, // A case of continuation class adding a new property in the class. This // is not what it was meant for. However, gcc supports it and so should we. // Make sure setter/getters are declared here. - ProcessPropertyDecl(PrimaryPDecl, CCPrimary, /* redeclaredProperty = */ 0, + ProcessPropertyDecl(PrimaryPDecl, CCPrimary, + /* redeclaredProperty = */ nullptr, /* lexicalDC = */ CDecl); PDecl->setGetterMethodDecl(PrimaryPDecl->getGetterMethodDecl()); PDecl->setSetterMethodDecl(PrimaryPDecl->getSetterMethodDecl()); if (ASTMutationListener *L = Context.getASTMutationListener()) - L->AddedObjCPropertyInClassExtension(PrimaryPDecl, /*OrigProp=*/0, CDecl); + L->AddedObjCPropertyInClassExtension(PrimaryPDecl, /*OrigProp=*/nullptr, + CDecl); return PrimaryPDecl; } if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) { @@ -441,7 +414,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, Diag(AtLoc, diag::err_type_mismatch_continuation_class) << PDecl->getType(); Diag(PIDecl->getLocation(), diag::note_property_declare); - return 0; + return nullptr; } } @@ -478,6 +451,18 @@ Sema::HandlePropertyInClassExtension(Scope *S, DeclContext *DC = cast<DeclContext>(CCPrimary); if (!ObjCPropertyDecl::findPropertyDecl(DC, PIDecl->getDeclName().getAsIdentifierInfo())) { + // In mrr mode, 'readwrite' property must have an explicit + // memory attribute. If none specified, select the default (assign). + if (!getLangOpts().ObjCAutoRefCount) { + if (!(PIkind & (ObjCDeclSpec::DQ_PR_assign | + ObjCDeclSpec::DQ_PR_retain | + ObjCDeclSpec::DQ_PR_strong | + ObjCDeclSpec::DQ_PR_copy | + ObjCDeclSpec::DQ_PR_unsafe_unretained | + ObjCDeclSpec::DQ_PR_weak))) + PIkind |= ObjCPropertyDecl::OBJC_PR_assign; + } + // Protocol is not in the primary class. Must build one for it. ObjCDeclSpec ProtocolPropertyODS; // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind @@ -520,7 +505,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, Diag(AtLoc, diag) << CCPrimary->getDeclName(); Diag(PIDecl->getLocation(), diag::note_property_declare); - return 0; + return nullptr; } *isOverridingProperty = true; // Make sure setter decl is synthesized, and added to primary class's list. @@ -565,7 +550,7 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, if (T->isObjCObjectType()) { SourceLocation StarLoc = TInfo->getTypeLoc().getLocEnd(); - StarLoc = PP.getLocForEndOfToken(StarLoc); + StarLoc = getLocForEndOfToken(StarLoc); Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object) << FixItHint::CreateInsertion(StarLoc, "*"); T = Context.getObjCObjectPointerType(T); @@ -763,18 +748,14 @@ DiagnosePropertyMismatchDeclInProtocols(Sema &S, SourceLocation AtLoc, ObjCInterfaceDecl *ClassDecl, ObjCPropertyDecl *Property) { ObjCInterfaceDecl::ProtocolPropertyMap PropMap; - for (ObjCInterfaceDecl::all_protocol_iterator - PI = ClassDecl->all_referenced_protocol_begin(), - E = ClassDecl->all_referenced_protocol_end(); PI != E; ++PI) { - if (const ObjCProtocolDecl *PDecl = (*PI)->getDefinition()) + for (const auto *PI : ClassDecl->all_referenced_protocols()) { + if (const ObjCProtocolDecl *PDecl = PI->getDefinition()) PDecl->collectInheritedProtocolProperties(Property, PropMap); } if (ObjCInterfaceDecl *SDecl = ClassDecl->getSuperClass()) while (SDecl) { - for (ObjCInterfaceDecl::all_protocol_iterator - PI = SDecl->all_referenced_protocol_begin(), - E = SDecl->all_referenced_protocol_end(); PI != E; ++PI) { - if (const ObjCProtocolDecl *PDecl = (*PI)->getDefinition()) + for (const auto *PI : SDecl->all_referenced_protocols()) { + if (const ObjCProtocolDecl *PDecl = PI->getDefinition()) PDecl->collectInheritedProtocolProperties(Property, PropMap); } SDecl = SDecl->getSuperClass(); @@ -824,19 +805,19 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // Make sure we have a context for the property implementation declaration. if (!ClassImpDecl) { Diag(AtLoc, diag::error_missing_property_context); - return 0; + return nullptr; } if (PropertyIvarLoc.isInvalid()) PropertyIvarLoc = PropertyLoc; SourceLocation PropertyDiagLoc = PropertyLoc; if (PropertyDiagLoc.isInvalid()) PropertyDiagLoc = ClassImpDecl->getLocStart(); - ObjCPropertyDecl *property = 0; - ObjCInterfaceDecl* IDecl = 0; + ObjCPropertyDecl *property = nullptr; + ObjCInterfaceDecl *IDecl = nullptr; // Find the class or category class where this property must have // a declaration. - ObjCImplementationDecl *IC = 0; - ObjCCategoryImplDecl* CatImplClass = 0; + ObjCImplementationDecl *IC = nullptr; + ObjCCategoryImplDecl *CatImplClass = nullptr; if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) { IDecl = IC->getClassInterface(); // We always synthesize an interface for an implementation @@ -848,7 +829,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, property = IDecl->FindPropertyDeclaration(PropertyId); if (!property) { Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); - return 0; + return nullptr; } unsigned PIkind = property->getPropertyAttributesAsWritten(); if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic | @@ -865,7 +846,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, if (!CD->IsClassExtension()) { Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName(); Diag(property->getLocation(), diag::note_property_declare); - return 0; + return nullptr; } } if (Synthesize&& @@ -875,9 +856,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, bool ReadWriteProperty = false; // Search into the class extensions and see if 'readonly property is // redeclared 'readwrite', then no warning is to be issued. - for (ObjCInterfaceDecl::known_extensions_iterator - Ext = IDecl->known_extensions_begin(), - ExtEnd = IDecl->known_extensions_end(); Ext != ExtEnd; ++Ext) { + for (auto *Ext : IDecl->known_extensions()) { DeclContext::lookup_result R = Ext->lookup(property->getDeclName()); if (!R.empty()) if (ObjCPropertyDecl *ExtProp = dyn_cast<ObjCPropertyDecl>(R[0])) { @@ -891,7 +870,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, if (!ReadWriteProperty) { Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property) - << property->getName(); + << property; SourceLocation readonlyLoc; if (LocPropertyAttribute(Context, "readonly", property->getLParenLoc(), readonlyLoc)) { @@ -910,12 +889,12 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) { if (Synthesize) { Diag(AtLoc, diag::error_synthesize_category_decl); - return 0; + return nullptr; } IDecl = CatImplClass->getClassInterface(); if (!IDecl) { Diag(AtLoc, diag::error_missing_property_interface); - return 0; + return nullptr; } ObjCCategoryDecl *Category = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); @@ -923,19 +902,19 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // If category for this implementation not found, it is an error which // has already been reported eralier. if (!Category) - return 0; + return nullptr; // Look for this property declaration in @implementation's category property = Category->FindPropertyDeclaration(PropertyId); if (!property) { Diag(PropertyLoc, diag::error_bad_category_property_decl) << Category->getDeclName(); - return 0; + return nullptr; } } else { Diag(AtLoc, diag::error_bad_property_context); - return 0; + return nullptr; } - ObjCIvarDecl *Ivar = 0; + ObjCIvarDecl *Ivar = nullptr; bool CompleteTypeErr = false; bool compat = true; // Check that we have a valid, previously declared ivar for @synthesize @@ -983,14 +962,14 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // an ivar matching property name and issue warning; since this // is the most common case of not using an ivar used for backing // property in non-default synthesis case. - ObjCInterfaceDecl *ClassDeclared=0; + ObjCInterfaceDecl *ClassDeclared=nullptr; ObjCIvarDecl *originalIvar = IDecl->lookupInstanceVariable(property->getIdentifier(), ClassDeclared); if (originalIvar) { Diag(PropertyDiagLoc, diag::warn_autosynthesis_property_ivar_match) - << PropertyId << (Ivar == 0) << PropertyIvar + << PropertyId << (Ivar == nullptr) << PropertyIvar << originalIvar->getIdentifier(); Diag(property->getLocation(), diag::note_property_declare); Diag(originalIvar->getLocation(), diag::note_ivar_decl); @@ -1049,9 +1028,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyIvarLoc,PropertyIvarLoc, PropertyIvar, - PropertyIvarType, /*Dinfo=*/0, + PropertyIvarType, /*Dinfo=*/nullptr, ObjCIvarDecl::Private, - (Expr *)0, true); + (Expr *)nullptr, true); if (RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType, diag::err_abstract_type_in_decl, @@ -1163,21 +1142,23 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(), - VK_RValue, PropertyDiagLoc); + VK_LValue, PropertyDiagLoc); MarkDeclRefReferenced(SelfExpr); + Expr *LoadSelfExpr = + ImplicitCastExpr::Create(Context, SelfDecl->getType(), + CK_LValueToRValue, SelfExpr, nullptr, + VK_RValue); Expr *IvarRefExpr = new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc, Ivar->getLocation(), - SelfExpr, true, true); - ExprResult Res = - PerformCopyInitialization(InitializedEntity::InitializeResult( - PropertyDiagLoc, - getterMethod->getResultType(), - /*NRVO=*/false), - PropertyDiagLoc, - Owned(IvarRefExpr)); + LoadSelfExpr, true, true); + ExprResult Res = PerformCopyInitialization( + InitializedEntity::InitializeResult(PropertyDiagLoc, + getterMethod->getReturnType(), + /*NRVO=*/false), + PropertyDiagLoc, IvarRefExpr); if (!Res.isInvalid()) { - Expr *ResExpr = Res.takeAs<Expr>(); + Expr *ResExpr = Res.getAs<Expr>(); if (ResExpr) ResExpr = MaybeCreateExprWithCleanups(ResExpr); PIDecl->setGetterCXXConstructor(ResExpr); @@ -1211,12 +1192,16 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(), - VK_RValue, PropertyDiagLoc); + VK_LValue, PropertyDiagLoc); MarkDeclRefReferenced(SelfExpr); + Expr *LoadSelfExpr = + ImplicitCastExpr::Create(Context, SelfDecl->getType(), + CK_LValueToRValue, SelfExpr, nullptr, + VK_RValue); Expr *lhs = new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc, Ivar->getLocation(), - SelfExpr, true, true); + LoadSelfExpr, true, true); ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); ParmVarDecl *Param = (*P); QualType T = Param->getType().getNonReferenceType(); @@ -1227,7 +1212,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, BO_Assign, lhs, rhs); if (property->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic) { - Expr *callExpr = Res.takeAs<Expr>(); + Expr *callExpr = Res.getAs<Expr>(); if (const CXXOperatorCallExpr *CXXCE = dyn_cast_or_null<CXXOperatorCallExpr>(callExpr)) if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee()) @@ -1240,7 +1225,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, diag::note_callee_decl) << FuncDecl; } } - PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>()); + PIDecl->setSetterCXXAssignment(Res.getAs<Expr>()); } } @@ -1258,7 +1243,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, = IC->FindPropertyImplDecl(PropertyId)) { Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; Diag(PPIDecl->getLocation(), diag::note_previous_declaration); - return 0; + return nullptr; } IC->addPropertyImplementation(PIDecl); if (getLangOpts().ObjCDefaultSynthProperties && @@ -1267,8 +1252,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // Diagnose if an ivar was lazily synthesdized due to a previous // use and if 1) property is @dynamic or 2) property is synthesized // but it requires an ivar of different name. - ObjCInterfaceDecl *ClassDeclared=0; - ObjCIvarDecl *Ivar = 0; + ObjCInterfaceDecl *ClassDeclared=nullptr; + ObjCIvarDecl *Ivar = nullptr; if (!Synthesize) Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); else { @@ -1297,7 +1282,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, CatImplClass->FindPropertyImplDecl(PropertyId)) { Diag(PropertyDiagLoc, diag::error_property_implemented) << PropertyId; Diag(PPIDecl->getLocation(), diag::note_previous_declaration); - return 0; + return nullptr; } CatImplClass->addPropertyImplementation(PIDecl); } @@ -1394,7 +1379,7 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, SourceLocation Loc) { if (!GetterMethod) return false; - QualType GetterType = GetterMethod->getResultType().getNonReferenceType(); + QualType GetterType = GetterMethod->getReturnType().getNonReferenceType(); QualType PropertyIvarType = property->getType().getNonReferenceType(); bool compat = Context.hasSameType(PropertyIvarType, GetterType); if (!compat) { @@ -1433,37 +1418,32 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, /// CollectImmediateProperties - This routine collects all properties in /// the class and its conforming protocols; but not those in its super class. -void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, - ObjCContainerDecl::PropertyMap &PropMap, - ObjCContainerDecl::PropertyMap &SuperPropMap) { +static void CollectImmediateProperties(ObjCContainerDecl *CDecl, + ObjCContainerDecl::PropertyMap &PropMap, + ObjCContainerDecl::PropertyMap &SuperPropMap, + bool IncludeProtocols = true) { + if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { - for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), - E = IDecl->prop_end(); P != E; ++P) { - ObjCPropertyDecl *Prop = *P; + for (auto *Prop : IDecl->properties()) PropMap[Prop->getIdentifier()] = Prop; + if (IncludeProtocols) { + // Scan through class's protocols. + for (auto *PI : IDecl->all_referenced_protocols()) + CollectImmediateProperties(PI, PropMap, SuperPropMap); } - // scan through class's protocols. - for (ObjCInterfaceDecl::all_protocol_iterator - PI = IDecl->all_referenced_protocol_begin(), - E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) - CollectImmediateProperties((*PI), PropMap, SuperPropMap); } if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { if (!CATDecl->IsClassExtension()) - for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(), - E = CATDecl->prop_end(); P != E; ++P) { - ObjCPropertyDecl *Prop = *P; + for (auto *Prop : CATDecl->properties()) PropMap[Prop->getIdentifier()] = Prop; - } - // scan through class's protocols. - for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(), - E = CATDecl->protocol_end(); PI != E; ++PI) - CollectImmediateProperties((*PI), PropMap, SuperPropMap); + if (IncludeProtocols) { + // Scan through class's protocols. + for (auto *PI : CATDecl->protocols()) + CollectImmediateProperties(PI, PropMap, SuperPropMap); + } } else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { - for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), - E = PDecl->prop_end(); P != E; ++P) { - ObjCPropertyDecl *Prop = *P; + for (auto *Prop : PDecl->properties()) { ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()]; // Exclude property for protocols which conform to class's super-class, // as super-class has to implement the property. @@ -1475,9 +1455,8 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, } } // scan through protocol's protocols. - for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), - E = PDecl->protocol_end(); PI != E; ++PI) - CollectImmediateProperties((*PI), PropMap, SuperPropMap); + for (auto *PI : PDecl->protocols()) + CollectImmediateProperties(PI, PropMap, SuperPropMap); } } @@ -1510,17 +1489,35 @@ Sema::IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, // look up a property declaration whose one of its accessors is implemented // by this method. - for (ObjCContainerDecl::prop_iterator P = IFace->prop_begin(), - E = IFace->prop_end(); P != E; ++P) { - ObjCPropertyDecl *property = *P; - if ((property->getGetterName() == IMD->getSelector() || - property->getSetterName() == IMD->getSelector()) && - (property->getPropertyIvarDecl() == IV)) + for (const auto *Property : IFace->properties()) { + if ((Property->getGetterName() == IMD->getSelector() || + Property->getSetterName() == IMD->getSelector()) && + (Property->getPropertyIvarDecl() == IV)) return true; } return false; } +static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, + ObjCPropertyDecl *Prop) { + bool SuperClassImplementsGetter = false; + bool SuperClassImplementsSetter = false; + if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) + SuperClassImplementsSetter = true; + + while (IDecl->getSuperClass()) { + ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); + if (!SuperClassImplementsGetter && SDecl->getInstanceMethod(Prop->getGetterName())) + SuperClassImplementsGetter = true; + + if (!SuperClassImplementsSetter && SDecl->getInstanceMethod(Prop->getSetterName())) + SuperClassImplementsSetter = true; + if (SuperClassImplementsGetter && SuperClassImplementsSetter) + return true; + IDecl = IDecl->getSuperClass(); + } + return false; +} /// \brief Default synthesizes all properties which must be synthesized /// in class's \@implementation. @@ -1559,7 +1556,7 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl, !IMPDecl->getInstanceMethod(Prop->getSetterName()) && !IDecl->HasUserDeclaredSetterMethod(Prop)) { Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property) - << Prop->getIdentifier()->getName(); + << Prop->getIdentifier(); Diag(PropInSuperClass->getLocation(), diag::note_property_declare); } continue; @@ -1568,17 +1565,23 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl, IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) { if (PID->getPropertyDecl() != Prop) { Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property) - << Prop->getIdentifier()->getName(); + << Prop->getIdentifier(); if (!PID->getLocation().isInvalid()) Diag(PID->getLocation(), diag::note_property_synthesize); } continue; } - if (isa<ObjCProtocolDecl>(Prop->getDeclContext())) { + if (ObjCProtocolDecl *Proto = + dyn_cast<ObjCProtocolDecl>(Prop->getDeclContext())) { // We won't auto-synthesize properties declared in protocols. - Diag(IMPDecl->getLocation(), - diag::warn_auto_synthesizing_protocol_property); - Diag(Prop->getLocation(), diag::note_property_declare); + // Suppress the warning if class's superclass implements property's + // getter and implements property's setter (if readwrite property). + if (!SuperClassImplementsProperty(IDecl, Prop)) { + Diag(IMPDecl->getLocation(), + diag::warn_auto_synthesizing_protocol_property) + << Prop << Proto; + Diag(Prop->getLocation(), diag::note_property_declare); + } continue; } @@ -1610,44 +1613,108 @@ void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D) { DefaultSynthesizeProperties(S, IC, IDecl); } +static void DiagnoseUnimplementedAccessor(Sema &S, + ObjCInterfaceDecl *PrimaryClass, + Selector Method, + ObjCImplDecl* IMPDecl, + ObjCContainerDecl *CDecl, + ObjCCategoryDecl *C, + ObjCPropertyDecl *Prop, + Sema::SelectorSet &SMap) { + // When reporting on missing property setter/getter implementation in + // categories, do not report when they are declared in primary class, + // class's protocol, or one of it super classes. This is because, + // the class is going to implement them. + if (!SMap.count(Method) && + (PrimaryClass == nullptr || + !PrimaryClass->lookupPropertyAccessor(Method, C))) { + S.Diag(IMPDecl->getLocation(), + isa<ObjCCategoryDecl>(CDecl) ? + diag::warn_setter_getter_impl_required_in_category : + diag::warn_setter_getter_impl_required) + << Prop->getDeclName() << Method; + S.Diag(Prop->getLocation(), + diag::note_property_declare); + if (S.LangOpts.ObjCDefaultSynthProperties && + S.LangOpts.ObjCRuntime.isNonFragile()) + if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl)) + if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs()) + S.Diag(RID->getLocation(), diag::note_suppressed_class_declare); + } +} + void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, - ObjCContainerDecl *CDecl) { - ObjCContainerDecl::PropertyMap NoNeedToImplPropMap; - ObjCInterfaceDecl *IDecl; - // Gather properties which need not be implemented in this class - // or category. - if (!(IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))) - if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) { - // For categories, no need to implement properties declared in - // its primary class (and its super classes) if property is - // declared in one of those containers. - if ((IDecl = C->getClassInterface())) { - ObjCInterfaceDecl::PropertyDeclOrder PO; - IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO); + ObjCContainerDecl *CDecl, + bool SynthesizeProperties) { + ObjCContainerDecl::PropertyMap PropMap; + ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl); + + if (!SynthesizeProperties) { + ObjCContainerDecl::PropertyMap NoNeedToImplPropMap; + // Gather properties which need not be implemented in this class + // or category. + if (!IDecl) + if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) { + // For categories, no need to implement properties declared in + // its primary class (and its super classes) if property is + // declared in one of those containers. + if ((IDecl = C->getClassInterface())) { + ObjCInterfaceDecl::PropertyDeclOrder PO; + IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO); + } + } + if (IDecl) + CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap); + + CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap); + } + + // Scan the @interface to see if any of the protocols it adopts + // require an explicit implementation, via attribute + // 'objc_protocol_requires_explicit_implementation'. + if (IDecl) { + std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap; + + for (auto *PDecl : IDecl->all_referenced_protocols()) { + if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) + continue; + // Lazily construct a set of all the properties in the @interface + // of the class, without looking at the superclass. We cannot + // use the call to CollectImmediateProperties() above as that + // utilizes information from the super class's properties as well + // as scans the adopted protocols. This work only triggers for protocols + // with the attribute, which is very rare, and only occurs when + // analyzing the @implementation. + if (!LazyMap) { + ObjCContainerDecl::PropertyMap NoNeedToImplPropMap; + LazyMap.reset(new ObjCContainerDecl::PropertyMap()); + CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap, + /* IncludeProtocols */ false); + } + // Add the properties of 'PDecl' to the list of properties that + // need to be implemented. + for (auto *PropDecl : PDecl->properties()) { + if ((*LazyMap)[PropDecl->getIdentifier()]) + continue; + PropMap[PropDecl->getIdentifier()] = PropDecl; } } - if (IDecl) - CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap); - - ObjCContainerDecl::PropertyMap PropMap; - CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap); + } + if (PropMap.empty()) return; llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; - for (ObjCImplDecl::propimpl_iterator - I = IMPDecl->propimpl_begin(), - EI = IMPDecl->propimpl_end(); I != EI; ++I) + for (const auto *I : IMPDecl->property_impls()) PropImplMap.insert(I->getPropertyDecl()); SelectorSet InsMap; // Collect property accessors implemented in current implementation. - for (ObjCImplementationDecl::instmeth_iterator - I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I) - InsMap.insert((*I)->getSelector()); + for (const auto *I : IMPDecl->instance_methods()) + InsMap.insert(I->getSelector()); ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl); - ObjCInterfaceDecl *PrimaryClass = 0; + ObjCInterfaceDecl *PrimaryClass = nullptr; if (C && !C->IsClassExtension()) if ((PrimaryClass = C->getClassInterface())) // Report unimplemented properties in the category as well. @@ -1655,9 +1722,8 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, // When reporting on missing setter/getters, do not report when // setter/getter is implemented in category's primary class // implementation. - for (ObjCImplementationDecl::instmeth_iterator - I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I) - InsMap.insert((*I)->getSelector()); + for (const auto *I : IMP->instance_methods()) + InsMap.insert(I->getSelector()); } for (ObjCContainerDecl::PropertyMap::iterator @@ -1669,45 +1735,14 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, PropImplMap.count(Prop) || Prop->getAvailability() == AR_Unavailable) continue; - // When reporting on missing property getter implementation in - // categories, do not report when they are declared in primary class, - // class's protocol, or one of it super classes. This is because, - // the class is going to implement them. - if (!InsMap.count(Prop->getGetterName()) && - (PrimaryClass == 0 || - !PrimaryClass->lookupPropertyAccessor(Prop->getGetterName(), C))) { - Diag(IMPDecl->getLocation(), - isa<ObjCCategoryDecl>(CDecl) ? - diag::warn_setter_getter_impl_required_in_category : - diag::warn_setter_getter_impl_required) - << Prop->getDeclName() << Prop->getGetterName(); - Diag(Prop->getLocation(), - diag::note_property_declare); - if (LangOpts.ObjCDefaultSynthProperties && LangOpts.ObjCRuntime.isNonFragile()) - if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl)) - if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs()) - Diag(RID->getLocation(), diag::note_suppressed_class_declare); - - } - // When reporting on missing property setter implementation in - // categories, do not report when they are declared in primary class, - // class's protocol, or one of it super classes. This is because, - // the class is going to implement them. - if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName()) && - (PrimaryClass == 0 || - !PrimaryClass->lookupPropertyAccessor(Prop->getSetterName(), C))) { - Diag(IMPDecl->getLocation(), - isa<ObjCCategoryDecl>(CDecl) ? - diag::warn_setter_getter_impl_required_in_category : - diag::warn_setter_getter_impl_required) - << Prop->getDeclName() << Prop->getSetterName(); - Diag(Prop->getLocation(), - diag::note_property_declare); - if (LangOpts.ObjCDefaultSynthProperties && LangOpts.ObjCRuntime.isNonFragile()) - if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl)) - if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs()) - Diag(RID->getLocation(), diag::note_suppressed_class_declare); - } + + // Diagnose unimplemented getters and setters. + DiagnoseUnimplementedAccessor(*this, + PrimaryClass, Prop->getGetterName(), IMPDecl, CDecl, C, Prop, InsMap); + if (!Prop->isReadOnly()) + DiagnoseUnimplementedAccessor(*this, + PrimaryClass, Prop->getSetterName(), + IMPDecl, CDecl, C, Prop, InsMap); } } @@ -1717,12 +1752,9 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, // Rules apply in non-GC mode only if (getLangOpts().getGC() != LangOptions::NonGC) return; - for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), - E = IDecl->prop_end(); - I != E; ++I) { - ObjCPropertyDecl *Property = *I; - ObjCMethodDecl *GetterMethod = 0; - ObjCMethodDecl *SetterMethod = 0; + for (const auto *Property : IDecl->properties()) { + ObjCMethodDecl *GetterMethod = nullptr; + ObjCMethodDecl *SetterMethod = nullptr; bool LookedUpGetterSetter = false; unsigned Attributes = Property->getPropertyAttributes(); @@ -1758,15 +1790,14 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, if (!LookedUpGetterSetter) { GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); - LookedUpGetterSetter = true; } if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { SourceLocation MethodLoc = (GetterMethod ? GetterMethod->getLocation() : SetterMethod->getLocation()); Diag(MethodLoc, diag::warn_atomic_property_rule) - << Property->getIdentifier() << (GetterMethod != 0) - << (SetterMethod != 0); + << Property->getIdentifier() << (GetterMethod != nullptr) + << (SetterMethod != nullptr); // fixit stuff. if (!AttributesAsWritten) { if (Property->getLParenLoc().isValid()) { @@ -1805,12 +1836,7 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D if (getLangOpts().getGC() == LangOptions::GCOnly) return; - for (ObjCImplementationDecl::propimpl_iterator - i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) { - ObjCPropertyImplDecl *PID = *i; - if (PID->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) - continue; - + for (const auto *PID : D->property_impls()) { const ObjCPropertyDecl *PD = PID->getPropertyDecl(); if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() && !D->getInstanceMethod(PD->getGetterName())) { @@ -1821,27 +1847,51 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D if (family == OMF_alloc || family == OMF_copy || family == OMF_mutableCopy || family == OMF_new) { if (getLangOpts().ObjCAutoRefCount) - Diag(PID->getLocation(), diag::err_ownin_getter_rule); + Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule); else - Diag(PID->getLocation(), diag::warn_owning_getter_rule); - Diag(PD->getLocation(), diag::note_property_declare); + Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule); } } } } +void Sema::DiagnoseMissingDesignatedInitOverrides( + const ObjCImplementationDecl *ImplD, + const ObjCInterfaceDecl *IFD) { + assert(IFD->hasDesignatedInitializers()); + const ObjCInterfaceDecl *SuperD = IFD->getSuperClass(); + if (!SuperD) + return; + + SelectorSet InitSelSet; + for (const auto *I : ImplD->instance_methods()) + if (I->getMethodFamily() == OMF_init) + InitSelSet.insert(I->getSelector()); + + SmallVector<const ObjCMethodDecl *, 8> DesignatedInits; + SuperD->getDesignatedInitializers(DesignatedInits); + for (SmallVector<const ObjCMethodDecl *, 8>::iterator + I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) { + const ObjCMethodDecl *MD = *I; + if (!InitSelSet.count(MD->getSelector())) { + Diag(ImplD->getLocation(), + diag::warn_objc_implementation_missing_designated_init_override) + << MD->getSelector(); + Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here); + } + } +} + /// AddPropertyAttrs - Propagates attributes from a property to the /// implicitly-declared getter or setter for that property. static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, ObjCPropertyDecl *Property) { // Should we just clone all attributes over? - for (Decl::attr_iterator A = Property->attr_begin(), - AEnd = Property->attr_end(); - A != AEnd; ++A) { - if (isa<DeprecatedAttr>(*A) || - isa<UnavailableAttr>(*A) || - isa<AvailabilityAttr>(*A)) - PropertyMethod->addAttr((*A)->clone(S.Context)); + for (const auto *A : Property->attrs()) { + if (isa<DeprecatedAttr>(A) || + isa<UnavailableAttr>(A) || + isa<AvailabilityAttr>(A)) + PropertyMethod->addAttr(A->clone(S.Context)); } } @@ -1857,6 +1907,9 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCMethodDecl *GetterMethod, *SetterMethod; + if (CD->isInvalidDecl()) + return; + GetterMethod = CD->getInstanceMethod(property->getGetterName()); SetterMethod = CD->getInstanceMethod(property->getSetterName()); DiagnosePropertyAccessorMismatch(property, GetterMethod, @@ -1866,8 +1919,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCPropertyDecl::PropertyAttributeKind CAttr = property->getPropertyAttributes(); if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && - Context.getCanonicalType(SetterMethod->getResultType()) != - Context.VoidTy) + Context.getCanonicalType(SetterMethod->getReturnType()) != + Context.VoidTy) Diag(SetterMethod->getLocation(), diag::err_setter_type_void); if (SetterMethod->param_size() != 1 || !Context.hasSameUnqualifiedType( @@ -1897,8 +1950,9 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, property->getGetterName(), - property->getType(), 0, CD, /*isInstance=*/true, - /*isVariadic=*/false, /*isPropertyAccessor=*/true, + property->getType(), nullptr, CD, + /*isInstance=*/true, /*isVariadic=*/false, + /*isPropertyAccessor=*/true, /*isImplicitlyDeclared=*/true, /*isDefined=*/false, (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) ? @@ -1913,12 +1967,17 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, if (lexicalDC) GetterMethod->setLexicalDeclContext(lexicalDC); if (property->hasAttr<NSReturnsNotRetainedAttr>()) - GetterMethod->addAttr( - ::new (Context) NSReturnsNotRetainedAttr(Loc, Context)); + GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context, + Loc)); if (property->hasAttr<ObjCReturnsInnerPointerAttr>()) GetterMethod->addAttr( - ::new (Context) ObjCReturnsInnerPointerAttr(Loc, Context)); + ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc)); + + if (const SectionAttr *SA = property->getAttr<SectionAttr>()) + GetterMethod->addAttr( + SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section, + SA->getName(), Loc)); if (getLangOpts().ObjCAutoRefCount) CheckARCMethodDecl(GetterMethod); @@ -1941,8 +2000,9 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, SetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, - property->getSetterName(), Context.VoidTy, 0, - CD, /*isInstance=*/true, /*isVariadic=*/false, + property->getSetterName(), Context.VoidTy, + nullptr, CD, /*isInstance=*/true, + /*isVariadic=*/false, /*isPropertyAccessor=*/true, /*isImplicitlyDeclared=*/true, /*isDefined=*/false, @@ -1957,9 +2017,9 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, Loc, Loc, property->getIdentifier(), property->getType().getUnqualifiedType(), - /*TInfo=*/0, + /*TInfo=*/nullptr, SC_None, - 0); + nullptr); SetterMethod->setMethodParams(Context, Argument, None); AddPropertyAttrs(*this, SetterMethod, property); @@ -1969,7 +2029,10 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, // and the real context should be the same. if (lexicalDC) SetterMethod->setLexicalDeclContext(lexicalDC); - + if (const SectionAttr *SA = property->getAttr<SectionAttr>()) + SetterMethod->addAttr( + SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section, + SA->getName(), Loc)); // It's possible for the user to have set a very odd custom // setter selector that causes it to have a method family. if (getLangOpts().ObjCAutoRefCount) @@ -2027,27 +2090,19 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl, QualType PropertyTy = PropertyDecl->getType(); unsigned PropertyOwnership = getOwnershipRule(Attributes); - if (Attributes & ObjCDeclSpec::DQ_PR_readonly) { - if (getLangOpts().ObjCAutoRefCount && - PropertyTy->isObjCRetainableType() && - !PropertyOwnership) { - // 'readonly' property with no obvious lifetime. - // its life time will be determined by its backing ivar. - return; - } - else if (PropertyOwnership) { - if (!getSourceManager().isInSystemHeader(Loc)) - Diag(Loc, diag::warn_objc_property_attr_mutually_exclusive) - << "readonly" << NameOfOwnershipAttribute(Attributes); - return; - } - } + // 'readonly' property with no obvious lifetime. + // its life time will be determined by its backing ivar. + if (getLangOpts().ObjCAutoRefCount && + Attributes & ObjCDeclSpec::DQ_PR_readonly && + PropertyTy->isObjCRetainableType() && + !PropertyOwnership) + return; // Check for copy or retain on non-object types. if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) && !PropertyTy->isObjCRetainableType() && - !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { + !PropertyDecl->hasAttr<ObjCNSObjectAttr>()) { Diag(Loc, diag::err_objc_property_requires_object) << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" : Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)"); @@ -2079,7 +2134,7 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl, << "assign" << "weak"; Attributes &= ~ObjCDeclSpec::DQ_PR_weak; } - if (PropertyDecl->getAttr<IBOutletCollectionAttr>()) + if (PropertyDecl->hasAttr<IBOutletCollectionAttr>()) Diag(Loc, diag::warn_iboutletcollection_property_assign); } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) { if (Attributes & ObjCDeclSpec::DQ_PR_copy) { |