TransProperties.cpp revision af9b5e9f3eede62347835d8dedd44df86cbcc308
17196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis//===--- TransProperties.cpp - Tranformations 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/Sema/SemaDiagnostic.h" 367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h" 377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis#include "clang/Lex/Lexer.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, 5344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_RetainToStrong, 5444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_RetainRemoved, 55b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis PropAction_AssignRemoved, 5644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_AssignRewritten, 5744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_MaybeAddStrong, 5844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropAction_MaybeAddWeakOrUnsafe 5944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis }; 6014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 617196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis struct PropData { 627196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCPropertyDecl *PropD; 637196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis ObjCIvarDecl *IvarD; 6414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyImplDecl *ImplD; 6514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 6614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropData(ObjCPropertyDecl *propD) : PropD(propD), IvarD(0), ImplD(0) { } 677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis }; 687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVector<PropData, 2> PropsTy; 7014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis typedef std::map<unsigned, PropsTy> AtPropDeclsTy; 7114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis AtPropDeclsTy AtProps; 7244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis llvm::DenseMap<IdentifierInfo *, PropActionKind> ActionOnProp; 737196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 747196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic: 75b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis explicit PropertiesRewriter(MigrationContext &MigrateCtx) 76b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { } 777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 7844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps) { 797196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (ObjCInterfaceDecl::prop_iterator 8044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis propI = D->prop_begin(), 8144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis propE = D->prop_end(); propI != propE; ++propI) { 8214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propI->getAtLoc().isInvalid()) 8314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 8414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropsTy &props = AtProps[propI->getAtLoc().getRawEncoding()]; 8514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis props.push_back(*propI); 867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 8744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 8844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 8944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doTransform(ObjCImplementationDecl *D) { 9044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis CurImplD = D; 9144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis ObjCInterfaceDecl *iface = D->getClassInterface(); 9244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (!iface) 9344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 9444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 9544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis collectProperties(iface, AtProps); 967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl> 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis prop_impl_iterator; 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (prop_impl_iterator 1007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = prop_impl_iterator(D->decls_begin()), 1017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = prop_impl_iterator(D->decls_end()); I != E; ++I) { 10214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyImplDecl *implD = *I; 10314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 10414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 10514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl *propD = implD->getPropertyDecl(); 10614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!propD || propD->isInvalidDecl()) 10714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 10814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCIvarDecl *ivarD = implD->getPropertyIvarDecl(); 10914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!ivarD || ivarD->isInvalidDecl()) 11014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis unsigned rawAtLoc = propD->getAtLoc().getRawEncoding(); 11214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis AtPropDeclsTy::iterator findAtLoc = AtProps.find(rawAtLoc); 11314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (findAtLoc == AtProps.end()) 11414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 11614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropsTy &props = findAtLoc->second; 11714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 11814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->PropD == propD) { 11914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->IvarD = ivarD; 12014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD = implD; 12114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis break; 12214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 12314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 1247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 12614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (AtPropDeclsTy::iterator 12714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { 1287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first); 1297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis PropsTy &props = I->second; 1301d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis if (!getPropertyType(props)->isObjCRetainableType()) 13114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 132bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (hasIvarWithExplicitARCOwnership(props)) 13314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 13414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 13514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Transaction Trans(Pass.TA); 13614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis rewriteProperty(props, atLoc); 1377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 13844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 13944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis AtPropDeclsTy AtExtProps; 14044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis // Look through extensions. 14144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (ObjCCategoryDecl *Cat = iface->getCategoryList(); 14244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis Cat; Cat = Cat->getNextClassCategory()) 14344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (Cat->IsClassExtension()) 14444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis collectProperties(Cat, AtExtProps); 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; 16644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_RetainToStrong: 16744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis rewriteAttribute("retain", "strong", atLoc); 16844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 16944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_RetainRemoved: 17044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis removeAttribute("retain", atLoc); 17144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 172b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis case PropAction_AssignRemoved: 173b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return removeAssignForDefaultStrong(props, atLoc); 17444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_AssignRewritten: 17544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return rewriteAssign(props, atLoc); 17644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_MaybeAddStrong: 17744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return maybeAddStrongAttr(props, atLoc); 17844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_MaybeAddWeakOrUnsafe: 17944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc); 18044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 18144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 18244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 18344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doActionForExtensionProp(PropsTy &props, SourceLocation atLoc) { 18444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis llvm::DenseMap<IdentifierInfo *, PropActionKind>::iterator I; 18544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis I = ActionOnProp.find(props[0].PropD->getIdentifier()); 18644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (I == ActionOnProp.end()) 18744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 18844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 18944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis doPropAction(I->second, props, atLoc, false); 19044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 19144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 19244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void rewriteProperty(PropsTy &props, SourceLocation atLoc) { 19314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props); 19414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 19514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propAttrs & (ObjCPropertyDecl::OBJC_PR_copy | 19614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_unsafe_unretained | 19714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_strong | 19814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_weak)) 19914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return; 20014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 20114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_retain) { 20201b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_readonly) 20344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_RetainToStrong, props, atLoc); 20401b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis else 20544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis // strong is the default. 20644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_RetainRemoved, props, atLoc); 2077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 20814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 209b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props); 210b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 21118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_assign) { 212b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (HasIvarAssignedAPlusOneObject || 213b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) { 214b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return doPropAction(PropAction_AssignRemoved, props, atLoc); 21518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 21644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_AssignRewritten, props, atLoc); 21718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 21818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 219b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (HasIvarAssignedAPlusOneObject || 220b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) 221af9b5e9f3eede62347835d8dedd44df86cbcc308Argyrios Kyrtzidis return; // 'strong' by default. 22214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 22344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc); 2247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 226b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis void removeAssignForDefaultStrong(PropsTy &props, 227b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation atLoc) const { 228b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis removeAttribute("retain", atLoc); 229b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!removeAttribute("assign", atLoc)) 230b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return; 231b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 232b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 233b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (I->ImplD) 234b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 235b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis I->ImplD->getLocation()); 236b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 237b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 238b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 23914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void rewriteAssign(PropsTy &props, SourceLocation atLoc) const { 240b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 241b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 24214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 24314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis bool rewroteAttr = rewriteAttribute("assign", 24414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak ? "weak" : "unsafe_unretained", 24514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis atLoc); 24614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!rewroteAttr) 24714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak = false; 2487196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 24914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 25014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) 25114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(I->IvarD->getLocation(), 25214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak ? "__weak " : "__unsafe_unretained "); 25314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) 25414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 25514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 25614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 2577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2587196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 25914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void maybeAddWeakOrUnsafeUnretainedAttr(PropsTy &props, 26014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 26114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props); 26214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 263b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 264b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 26518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!(propAttrs & ObjCPropertyDecl::OBJC_PR_readonly) || 26618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis !hasAllIvarsBacked(props)) { 26718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained", 26818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis atLoc); 26918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!addedAttr) 27018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis canUseWeak = false; 27118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 27214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 27314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 27414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) 27514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(I->IvarD->getLocation(), 27614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak ? "__weak " : "__unsafe_unretained "); 27714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) { 278b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 27914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 28014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.clearDiagnostic( 28114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis diag::err_arc_objc_property_default_assign_on_object, 28214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 2837196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 28718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis void maybeAddStrongAttr(PropsTy &props, SourceLocation atLoc) const { 28818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props); 28918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 290ae7c25dab5ed7c8fc05462c8daf48e7d0945d364Argyrios Kyrtzidis if (!(propAttrs & ObjCPropertyDecl::OBJC_PR_readonly)) 291ae7c25dab5ed7c8fc05462c8daf48e7d0945d364Argyrios Kyrtzidis return; // 'strong' by default. 292ae7c25dab5ed7c8fc05462c8daf48e7d0945d364Argyrios Kyrtzidis 293ae7c25dab5ed7c8fc05462c8daf48e7d0945d364Argyrios Kyrtzidis if (!hasAllIvarsBacked(props)) { 29418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis addAttribute("strong", atLoc); 29518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 29618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 29718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 29818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (I->ImplD) { 29918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 30018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis I->ImplD->getLocation()); 30118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Pass.TA.clearDiagnostic( 30218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis diag::err_arc_objc_property_default_assign_on_object, 30318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis I->ImplD->getLocation()); 30418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 30518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 30618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 30718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 30801b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis bool removeAttribute(StringRef fromAttr, SourceLocation atLoc) const { 30901b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis return rewriteAttribute(fromAttr, StringRef(), atLoc); 31001b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis } 31101b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis 3125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool rewriteAttribute(StringRef fromAttr, StringRef toAttr, 31314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 314b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc); 3157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool addAttribute(StringRef attr, SourceLocation atLoc) const { 31814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (atLoc.isMacroID()) 31914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 32014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 3217196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 3227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Break down the source location. 3247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc); 3257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Try to load the file buffer. 3277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool invalidTemp = false; 3285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 3297196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (invalidTemp) 33014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 3317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 3337196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3347196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Lex from the start of the given location. 3357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 3367196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Pass.Ctx.getLangOptions(), 3377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 3387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Token tok; 3397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 34014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::at)) return false; 3417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 34214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 3435f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (StringRef(tok.getRawIdentifierData(), tok.getLength()) 3447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis != "property") 34514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 3467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 3477196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 34814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::l_paren)) { 34914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string("(") + attr.str() + ") "); 35014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 35114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 35214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 3537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 3547196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (tok.is(tok::r_paren)) { 35514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), attr); 35614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 35714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 35814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 35914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 36014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 36114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string(attr) + ", "); 36214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 36314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 36414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 36518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis class PlusOneAssign : public RecursiveASTVisitor<PlusOneAssign> { 36618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCIvarDecl *Ivar; 36718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis public: 36818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {} 36918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 37018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool VisitBinAssign(BinaryOperator *E) { 37118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Expr *lhs = E->getLHS()->IgnoreParenImpCasts(); 37218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(lhs)) { 37318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (RE->getDecl() != Ivar) 37418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 37518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 37694a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis if (ObjCMessageExpr * 37794a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis ME = dyn_cast<ObjCMessageExpr>(E->getRHS()->IgnoreParenCasts())) 37894a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis if (ME->getMethodFamily() == OMF_retain) 37994a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis return false; 38094a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis 38118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E->getRHS()); 38218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis while (implCE && implCE->getCastKind() == CK_BitCast) 38318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr()); 38418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 38533e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall if (implCE && implCE->getCastKind() == CK_ARCConsumeObject) 38618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 38718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 38818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 38918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 39018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 39118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis }; 39218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 39318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool hasIvarAssignedAPlusOneObject(PropsTy &props) const { 39418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 39518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign oneAssign(I->IvarD); 39618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool notFound = oneAssign.TraverseDecl(CurImplD); 39718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!notFound) 39818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 39918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 40018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 40118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 40218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 40318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 404bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis bool hasIvarWithExplicitARCOwnership(PropsTy &props) const { 405bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (Pass.isGCMigration()) 406bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis return false; 407bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis 40814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 40914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 41014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isa<AttributedType>(I->IvarD->getType())) 41114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 41214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->IvarD->getType().getLocalQualifiers().getObjCLifetime() 41314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis != Qualifiers::OCL_Strong) 41414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 4157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 4167196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 4177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 41814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 41914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 42014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 42118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool hasAllIvarsBacked(PropsTy &props) const { 42214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 42318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!isUserDeclared(I->IvarD)) 42414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 42514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 42614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 42714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 42814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 429b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // \brief Returns true if all declarations in the @property have GC __weak. 430b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const { 431b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!Pass.isGCMigration()) 432b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 433b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (props.empty()) 434b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 435b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.AtPropsWeak.count(atLoc.getRawEncoding()); 436b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 437b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 43814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis bool isUserDeclared(ObjCIvarDecl *ivarD) const { 43914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ivarD && !ivarD->getSynthesize(); 44014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 44114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 44214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis QualType getPropertyType(PropsTy &props) const { 44314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 4441d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis QualType ty = props[0].PropD->getType().getUnqualifiedType(); 44514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 44614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 44714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 4481d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis assert(ty == I->PropD->getType().getUnqualifiedType()); 44914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 45014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 45114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ty; 45214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 45314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 45414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 45514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis getPropertyAttrs(PropsTy &props) const { 45614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 45714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 45814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis attrs = props[0].PropD->getPropertyAttributesAsWritten(); 45914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 46014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 46114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 46214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(attrs == I->PropD->getPropertyAttributesAsWritten()); 46314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 46414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 46514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return attrs; 4667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 4677196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 4687196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 4697196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // anonymous namespace 4707196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 471b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidisvoid PropertyRewriteTraverser::traverseObjCImplementation( 472b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis ObjCImplementationContext &ImplCtx) { 473b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis PropertiesRewriter(ImplCtx.getMigrationContext()) 474b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis .doTransform(ImplCtx.getImplementationDecl()); 4757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 476