1accaf19bc1129c0273ec50dba52318e60bc29103Benjamin Kramer//===--- TransProperties.cpp - Transformations to ARC mode ----------------===// 27196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 37196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 47196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 57196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 67196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 77196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 87196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 97196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 1014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis// rewriteProperties: 117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 1214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis// - Adds strong/weak/unsafe_unretained ownership specifier to properties that 1314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis// are missing one. 1414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis// - Migrates properties from (retain) to (strong) and (assign) to 1514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis// (unsafe_unretained/weak). 1614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis// - If a property is synthesized, adds the ownership specifier in the ivar 1714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis// backing the property. 187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// @interface Foo : NSObject { 207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// NSObject *x; 217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// } 227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// @property (assign) id x; 237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// @end 247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// ----> 257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// @interface Foo : NSObject { 267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// NSObject *__weak x; 277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// } 287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// @property (weak) id x; 297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// @end 307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis// 317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Transforms.h" 347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "Internals.h" 357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h" 367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Lex/Lexer.h" 3755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/SemaDiagnostic.h" 3814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#include <map> 397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace clang; 417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace arcmt; 427196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisusing namespace trans; 437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidisnamespace { 457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 4614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidisclass PropertiesRewriter { 47b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis MigrationContext &MigrateCtx; 487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis MigrationPass &Pass; 4918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCImplementationDecl *CurImplD; 5044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 5144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis enum PropActionKind { 5244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_None, 5386f960143c73f573919255c4465de71f85793c2eFariborz Jahanian PropAction_RetainReplacedWithStrong, 54b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis PropAction_AssignRemoved, 5544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_AssignRewritten, 5644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_MaybeAddWeakOrUnsafe 5744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis }; 5814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis struct PropData { 607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyDecl *PropD; 617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCIvarDecl *IvarD; 6214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyImplDecl *ImplD; 6314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PropData(ObjCPropertyDecl *propD) 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : PropD(propD), IvarD(nullptr), ImplD(nullptr) {} 667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis }; 677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVector<PropData, 2> PropsTy; 6914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis typedef std::map<unsigned, PropsTy> AtPropDeclsTy; 7014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis AtPropDeclsTy AtProps; 7144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis llvm::DenseMap<IdentifierInfo *, PropActionKind> ActionOnProp; 727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic: 74b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis explicit PropertiesRewriter(MigrationContext &MigrateCtx) 75b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { } 767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 770fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps, 786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AtPropDeclsTy *PrevAtProps = nullptr) { 79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Prop : D->properties()) { 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Prop->getAtLoc().isInvalid()) 8114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned RawLoc = Prop->getAtLoc().getRawEncoding(); 830fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis if (PrevAtProps) 840fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis if (PrevAtProps->find(RawLoc) != PrevAtProps->end()) 850fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis continue; 860fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis PropsTy &props = AtProps[RawLoc]; 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines props.push_back(Prop); 887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 8944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 9044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 9144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doTransform(ObjCImplementationDecl *D) { 9244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis CurImplD = D; 9344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis ObjCInterfaceDecl *iface = D->getClassInterface(); 9444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (!iface) 9544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 9644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 9744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis collectProperties(iface, AtProps); 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl> 1007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis prop_impl_iterator; 1017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (prop_impl_iterator 1027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = prop_impl_iterator(D->decls_begin()), 1037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = prop_impl_iterator(D->decls_end()); I != E; ++I) { 104581deb3da481053c4993c7600f97acf7768caac5David Blaikie ObjCPropertyImplDecl *implD = *I; 10514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 10614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 10714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl *propD = implD->getPropertyDecl(); 10814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!propD || propD->isInvalidDecl()) 10914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCIvarDecl *ivarD = implD->getPropertyIvarDecl(); 11114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!ivarD || ivarD->isInvalidDecl()) 11214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis unsigned rawAtLoc = propD->getAtLoc().getRawEncoding(); 11414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis AtPropDeclsTy::iterator findAtLoc = AtProps.find(rawAtLoc); 11514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (findAtLoc == AtProps.end()) 11614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 11814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropsTy &props = findAtLoc->second; 11914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 12014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->PropD == propD) { 12114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->IvarD = ivarD; 12214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD = implD; 12314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis break; 12414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 12514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 1267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 12814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (AtPropDeclsTy::iterator 12914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { 1307196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first); 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis PropsTy &props = I->second; 1321d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis if (!getPropertyType(props)->isObjCRetainableType()) 13314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 134bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (hasIvarWithExplicitARCOwnership(props)) 13514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 13614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 13714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Transaction Trans(Pass.TA); 13814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis rewriteProperty(props, atLoc); 1397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 14044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 14144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis AtPropDeclsTy AtExtProps; 14244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis // Look through extensions. 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Ext : iface->visible_extensions()) 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines collectProperties(Ext, AtExtProps, &AtProps); 14544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 14644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (AtPropDeclsTy::iterator 14744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) { 14844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first); 14944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropsTy &props = I->second; 15044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis Transaction Trans(Pass.TA); 15144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis doActionForExtensionProp(props, atLoc); 15244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 1537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 15514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidisprivate: 15644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doPropAction(PropActionKind kind, 15744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropsTy &props, SourceLocation atLoc, 15844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis bool markAction = true) { 15944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (markAction) 16044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 16144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis ActionOnProp[I->PropD->getIdentifier()] = kind; 16244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 16344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis switch (kind) { 16444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_None: 16544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 16686f960143c73f573919255c4465de71f85793c2eFariborz Jahanian case PropAction_RetainReplacedWithStrong: { 16786f960143c73f573919255c4465de71f85793c2eFariborz Jahanian StringRef toAttr = "strong"; 16886f960143c73f573919255c4465de71f85793c2eFariborz Jahanian MigrateCtx.rewritePropertyAttribute("retain", toAttr, atLoc); 16944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 17086f960143c73f573919255c4465de71f85793c2eFariborz Jahanian } 171b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis case PropAction_AssignRemoved: 172b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return removeAssignForDefaultStrong(props, atLoc); 17344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_AssignRewritten: 17444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return rewriteAssign(props, atLoc); 17544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_MaybeAddWeakOrUnsafe: 17644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc); 17744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 17844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 17944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 18044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doActionForExtensionProp(PropsTy &props, SourceLocation atLoc) { 18144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis llvm::DenseMap<IdentifierInfo *, PropActionKind>::iterator I; 18244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis I = ActionOnProp.find(props[0].PropD->getIdentifier()); 18344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (I == ActionOnProp.end()) 18444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 18544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 18644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis doPropAction(I->second, props, atLoc, false); 18744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 18844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 18944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void rewriteProperty(PropsTy &props, SourceLocation atLoc) { 19014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props); 19114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 19214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propAttrs & (ObjCPropertyDecl::OBJC_PR_copy | 19314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_unsafe_unretained | 19414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_strong | 19514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_weak)) 19614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return; 19714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 19814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_retain) { 1998b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis // strong is the default. 20086f960143c73f573919255c4465de71f85793c2eFariborz Jahanian return doPropAction(PropAction_RetainReplacedWithStrong, props, atLoc); 2017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 20214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 203b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props); 204b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 20518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_assign) { 2062f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian if (HasIvarAssignedAPlusOneObject) 207b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return doPropAction(PropAction_AssignRemoved, props, atLoc); 20844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_AssignRewritten, props, atLoc); 20918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 21018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 211b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (HasIvarAssignedAPlusOneObject || 212b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) 213af9b5e9f3eede62347835d8dedd44df86cbcc308Argyrios Kyrtzidis return; // 'strong' by default. 21414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 21544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc); 2167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 218b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis void removeAssignForDefaultStrong(PropsTy &props, 219b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation atLoc) const { 220b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis removeAttribute("retain", atLoc); 221b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!removeAttribute("assign", atLoc)) 222b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return; 223b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 224b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 225b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (I->ImplD) 226135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, 227135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis diag::err_arc_assign_property_ownership, 228135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis diag::err_arc_inconsistent_property_ownership, 229135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis I->IvarD->getLocation()); 230b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 231b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 232b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 23314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void rewriteAssign(PropsTy &props, SourceLocation atLoc) const { 234b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 235b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 2362f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian const char *toWhich = 2372f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "strong" : 2382f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (canUseWeak ? "weak" : "unsafe_unretained"); 23914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 2402f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian bool rewroteAttr = rewriteAttribute("assign", toWhich, atLoc); 24114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!rewroteAttr) 24214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak = false; 2437196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 24414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 2456d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 2466d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (I->IvarD && 2472f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) { 2482f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian const char *toWhich = 2492f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "__strong " : 2502f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (canUseWeak ? "__weak " : "__unsafe_unretained "); 2512f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian Pass.TA.insert(I->IvarD->getLocation(), toWhich); 2522f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian } 2536d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis } 25414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) 255135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, 256135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis diag::err_arc_assign_property_ownership, 257135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis diag::err_arc_inconsistent_property_ownership, 258135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis I->IvarD->getLocation()); 25914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 2607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 26214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void maybeAddWeakOrUnsafeUnretainedAttr(PropsTy &props, 26314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 264b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 265b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 2668b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis 2678b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained", 2688b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis atLoc); 2698b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis if (!addedAttr) 2708b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis canUseWeak = false; 27114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 27214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 2736d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 2746d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (I->IvarD && 2756d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) 2766d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis Pass.TA.insert(I->IvarD->getLocation(), 2776d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis canUseWeak ? "__weak " : "__unsafe_unretained "); 2786d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis } 27914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) { 280135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, 281135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis diag::err_arc_assign_property_ownership, 282135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis diag::err_arc_inconsistent_property_ownership, 283135aa60c613bdcc0e8e237b12bf93cab04284419Argyrios Kyrtzidis I->IvarD->getLocation()); 28414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.clearDiagnostic( 28514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis diag::err_arc_objc_property_default_assign_on_object, 28614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 2877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 29101b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis bool removeAttribute(StringRef fromAttr, SourceLocation atLoc) const { 2926da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return MigrateCtx.removePropertyAttribute(fromAttr, atLoc); 29301b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis } 29401b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis 2955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool rewriteAttribute(StringRef fromAttr, StringRef toAttr, 29614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 297b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc); 2987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool addAttribute(StringRef attr, SourceLocation atLoc) const { 3016da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return MigrateCtx.addPropertyAttribute(attr, atLoc); 30214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 30314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 30418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis class PlusOneAssign : public RecursiveASTVisitor<PlusOneAssign> { 30518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCIvarDecl *Ivar; 30618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis public: 30718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {} 30818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 30918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool VisitBinAssign(BinaryOperator *E) { 31018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Expr *lhs = E->getLHS()->IgnoreParenImpCasts(); 31118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(lhs)) { 31218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (RE->getDecl() != Ivar) 31318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 31418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 3151b8fbd3601e009803565e74d2ec54abecb5cbf73Argyrios Kyrtzidis if (isPlusOneAssign(E)) 31694a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis return false; 31718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 31818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 31918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 32018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 32118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis }; 32218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 32318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool hasIvarAssignedAPlusOneObject(PropsTy &props) const { 32418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 32518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign oneAssign(I->IvarD); 32618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool notFound = oneAssign.TraverseDecl(CurImplD); 32718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!notFound) 32818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 32918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 33018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 33118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 33218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 33318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 334bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis bool hasIvarWithExplicitARCOwnership(PropsTy &props) const { 335bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (Pass.isGCMigration()) 336bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis return false; 337bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis 33814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 33914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 34014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isa<AttributedType>(I->IvarD->getType())) 34114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 34214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->IvarD->getType().getLocalQualifiers().getObjCLifetime() 34314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis != Qualifiers::OCL_Strong) 34414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 3457196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 34814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 34914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 35014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 351b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // \brief Returns true if all declarations in the @property have GC __weak. 352b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const { 353b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!Pass.isGCMigration()) 354b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 355b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (props.empty()) 356b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 357b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.AtPropsWeak.count(atLoc.getRawEncoding()); 358b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 359b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 36014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis bool isUserDeclared(ObjCIvarDecl *ivarD) const { 36114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ivarD && !ivarD->getSynthesize(); 36214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 36314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 36414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis QualType getPropertyType(PropsTy &props) const { 36514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 3661d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis QualType ty = props[0].PropD->getType().getUnqualifiedType(); 36714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 36814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 36914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 3701d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis assert(ty == I->PropD->getType().getUnqualifiedType()); 37114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 37214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 37314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ty; 37414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 37514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 37614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 37714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis getPropertyAttrs(PropsTy &props) const { 37814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 37914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 38014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis attrs = props[0].PropD->getPropertyAttributesAsWritten(); 38114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 38214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 38314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 38414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(attrs == I->PropD->getPropertyAttributesAsWritten()); 38514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 38614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 38714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return attrs; 3887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 3907196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3917196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // anonymous namespace 3927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 393b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidisvoid PropertyRewriteTraverser::traverseObjCImplementation( 394b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis ObjCImplementationContext &ImplCtx) { 395b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis PropertiesRewriter(ImplCtx.getMigrationContext()) 396b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis .doTransform(ImplCtx.getImplementationDecl()); 3977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 398