TransProperties.cpp revision 6d7d16d45c1d601483e46a77bd2fa1d199219721
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_RetainRemoved, 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 6414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropData(ObjCPropertyDecl *propD) : PropD(propD), IvarD(0), ImplD(0) { } 657196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis }; 667196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVector<PropData, 2> PropsTy; 6814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis typedef std::map<unsigned, PropsTy> AtPropDeclsTy; 6914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis AtPropDeclsTy AtProps; 7044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis llvm::DenseMap<IdentifierInfo *, PropActionKind> ActionOnProp; 717196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 727196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidispublic: 73b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis explicit PropertiesRewriter(MigrationContext &MigrateCtx) 74b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { } 757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 7644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps) { 777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (ObjCInterfaceDecl::prop_iterator 7844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis propI = D->prop_begin(), 7944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis propE = D->prop_end(); propI != propE; ++propI) { 8014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propI->getAtLoc().isInvalid()) 8114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 8214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropsTy &props = AtProps[propI->getAtLoc().getRawEncoding()]; 8314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis props.push_back(*propI); 847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 8544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 8644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 8744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doTransform(ObjCImplementationDecl *D) { 8844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis CurImplD = D; 8944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis ObjCInterfaceDecl *iface = D->getClassInterface(); 9044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (!iface) 9144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 9244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 9344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis collectProperties(iface, AtProps); 947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl> 967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis prop_impl_iterator; 977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (prop_impl_iterator 987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = prop_impl_iterator(D->decls_begin()), 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = prop_impl_iterator(D->decls_end()); I != E; ++I) { 10014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyImplDecl *implD = *I; 10114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 10214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 10314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl *propD = implD->getPropertyDecl(); 10414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!propD || propD->isInvalidDecl()) 10514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 10614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCIvarDecl *ivarD = implD->getPropertyIvarDecl(); 10714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!ivarD || ivarD->isInvalidDecl()) 10814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 10914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis unsigned rawAtLoc = propD->getAtLoc().getRawEncoding(); 11014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis AtPropDeclsTy::iterator findAtLoc = AtProps.find(rawAtLoc); 11114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (findAtLoc == AtProps.end()) 11214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 11414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropsTy &props = findAtLoc->second; 11514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 11614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->PropD == propD) { 11714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->IvarD = ivarD; 11814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD = implD; 11914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis break; 12014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 12114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 1227196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1237196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 12414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (AtPropDeclsTy::iterator 12514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { 1267196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first); 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis PropsTy &props = I->second; 1281d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis if (!getPropertyType(props)->isObjCRetainableType()) 12914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 130bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (hasIvarWithExplicitARCOwnership(props)) 13114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 13214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 13314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Transaction Trans(Pass.TA); 13414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis rewriteProperty(props, atLoc); 1357196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 13644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 13744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis AtPropDeclsTy AtExtProps; 13844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis // Look through extensions. 13944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (ObjCCategoryDecl *Cat = iface->getCategoryList(); 14044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis Cat; Cat = Cat->getNextClassCategory()) 14144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (Cat->IsClassExtension()) 14244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis collectProperties(Cat, AtExtProps); 14344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 14444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (AtPropDeclsTy::iterator 14544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) { 14644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first); 14744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropsTy &props = I->second; 14844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis Transaction Trans(Pass.TA); 14944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis doActionForExtensionProp(props, atLoc); 15044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 1517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 15314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidisprivate: 15444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doPropAction(PropActionKind kind, 15544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropsTy &props, SourceLocation atLoc, 15644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis bool markAction = true) { 15744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (markAction) 15844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 15944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis ActionOnProp[I->PropD->getIdentifier()] = kind; 16044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 16144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis switch (kind) { 16244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_None: 16344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 16444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_RetainRemoved: 16544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis removeAttribute("retain", atLoc); 16644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 167b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis case PropAction_AssignRemoved: 168b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return removeAssignForDefaultStrong(props, atLoc); 16944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_AssignRewritten: 17044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return rewriteAssign(props, atLoc); 17144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_MaybeAddWeakOrUnsafe: 17244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc); 17344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 17444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 17544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 17644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doActionForExtensionProp(PropsTy &props, SourceLocation atLoc) { 17744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis llvm::DenseMap<IdentifierInfo *, PropActionKind>::iterator I; 17844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis I = ActionOnProp.find(props[0].PropD->getIdentifier()); 17944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (I == ActionOnProp.end()) 18044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 18144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 18244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis doPropAction(I->second, props, atLoc, false); 18344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 18444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 18544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void rewriteProperty(PropsTy &props, SourceLocation atLoc) { 18614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props); 18714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 18814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propAttrs & (ObjCPropertyDecl::OBJC_PR_copy | 18914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_unsafe_unretained | 19014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_strong | 19114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::OBJC_PR_weak)) 19214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return; 19314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 19414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_retain) { 1958b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis // strong is the default. 1968b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis return doPropAction(PropAction_RetainRemoved, props, atLoc); 1977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 19814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 199b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props); 200b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 20118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_assign) { 202b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (HasIvarAssignedAPlusOneObject || 203b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) { 204b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return doPropAction(PropAction_AssignRemoved, props, atLoc); 20518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 20644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_AssignRewritten, props, atLoc); 20718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 20818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 209b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (HasIvarAssignedAPlusOneObject || 210b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) 211af9b5e9f3eede62347835d8dedd44df86cbcc308Argyrios Kyrtzidis return; // 'strong' by default. 21214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 21344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc); 2147196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 216b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis void removeAssignForDefaultStrong(PropsTy &props, 217b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation atLoc) const { 218b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis removeAttribute("retain", atLoc); 219b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!removeAttribute("assign", atLoc)) 220b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return; 221b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 222b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 223b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (I->ImplD) 224b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 225b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis I->ImplD->getLocation()); 226b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 227b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 228b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 22914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void rewriteAssign(PropsTy &props, SourceLocation atLoc) const { 230b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 231b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 23214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 23314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis bool rewroteAttr = rewriteAttribute("assign", 23414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak ? "weak" : "unsafe_unretained", 23514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis atLoc); 23614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!rewroteAttr) 23714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak = false; 2387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 23914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 2406d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 2416d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (I->IvarD && 2426d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) 2436d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis Pass.TA.insert(I->IvarD->getLocation(), 2446d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis canUseWeak ? "__weak " : "__unsafe_unretained "); 2456d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis } 24614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) 24714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 24814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 24914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 2507196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 25214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void maybeAddWeakOrUnsafeUnretainedAttr(PropsTy &props, 25314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 254b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 255b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 2568b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis 2578b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained", 2588b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis atLoc); 2598b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis if (!addedAttr) 2608b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis canUseWeak = false; 26114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 26214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 2636d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 2646d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (I->IvarD && 2656d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) 2666d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis Pass.TA.insert(I->IvarD->getLocation(), 2676d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis canUseWeak ? "__weak " : "__unsafe_unretained "); 2686d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis } 26914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) { 270b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 27114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 27214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.clearDiagnostic( 27314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis diag::err_arc_objc_property_default_assign_on_object, 27414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 2757196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2767196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2777196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 27901b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis bool removeAttribute(StringRef fromAttr, SourceLocation atLoc) const { 28001b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis return rewriteAttribute(fromAttr, StringRef(), atLoc); 28101b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis } 28201b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis 2835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool rewriteAttribute(StringRef fromAttr, StringRef toAttr, 28414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 285b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc); 2867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool addAttribute(StringRef attr, SourceLocation atLoc) const { 28914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (atLoc.isMacroID()) 29014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 29114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 2927196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceManager &SM = Pass.Ctx.getSourceManager(); 2937196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2947196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Break down the source location. 2957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc); 2967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2977196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Try to load the file buffer. 2987196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis bool invalidTemp = false; 2995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 3007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (invalidTemp) 30114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 3027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis const char *tokenBegin = file.data() + locInfo.second; 3047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 3057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis // Lex from the start of the given location. 3067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 3077196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Pass.Ctx.getLangOptions(), 3087196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis file.begin(), tokenBegin, file.end()); 3097196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis Token tok; 3107196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 31114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::at)) return false; 3127196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 31314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 3145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (StringRef(tok.getRawIdentifierData(), tok.getLength()) 3157196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis != "property") 31614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 3177196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 3187196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 31914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::l_paren)) { 32014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string("(") + attr.str() + ") "); 32114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 32214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 32314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 3247196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis lexer.LexFromRawLexer(tok); 3257196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis if (tok.is(tok::r_paren)) { 32614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), attr); 32714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 32814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 32914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 33014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (tok.isNot(tok::raw_identifier)) return false; 33114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 33214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.insert(tok.getLocation(), std::string(attr) + ", "); 33314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 33414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 33514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 33618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis class PlusOneAssign : public RecursiveASTVisitor<PlusOneAssign> { 33718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCIvarDecl *Ivar; 33818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis public: 33918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {} 34018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 34118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool VisitBinAssign(BinaryOperator *E) { 34218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Expr *lhs = E->getLHS()->IgnoreParenImpCasts(); 34318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(lhs)) { 34418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (RE->getDecl() != Ivar) 34518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 34618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 34794a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis if (ObjCMessageExpr * 34894a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis ME = dyn_cast<ObjCMessageExpr>(E->getRHS()->IgnoreParenCasts())) 34994a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis if (ME->getMethodFamily() == OMF_retain) 35094a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis return false; 35194a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis 35218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E->getRHS()); 35318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis while (implCE && implCE->getCastKind() == CK_BitCast) 35418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr()); 35518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 35633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall if (implCE && implCE->getCastKind() == CK_ARCConsumeObject) 35718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 35818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 35918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 36018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 36118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 36218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis }; 36318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 36418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool hasIvarAssignedAPlusOneObject(PropsTy &props) const { 36518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 36618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign oneAssign(I->IvarD); 36718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool notFound = oneAssign.TraverseDecl(CurImplD); 36818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!notFound) 36918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 37018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 37118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 37218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 37318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 37418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 375bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis bool hasIvarWithExplicitARCOwnership(PropsTy &props) const { 376bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (Pass.isGCMigration()) 377bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis return false; 378bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis 37914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 38014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 38114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isa<AttributedType>(I->IvarD->getType())) 38214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 38314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->IvarD->getType().getLocalQualifiers().getObjCLifetime() 38414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis != Qualifiers::OCL_Strong) 38514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 3867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3887196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 38914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 39014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 39114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 39218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool hasAllIvarsBacked(PropsTy &props) const { 39314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 39418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!isUserDeclared(I->IvarD)) 39514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 39614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 39714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 39814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 39914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 400b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // \brief Returns true if all declarations in the @property have GC __weak. 401b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const { 402b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!Pass.isGCMigration()) 403b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 404b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (props.empty()) 405b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 406b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.AtPropsWeak.count(atLoc.getRawEncoding()); 407b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 408b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 40914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis bool isUserDeclared(ObjCIvarDecl *ivarD) const { 41014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ivarD && !ivarD->getSynthesize(); 41114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 41214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 41314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis QualType getPropertyType(PropsTy &props) const { 41414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 4151d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis QualType ty = props[0].PropD->getType().getUnqualifiedType(); 41614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 41714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 41814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 4191d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis assert(ty == I->PropD->getType().getUnqualifiedType()); 42014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 42114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 42214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ty; 42314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 42414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 42514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 42614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis getPropertyAttrs(PropsTy &props) const { 42714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 42814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 42914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis attrs = props[0].PropD->getPropertyAttributesAsWritten(); 43014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 43114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 43214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 43314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(attrs == I->PropD->getPropertyAttributesAsWritten()); 43414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 43514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 43614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return attrs; 4377196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 4387196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 4397196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 4407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // anonymous namespace 4417196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 442b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidisvoid PropertyRewriteTraverser::traverseObjCImplementation( 443b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis ObjCImplementationContext &ImplCtx) { 444b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis PropertiesRewriter(ImplCtx.getMigrationContext()) 445b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis .doTransform(ImplCtx.getImplementationDecl()); 4467196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 447