annotate clang/lib/ARCMigrate/TransProperties.cpp @ 176:de4ac79aef9d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 17:13:11 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===--- TransProperties.cpp - Transformations to ARC mode ----------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // rewriteProperties:
anatofuz
parents:
diff changeset
10 //
anatofuz
parents:
diff changeset
11 // - Adds strong/weak/unsafe_unretained ownership specifier to properties that
anatofuz
parents:
diff changeset
12 // are missing one.
anatofuz
parents:
diff changeset
13 // - Migrates properties from (retain) to (strong) and (assign) to
anatofuz
parents:
diff changeset
14 // (unsafe_unretained/weak).
anatofuz
parents:
diff changeset
15 // - If a property is synthesized, adds the ownership specifier in the ivar
anatofuz
parents:
diff changeset
16 // backing the property.
anatofuz
parents:
diff changeset
17 //
anatofuz
parents:
diff changeset
18 // @interface Foo : NSObject {
anatofuz
parents:
diff changeset
19 // NSObject *x;
anatofuz
parents:
diff changeset
20 // }
anatofuz
parents:
diff changeset
21 // @property (assign) id x;
anatofuz
parents:
diff changeset
22 // @end
anatofuz
parents:
diff changeset
23 // ---->
anatofuz
parents:
diff changeset
24 // @interface Foo : NSObject {
anatofuz
parents:
diff changeset
25 // NSObject *__weak x;
anatofuz
parents:
diff changeset
26 // }
anatofuz
parents:
diff changeset
27 // @property (weak) id x;
anatofuz
parents:
diff changeset
28 // @end
anatofuz
parents:
diff changeset
29 //
anatofuz
parents:
diff changeset
30 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
31
anatofuz
parents:
diff changeset
32 #include "Transforms.h"
anatofuz
parents:
diff changeset
33 #include "Internals.h"
anatofuz
parents:
diff changeset
34 #include "clang/Basic/SourceManager.h"
anatofuz
parents:
diff changeset
35 #include "clang/Lex/Lexer.h"
anatofuz
parents:
diff changeset
36 #include "clang/Sema/SemaDiagnostic.h"
anatofuz
parents:
diff changeset
37 #include <map>
anatofuz
parents:
diff changeset
38
anatofuz
parents:
diff changeset
39 using namespace clang;
anatofuz
parents:
diff changeset
40 using namespace arcmt;
anatofuz
parents:
diff changeset
41 using namespace trans;
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 namespace {
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45 class PropertiesRewriter {
anatofuz
parents:
diff changeset
46 MigrationContext &MigrateCtx;
anatofuz
parents:
diff changeset
47 MigrationPass &Pass;
anatofuz
parents:
diff changeset
48 ObjCImplementationDecl *CurImplD;
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 enum PropActionKind {
anatofuz
parents:
diff changeset
51 PropAction_None,
anatofuz
parents:
diff changeset
52 PropAction_RetainReplacedWithStrong,
anatofuz
parents:
diff changeset
53 PropAction_AssignRemoved,
anatofuz
parents:
diff changeset
54 PropAction_AssignRewritten,
anatofuz
parents:
diff changeset
55 PropAction_MaybeAddWeakOrUnsafe
anatofuz
parents:
diff changeset
56 };
anatofuz
parents:
diff changeset
57
anatofuz
parents:
diff changeset
58 struct PropData {
anatofuz
parents:
diff changeset
59 ObjCPropertyDecl *PropD;
anatofuz
parents:
diff changeset
60 ObjCIvarDecl *IvarD;
anatofuz
parents:
diff changeset
61 ObjCPropertyImplDecl *ImplD;
anatofuz
parents:
diff changeset
62
anatofuz
parents:
diff changeset
63 PropData(ObjCPropertyDecl *propD)
anatofuz
parents:
diff changeset
64 : PropD(propD), IvarD(nullptr), ImplD(nullptr) {}
anatofuz
parents:
diff changeset
65 };
anatofuz
parents:
diff changeset
66
anatofuz
parents:
diff changeset
67 typedef SmallVector<PropData, 2> PropsTy;
anatofuz
parents:
diff changeset
68 typedef std::map<unsigned, PropsTy> AtPropDeclsTy;
anatofuz
parents:
diff changeset
69 AtPropDeclsTy AtProps;
anatofuz
parents:
diff changeset
70 llvm::DenseMap<IdentifierInfo *, PropActionKind> ActionOnProp;
anatofuz
parents:
diff changeset
71
anatofuz
parents:
diff changeset
72 public:
anatofuz
parents:
diff changeset
73 explicit PropertiesRewriter(MigrationContext &MigrateCtx)
anatofuz
parents:
diff changeset
74 : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { }
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76 static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps,
anatofuz
parents:
diff changeset
77 AtPropDeclsTy *PrevAtProps = nullptr) {
anatofuz
parents:
diff changeset
78 for (auto *Prop : D->instance_properties()) {
anatofuz
parents:
diff changeset
79 if (Prop->getAtLoc().isInvalid())
anatofuz
parents:
diff changeset
80 continue;
anatofuz
parents:
diff changeset
81 unsigned RawLoc = Prop->getAtLoc().getRawEncoding();
anatofuz
parents:
diff changeset
82 if (PrevAtProps)
anatofuz
parents:
diff changeset
83 if (PrevAtProps->find(RawLoc) != PrevAtProps->end())
anatofuz
parents:
diff changeset
84 continue;
anatofuz
parents:
diff changeset
85 PropsTy &props = AtProps[RawLoc];
anatofuz
parents:
diff changeset
86 props.push_back(Prop);
anatofuz
parents:
diff changeset
87 }
anatofuz
parents:
diff changeset
88 }
anatofuz
parents:
diff changeset
89
anatofuz
parents:
diff changeset
90 void doTransform(ObjCImplementationDecl *D) {
anatofuz
parents:
diff changeset
91 CurImplD = D;
anatofuz
parents:
diff changeset
92 ObjCInterfaceDecl *iface = D->getClassInterface();
anatofuz
parents:
diff changeset
93 if (!iface)
anatofuz
parents:
diff changeset
94 return;
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 collectProperties(iface, AtProps);
anatofuz
parents:
diff changeset
97
anatofuz
parents:
diff changeset
98 // Look through extensions.
anatofuz
parents:
diff changeset
99 for (auto *Ext : iface->visible_extensions())
anatofuz
parents:
diff changeset
100 collectProperties(Ext, AtProps);
anatofuz
parents:
diff changeset
101
anatofuz
parents:
diff changeset
102 typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl>
anatofuz
parents:
diff changeset
103 prop_impl_iterator;
anatofuz
parents:
diff changeset
104 for (prop_impl_iterator
anatofuz
parents:
diff changeset
105 I = prop_impl_iterator(D->decls_begin()),
anatofuz
parents:
diff changeset
106 E = prop_impl_iterator(D->decls_end()); I != E; ++I) {
anatofuz
parents:
diff changeset
107 ObjCPropertyImplDecl *implD = *I;
anatofuz
parents:
diff changeset
108 if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
anatofuz
parents:
diff changeset
109 continue;
anatofuz
parents:
diff changeset
110 ObjCPropertyDecl *propD = implD->getPropertyDecl();
anatofuz
parents:
diff changeset
111 if (!propD || propD->isInvalidDecl())
anatofuz
parents:
diff changeset
112 continue;
anatofuz
parents:
diff changeset
113 ObjCIvarDecl *ivarD = implD->getPropertyIvarDecl();
anatofuz
parents:
diff changeset
114 if (!ivarD || ivarD->isInvalidDecl())
anatofuz
parents:
diff changeset
115 continue;
anatofuz
parents:
diff changeset
116 unsigned rawAtLoc = propD->getAtLoc().getRawEncoding();
anatofuz
parents:
diff changeset
117 AtPropDeclsTy::iterator findAtLoc = AtProps.find(rawAtLoc);
anatofuz
parents:
diff changeset
118 if (findAtLoc == AtProps.end())
anatofuz
parents:
diff changeset
119 continue;
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 PropsTy &props = findAtLoc->second;
anatofuz
parents:
diff changeset
122 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
anatofuz
parents:
diff changeset
123 if (I->PropD == propD) {
anatofuz
parents:
diff changeset
124 I->IvarD = ivarD;
anatofuz
parents:
diff changeset
125 I->ImplD = implD;
anatofuz
parents:
diff changeset
126 break;
anatofuz
parents:
diff changeset
127 }
anatofuz
parents:
diff changeset
128 }
anatofuz
parents:
diff changeset
129 }
anatofuz
parents:
diff changeset
130
anatofuz
parents:
diff changeset
131 for (AtPropDeclsTy::iterator
anatofuz
parents:
diff changeset
132 I = AtProps.begin(), E = AtProps.end(); I != E; ++I) {
anatofuz
parents:
diff changeset
133 SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first);
anatofuz
parents:
diff changeset
134 PropsTy &props = I->second;
anatofuz
parents:
diff changeset
135 if (!getPropertyType(props)->isObjCRetainableType())
anatofuz
parents:
diff changeset
136 continue;
anatofuz
parents:
diff changeset
137 if (hasIvarWithExplicitARCOwnership(props))
anatofuz
parents:
diff changeset
138 continue;
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 Transaction Trans(Pass.TA);
anatofuz
parents:
diff changeset
141 rewriteProperty(props, atLoc);
anatofuz
parents:
diff changeset
142 }
anatofuz
parents:
diff changeset
143 }
anatofuz
parents:
diff changeset
144
anatofuz
parents:
diff changeset
145 private:
anatofuz
parents:
diff changeset
146 void doPropAction(PropActionKind kind,
anatofuz
parents:
diff changeset
147 PropsTy &props, SourceLocation atLoc,
anatofuz
parents:
diff changeset
148 bool markAction = true) {
anatofuz
parents:
diff changeset
149 if (markAction)
anatofuz
parents:
diff changeset
150 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I)
anatofuz
parents:
diff changeset
151 ActionOnProp[I->PropD->getIdentifier()] = kind;
anatofuz
parents:
diff changeset
152
anatofuz
parents:
diff changeset
153 switch (kind) {
anatofuz
parents:
diff changeset
154 case PropAction_None:
anatofuz
parents:
diff changeset
155 return;
anatofuz
parents:
diff changeset
156 case PropAction_RetainReplacedWithStrong: {
anatofuz
parents:
diff changeset
157 StringRef toAttr = "strong";
anatofuz
parents:
diff changeset
158 MigrateCtx.rewritePropertyAttribute("retain", toAttr, atLoc);
anatofuz
parents:
diff changeset
159 return;
anatofuz
parents:
diff changeset
160 }
anatofuz
parents:
diff changeset
161 case PropAction_AssignRemoved:
anatofuz
parents:
diff changeset
162 return removeAssignForDefaultStrong(props, atLoc);
anatofuz
parents:
diff changeset
163 case PropAction_AssignRewritten:
anatofuz
parents:
diff changeset
164 return rewriteAssign(props, atLoc);
anatofuz
parents:
diff changeset
165 case PropAction_MaybeAddWeakOrUnsafe:
anatofuz
parents:
diff changeset
166 return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc);
anatofuz
parents:
diff changeset
167 }
anatofuz
parents:
diff changeset
168 }
anatofuz
parents:
diff changeset
169
anatofuz
parents:
diff changeset
170 void rewriteProperty(PropsTy &props, SourceLocation atLoc) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
171 ObjCPropertyAttribute::Kind propAttrs = getPropertyAttrs(props);
150
anatofuz
parents:
diff changeset
172
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
173 if (propAttrs &
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
174 (ObjCPropertyAttribute::kind_copy |
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
175 ObjCPropertyAttribute::kind_unsafe_unretained |
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
176 ObjCPropertyAttribute::kind_strong | ObjCPropertyAttribute::kind_weak))
150
anatofuz
parents:
diff changeset
177 return;
anatofuz
parents:
diff changeset
178
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
179 if (propAttrs & ObjCPropertyAttribute::kind_retain) {
150
anatofuz
parents:
diff changeset
180 // strong is the default.
anatofuz
parents:
diff changeset
181 return doPropAction(PropAction_RetainReplacedWithStrong, props, atLoc);
anatofuz
parents:
diff changeset
182 }
anatofuz
parents:
diff changeset
183
anatofuz
parents:
diff changeset
184 bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props);
anatofuz
parents:
diff changeset
185
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
186 if (propAttrs & ObjCPropertyAttribute::kind_assign) {
150
anatofuz
parents:
diff changeset
187 if (HasIvarAssignedAPlusOneObject)
anatofuz
parents:
diff changeset
188 return doPropAction(PropAction_AssignRemoved, props, atLoc);
anatofuz
parents:
diff changeset
189 return doPropAction(PropAction_AssignRewritten, props, atLoc);
anatofuz
parents:
diff changeset
190 }
anatofuz
parents:
diff changeset
191
anatofuz
parents:
diff changeset
192 if (HasIvarAssignedAPlusOneObject ||
anatofuz
parents:
diff changeset
193 (Pass.isGCMigration() && !hasGCWeak(props, atLoc)))
anatofuz
parents:
diff changeset
194 return; // 'strong' by default.
anatofuz
parents:
diff changeset
195
anatofuz
parents:
diff changeset
196 return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc);
anatofuz
parents:
diff changeset
197 }
anatofuz
parents:
diff changeset
198
anatofuz
parents:
diff changeset
199 void removeAssignForDefaultStrong(PropsTy &props,
anatofuz
parents:
diff changeset
200 SourceLocation atLoc) const {
anatofuz
parents:
diff changeset
201 removeAttribute("retain", atLoc);
anatofuz
parents:
diff changeset
202 if (!removeAttribute("assign", atLoc))
anatofuz
parents:
diff changeset
203 return;
anatofuz
parents:
diff changeset
204
anatofuz
parents:
diff changeset
205 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
anatofuz
parents:
diff changeset
206 if (I->ImplD)
anatofuz
parents:
diff changeset
207 Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership,
anatofuz
parents:
diff changeset
208 diag::err_arc_assign_property_ownership,
anatofuz
parents:
diff changeset
209 diag::err_arc_inconsistent_property_ownership,
anatofuz
parents:
diff changeset
210 I->IvarD->getLocation());
anatofuz
parents:
diff changeset
211 }
anatofuz
parents:
diff changeset
212 }
anatofuz
parents:
diff changeset
213
anatofuz
parents:
diff changeset
214 void rewriteAssign(PropsTy &props, SourceLocation atLoc) const {
anatofuz
parents:
diff changeset
215 bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props),
anatofuz
parents:
diff changeset
216 /*AllowOnUnknownClass=*/Pass.isGCMigration());
anatofuz
parents:
diff changeset
217 const char *toWhich =
anatofuz
parents:
diff changeset
218 (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "strong" :
anatofuz
parents:
diff changeset
219 (canUseWeak ? "weak" : "unsafe_unretained");
anatofuz
parents:
diff changeset
220
anatofuz
parents:
diff changeset
221 bool rewroteAttr = rewriteAttribute("assign", toWhich, atLoc);
anatofuz
parents:
diff changeset
222 if (!rewroteAttr)
anatofuz
parents:
diff changeset
223 canUseWeak = false;
anatofuz
parents:
diff changeset
224
anatofuz
parents:
diff changeset
225 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
anatofuz
parents:
diff changeset
226 if (isUserDeclared(I->IvarD)) {
anatofuz
parents:
diff changeset
227 if (I->IvarD &&
anatofuz
parents:
diff changeset
228 I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) {
anatofuz
parents:
diff changeset
229 const char *toWhich =
anatofuz
parents:
diff changeset
230 (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "__strong " :
anatofuz
parents:
diff changeset
231 (canUseWeak ? "__weak " : "__unsafe_unretained ");
anatofuz
parents:
diff changeset
232 Pass.TA.insert(I->IvarD->getLocation(), toWhich);
anatofuz
parents:
diff changeset
233 }
anatofuz
parents:
diff changeset
234 }
anatofuz
parents:
diff changeset
235 if (I->ImplD)
anatofuz
parents:
diff changeset
236 Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership,
anatofuz
parents:
diff changeset
237 diag::err_arc_assign_property_ownership,
anatofuz
parents:
diff changeset
238 diag::err_arc_inconsistent_property_ownership,
anatofuz
parents:
diff changeset
239 I->IvarD->getLocation());
anatofuz
parents:
diff changeset
240 }
anatofuz
parents:
diff changeset
241 }
anatofuz
parents:
diff changeset
242
anatofuz
parents:
diff changeset
243 void maybeAddWeakOrUnsafeUnretainedAttr(PropsTy &props,
anatofuz
parents:
diff changeset
244 SourceLocation atLoc) const {
anatofuz
parents:
diff changeset
245 bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props),
anatofuz
parents:
diff changeset
246 /*AllowOnUnknownClass=*/Pass.isGCMigration());
anatofuz
parents:
diff changeset
247
anatofuz
parents:
diff changeset
248 bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained",
anatofuz
parents:
diff changeset
249 atLoc);
anatofuz
parents:
diff changeset
250 if (!addedAttr)
anatofuz
parents:
diff changeset
251 canUseWeak = false;
anatofuz
parents:
diff changeset
252
anatofuz
parents:
diff changeset
253 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
anatofuz
parents:
diff changeset
254 if (isUserDeclared(I->IvarD)) {
anatofuz
parents:
diff changeset
255 if (I->IvarD &&
anatofuz
parents:
diff changeset
256 I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak)
anatofuz
parents:
diff changeset
257 Pass.TA.insert(I->IvarD->getLocation(),
anatofuz
parents:
diff changeset
258 canUseWeak ? "__weak " : "__unsafe_unretained ");
anatofuz
parents:
diff changeset
259 }
anatofuz
parents:
diff changeset
260 if (I->ImplD) {
anatofuz
parents:
diff changeset
261 Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership,
anatofuz
parents:
diff changeset
262 diag::err_arc_assign_property_ownership,
anatofuz
parents:
diff changeset
263 diag::err_arc_inconsistent_property_ownership,
anatofuz
parents:
diff changeset
264 I->IvarD->getLocation());
anatofuz
parents:
diff changeset
265 Pass.TA.clearDiagnostic(
anatofuz
parents:
diff changeset
266 diag::err_arc_objc_property_default_assign_on_object,
anatofuz
parents:
diff changeset
267 I->ImplD->getLocation());
anatofuz
parents:
diff changeset
268 }
anatofuz
parents:
diff changeset
269 }
anatofuz
parents:
diff changeset
270 }
anatofuz
parents:
diff changeset
271
anatofuz
parents:
diff changeset
272 bool removeAttribute(StringRef fromAttr, SourceLocation atLoc) const {
anatofuz
parents:
diff changeset
273 return MigrateCtx.removePropertyAttribute(fromAttr, atLoc);
anatofuz
parents:
diff changeset
274 }
anatofuz
parents:
diff changeset
275
anatofuz
parents:
diff changeset
276 bool rewriteAttribute(StringRef fromAttr, StringRef toAttr,
anatofuz
parents:
diff changeset
277 SourceLocation atLoc) const {
anatofuz
parents:
diff changeset
278 return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc);
anatofuz
parents:
diff changeset
279 }
anatofuz
parents:
diff changeset
280
anatofuz
parents:
diff changeset
281 bool addAttribute(StringRef attr, SourceLocation atLoc) const {
anatofuz
parents:
diff changeset
282 return MigrateCtx.addPropertyAttribute(attr, atLoc);
anatofuz
parents:
diff changeset
283 }
anatofuz
parents:
diff changeset
284
anatofuz
parents:
diff changeset
285 class PlusOneAssign : public RecursiveASTVisitor<PlusOneAssign> {
anatofuz
parents:
diff changeset
286 ObjCIvarDecl *Ivar;
anatofuz
parents:
diff changeset
287 public:
anatofuz
parents:
diff changeset
288 PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {}
anatofuz
parents:
diff changeset
289
anatofuz
parents:
diff changeset
290 bool VisitBinAssign(BinaryOperator *E) {
anatofuz
parents:
diff changeset
291 Expr *lhs = E->getLHS()->IgnoreParenImpCasts();
anatofuz
parents:
diff changeset
292 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(lhs)) {
anatofuz
parents:
diff changeset
293 if (RE->getDecl() != Ivar)
anatofuz
parents:
diff changeset
294 return true;
anatofuz
parents:
diff changeset
295
anatofuz
parents:
diff changeset
296 if (isPlusOneAssign(E))
anatofuz
parents:
diff changeset
297 return false;
anatofuz
parents:
diff changeset
298 }
anatofuz
parents:
diff changeset
299
anatofuz
parents:
diff changeset
300 return true;
anatofuz
parents:
diff changeset
301 }
anatofuz
parents:
diff changeset
302 };
anatofuz
parents:
diff changeset
303
anatofuz
parents:
diff changeset
304 bool hasIvarAssignedAPlusOneObject(PropsTy &props) const {
anatofuz
parents:
diff changeset
305 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
anatofuz
parents:
diff changeset
306 PlusOneAssign oneAssign(I->IvarD);
anatofuz
parents:
diff changeset
307 bool notFound = oneAssign.TraverseDecl(CurImplD);
anatofuz
parents:
diff changeset
308 if (!notFound)
anatofuz
parents:
diff changeset
309 return true;
anatofuz
parents:
diff changeset
310 }
anatofuz
parents:
diff changeset
311
anatofuz
parents:
diff changeset
312 return false;
anatofuz
parents:
diff changeset
313 }
anatofuz
parents:
diff changeset
314
anatofuz
parents:
diff changeset
315 bool hasIvarWithExplicitARCOwnership(PropsTy &props) const {
anatofuz
parents:
diff changeset
316 if (Pass.isGCMigration())
anatofuz
parents:
diff changeset
317 return false;
anatofuz
parents:
diff changeset
318
anatofuz
parents:
diff changeset
319 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
anatofuz
parents:
diff changeset
320 if (isUserDeclared(I->IvarD)) {
anatofuz
parents:
diff changeset
321 if (isa<AttributedType>(I->IvarD->getType()))
anatofuz
parents:
diff changeset
322 return true;
anatofuz
parents:
diff changeset
323 if (I->IvarD->getType().getLocalQualifiers().getObjCLifetime()
anatofuz
parents:
diff changeset
324 != Qualifiers::OCL_Strong)
anatofuz
parents:
diff changeset
325 return true;
anatofuz
parents:
diff changeset
326 }
anatofuz
parents:
diff changeset
327 }
anatofuz
parents:
diff changeset
328
anatofuz
parents:
diff changeset
329 return false;
anatofuz
parents:
diff changeset
330 }
anatofuz
parents:
diff changeset
331
anatofuz
parents:
diff changeset
332 // Returns true if all declarations in the @property have GC __weak.
anatofuz
parents:
diff changeset
333 bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const {
anatofuz
parents:
diff changeset
334 if (!Pass.isGCMigration())
anatofuz
parents:
diff changeset
335 return false;
anatofuz
parents:
diff changeset
336 if (props.empty())
anatofuz
parents:
diff changeset
337 return false;
anatofuz
parents:
diff changeset
338 return MigrateCtx.AtPropsWeak.count(atLoc.getRawEncoding());
anatofuz
parents:
diff changeset
339 }
anatofuz
parents:
diff changeset
340
anatofuz
parents:
diff changeset
341 bool isUserDeclared(ObjCIvarDecl *ivarD) const {
anatofuz
parents:
diff changeset
342 return ivarD && !ivarD->getSynthesize();
anatofuz
parents:
diff changeset
343 }
anatofuz
parents:
diff changeset
344
anatofuz
parents:
diff changeset
345 QualType getPropertyType(PropsTy &props) const {
anatofuz
parents:
diff changeset
346 assert(!props.empty());
anatofuz
parents:
diff changeset
347 QualType ty = props[0].PropD->getType().getUnqualifiedType();
anatofuz
parents:
diff changeset
348
anatofuz
parents:
diff changeset
349 #ifndef NDEBUG
anatofuz
parents:
diff changeset
350 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I)
anatofuz
parents:
diff changeset
351 assert(ty == I->PropD->getType().getUnqualifiedType());
anatofuz
parents:
diff changeset
352 #endif
anatofuz
parents:
diff changeset
353
anatofuz
parents:
diff changeset
354 return ty;
anatofuz
parents:
diff changeset
355 }
anatofuz
parents:
diff changeset
356
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
357 ObjCPropertyAttribute::Kind getPropertyAttrs(PropsTy &props) const {
150
anatofuz
parents:
diff changeset
358 assert(!props.empty());
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
359 ObjCPropertyAttribute::Kind attrs =
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
360 props[0].PropD->getPropertyAttributesAsWritten();
150
anatofuz
parents:
diff changeset
361
anatofuz
parents:
diff changeset
362 #ifndef NDEBUG
anatofuz
parents:
diff changeset
363 for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I)
anatofuz
parents:
diff changeset
364 assert(attrs == I->PropD->getPropertyAttributesAsWritten());
anatofuz
parents:
diff changeset
365 #endif
anatofuz
parents:
diff changeset
366
anatofuz
parents:
diff changeset
367 return attrs;
anatofuz
parents:
diff changeset
368 }
anatofuz
parents:
diff changeset
369 };
anatofuz
parents:
diff changeset
370
anatofuz
parents:
diff changeset
371 } // anonymous namespace
anatofuz
parents:
diff changeset
372
anatofuz
parents:
diff changeset
373 void PropertyRewriteTraverser::traverseObjCImplementation(
anatofuz
parents:
diff changeset
374 ObjCImplementationContext &ImplCtx) {
anatofuz
parents:
diff changeset
375 PropertiesRewriter(ImplCtx.getMigrationContext())
anatofuz
parents:
diff changeset
376 .doTransform(ImplCtx.getImplementationDecl());
anatofuz
parents:
diff changeset
377 }