TransProperties.cpp revision 262bc18e32500558af7cb0afa205b34bd37bafed
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, 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 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 760fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps, 770fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis AtPropDeclsTy *PrevAtProps = 0) { 787196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (ObjCInterfaceDecl::prop_iterator 7944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis propI = D->prop_begin(), 8044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis propE = D->prop_end(); propI != propE; ++propI) { 8114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (propI->getAtLoc().isInvalid()) 8214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 830fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis unsigned RawLoc = propI->getAtLoc().getRawEncoding(); 840fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis if (PrevAtProps) 850fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis if (PrevAtProps->find(RawLoc) != PrevAtProps->end()) 860fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis continue; 870fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis PropsTy &props = AtProps[RawLoc]; 88262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie props.push_back(&*propI); 897196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 9044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 9144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 9244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doTransform(ObjCImplementationDecl *D) { 9344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis CurImplD = D; 9444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis ObjCInterfaceDecl *iface = D->getClassInterface(); 9544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (!iface) 9644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 9744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 9844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis collectProperties(iface, AtProps); 997196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 1007196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl> 1017196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis prop_impl_iterator; 1027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis for (prop_impl_iterator 1037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis I = prop_impl_iterator(D->decls_begin()), 1047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis E = prop_impl_iterator(D->decls_end()); I != E; ++I) { 105262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie ObjCPropertyImplDecl *implD = &*I; 10614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 10714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 10814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl *propD = implD->getPropertyDecl(); 10914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!propD || propD->isInvalidDecl()) 11014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCIvarDecl *ivarD = implD->getPropertyIvarDecl(); 11214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!ivarD || ivarD->isInvalidDecl()) 11314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis unsigned rawAtLoc = propD->getAtLoc().getRawEncoding(); 11514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis AtPropDeclsTy::iterator findAtLoc = AtProps.find(rawAtLoc); 11614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (findAtLoc == AtProps.end()) 11714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 11814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 11914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis PropsTy &props = findAtLoc->second; 12014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 12114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->PropD == propD) { 12214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->IvarD = ivarD; 12314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD = implD; 12414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis break; 12514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 12614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 1277196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1287196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 12914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (AtPropDeclsTy::iterator 13014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { 1317196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first); 1327196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis PropsTy &props = I->second; 1331d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis if (!getPropertyType(props)->isObjCRetainableType()) 13414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 135bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (hasIvarWithExplicitARCOwnership(props)) 13614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis continue; 13714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 13814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Transaction Trans(Pass.TA); 13914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis rewriteProperty(props, atLoc); 1407196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 14144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 14244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis AtPropDeclsTy AtExtProps; 14344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis // Look through extensions. 14444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (ObjCCategoryDecl *Cat = iface->getCategoryList(); 14544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis Cat; Cat = Cat->getNextClassCategory()) 14644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (Cat->IsClassExtension()) 1470fd4a6869e9a12999af24b8df7a0275a0e6c18beArgyrios Kyrtzidis collectProperties(Cat, AtExtProps, &AtProps); 14844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 14944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (AtPropDeclsTy::iterator 15044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) { 15144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first); 15244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropsTy &props = I->second; 15344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis Transaction Trans(Pass.TA); 15444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis doActionForExtensionProp(props, atLoc); 15544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis } 1567196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 1577196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 15814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidisprivate: 15944679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis void doPropAction(PropActionKind kind, 16044679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis PropsTy &props, SourceLocation atLoc, 16144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis bool markAction = true) { 16244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis if (markAction) 16344679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 16444679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis ActionOnProp[I->PropD->getIdentifier()] = kind; 16544679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis 16644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis switch (kind) { 16744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_None: 16844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 16986f960143c73f573919255c4465de71f85793c2eFariborz Jahanian case PropAction_RetainReplacedWithStrong: { 17086f960143c73f573919255c4465de71f85793c2eFariborz Jahanian StringRef toAttr = "strong"; 17186f960143c73f573919255c4465de71f85793c2eFariborz Jahanian MigrateCtx.rewritePropertyAttribute("retain", toAttr, atLoc); 17244679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return; 17386f960143c73f573919255c4465de71f85793c2eFariborz Jahanian } 174b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis case PropAction_AssignRemoved: 175b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return removeAssignForDefaultStrong(props, atLoc); 17644679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis case PropAction_AssignRewritten: 17744679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return rewriteAssign(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) { 2028b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis // strong is the default. 20386f960143c73f573919255c4465de71f85793c2eFariborz Jahanian return doPropAction(PropAction_RetainReplacedWithStrong, props, atLoc); 2047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 20514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 206b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props); 207b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 20818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (propAttrs & ObjCPropertyDecl::OBJC_PR_assign) { 2092f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian if (HasIvarAssignedAPlusOneObject) 210b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return doPropAction(PropAction_AssignRemoved, props, atLoc); 21144679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_AssignRewritten, props, atLoc); 21218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 21318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 214b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (HasIvarAssignedAPlusOneObject || 215b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) 216af9b5e9f3eede62347835d8dedd44df86cbcc308Argyrios Kyrtzidis return; // 'strong' by default. 21714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 21844679012052b0d57f26a3aa141004687cb71a551Argyrios Kyrtzidis return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc); 2197196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2207196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 221b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis void removeAssignForDefaultStrong(PropsTy &props, 222b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis SourceLocation atLoc) const { 223b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis removeAttribute("retain", atLoc); 224b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!removeAttribute("assign", atLoc)) 225b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return; 226b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 227b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 228b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (I->ImplD) 229b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 230b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis I->ImplD->getLocation()); 231b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 232b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 233b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 23414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void rewriteAssign(PropsTy &props, SourceLocation atLoc) const { 235b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 236b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 2372f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian const char *toWhich = 2382f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "strong" : 2392f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (canUseWeak ? "weak" : "unsafe_unretained"); 24014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 2412f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian bool rewroteAttr = rewriteAttribute("assign", toWhich, atLoc); 24214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (!rewroteAttr) 24314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis canUseWeak = false; 2447196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 24514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 2466d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 2476d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (I->IvarD && 2482f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) { 2492f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian const char *toWhich = 2502f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "__strong " : 2512f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian (canUseWeak ? "__weak " : "__unsafe_unretained "); 2522f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian Pass.TA.insert(I->IvarD->getLocation(), toWhich); 2532f72ec9fc4d3c127b5c77e13346eb640deae396aFariborz Jahanian } 2546d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis } 25514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) 25614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 25714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 25814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 2597196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2607196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 26114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis void maybeAddWeakOrUnsafeUnretainedAttr(PropsTy &props, 26214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 263b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), 264b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis /*AllowOnUnknownClass=*/Pass.isGCMigration()); 2658b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis 2668b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained", 2678b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis atLoc); 2688b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis if (!addedAttr) 2698b08eb34565a644d3345b1bfee3542a8f4a6c300Argyrios Kyrtzidis canUseWeak = false; 27014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 27114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 2726d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 2736d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis if (I->IvarD && 2746d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) 2756d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis Pass.TA.insert(I->IvarD->getLocation(), 2766d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis canUseWeak ? "__weak " : "__unsafe_unretained "); 2776d7d16d45c1d601483e46a77bd2fa1d199219721Argyrios Kyrtzidis } 27814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->ImplD) { 279b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership, 28014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 28114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis Pass.TA.clearDiagnostic( 28214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis diag::err_arc_objc_property_default_assign_on_object, 28314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis I->ImplD->getLocation()); 2847196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2857196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2867196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2877196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 28801b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis bool removeAttribute(StringRef fromAttr, SourceLocation atLoc) const { 2896da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return MigrateCtx.removePropertyAttribute(fromAttr, atLoc); 29001b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis } 29101b2b9bb154d69cc695717876e903329f6f0973cArgyrios Kyrtzidis 2925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool rewriteAttribute(StringRef fromAttr, StringRef toAttr, 29314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis SourceLocation atLoc) const { 294b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc); 2957196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 2967196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 2975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner bool addAttribute(StringRef attr, SourceLocation atLoc) const { 2986da4274724f6bd0f24f0fbfd1af076cd14b14710Argyrios Kyrtzidis return MigrateCtx.addPropertyAttribute(attr, atLoc); 29914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 30014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 30118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis class PlusOneAssign : public RecursiveASTVisitor<PlusOneAssign> { 30218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ObjCIvarDecl *Ivar; 30318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis public: 30418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {} 30518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 30618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool VisitBinAssign(BinaryOperator *E) { 30718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis Expr *lhs = E->getLHS()->IgnoreParenImpCasts(); 30818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(lhs)) { 30918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (RE->getDecl() != Ivar) 31018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 31118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 31294a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis if (ObjCMessageExpr * 31394a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis ME = dyn_cast<ObjCMessageExpr>(E->getRHS()->IgnoreParenCasts())) 31494a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis if (ME->getMethodFamily() == OMF_retain) 31594a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis return false; 31694a9016a6b92cfebdb0b7d4dcad930248f1f301aArgyrios Kyrtzidis 31718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis ImplicitCastExpr *implCE = dyn_cast<ImplicitCastExpr>(E->getRHS()); 31818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis while (implCE && implCE->getCastKind() == CK_BitCast) 31918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis implCE = dyn_cast<ImplicitCastExpr>(implCE->getSubExpr()); 32018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 32133e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall if (implCE && implCE->getCastKind() == CK_ARCConsumeObject) 32218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 32318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 32418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 32518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 32618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 32718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis }; 32818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 32918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool hasIvarAssignedAPlusOneObject(PropsTy &props) const { 33018fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 33118fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis PlusOneAssign oneAssign(I->IvarD); 33218fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool notFound = oneAssign.TraverseDecl(CurImplD); 33318fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!notFound) 33418fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return true; 33518fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 33618fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 33718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis return false; 33818fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis } 33918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis 340bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis bool hasIvarWithExplicitARCOwnership(PropsTy &props) const { 341bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis if (Pass.isGCMigration()) 342bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis return false; 343bf8455c56cc5e328c31a2b56f5587cd0873ba0aeArgyrios Kyrtzidis 34414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { 34514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isUserDeclared(I->IvarD)) { 34614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (isa<AttributedType>(I->IvarD->getType())) 34714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 34814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis if (I->IvarD->getType().getLocalQualifiers().getObjCLifetime() 34914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis != Qualifiers::OCL_Strong) 35014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 3517196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3527196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 3537196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 35414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 35514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 35614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 35718fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis bool hasAllIvarsBacked(PropsTy &props) const { 35814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 35918fd0c6915b45c4daafe18e3cd324c13306f913fArgyrios Kyrtzidis if (!isUserDeclared(I->IvarD)) 36014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return false; 36114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 36214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return true; 36314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 36414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 365b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis // \brief Returns true if all declarations in the @property have GC __weak. 366b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const { 367b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (!Pass.isGCMigration()) 368b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 369b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis if (props.empty()) 370b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return false; 371b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis return MigrateCtx.AtPropsWeak.count(atLoc.getRawEncoding()); 372b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis } 373b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis 37414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis bool isUserDeclared(ObjCIvarDecl *ivarD) const { 37514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ivarD && !ivarD->getSynthesize(); 37614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 37714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 37814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis QualType getPropertyType(PropsTy &props) const { 37914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 3801d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis QualType ty = props[0].PropD->getType().getUnqualifiedType(); 38114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 38214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 38314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 3841d5fb8f6e85a5c9c7b9b611be655454159c92f12Argyrios Kyrtzidis assert(ty == I->PropD->getType().getUnqualifiedType()); 38514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 38614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 38714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return ty; 38814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis } 38914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 39014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 39114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis getPropertyAttrs(PropsTy &props) const { 39214c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(!props.empty()); 39314c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis ObjCPropertyDecl::PropertyAttributeKind 39414c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis attrs = props[0].PropD->getPropertyAttributesAsWritten(); 39514c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 39614c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#ifndef NDEBUG 39714c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) 39814c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis assert(attrs == I->PropD->getPropertyAttributesAsWritten()); 39914c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis#endif 40014c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis 40114c4b4405fdbb54445c2d2d6320ed4f9e2326696Argyrios Kyrtzidis return attrs; 4027196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis } 4037196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis}; 4047196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 4057196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} // anonymous namespace 4067196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis 407b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidisvoid PropertyRewriteTraverser::traverseObjCImplementation( 408b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis ObjCImplementationContext &ImplCtx) { 409b0e1e121b32a9a04b39f1b77b3068bce2f3be05aArgyrios Kyrtzidis PropertiesRewriter(ImplCtx.getMigrationContext()) 410b0d5db1b7cac1a0680877c17fe92c6d64cf1c730Argyrios Kyrtzidis .doTransform(ImplCtx.getImplementationDecl()); 4117196d06c2fb020a91a26e727be1871110b4a0dc9Argyrios Kyrtzidis} 412