Deleted Added
full compact
SemaObjCProperty.cpp (221345) SemaObjCProperty.cpp (224145)
1//===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//

--- 10 unchanged lines hidden (view full) ---

19#include "llvm/ADT/DenseSet.h"
20
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// Grammar actions.
25//===----------------------------------------------------------------------===//
26
1//===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//

--- 10 unchanged lines hidden (view full) ---

19#include "llvm/ADT/DenseSet.h"
20
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// Grammar actions.
25//===----------------------------------------------------------------------===//
26
27/// Check the internal consistency of a property declaration.
28static void checkARCPropertyDecl(Sema &S, ObjCPropertyDecl *property) {
29 if (property->isInvalidDecl()) return;
30
31 ObjCPropertyDecl::PropertyAttributeKind propertyKind
32 = property->getPropertyAttributes();
33 Qualifiers::ObjCLifetime propertyLifetime
34 = property->getType().getObjCLifetime();
35
36 // Nothing to do if we don't have a lifetime.
37 if (propertyLifetime == Qualifiers::OCL_None) return;
38
39 Qualifiers::ObjCLifetime expectedLifetime;
40 unsigned selector;
41
42 // Strong properties should have either strong or no lifetime.
43 if (propertyKind & (ObjCPropertyDecl::OBJC_PR_retain |
44 ObjCPropertyDecl::OBJC_PR_strong |
45 ObjCPropertyDecl::OBJC_PR_copy)) {
46 expectedLifetime = Qualifiers::OCL_Strong;
47 selector = 0;
48 } else if (propertyKind & ObjCPropertyDecl::OBJC_PR_weak) {
49 expectedLifetime = Qualifiers::OCL_Weak;
50 selector = 1;
51 } else if (propertyKind & (ObjCPropertyDecl::OBJC_PR_assign |
52 ObjCPropertyDecl::OBJC_PR_unsafe_unretained) &&
53 property->getType()->isObjCRetainableType()) {
54 expectedLifetime = Qualifiers::OCL_ExplicitNone;
55 selector = 2;
56 } else {
57 // We have a lifetime qualifier but no dominating property
58 // attribute. That's okay.
59 return;
60 }
61
62 if (propertyLifetime == expectedLifetime) return;
63
64 property->setInvalidDecl();
65 S.Diag(property->getLocation(),
66 diag::err_arc_inconsistent_property_ownership)
67 << property->getDeclName()
68 << selector
69 << propertyLifetime;
70}
71
27Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
28 FieldDeclarator &FD,
29 ObjCDeclSpec &ODS,
30 Selector GetterSel,
31 Selector SetterSel,
32 Decl *ClassCategory,
33 bool *isOverridingProperty,
34 tok::ObjCKeywordKind MethodImplKind,
35 DeclContext *lexicalDC) {
36 unsigned Attributes = ODS.getPropertyAttributes();
72Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
73 FieldDeclarator &FD,
74 ObjCDeclSpec &ODS,
75 Selector GetterSel,
76 Selector SetterSel,
77 Decl *ClassCategory,
78 bool *isOverridingProperty,
79 tok::ObjCKeywordKind MethodImplKind,
80 DeclContext *lexicalDC) {
81 unsigned Attributes = ODS.getPropertyAttributes();
82 TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
83 QualType T = TSI->getType();
84 if ((getLangOptions().getGCMode() != LangOptions::NonGC &&
85 T.isObjCGCWeak()) ||
86 (getLangOptions().ObjCAutoRefCount &&
87 T.getObjCLifetime() == Qualifiers::OCL_Weak))
88 Attributes |= ObjCDeclSpec::DQ_PR_weak;
89
37 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
38 // default is readwrite!
39 !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
40 // property is defaulted to 'assign' if it is readwrite and is
41 // not retain or copy
42 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
43 (isReadWrite &&
44 !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
90 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
91 // default is readwrite!
92 !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
93 // property is defaulted to 'assign' if it is readwrite and is
94 // not retain or copy
95 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
96 (isReadWrite &&
97 !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
45 !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
98 !(Attributes & ObjCDeclSpec::DQ_PR_strong) &&
99 !(Attributes & ObjCDeclSpec::DQ_PR_copy) &&
100 !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) &&
101 !(Attributes & ObjCDeclSpec::DQ_PR_weak)));
46
102
47 TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
48
49 // Proceed with constructing the ObjCPropertDecls.
50 ObjCContainerDecl *ClassDecl =
51 cast<ObjCContainerDecl>(ClassCategory);
52
53 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
54 if (CDecl->IsClassExtension()) {
55 Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
56 FD, GetterSel, SetterSel,
57 isAssign, isReadWrite,
58 Attributes,
59 isOverridingProperty, TSI,
60 MethodImplKind);
103 // Proceed with constructing the ObjCPropertDecls.
104 ObjCContainerDecl *ClassDecl =
105 cast<ObjCContainerDecl>(ClassCategory);
106
107 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
108 if (CDecl->IsClassExtension()) {
109 Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
110 FD, GetterSel, SetterSel,
111 isAssign, isReadWrite,
112 Attributes,
113 isOverridingProperty, TSI,
114 MethodImplKind);
61 if (Res)
115 if (Res) {
62 CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
116 CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
117 if (getLangOptions().ObjCAutoRefCount)
118 checkARCPropertyDecl(*this, cast<ObjCPropertyDecl>(Res));
119 }
63 return Res;
64 }
65
120 return Res;
121 }
122
66 Decl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
67 GetterSel, SetterSel,
68 isAssign, isReadWrite,
69 Attributes, TSI, MethodImplKind);
123 ObjCPropertyDecl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
124 GetterSel, SetterSel,
125 isAssign, isReadWrite,
126 Attributes, TSI, MethodImplKind);
70 if (lexicalDC)
71 Res->setLexicalDeclContext(lexicalDC);
72
73 // Validate the attributes on the @property.
74 CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
127 if (lexicalDC)
128 Res->setLexicalDeclContext(lexicalDC);
129
130 // Validate the attributes on the @property.
131 CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
132
133 if (getLangOptions().ObjCAutoRefCount)
134 checkARCPropertyDecl(*this, Res);
135
75 return Res;
76}
77
78Decl *
79Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
80 SourceLocation AtLoc, FieldDeclarator &FD,
81 Selector GetterSel, Selector SetterSel,
82 const bool isAssign,

--- 30 unchanged lines hidden (view full) ---

113 PropertyId, AtLoc, T);
114 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
115 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
116 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
117 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
118 // Set setter/getter selector name. Needed later.
119 PDecl->setGetterName(GetterSel);
120 PDecl->setSetterName(SetterSel);
136 return Res;
137}
138
139Decl *
140Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
141 SourceLocation AtLoc, FieldDeclarator &FD,
142 Selector GetterSel, Selector SetterSel,
143 const bool isAssign,

--- 30 unchanged lines hidden (view full) ---

174 PropertyId, AtLoc, T);
175 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
176 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
177 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
178 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
179 // Set setter/getter selector name. Needed later.
180 PDecl->setGetterName(GetterSel);
181 PDecl->setSetterName(SetterSel);
182 ProcessDeclAttributes(S, PDecl, FD.D);
121 DC->addDecl(PDecl);
122
123 // We need to look in the @interface to see if the @property was
124 // already declared.
125 if (!CCPrimary) {
126 Diag(CDecl->getLocation(), diag::err_continuation_class);
127 *isOverridingProperty = true;
128 return 0;

--- 5 unchanged lines hidden (view full) ---

134
135 if (!PIDecl) {
136 // No matching property found in the primary class. Just fall thru
137 // and add property to continuation class's primary class.
138 ObjCPropertyDecl *PDecl =
139 CreatePropertyDecl(S, CCPrimary, AtLoc,
140 FD, GetterSel, SetterSel, isAssign, isReadWrite,
141 Attributes, T, MethodImplKind, DC);
183 DC->addDecl(PDecl);
184
185 // We need to look in the @interface to see if the @property was
186 // already declared.
187 if (!CCPrimary) {
188 Diag(CDecl->getLocation(), diag::err_continuation_class);
189 *isOverridingProperty = true;
190 return 0;

--- 5 unchanged lines hidden (view full) ---

196
197 if (!PIDecl) {
198 // No matching property found in the primary class. Just fall thru
199 // and add property to continuation class's primary class.
200 ObjCPropertyDecl *PDecl =
201 CreatePropertyDecl(S, CCPrimary, AtLoc,
202 FD, GetterSel, SetterSel, isAssign, isReadWrite,
203 Attributes, T, MethodImplKind, DC);
142 // Mark written attribute as having no attribute because
143 // this is not a user-written property declaration in primary
144 // class.
145 PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr);
146
147 // A case of continuation class adding a new property in the class. This
148 // is not what it was meant for. However, gcc supports it and so should we.
149 // Make sure setter/getters are declared here.
150 ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0,
151 /* lexicalDC = */ CDecl);
152 return PDecl;
153 }
154
155 // The property 'PIDecl's readonly attribute will be over-ridden
156 // with continuation class's readwrite property attribute!
157 unsigned PIkind = PIDecl->getPropertyAttributesAsWritten();
158 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
159 unsigned retainCopyNonatomic =
160 (ObjCPropertyDecl::OBJC_PR_retain |
204
205 // A case of continuation class adding a new property in the class. This
206 // is not what it was meant for. However, gcc supports it and so should we.
207 // Make sure setter/getters are declared here.
208 ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0,
209 /* lexicalDC = */ CDecl);
210 return PDecl;
211 }
212
213 // The property 'PIDecl's readonly attribute will be over-ridden
214 // with continuation class's readwrite property attribute!
215 unsigned PIkind = PIDecl->getPropertyAttributesAsWritten();
216 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
217 unsigned retainCopyNonatomic =
218 (ObjCPropertyDecl::OBJC_PR_retain |
219 ObjCPropertyDecl::OBJC_PR_strong |
161 ObjCPropertyDecl::OBJC_PR_copy |
162 ObjCPropertyDecl::OBJC_PR_nonatomic);
163 if ((Attributes & retainCopyNonatomic) !=
164 (PIkind & retainCopyNonatomic)) {
165 Diag(AtLoc, diag::warn_property_attr_mismatch);
166 Diag(PIDecl->getLocation(), diag::note_property_declare);
167 }
168 DeclContext *DC = cast<DeclContext>(CCPrimary);

--- 15 unchanged lines hidden (view full) ---

184 CCPrimary, isOverridingProperty,
185 MethodImplKind,
186 /* lexicalDC = */ CDecl);
187 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy);
188 }
189 PIDecl->makeitReadWriteAttribute();
190 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
191 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
220 ObjCPropertyDecl::OBJC_PR_copy |
221 ObjCPropertyDecl::OBJC_PR_nonatomic);
222 if ((Attributes & retainCopyNonatomic) !=
223 (PIkind & retainCopyNonatomic)) {
224 Diag(AtLoc, diag::warn_property_attr_mismatch);
225 Diag(PIDecl->getLocation(), diag::note_property_declare);
226 }
227 DeclContext *DC = cast<DeclContext>(CCPrimary);

--- 15 unchanged lines hidden (view full) ---

243 CCPrimary, isOverridingProperty,
244 MethodImplKind,
245 /* lexicalDC = */ CDecl);
246 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy);
247 }
248 PIDecl->makeitReadWriteAttribute();
249 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
250 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
251 if (Attributes & ObjCDeclSpec::DQ_PR_strong)
252 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
192 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
193 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
194 PIDecl->setSetterName(SetterSel);
195 } else {
196 // Tailor the diagnostics for the common case where a readwrite
197 // property is declared both in the @interface and the continuation.
198 // This is a common error where the user often intended the original
199 // declaration to be readonly.

--- 67 unchanged lines hidden (view full) ---

267
268 ProcessDeclAttributes(S, PDecl, FD.D);
269
270 // Regardless of setter/getter attribute, we save the default getter/setter
271 // selector names in anticipation of declaration of setter/getter methods.
272 PDecl->setGetterName(GetterSel);
273 PDecl->setSetterName(SetterSel);
274
253 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
254 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
255 PIDecl->setSetterName(SetterSel);
256 } else {
257 // Tailor the diagnostics for the common case where a readwrite
258 // property is declared both in the @interface and the continuation.
259 // This is a common error where the user often intended the original
260 // declaration to be readonly.

--- 67 unchanged lines hidden (view full) ---

328
329 ProcessDeclAttributes(S, PDecl, FD.D);
330
331 // Regardless of setter/getter attribute, we save the default getter/setter
332 // selector names in anticipation of declaration of setter/getter methods.
333 PDecl->setGetterName(GetterSel);
334 PDecl->setSetterName(SetterSel);
335
336 unsigned attributesAsWritten = 0;
275 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
337 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
338 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly;
339 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
340 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite;
341 if (Attributes & ObjCDeclSpec::DQ_PR_getter)
342 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter;
343 if (Attributes & ObjCDeclSpec::DQ_PR_setter)
344 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter;
345 if (Attributes & ObjCDeclSpec::DQ_PR_assign)
346 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign;
347 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
348 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain;
349 if (Attributes & ObjCDeclSpec::DQ_PR_strong)
350 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong;
351 if (Attributes & ObjCDeclSpec::DQ_PR_weak)
352 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak;
353 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
354 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy;
355 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
356 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
357 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
358 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic;
359 if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
360 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic;
361
362 PDecl->setPropertyAttributesAsWritten(
363 (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten);
364
365 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
276 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
277
278 if (Attributes & ObjCDeclSpec::DQ_PR_getter)
279 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
280
281 if (Attributes & ObjCDeclSpec::DQ_PR_setter)
282 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
283
284 if (isReadWrite)
285 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
286
287 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
288 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
289
366 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
367
368 if (Attributes & ObjCDeclSpec::DQ_PR_getter)
369 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
370
371 if (Attributes & ObjCDeclSpec::DQ_PR_setter)
372 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
373
374 if (isReadWrite)
375 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
376
377 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
378 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
379
380 if (Attributes & ObjCDeclSpec::DQ_PR_strong)
381 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
382
383 if (Attributes & ObjCDeclSpec::DQ_PR_weak)
384 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak);
385
290 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
291 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
292
386 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
387 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
388
389 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
390 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
391
293 if (isAssign)
294 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
295
296 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
297 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
298 else if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
299 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic);
300
392 if (isAssign)
393 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
394
395 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
396 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
397 else if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
398 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic);
399
301 PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes());
302
400 // 'unsafe_unretained' is alias for 'assign'.
401 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
402 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
403 if (isAssign)
404 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
405
303 if (MethodImplKind == tok::objc_required)
304 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
305 else if (MethodImplKind == tok::objc_optional)
306 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
307
308 return PDecl;
309}
310
406 if (MethodImplKind == tok::objc_required)
407 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
408 else if (MethodImplKind == tok::objc_optional)
409 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
410
411 return PDecl;
412}
413
414static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc,
415 ObjCPropertyDecl *property,
416 ObjCIvarDecl *ivar) {
417 if (property->isInvalidDecl() || ivar->isInvalidDecl()) return;
311
418
419 QualType propertyType = property->getType();
420 Qualifiers::ObjCLifetime propertyLifetime = propertyType.getObjCLifetime();
421 ObjCPropertyDecl::PropertyAttributeKind propertyKind
422 = property->getPropertyAttributes();
423
424 QualType ivarType = ivar->getType();
425 Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime();
426
427 // Case 1: strong properties.
428 if (propertyLifetime == Qualifiers::OCL_Strong ||
429 (propertyKind & (ObjCPropertyDecl::OBJC_PR_retain |
430 ObjCPropertyDecl::OBJC_PR_strong |
431 ObjCPropertyDecl::OBJC_PR_copy))) {
432 switch (ivarLifetime) {
433 case Qualifiers::OCL_Strong:
434 // Okay.
435 return;
436
437 case Qualifiers::OCL_None:
438 case Qualifiers::OCL_Autoreleasing:
439 // These aren't valid lifetimes for object ivars; don't diagnose twice.
440 return;
441
442 case Qualifiers::OCL_ExplicitNone:
443 case Qualifiers::OCL_Weak:
444 S.Diag(propertyImplLoc, diag::err_arc_strong_property_ownership)
445 << property->getDeclName()
446 << ivar->getDeclName()
447 << ivarLifetime;
448 break;
449 }
450
451 // Case 2: weak properties.
452 } else if (propertyLifetime == Qualifiers::OCL_Weak ||
453 (propertyKind & ObjCPropertyDecl::OBJC_PR_weak)) {
454 switch (ivarLifetime) {
455 case Qualifiers::OCL_Weak:
456 // Okay.
457 return;
458
459 case Qualifiers::OCL_None:
460 case Qualifiers::OCL_Autoreleasing:
461 // These aren't valid lifetimes for object ivars; don't diagnose twice.
462 return;
463
464 case Qualifiers::OCL_ExplicitNone:
465 case Qualifiers::OCL_Strong:
466 S.Diag(propertyImplLoc, diag::error_weak_property)
467 << property->getDeclName()
468 << ivar->getDeclName();
469 break;
470 }
471
472 // Case 3: assign properties.
473 } else if ((propertyKind & ObjCPropertyDecl::OBJC_PR_assign) &&
474 propertyType->isObjCRetainableType()) {
475 switch (ivarLifetime) {
476 case Qualifiers::OCL_ExplicitNone:
477 // Okay.
478 return;
479
480 case Qualifiers::OCL_None:
481 case Qualifiers::OCL_Autoreleasing:
482 // These aren't valid lifetimes for object ivars; don't diagnose twice.
483 return;
484
485 case Qualifiers::OCL_Weak:
486 case Qualifiers::OCL_Strong:
487 S.Diag(propertyImplLoc, diag::err_arc_assign_property_ownership)
488 << property->getDeclName()
489 << ivar->getDeclName();
490 break;
491 }
492
493 // Any other property should be ignored.
494 } else {
495 return;
496 }
497
498 S.Diag(property->getLocation(), diag::note_property_declare);
499}
500
501
312/// ActOnPropertyImplDecl - This routine performs semantic checks and
313/// builds the AST node for a property implementation declaration; declared
314/// as @synthesize or @dynamic.
315///
316Decl *Sema::ActOnPropertyImplDecl(Scope *S,
317 SourceLocation AtLoc,
318 SourceLocation PropertyLoc,
319 bool Synthesize,

--- 71 unchanged lines hidden (view full) ---

391 }
392 } else {
393 Diag(AtLoc, diag::error_bad_property_context);
394 return 0;
395 }
396 ObjCIvarDecl *Ivar = 0;
397 // Check that we have a valid, previously declared ivar for @synthesize
398 if (Synthesize) {
502/// ActOnPropertyImplDecl - This routine performs semantic checks and
503/// builds the AST node for a property implementation declaration; declared
504/// as @synthesize or @dynamic.
505///
506Decl *Sema::ActOnPropertyImplDecl(Scope *S,
507 SourceLocation AtLoc,
508 SourceLocation PropertyLoc,
509 bool Synthesize,

--- 71 unchanged lines hidden (view full) ---

581 }
582 } else {
583 Diag(AtLoc, diag::error_bad_property_context);
584 return 0;
585 }
586 ObjCIvarDecl *Ivar = 0;
587 // Check that we have a valid, previously declared ivar for @synthesize
588 if (Synthesize) {
589 if (getLangOptions().ObjCAutoRefCount &&
590 !property->hasWrittenStorageAttribute() &&
591 property->getType()->isObjCRetainableType()) {
592 Diag(PropertyLoc, diag::err_arc_objc_property_default_assign_on_object);
593 Diag(property->getLocation(), diag::note_property_declare);
594 }
595
399 // @synthesize
400 if (!PropertyIvar)
401 PropertyIvar = PropertyId;
596 // @synthesize
597 if (!PropertyIvar)
598 PropertyIvar = PropertyId;
599 ObjCPropertyDecl::PropertyAttributeKind kind
600 = property->getPropertyAttributes();
402 QualType PropType = Context.getCanonicalType(property->getType());
403 QualType PropertyIvarType = PropType;
404 if (PropType->isReferenceType())
405 PropertyIvarType = cast<ReferenceType>(PropType)->getPointeeType();
406 // Check that this is a previously declared 'ivar' in 'IDecl' interface
407 ObjCInterfaceDecl *ClassDeclared;
408 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
409 if (!Ivar) {
601 QualType PropType = Context.getCanonicalType(property->getType());
602 QualType PropertyIvarType = PropType;
603 if (PropType->isReferenceType())
604 PropertyIvarType = cast<ReferenceType>(PropType)->getPointeeType();
605 // Check that this is a previously declared 'ivar' in 'IDecl' interface
606 ObjCInterfaceDecl *ClassDeclared;
607 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
608 if (!Ivar) {
609 // In ARC, give the ivar a lifetime qualifier based on its
610 // property attributes.
611 if (getLangOptions().ObjCAutoRefCount &&
612 !PropertyIvarType.getObjCLifetime()) {
613
614 // retain/copy have retaining lifetime.
615 if (kind & (ObjCPropertyDecl::OBJC_PR_retain |
616 ObjCPropertyDecl::OBJC_PR_strong |
617 ObjCPropertyDecl::OBJC_PR_copy)) {
618 Qualifiers qs;
619 qs.addObjCLifetime(Qualifiers::OCL_Strong);
620 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
621 }
622 else if (kind & ObjCPropertyDecl::OBJC_PR_weak) {
623 if (!getLangOptions().ObjCRuntimeHasWeak) {
624 Diag(PropertyLoc, diag::err_arc_weak_no_runtime);
625 Diag(property->getLocation(), diag::note_property_declare);
626 }
627 Qualifiers qs;
628 qs.addObjCLifetime(Qualifiers::OCL_Weak);
629 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
630 }
631 else if (kind & ObjCPropertyDecl::OBJC_PR_assign &&
632 PropertyIvarType->isObjCRetainableType()) {
633 // assume that an 'assign' property synthesizes __unsafe_unretained
634 // ivar
635 Qualifiers qs;
636 qs.addObjCLifetime(Qualifiers::OCL_ExplicitNone);
637 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
638 }
639 }
640
641 if (kind & ObjCPropertyDecl::OBJC_PR_weak &&
642 !getLangOptions().ObjCAutoRefCount &&
643 getLangOptions().getGCMode() == LangOptions::NonGC) {
644 Diag(PropertyLoc, diag::error_synthesize_weak_non_arc_or_gc);
645 Diag(property->getLocation(), diag::note_property_declare);
646 }
647
410 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,
411 PropertyLoc, PropertyLoc, PropertyIvar,
412 PropertyIvarType, /*Dinfo=*/0,
413 ObjCIvarDecl::Private,
414 (Expr *)0, true);
415 ClassImpDecl->addDecl(Ivar);
416 IDecl->makeDeclVisibleInContext(Ivar, false);
417 property->setPropertyIvarDecl(Ivar);

--- 12 unchanged lines hidden (view full) ---

430 // Note! I deliberately want it to fall thru so more errors are caught.
431 }
432 QualType IvarType = Context.getCanonicalType(Ivar->getType());
433
434 // Check that type of property and its ivar are type compatible.
435 if (PropertyIvarType != IvarType) {
436 bool compat = false;
437 if (isa<ObjCObjectPointerType>(PropertyIvarType)
648 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,
649 PropertyLoc, PropertyLoc, PropertyIvar,
650 PropertyIvarType, /*Dinfo=*/0,
651 ObjCIvarDecl::Private,
652 (Expr *)0, true);
653 ClassImpDecl->addDecl(Ivar);
654 IDecl->makeDeclVisibleInContext(Ivar, false);
655 property->setPropertyIvarDecl(Ivar);

--- 12 unchanged lines hidden (view full) ---

668 // Note! I deliberately want it to fall thru so more errors are caught.
669 }
670 QualType IvarType = Context.getCanonicalType(Ivar->getType());
671
672 // Check that type of property and its ivar are type compatible.
673 if (PropertyIvarType != IvarType) {
674 bool compat = false;
675 if (isa<ObjCObjectPointerType>(PropertyIvarType)
438 && isa<ObjCObjectPointerType>(IvarType))
676 && isa(IvarType))
439 compat =
440 Context.canAssignObjCInterfaces(
441 PropertyIvarType->getAs<ObjCObjectPointerType>(),
442 IvarType->getAs<ObjCObjectPointerType>());
443 else {
444 SourceLocation Loc = PropertyIvarLoc;
445 if (Loc.isInvalid())
446 Loc = PropertyLoc;

--- 18 unchanged lines hidden (view full) ---

465 lhsType->isArithmeticType()) {
466 Diag(PropertyLoc, diag::error_property_ivar_type)
467 << property->getDeclName() << PropType
468 << Ivar->getDeclName() << IvarType;
469 Diag(Ivar->getLocation(), diag::note_ivar_decl);
470 // Fall thru - see previous comment
471 }
472 // __weak is explicit. So it works on Canonical type.
677 compat =
678 Context.canAssignObjCInterfaces(
679 PropertyIvarType->getAs<ObjCObjectPointerType>(),
680 IvarType->getAs<ObjCObjectPointerType>());
681 else {
682 SourceLocation Loc = PropertyIvarLoc;
683 if (Loc.isInvalid())
684 Loc = PropertyLoc;

--- 18 unchanged lines hidden (view full) ---

703 lhsType->isArithmeticType()) {
704 Diag(PropertyLoc, diag::error_property_ivar_type)
705 << property->getDeclName() << PropType
706 << Ivar->getDeclName() << IvarType;
707 Diag(Ivar->getLocation(), diag::note_ivar_decl);
708 // Fall thru - see previous comment
709 }
710 // __weak is explicit. So it works on Canonical type.
473 if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
474 getLangOptions().getGCMode() != LangOptions::NonGC) {
711 if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
712 getLangOptions().getGCMode() != LangOptions::NonGC)) {
475 Diag(PropertyLoc, diag::error_weak_property)
476 << property->getDeclName() << Ivar->getDeclName();
477 // Fall thru - see previous comment
478 }
713 Diag(PropertyLoc, diag::error_weak_property)
714 << property->getDeclName() << Ivar->getDeclName();
715 // Fall thru - see previous comment
716 }
717 // Fall thru - see previous comment
479 if ((property->getType()->isObjCObjectPointerType() ||
480 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
481 getLangOptions().getGCMode() != LangOptions::NonGC) {
482 Diag(PropertyLoc, diag::error_strong_property)
483 << property->getDeclName() << Ivar->getDeclName();
484 // Fall thru - see previous comment
485 }
486 }
718 if ((property->getType()->isObjCObjectPointerType() ||
719 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
720 getLangOptions().getGCMode() != LangOptions::NonGC) {
721 Diag(PropertyLoc, diag::error_strong_property)
722 << property->getDeclName() << Ivar->getDeclName();
723 // Fall thru - see previous comment
724 }
725 }
726 if (getLangOptions().ObjCAutoRefCount)
727 checkARCPropertyImpl(*this, PropertyLoc, property, Ivar);
487 } else if (PropertyIvar)
488 // @dynamic
489 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
728 } else if (PropertyIvar)
729 // @dynamic
730 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
731
490 assert (property && "ActOnPropertyImplDecl - property declaration missing");
491 ObjCPropertyImplDecl *PIDecl =
492 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
493 property,
494 (Synthesize ?
495 ObjCPropertyImplDecl::Synthesize
496 : ObjCPropertyImplDecl::Dynamic),
497 Ivar, PropertyIvarLoc);

--- 20 unchanged lines hidden (view full) ---

518 Owned(IvarRefExpr));
519 if (!Res.isInvalid()) {
520 Expr *ResExpr = Res.takeAs<Expr>();
521 if (ResExpr)
522 ResExpr = MaybeCreateExprWithCleanups(ResExpr);
523 PIDecl->setGetterCXXConstructor(ResExpr);
524 }
525 }
732 assert (property && "ActOnPropertyImplDecl - property declaration missing");
733 ObjCPropertyImplDecl *PIDecl =
734 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
735 property,
736 (Synthesize ?
737 ObjCPropertyImplDecl::Synthesize
738 : ObjCPropertyImplDecl::Dynamic),
739 Ivar, PropertyIvarLoc);

--- 20 unchanged lines hidden (view full) ---

760 Owned(IvarRefExpr));
761 if (!Res.isInvalid()) {
762 Expr *ResExpr = Res.takeAs<Expr>();
763 if (ResExpr)
764 ResExpr = MaybeCreateExprWithCleanups(ResExpr);
765 PIDecl->setGetterCXXConstructor(ResExpr);
766 }
767 }
768 if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
769 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
770 Diag(getterMethod->getLocation(),
771 diag::warn_property_getter_owning_mismatch);
772 Diag(property->getLocation(), diag::note_property_declare);
773 }
526 }
527 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
528 setterMethod->createImplicitParams(Context, IDecl);
529 if (getLangOptions().CPlusPlus && Synthesize
530 && Ivar->getType()->isRecordType()) {
531 // FIXME. Eventually we want to do this for Objective-C as well.
532 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
533 DeclRefExpr *SelfExpr =

--- 93 unchanged lines hidden (view full) ---

627 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
628 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
629 Diag(Property->getLocation(), diag::warn_readonly_property)
630 << Property->getDeclName() << inheritedName;
631 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
632 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
633 Diag(Property->getLocation(), diag::warn_property_attribute)
634 << Property->getDeclName() << "copy" << inheritedName;
774 }
775 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
776 setterMethod->createImplicitParams(Context, IDecl);
777 if (getLangOptions().CPlusPlus && Synthesize
778 && Ivar->getType()->isRecordType()) {
779 // FIXME. Eventually we want to do this for Objective-C as well.
780 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
781 DeclRefExpr *SelfExpr =

--- 93 unchanged lines hidden (view full) ---

875 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
876 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
877 Diag(Property->getLocation(), diag::warn_readonly_property)
878 << Property->getDeclName() << inheritedName;
879 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
880 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
881 Diag(Property->getLocation(), diag::warn_property_attribute)
882 << Property->getDeclName() << "copy" << inheritedName;
635 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
636 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
637 Diag(Property->getLocation(), diag::warn_property_attribute)
638 << Property->getDeclName() << "retain" << inheritedName;
883 else {
884 unsigned CAttrRetain =
885 (CAttr &
886 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
887 unsigned SAttrRetain =
888 (SAttr &
889 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
890 bool CStrong = (CAttrRetain != 0);
891 bool SStrong = (SAttrRetain != 0);
892 if (CStrong != SStrong)
893 Diag(Property->getLocation(), diag::warn_property_attribute)
894 << Property->getDeclName() << "retain (or strong)" << inheritedName;
895 }
639
640 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
641 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
642 Diag(Property->getLocation(), diag::warn_property_attribute)
643 << Property->getDeclName() << "atomic" << inheritedName;
644 if (Property->getSetterName() != SuperProperty->getSetterName())
645 Diag(Property->getLocation(), diag::warn_property_attribute)
646 << Property->getDeclName() << "setter" << inheritedName;
647 if (Property->getGetterName() != SuperProperty->getGetterName())
648 Diag(Property->getLocation(), diag::warn_property_attribute)
649 << Property->getDeclName() << "getter" << inheritedName;
650
651 QualType LHSType =
652 Context.getCanonicalType(SuperProperty->getType());
653 QualType RHSType =
654 Context.getCanonicalType(Property->getType());
655
896
897 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
898 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
899 Diag(Property->getLocation(), diag::warn_property_attribute)
900 << Property->getDeclName() << "atomic" << inheritedName;
901 if (Property->getSetterName() != SuperProperty->getSetterName())
902 Diag(Property->getLocation(), diag::warn_property_attribute)
903 << Property->getDeclName() << "setter" << inheritedName;
904 if (Property->getGetterName() != SuperProperty->getGetterName())
905 Diag(Property->getLocation(), diag::warn_property_attribute)
906 << Property->getDeclName() << "getter" << inheritedName;
907
908 QualType LHSType =
909 Context.getCanonicalType(SuperProperty->getType());
910 QualType RHSType =
911 Context.getCanonicalType(Property->getType());
912
656 if (!Context.typesAreCompatible(LHSType, RHSType)) {
657 // FIXME: Incorporate this test with typesAreCompatible.
658 if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType())
659 if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false))
660 return;
661 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
662 << Property->getType() << SuperProperty->getType() << inheritedName;
913 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) {
914 // Do cases not handled in above.
915 // FIXME. For future support of covariant property types, revisit this.
916 bool IncompatibleObjC = false;
917 QualType ConvertedType;
918 if (!isObjCPointerConversion(RHSType, LHSType,
919 ConvertedType, IncompatibleObjC) ||
920 IncompatibleObjC)
921 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
922 << Property->getType() << SuperProperty->getType() << inheritedName;
663 }
664}
665
666bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
667 ObjCMethodDecl *GetterMethod,
668 SourceLocation Loc) {
669 if (GetterMethod &&
670 GetterMethod->getResultType() != property->getType()) {

--- 374 unchanged lines hidden (view full) ---

1045 PropImplMap.insert((*I)->getPropertyDecl());
1046
1047 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator
1048 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
1049 ObjCPropertyDecl *Prop = P->second;
1050 // Is there a matching propery synthesize/dynamic?
1051 if (Prop->isInvalidDecl() ||
1052 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
923 }
924}
925
926bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
927 ObjCMethodDecl *GetterMethod,
928 SourceLocation Loc) {
929 if (GetterMethod &&
930 GetterMethod->getResultType() != property->getType()) {

--- 374 unchanged lines hidden (view full) ---

1305 PropImplMap.insert((*I)->getPropertyDecl());
1306
1307 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator
1308 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
1309 ObjCPropertyDecl *Prop = P->second;
1310 // Is there a matching propery synthesize/dynamic?
1311 if (Prop->isInvalidDecl() ||
1312 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
1053 PropImplMap.count(Prop))
1313 PropImplMap.count(Prop) || Prop->hasAttr<UnavailableAttr>())
1054 continue;
1055 if (!InsMap.count(Prop->getGetterName())) {
1056 Diag(Prop->getLocation(),
1057 isa<ObjCCategoryDecl>(CDecl) ?
1058 diag::warn_setter_getter_impl_required_in_category :
1059 diag::warn_setter_getter_impl_required)
1060 << Prop->getDeclName() << Prop->getGetterName();
1061 Diag(IMPDecl->getLocation(),

--- 68 unchanged lines hidden (view full) ---

1130 Diag(MethodLoc, diag::warn_atomic_property_rule)
1131 << Property->getIdentifier();
1132 Diag(Property->getLocation(), diag::note_property_declare);
1133 }
1134 }
1135 }
1136}
1137
1314 continue;
1315 if (!InsMap.count(Prop->getGetterName())) {
1316 Diag(Prop->getLocation(),
1317 isa<ObjCCategoryDecl>(CDecl) ?
1318 diag::warn_setter_getter_impl_required_in_category :
1319 diag::warn_setter_getter_impl_required)
1320 << Prop->getDeclName() << Prop->getGetterName();
1321 Diag(IMPDecl->getLocation(),

--- 68 unchanged lines hidden (view full) ---

1390 Diag(MethodLoc, diag::warn_atomic_property_rule)
1391 << Property->getIdentifier();
1392 Diag(Property->getLocation(), diag::note_property_declare);
1393 }
1394 }
1395 }
1396}
1397
1398void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) {
1399 if (getLangOptions().getGCMode() == LangOptions::GCOnly)
1400 return;
1401
1402 for (ObjCImplementationDecl::propimpl_iterator
1403 i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
1404 ObjCPropertyImplDecl *PID = *i;
1405 if (PID->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
1406 continue;
1407
1408 const ObjCPropertyDecl *PD = PID->getPropertyDecl();
1409 if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() &&
1410 !D->getInstanceMethod(PD->getGetterName())) {
1411 ObjCMethodDecl *method = PD->getGetterMethodDecl();
1412 if (!method)
1413 continue;
1414 ObjCMethodFamily family = method->getMethodFamily();
1415 if (family == OMF_alloc || family == OMF_copy ||
1416 family == OMF_mutableCopy || family == OMF_new) {
1417 if (getLangOptions().ObjCAutoRefCount)
1418 Diag(PID->getLocation(), diag::err_ownin_getter_rule);
1419 else
1420 Diag(PID->getLocation(), diag::warn_ownin_getter_rule);
1421 Diag(PD->getLocation(), diag::note_property_declare);
1422 }
1423 }
1424 }
1425}
1426
1138/// AddPropertyAttrs - Propagates attributes from a property to the
1139/// implicitly-declared getter or setter for that property.
1140static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod,
1141 ObjCPropertyDecl *Property) {
1142 // Should we just clone all attributes over?
1143 for (Decl::attr_iterator A = Property->attr_begin(),
1144 AEnd = Property->attr_end();
1145 A != AEnd; ++A) {

--- 63 unchanged lines hidden (view full) ---

1209 CD->addDecl(GetterMethod);
1210
1211 AddPropertyAttrs(*this, GetterMethod, property);
1212
1213 // FIXME: Eventually this shouldn't be needed, as the lexical context
1214 // and the real context should be the same.
1215 if (lexicalDC)
1216 GetterMethod->setLexicalDeclContext(lexicalDC);
1427/// AddPropertyAttrs - Propagates attributes from a property to the
1428/// implicitly-declared getter or setter for that property.
1429static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod,
1430 ObjCPropertyDecl *Property) {
1431 // Should we just clone all attributes over?
1432 for (Decl::attr_iterator A = Property->attr_begin(),
1433 AEnd = Property->attr_end();
1434 A != AEnd; ++A) {

--- 63 unchanged lines hidden (view full) ---

1498 CD->addDecl(GetterMethod);
1499
1500 AddPropertyAttrs(*this, GetterMethod, property);
1501
1502 // FIXME: Eventually this shouldn't be needed, as the lexical context
1503 // and the real context should be the same.
1504 if (lexicalDC)
1505 GetterMethod->setLexicalDeclContext(lexicalDC);
1506 if (property->hasAttr<NSReturnsNotRetainedAttr>())
1507 GetterMethod->addAttr(
1508 ::new (Context) NSReturnsNotRetainedAttr(Loc, Context));
1217 } else
1218 // A user declared getter will be synthesize when @synthesize of
1219 // the property with the same name is seen in the @implementation
1220 GetterMethod->setSynthesized(true);
1221 property->setGetterMethodDecl(GetterMethod);
1222
1223 // Skip setter if property is read-only.
1224 if (!property->isReadOnly()) {

--- 15 unchanged lines hidden (view full) ---

1240 ObjCMethodDecl::Optional :
1241 ObjCMethodDecl::Required);
1242
1243 // Invent the arguments for the setter. We don't bother making a
1244 // nice name for the argument.
1245 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
1246 Loc, Loc,
1247 property->getIdentifier(),
1509 } else
1510 // A user declared getter will be synthesize when @synthesize of
1511 // the property with the same name is seen in the @implementation
1512 GetterMethod->setSynthesized(true);
1513 property->setGetterMethodDecl(GetterMethod);
1514
1515 // Skip setter if property is read-only.
1516 if (!property->isReadOnly()) {

--- 15 unchanged lines hidden (view full) ---

1532 ObjCMethodDecl::Optional :
1533 ObjCMethodDecl::Required);
1534
1535 // Invent the arguments for the setter. We don't bother making a
1536 // nice name for the argument.
1537 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
1538 Loc, Loc,
1539 property->getIdentifier(),
1248 property->getType(),
1540 property->getType().getUnqualifiedType(),
1249 /*TInfo=*/0,
1250 SC_None,
1251 SC_None,
1252 0);
1253 SetterMethod->setMethodParams(Context, &Argument, 1, 1);
1254
1255 AddPropertyAttrs(*this, SetterMethod, property);
1256

--- 25 unchanged lines hidden (view full) ---

1282 if (SetterMethod)
1283 AddInstanceMethodToGlobalPool(SetterMethod);
1284}
1285
1286void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
1287 SourceLocation Loc,
1288 unsigned &Attributes) {
1289 // FIXME: Improve the reported location.
1541 /*TInfo=*/0,
1542 SC_None,
1543 SC_None,
1544 0);
1545 SetterMethod->setMethodParams(Context, &Argument, 1, 1);
1546
1547 AddPropertyAttrs(*this, SetterMethod, property);
1548

--- 25 unchanged lines hidden (view full) ---

1574 if (SetterMethod)
1575 AddInstanceMethodToGlobalPool(SetterMethod);
1576}
1577
1578void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
1579 SourceLocation Loc,
1580 unsigned &Attributes) {
1581 // FIXME: Improve the reported location.
1290 if (!PDecl)
1582 if (!PDecl || PDecl->isInvalidDecl())
1291 return;
1292
1293 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl);
1294 QualType PropertyTy = PropertyDecl->getType();
1295
1296 // readonly and readwrite/assign/retain/copy conflict.
1297 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1298 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
1299 ObjCDeclSpec::DQ_PR_assign |
1583 return;
1584
1585 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl);
1586 QualType PropertyTy = PropertyDecl->getType();
1587
1588 // readonly and readwrite/assign/retain/copy conflict.
1589 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1590 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
1591 ObjCDeclSpec::DQ_PR_assign |
1592 ObjCDeclSpec::DQ_PR_unsafe_unretained |
1300 ObjCDeclSpec::DQ_PR_copy |
1593 ObjCDeclSpec::DQ_PR_copy |
1301 ObjCDeclSpec::DQ_PR_retain))) {
1594 ObjCDeclSpec::DQ_PR_retain |
1595 ObjCDeclSpec::DQ_PR_strong))) {
1302 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ?
1303 "readwrite" :
1304 (Attributes & ObjCDeclSpec::DQ_PR_assign) ?
1305 "assign" :
1596 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ?
1597 "readwrite" :
1598 (Attributes & ObjCDeclSpec::DQ_PR_assign) ?
1599 "assign" :
1600 (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) ?
1601 "unsafe_unretained" :
1306 (Attributes & ObjCDeclSpec::DQ_PR_copy) ?
1307 "copy" : "retain";
1308
1309 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ?
1310 diag::err_objc_property_attr_mutually_exclusive :
1311 diag::warn_objc_property_attr_mutually_exclusive)
1312 << "readonly" << which;
1313 }
1314
1315 // Check for copy or retain on non-object types.
1602 (Attributes & ObjCDeclSpec::DQ_PR_copy) ?
1603 "copy" : "retain";
1604
1605 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ?
1606 diag::err_objc_property_attr_mutually_exclusive :
1607 diag::warn_objc_property_attr_mutually_exclusive)
1608 << "readonly" << which;
1609 }
1610
1611 // Check for copy or retain on non-object types.
1316 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
1317 !PropertyTy->isObjCObjectPointerType() &&
1318 !PropertyTy->isBlockPointerType() &&
1319 !Context.isObjCNSObjectType(PropertyTy) &&
1612 if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
1613 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) &&
1614 !PropertyTy->isObjCRetainableType() &&
1320 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) {
1321 Diag(Loc, diag::err_objc_property_requires_object)
1615 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) {
1616 Diag(Loc, diag::err_objc_property_requires_object)
1322 << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
1323 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
1617 << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" :
1618 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)");
1619 Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
1620 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong);
1324 }
1325
1326 // Check for more than one of { assign, copy, retain }.
1327 if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
1328 if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1329 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1330 << "assign" << "copy";
1331 Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
1332 }
1333 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1334 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1335 << "assign" << "retain";
1336 Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
1337 }
1621 }
1622
1623 // Check for more than one of { assign, copy, retain }.
1624 if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
1625 if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1626 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1627 << "assign" << "copy";
1628 Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
1629 }
1630 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1631 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1632 << "assign" << "retain";
1633 Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
1634 }
1635 if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
1636 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1637 << "assign" << "strong";
1638 Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
1639 }
1640 if (getLangOptions().ObjCAutoRefCount &&
1641 (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
1642 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1643 << "assign" << "weak";
1644 Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
1645 }
1646 } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) {
1647 if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1648 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1649 << "unsafe_unretained" << "copy";
1650 Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
1651 }
1652 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1653 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1654 << "unsafe_unretained" << "retain";
1655 Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
1656 }
1657 if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
1658 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1659 << "unsafe_unretained" << "strong";
1660 Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
1661 }
1662 if (getLangOptions().ObjCAutoRefCount &&
1663 (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
1664 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1665 << "unsafe_unretained" << "weak";
1666 Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
1667 }
1338 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1339 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1340 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1341 << "copy" << "retain";
1342 Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
1343 }
1668 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1669 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1670 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1671 << "copy" << "retain";
1672 Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
1673 }
1674 if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
1675 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1676 << "copy" << "strong";
1677 Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
1678 }
1679 if (Attributes & ObjCDeclSpec::DQ_PR_weak) {
1680 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1681 << "copy" << "weak";
1682 Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
1683 }
1344 }
1684 }
1685 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) &&
1686 (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
1687 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1688 << "retain" << "weak";
1689 Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
1690 }
1691 else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) &&
1692 (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
1693 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1694 << "strong" << "weak";
1695 Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
1696 }
1345
1346 // Warn if user supplied no assignment attribute, property is
1347 // readwrite, and this is an object type.
1348 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
1697
1698 // Warn if user supplied no assignment attribute, property is
1699 // readwrite, and this is an object type.
1700 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
1349 ObjCDeclSpec::DQ_PR_retain)) &&
1701 ObjCDeclSpec::DQ_PR_unsafe_unretained |
1702 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong |
1703 ObjCDeclSpec::DQ_PR_weak)) &&
1350 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1351 PropertyTy->isObjCObjectPointerType()) {
1352 // Skip this warning in gc-only mode.
1353 if (getLangOptions().getGCMode() != LangOptions::GCOnly)
1354 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
1355
1356 // If non-gc code warn that this is likely inappropriate.
1357 if (getLangOptions().getGCMode() == LangOptions::NonGC)

--- 14 unchanged lines hidden ---
1704 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1705 PropertyTy->isObjCObjectPointerType()) {
1706 // Skip this warning in gc-only mode.
1707 if (getLangOptions().getGCMode() != LangOptions::GCOnly)
1708 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
1709
1710 // If non-gc code warn that this is likely inappropriate.
1711 if (getLangOptions().getGCMode() == LangOptions::NonGC)

--- 14 unchanged lines hidden ---