blob: fb337ba1d71a37f7616e87f179bd41196f63c77f [file] [log] [blame]
Chris Lattner89375192008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
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//===----------------------------------------------------------------------===//
9//
10// This file implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
Argyrios Kyrtzidis7d847c92011-09-01 00:58:55 +000016#include "clang/AST/ASTMutationListener.h"
Benjamin Kramerea70eb32012-12-01 15:09:41 +000017#include "clang/AST/Attr.h"
18#include "clang/AST/Stmt.h"
Steve Naroffc4173fa2009-02-22 19:35:57 +000019#include "llvm/ADT/STLExtras.h"
Anna Zaks454477c2012-09-27 19:45:11 +000020#include "llvm/ADT/SmallString.h"
Chris Lattner89375192008-03-16 00:19:01 +000021using namespace clang;
22
Chris Lattner8d8829e2008-03-16 00:49:28 +000023//===----------------------------------------------------------------------===//
Chris Lattner4d1eb762009-02-20 21:16:26 +000024// ObjCListBase
25//===----------------------------------------------------------------------===//
26
Chris Lattner22298722009-02-20 21:35:13 +000027void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
Douglas Gregorb412e172010-07-25 18:17:45 +000028 List = 0;
Chris Lattner4d1eb762009-02-20 21:16:26 +000029 if (Elts == 0) return; // Setting to an empty list is a noop.
Mike Stump11289f42009-09-09 15:08:12 +000030
31
Chris Lattner7c981a72009-02-20 21:44:01 +000032 List = new (Ctx) void*[Elts];
Chris Lattner4d1eb762009-02-20 21:16:26 +000033 NumElts = Elts;
34 memcpy(List, InList, sizeof(void*)*Elts);
35}
36
Douglas Gregor002b6712010-01-16 15:02:53 +000037void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
38 const SourceLocation *Locs, ASTContext &Ctx) {
39 if (Elts == 0)
40 return;
41
42 Locations = new (Ctx) SourceLocation[Elts];
43 memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
44 set(InList, Elts, Ctx);
45}
46
Chris Lattner4d1eb762009-02-20 21:16:26 +000047//===----------------------------------------------------------------------===//
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +000048// ObjCInterfaceDecl
Chris Lattner8d8829e2008-03-16 00:49:28 +000049//===----------------------------------------------------------------------===//
50
David Blaikie68e081d2011-12-20 02:48:34 +000051void ObjCContainerDecl::anchor() { }
52
Fariborz Jahanian68453832009-06-05 18:16:35 +000053/// getIvarDecl - This method looks up an ivar in this ContextDecl.
54///
55ObjCIvarDecl *
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +000056ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
David Blaikieff7d47a2012-12-19 00:45:41 +000057 lookup_const_result R = lookup(Id);
58 for (lookup_const_iterator Ivar = R.begin(), IvarEnd = R.end();
59 Ivar != IvarEnd; ++Ivar) {
Fariborz Jahanian68453832009-06-05 18:16:35 +000060 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
61 return ivar;
62 }
63 return 0;
64}
65
Argyrios Kyrtzidis6de05602009-07-25 22:15:22 +000066// Get the local instance/class method declared in this interface.
Douglas Gregorbcced4e2009-04-09 21:40:53 +000067ObjCMethodDecl *
Argyrios Kyrtzidisbd8cd3e2013-03-29 21:51:48 +000068ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
69 bool AllowHidden) const {
Douglas Gregoreed49792013-01-17 00:38:46 +000070 // If this context is a hidden protocol definition, don't find any
71 // methods there.
72 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
73 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
Argyrios Kyrtzidisbd8cd3e2013-03-29 21:51:48 +000074 if (Def->isHidden() && !AllowHidden)
Douglas Gregoreed49792013-01-17 00:38:46 +000075 return 0;
76 }
77
Steve Naroffc4173fa2009-02-22 19:35:57 +000078 // Since instance & class methods can have the same name, the loop below
79 // ensures we get the correct method.
80 //
81 // @interface Whatever
82 // - (int) class_method;
83 // + (float) class_method;
84 // @end
85 //
David Blaikieff7d47a2012-12-19 00:45:41 +000086 lookup_const_result R = lookup(Sel);
87 for (lookup_const_iterator Meth = R.begin(), MethEnd = R.end();
88 Meth != MethEnd; ++Meth) {
Steve Naroffc4173fa2009-02-22 19:35:57 +000089 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
Argyrios Kyrtzidis6de05602009-07-25 22:15:22 +000090 if (MD && MD->isInstanceMethod() == isInstance)
Steve Naroffc4173fa2009-02-22 19:35:57 +000091 return MD;
92 }
Steve Naroff35c62ae2009-01-08 17:28:14 +000093 return 0;
94}
95
Fariborz Jahanian1446b342013-03-21 20:50:53 +000096/// HasUserDeclaredSetterMethod - This routine returns 'true' if a user declared setter
97/// method was found in the class, its protocols, its super classes or categories.
98/// It also returns 'true' if one of its categories has declared a 'readwrite' property.
99/// This is because, user must provide a setter method for the category's 'readwrite'
100/// property.
101bool
102ObjCContainerDecl::HasUserDeclaredSetterMethod(const ObjCPropertyDecl *Property) const {
103 Selector Sel = Property->getSetterName();
104 lookup_const_result R = lookup(Sel);
105 for (lookup_const_iterator Meth = R.begin(), MethEnd = R.end();
106 Meth != MethEnd; ++Meth) {
107 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
108 if (MD && MD->isInstanceMethod() && !MD->isImplicit())
109 return true;
110 }
111
112 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
113 // Also look into categories, including class extensions, looking
114 // for a user declared instance method.
Aaron Ballman3fe486a2014-03-13 21:23:55 +0000115 for (const auto *Cat : ID->visible_categories()) {
Fariborz Jahanian1446b342013-03-21 20:50:53 +0000116 if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
117 if (!MD->isImplicit())
118 return true;
119 if (Cat->IsClassExtension())
120 continue;
121 // Also search through the categories looking for a 'readwrite' declaration
122 // of this property. If one found, presumably a setter will be provided
123 // (properties declared in categories will not get auto-synthesized).
Aaron Ballmand174edf2014-03-13 19:11:50 +0000124 for (const auto *P : Cat->properties())
Fariborz Jahanian1446b342013-03-21 20:50:53 +0000125 if (P->getIdentifier() == Property->getIdentifier()) {
126 if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite)
127 return true;
128 break;
129 }
130 }
131
132 // Also look into protocols, for a user declared instance method.
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000133 for (const auto *Proto : ID->all_referenced_protocols())
Fariborz Jahanian1446b342013-03-21 20:50:53 +0000134 if (Proto->HasUserDeclaredSetterMethod(Property))
135 return true;
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000136
Fariborz Jahanian1446b342013-03-21 20:50:53 +0000137 // And in its super class.
138 ObjCInterfaceDecl *OSC = ID->getSuperClass();
139 while (OSC) {
140 if (OSC->HasUserDeclaredSetterMethod(Property))
141 return true;
142 OSC = OSC->getSuperClass();
143 }
144 }
145 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(this))
146 for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
147 E = PD->protocol_end(); PI != E; ++PI) {
148 if ((*PI)->HasUserDeclaredSetterMethod(Property))
149 return true;
150 }
151 return false;
152}
153
Ted Kremenek4fb821e2010-03-15 20:11:46 +0000154ObjCPropertyDecl *
Ted Kremenekddcd1092010-03-15 20:11:53 +0000155ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
Ted Kremenek4fb821e2010-03-15 20:11:46 +0000156 IdentifierInfo *propertyID) {
Douglas Gregoreed49792013-01-17 00:38:46 +0000157 // If this context is a hidden protocol definition, don't find any
158 // property.
159 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
160 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
161 if (Def->isHidden())
162 return 0;
163 }
Ted Kremenek4fb821e2010-03-15 20:11:46 +0000164
David Blaikieff7d47a2012-12-19 00:45:41 +0000165 DeclContext::lookup_const_result R = DC->lookup(propertyID);
166 for (DeclContext::lookup_const_iterator I = R.begin(), E = R.end(); I != E;
167 ++I)
Ted Kremenek4fb821e2010-03-15 20:11:46 +0000168 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
169 return PD;
170
171 return 0;
172}
173
Anna Zaks454477c2012-09-27 19:45:11 +0000174IdentifierInfo *
175ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
176 SmallString<128> ivarName;
177 {
178 llvm::raw_svector_ostream os(ivarName);
179 os << '_' << getIdentifier()->getName();
180 }
181 return &Ctx.Idents.get(ivarName.str());
182}
183
Fariborz Jahaniana054e992008-04-21 19:04:53 +0000184/// FindPropertyDeclaration - Finds declaration of the property given its name
185/// in 'PropertyId' and returns it. It returns 0, if not found.
Fariborz Jahaniana054e992008-04-21 19:04:53 +0000186ObjCPropertyDecl *
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000187ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
Douglas Gregoreed49792013-01-17 00:38:46 +0000188 // Don't find properties within hidden protocol definitions.
189 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
190 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
191 if (Def->isHidden())
192 return 0;
193 }
Mike Stump11289f42009-09-09 15:08:12 +0000194
Ted Kremenekddcd1092010-03-15 20:11:53 +0000195 if (ObjCPropertyDecl *PD =
196 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
197 return PD;
Mike Stump11289f42009-09-09 15:08:12 +0000198
Ted Kremenekddcd1092010-03-15 20:11:53 +0000199 switch (getKind()) {
200 default:
201 break;
202 case Decl::ObjCProtocol: {
203 const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
204 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
205 E = PID->protocol_end(); I != E; ++I)
Fariborz Jahanian30a42922010-02-15 21:55:26 +0000206 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
207 return P;
Ted Kremenekddcd1092010-03-15 20:11:53 +0000208 break;
209 }
210 case Decl::ObjCInterface: {
211 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
Douglas Gregor048fbfa2013-01-16 23:00:23 +0000212 // Look through categories (but not extensions).
Aaron Ballman3fe486a2014-03-13 21:23:55 +0000213 for (const auto *Cat : OID->visible_categories()) {
Ted Kremenekddcd1092010-03-15 20:11:53 +0000214 if (!Cat->IsClassExtension())
215 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
216 return P;
Douglas Gregor048fbfa2013-01-16 23:00:23 +0000217 }
Ted Kremenekddcd1092010-03-15 20:11:53 +0000218
219 // Look through protocols.
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000220 for (const auto *I : OID->all_referenced_protocols())
221 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
Ted Kremenekddcd1092010-03-15 20:11:53 +0000222 return P;
223
224 // Finally, check the super class.
225 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
226 return superClass->FindPropertyDeclaration(PropertyId);
227 break;
228 }
229 case Decl::ObjCCategory: {
230 const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
231 // Look through protocols.
232 if (!OCD->IsClassExtension())
233 for (ObjCCategoryDecl::protocol_iterator
234 I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
235 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
236 return P;
237
238 break;
Fariborz Jahaniandab04842009-01-19 18:16:19 +0000239 }
240 }
Steve Narofff9c65242008-06-05 13:55:23 +0000241 return 0;
242}
243
David Blaikie68e081d2011-12-20 02:48:34 +0000244void ObjCInterfaceDecl::anchor() { }
245
Fariborz Jahaniande8db162009-11-02 22:45:15 +0000246/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
247/// with name 'PropertyId' in the primary class; including those in protocols
Ted Kremenekd133a862010-03-15 20:30:07 +0000248/// (direct or indirect) used by the primary class.
Fariborz Jahaniande8db162009-11-02 22:45:15 +0000249///
250ObjCPropertyDecl *
Ted Kremenekd133a862010-03-15 20:30:07 +0000251ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
Fariborz Jahaniande8db162009-11-02 22:45:15 +0000252 IdentifierInfo *PropertyId) const {
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000253 // FIXME: Should make sure no callers ever do this.
254 if (!hasDefinition())
255 return 0;
256
257 if (data().ExternallyCompleted)
Douglas Gregor73693022010-12-01 23:49:52 +0000258 LoadExternalDefinition();
259
Ted Kremenekd133a862010-03-15 20:30:07 +0000260 if (ObjCPropertyDecl *PD =
261 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
262 return PD;
263
Fariborz Jahaniande8db162009-11-02 22:45:15 +0000264 // Look through protocols.
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000265 for (const auto *I : all_referenced_protocols())
266 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
Fariborz Jahaniande8db162009-11-02 22:45:15 +0000267 return P;
Ted Kremenekd133a862010-03-15 20:30:07 +0000268
Fariborz Jahaniande8db162009-11-02 22:45:15 +0000269 return 0;
270}
271
Fariborz Jahanianaedaaa42013-02-14 22:33:34 +0000272void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
273 PropertyDeclOrder &PO) const {
Aaron Ballmand174edf2014-03-13 19:11:50 +0000274 for (auto *Prop : properties()) {
Anna Zaks673d76b2012-10-18 19:17:53 +0000275 PM[Prop->getIdentifier()] = Prop;
Fariborz Jahanianaedaaa42013-02-14 22:33:34 +0000276 PO.push_back(Prop);
Anna Zaks673d76b2012-10-18 19:17:53 +0000277 }
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000278 for (const auto *PI : all_referenced_protocols())
279 PI->collectPropertiesToImplement(PM, PO);
Anna Zaks408f7d02012-10-31 01:18:22 +0000280 // Note, the properties declared only in class extensions are still copied
281 // into the main @interface's property list, and therefore we don't
282 // explicitly, have to search class extension properties.
Anna Zaks673d76b2012-10-18 19:17:53 +0000283}
284
Benjamin Kramerea70eb32012-12-01 15:09:41 +0000285bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {
286 const ObjCInterfaceDecl *Class = this;
287 while (Class) {
288 if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
289 return true;
290 Class = Class->getSuperClass();
291 }
292 return false;
293}
294
295const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
296 const ObjCInterfaceDecl *Class = this;
297 while (Class) {
298 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
299 return Class;
300 Class = Class->getSuperClass();
301 }
302 return 0;
303}
304
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000305void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
306 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
307 ASTContext &C)
308{
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000309 if (data().ExternallyCompleted)
Douglas Gregor73693022010-12-01 23:49:52 +0000310 LoadExternalDefinition();
311
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000312 if (data().AllReferencedProtocols.empty() &&
313 data().ReferencedProtocols.empty()) {
314 data().AllReferencedProtocols.set(ExtList, ExtNum, C);
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000315 return;
316 }
Ted Kremenek0ef508d2010-09-01 01:21:15 +0000317
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000318 // Check for duplicate protocol in class's protocol list.
Ted Kremenek0ef508d2010-09-01 01:21:15 +0000319 // This is O(n*m). But it is extremely rare and number of protocols in
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000320 // class or its extension are very few.
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000321 SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000322 for (unsigned i = 0; i < ExtNum; i++) {
323 bool protocolExists = false;
324 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000325 for (auto *Proto : all_referenced_protocols()) {
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000326 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
327 protocolExists = true;
328 break;
329 }
330 }
331 // Do we want to warn on a protocol in extension class which
332 // already exist in the class? Probably not.
Ted Kremenek0ef508d2010-09-01 01:21:15 +0000333 if (!protocolExists)
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000334 ProtocolRefs.push_back(ProtoInExtension);
335 }
Ted Kremenek0ef508d2010-09-01 01:21:15 +0000336
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000337 if (ProtocolRefs.empty())
338 return;
Ted Kremenek0ef508d2010-09-01 01:21:15 +0000339
Fariborz Jahanian8764c742009-10-05 21:32:49 +0000340 // Merge ProtocolRefs into class's protocol list;
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000341 for (auto *P : all_referenced_protocols()) {
342 ProtocolRefs.push_back(P);
Douglas Gregor002b6712010-01-16 15:02:53 +0000343 }
Ted Kremenek0ef508d2010-09-01 01:21:15 +0000344
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000345 data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
Fariborz Jahanian092cd6e2009-10-05 20:41:32 +0000346}
347
Argyrios Kyrtzidisb9a405b2013-12-05 07:07:03 +0000348const ObjCInterfaceDecl *
349ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
350 const ObjCInterfaceDecl *IFace = this;
351 while (IFace) {
352 if (IFace->hasDesignatedInitializers())
353 return IFace;
354 if (!IFace->inheritsDesignatedInitializers())
355 break;
356 IFace = IFace->getSuperClass();
357 }
358 return 0;
359}
360
361bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
362 switch (data().InheritedDesignatedInitializers) {
363 case DefinitionData::IDI_Inherited:
364 return true;
365 case DefinitionData::IDI_NotInherited:
366 return false;
367 case DefinitionData::IDI_Unknown: {
368 bool isIntroducingInitializers = false;
Aaron Ballmanf26acce2014-03-13 19:50:17 +0000369 for (const auto *MD : instance_methods()) {
Argyrios Kyrtzidisb9a405b2013-12-05 07:07:03 +0000370 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding()) {
371 isIntroducingInitializers = true;
372 break;
373 }
374 }
375 // If the class introduced initializers we conservatively assume that we
376 // don't know if any of them is a designated initializer to avoid possible
377 // misleading warnings.
378 if (isIntroducingInitializers) {
379 data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
380 return false;
381 } else {
382 data().InheritedDesignatedInitializers = DefinitionData::IDI_Inherited;
383 return true;
384 }
385 }
386 }
387
388 llvm_unreachable("unexpected InheritedDesignatedInitializers value");
389}
390
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +0000391void ObjCInterfaceDecl::getDesignatedInitializers(
392 llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
Fariborz Jahanian0c325312014-03-11 18:56:18 +0000393 // Check for a complete definition and recover if not so.
394 if (!isThisDeclarationADefinition())
395 return;
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +0000396 if (data().ExternallyCompleted)
397 LoadExternalDefinition();
398
Argyrios Kyrtzidisb9a405b2013-12-05 07:07:03 +0000399 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +0000400 if (!IFace)
401 return;
Argyrios Kyrtzidisb9a405b2013-12-05 07:07:03 +0000402
Aaron Ballmanf26acce2014-03-13 19:50:17 +0000403 for (const auto *MD : IFace->instance_methods())
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000404 if (MD->isThisDeclarationADesignatedInitializer())
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +0000405 Methods.push_back(MD);
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +0000406}
407
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000408bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
409 const ObjCMethodDecl **InitMethod) const {
Fariborz Jahanian0c325312014-03-11 18:56:18 +0000410 // Check for a complete definition and recover if not so.
411 if (!isThisDeclarationADefinition())
412 return false;
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000413 if (data().ExternallyCompleted)
414 LoadExternalDefinition();
415
Argyrios Kyrtzidisb9a405b2013-12-05 07:07:03 +0000416 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000417 if (!IFace)
418 return false;
419
Argyrios Kyrtzidise919fc22013-12-10 18:36:43 +0000420 if (const ObjCMethodDecl *MD = IFace->getMethod(Sel, /*isInstance=*/true)) {
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000421 if (MD->isThisDeclarationADesignatedInitializer()) {
422 if (InitMethod)
423 *InitMethod = MD;
424 return true;
425 }
426 }
427 return false;
428}
429
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000430void ObjCInterfaceDecl::allocateDefinitionData() {
431 assert(!hasDefinition() && "ObjC class already has a definition");
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000432 Data.setPointer(new (getASTContext()) DefinitionData());
433 Data.getPointer()->Definition = this;
Douglas Gregor7671e532011-12-16 16:34:57 +0000434
435 // Make the type point at the definition, now that we have one.
436 if (TypeForDecl)
437 cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
Douglas Gregorab1ec82e2011-12-16 03:12:41 +0000438}
439
440void ObjCInterfaceDecl::startDefinition() {
441 allocateDefinitionData();
442
Douglas Gregor66b310c2011-12-15 18:03:09 +0000443 // Update all of the declarations with a pointer to the definition.
Aaron Ballman86c93902014-03-06 23:45:36 +0000444 for (auto RD : redecls()) {
445 if (RD != this)
Douglas Gregora323c4c2011-12-15 18:17:27 +0000446 RD->Data = Data;
Douglas Gregor66b310c2011-12-15 18:03:09 +0000447 }
Argyrios Kyrtzidisb97a4022011-11-12 21:07:46 +0000448}
449
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000450ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
451 ObjCInterfaceDecl *&clsDeclared) {
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000452 // FIXME: Should make sure no callers ever do this.
453 if (!hasDefinition())
454 return 0;
455
456 if (data().ExternallyCompleted)
Argyrios Kyrtzidis4e8b1362011-10-19 02:25:16 +0000457 LoadExternalDefinition();
458
Chris Lattner89375192008-03-16 00:19:01 +0000459 ObjCInterfaceDecl* ClassDecl = this;
460 while (ClassDecl != NULL) {
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000461 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
Fariborz Jahanian68453832009-06-05 18:16:35 +0000462 clsDeclared = ClassDecl;
463 return I;
Chris Lattner89375192008-03-16 00:19:01 +0000464 }
Douglas Gregor048fbfa2013-01-16 23:00:23 +0000465
466 for (ObjCInterfaceDecl::visible_extensions_iterator
467 Ext = ClassDecl->visible_extensions_begin(),
468 ExtEnd = ClassDecl->visible_extensions_end();
469 Ext != ExtEnd; ++Ext) {
470 if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
Fariborz Jahanianafe13862010-02-23 01:26:30 +0000471 clsDeclared = ClassDecl;
472 return I;
473 }
Fariborz Jahanian3bf0ded2010-06-22 23:20:40 +0000474 }
Fariborz Jahanianafe13862010-02-23 01:26:30 +0000475
Chris Lattner89375192008-03-16 00:19:01 +0000476 ClassDecl = ClassDecl->getSuperClass();
477 }
478 return NULL;
479}
480
Fariborz Jahaniandb3a4c12009-05-22 17:12:32 +0000481/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
482/// class whose name is passed as argument. If it is not one of the super classes
483/// the it returns NULL.
484ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
485 const IdentifierInfo*ICName) {
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000486 // FIXME: Should make sure no callers ever do this.
487 if (!hasDefinition())
488 return 0;
489
490 if (data().ExternallyCompleted)
Argyrios Kyrtzidis4e8b1362011-10-19 02:25:16 +0000491 LoadExternalDefinition();
492
Fariborz Jahaniandb3a4c12009-05-22 17:12:32 +0000493 ObjCInterfaceDecl* ClassDecl = this;
494 while (ClassDecl != NULL) {
495 if (ClassDecl->getIdentifier() == ICName)
496 return ClassDecl;
497 ClassDecl = ClassDecl->getSuperClass();
498 }
499 return NULL;
500}
501
Fariborz Jahanian56f48d02013-07-10 21:30:22 +0000502ObjCProtocolDecl *
503ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
Aaron Ballmana9f49e32014-03-13 20:55:22 +0000504 for (auto *P : all_referenced_protocols())
505 if (P->lookupProtocolNamed(Name))
506 return P;
Fariborz Jahanian56f48d02013-07-10 21:30:22 +0000507 ObjCInterfaceDecl *SuperClass = getSuperClass();
508 return SuperClass ? SuperClass->lookupNestedProtocol(Name) : NULL;
509}
510
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000511/// lookupMethod - This method returns an instance/class method by looking in
Chris Lattner89375192008-03-16 00:19:01 +0000512/// the class, its categories, and its super classes (using a linear search).
Fariborz Jahanian73e244a2013-04-25 21:59:34 +0000513/// When argument category "C" is specified, any implicit method found
514/// in this category is ignored.
Fariborz Jahanianc806b902012-04-05 22:14:12 +0000515ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
Ted Kremenek00781502013-11-23 01:01:29 +0000516 bool isInstance,
517 bool shallowCategoryLookup,
518 bool followSuper,
Ted Kremenekf41cf7f12013-12-10 19:43:48 +0000519 const ObjCCategoryDecl *C) const
Ted Kremenek00781502013-11-23 01:01:29 +0000520{
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000521 // FIXME: Should make sure no callers ever do this.
522 if (!hasDefinition())
523 return 0;
524
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000525 const ObjCInterfaceDecl* ClassDecl = this;
Chris Lattner89375192008-03-16 00:19:01 +0000526 ObjCMethodDecl *MethodDecl = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000527
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000528 if (data().ExternallyCompleted)
Douglas Gregor73693022010-12-01 23:49:52 +0000529 LoadExternalDefinition();
530
Ted Kremenek00781502013-11-23 01:01:29 +0000531 while (ClassDecl) {
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000532 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
Chris Lattner89375192008-03-16 00:19:01 +0000533 return MethodDecl;
Mike Stump11289f42009-09-09 15:08:12 +0000534
Chris Lattner89375192008-03-16 00:19:01 +0000535 // Didn't find one yet - look through protocols.
Aaron Ballmana49c5062014-03-13 20:29:09 +0000536 for (const auto *I : ClassDecl->protocols())
537 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
Chris Lattner89375192008-03-16 00:19:01 +0000538 return MethodDecl;
Fariborz Jahanianc806b902012-04-05 22:14:12 +0000539
540 // Didn't find one yet - now look through categories.
Aaron Ballman3fe486a2014-03-13 21:23:55 +0000541 for (const auto *Cat : ClassDecl->visible_categories()) {
Fariborz Jahanian73e244a2013-04-25 21:59:34 +0000542 if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
Aaron Ballman3fe486a2014-03-13 21:23:55 +0000543 if (C != Cat || !MethodDecl->isImplicit())
Fariborz Jahanianeb3f1002013-04-24 17:06:38 +0000544 return MethodDecl;
Fariborz Jahanian29082a52012-02-09 21:30:24 +0000545
Fariborz Jahanian73e244a2013-04-25 21:59:34 +0000546 if (!shallowCategoryLookup) {
547 // Didn't find one yet - look through protocols.
548 const ObjCList<ObjCProtocolDecl> &Protocols =
549 Cat->getReferencedProtocols();
550 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
551 E = Protocols.end(); I != E; ++I)
552 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
Aaron Ballman3fe486a2014-03-13 21:23:55 +0000553 if (C != Cat || !MethodDecl->isImplicit())
Fariborz Jahanianeb3f1002013-04-24 17:06:38 +0000554 return MethodDecl;
Fariborz Jahanian29082a52012-02-09 21:30:24 +0000555 }
Fariborz Jahanian73e244a2013-04-25 21:59:34 +0000556 }
Ted Kremenek00781502013-11-23 01:01:29 +0000557
558 if (!followSuper)
559 return NULL;
560
561 // Get the super class (if any).
Chris Lattner89375192008-03-16 00:19:01 +0000562 ClassDecl = ClassDecl->getSuperClass();
563 }
564 return NULL;
565}
566
Anna Zaksc77a3b12012-07-27 19:07:44 +0000567// Will search "local" class/category implementations for a method decl.
568// If failed, then we search in class's root for an instance method.
569// Returns 0 if no method is found.
Fariborz Jahanianecbbb6e2010-12-03 23:37:08 +0000570ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
571 const Selector &Sel,
Anna Zaks7044adc2012-07-30 20:31:21 +0000572 bool Instance) const {
Douglas Gregorc0ac7d62011-12-15 05:27:12 +0000573 // FIXME: Should make sure no callers ever do this.
574 if (!hasDefinition())
575 return 0;
576
577 if (data().ExternallyCompleted)
Argyrios Kyrtzidis4e8b1362011-10-19 02:25:16 +0000578 LoadExternalDefinition();
579
Steve Naroffbb69c942009-10-01 23:46:04 +0000580 ObjCMethodDecl *Method = 0;
581 if (ObjCImplementationDecl *ImpDecl = getImplementation())
Fariborz Jahanianecbbb6e2010-12-03 23:37:08 +0000582 Method = Instance ? ImpDecl->getInstanceMethod(Sel)
583 : ImpDecl->getClassMethod(Sel);
Anna Zaksc77a3b12012-07-27 19:07:44 +0000584
585 // Look through local category implementations associated with the class.
586 if (!Method)
587 Method = Instance ? getCategoryInstanceMethod(Sel)
588 : getCategoryClassMethod(Sel);
589
590 // Before we give up, check if the selector is an instance method.
591 // But only in the root. This matches gcc's behavior and what the
592 // runtime expects.
593 if (!Instance && !Method && !getSuperClass()) {
594 Method = lookupInstanceMethod(Sel);
595 // Look through local category implementations associated
596 // with the root class.
597 if (!Method)
598 Method = lookupPrivateMethod(Sel, true);
599 }
600
Steve Naroffbb69c942009-10-01 23:46:04 +0000601 if (!Method && getSuperClass())
Fariborz Jahanianecbbb6e2010-12-03 23:37:08 +0000602 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
Steve Naroffbb69c942009-10-01 23:46:04 +0000603 return Method;
604}
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000605
606//===----------------------------------------------------------------------===//
607// ObjCMethodDecl
608//===----------------------------------------------------------------------===//
609
Alp Toker314cc812014-01-25 16:55:45 +0000610ObjCMethodDecl *ObjCMethodDecl::Create(
611 ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
612 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
613 DeclContext *contextDecl, bool isInstance, bool isVariadic,
614 bool isPropertyAccessor, bool isImplicitlyDeclared, bool isDefined,
615 ImplementationControl impControl, bool HasRelatedResultType) {
Richard Smithf7981722013-11-22 09:01:48 +0000616 return new (C, contextDecl) ObjCMethodDecl(
Alp Toker314cc812014-01-25 16:55:45 +0000617 beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
Richard Smithf7981722013-11-22 09:01:48 +0000618 isVariadic, isPropertyAccessor, isImplicitlyDeclared, isDefined,
619 impControl, HasRelatedResultType);
Chris Lattner89375192008-03-16 00:19:01 +0000620}
621
Douglas Gregor72172e92012-01-05 21:55:30 +0000622ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000623 return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
624 Selector(), QualType(), 0, 0);
Douglas Gregor72172e92012-01-05 21:55:30 +0000625}
626
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000627bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
628 return getMethodFamily() == OMF_init &&
629 hasAttr<ObjCDesignatedInitializerAttr>();
630}
631
Argyrios Kyrtzidisfcded9b2013-12-03 21:11:43 +0000632bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
633 const ObjCMethodDecl **InitMethod) const {
634 if (getMethodFamily() != OMF_init)
635 return false;
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000636 const DeclContext *DC = getDeclContext();
637 if (isa<ObjCProtocolDecl>(DC))
638 return false;
639 if (const ObjCInterfaceDecl *ID = getClassInterface())
Argyrios Kyrtzidisfcded9b2013-12-03 21:11:43 +0000640 return ID->isDesignatedInitializer(getSelector(), InitMethod);
Argyrios Kyrtzidis22bfa2c2013-12-03 21:11:36 +0000641 return false;
642}
643
Douglas Gregora6017bb2012-10-09 17:21:28 +0000644Stmt *ObjCMethodDecl::getBody() const {
645 return Body.get(getASTContext().getExternalSource());
646}
647
Argyrios Kyrtzidisdcaaa212011-10-14 08:02:31 +0000648void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
649 assert(PrevMethod);
650 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
651 IsRedeclaration = true;
Argyrios Kyrtzidisdb215962011-10-14 17:41:52 +0000652 PrevMethod->HasRedeclaration = true;
Argyrios Kyrtzidisdcaaa212011-10-14 08:02:31 +0000653}
654
Argyrios Kyrtzidisb8c3aaf2011-10-03 06:37:04 +0000655void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
656 ArrayRef<ParmVarDecl*> Params,
657 ArrayRef<SourceLocation> SelLocs) {
658 ParamsAndSelLocs = 0;
659 NumParams = Params.size();
660 if (Params.empty() && SelLocs.empty())
661 return;
662
663 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
664 sizeof(SourceLocation) * SelLocs.size();
665 ParamsAndSelLocs = C.Allocate(Size);
666 std::copy(Params.begin(), Params.end(), getParams());
667 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
668}
669
670void ObjCMethodDecl::getSelectorLocs(
671 SmallVectorImpl<SourceLocation> &SelLocs) const {
672 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
673 SelLocs.push_back(getSelectorLoc(i));
674}
675
676void ObjCMethodDecl::setMethodParams(ASTContext &C,
677 ArrayRef<ParmVarDecl*> Params,
678 ArrayRef<SourceLocation> SelLocs) {
679 assert((!SelLocs.empty() || isImplicit()) &&
680 "No selector locs for non-implicit method");
681 if (isImplicit())
Dmitri Gribenko44ebbd52013-05-05 00:41:58 +0000682 return setParamsAndSelLocs(C, Params, llvm::None);
Argyrios Kyrtzidisb8c3aaf2011-10-03 06:37:04 +0000683
Argyrios Kyrtzidis33b4bfc2012-06-16 00:46:02 +0000684 SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
685 DeclEndLoc);
Argyrios Kyrtzidisb8c3aaf2011-10-03 06:37:04 +0000686 if (SelLocsKind != SelLoc_NonStandard)
Dmitri Gribenko44ebbd52013-05-05 00:41:58 +0000687 return setParamsAndSelLocs(C, Params, llvm::None);
Argyrios Kyrtzidisb8c3aaf2011-10-03 06:37:04 +0000688
689 setParamsAndSelLocs(C, Params, SelLocs);
690}
691
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000692/// \brief A definition will return its interface declaration.
693/// An interface declaration will return its definition.
694/// Otherwise it will return itself.
695ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
696 ASTContext &Ctx = getASTContext();
Argyrios Kyrtzidisdb215962011-10-14 17:41:52 +0000697 ObjCMethodDecl *Redecl = 0;
698 if (HasRedeclaration)
699 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
Argyrios Kyrtzidisc5e829c2011-10-14 06:48:06 +0000700 if (Redecl)
701 return Redecl;
702
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000703 Decl *CtxD = cast<Decl>(getDeclContext());
704
Argyrios Kyrtzidis0f6d5ca2013-05-30 18:53:21 +0000705 if (!CtxD->isInvalidDecl()) {
706 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
707 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
708 if (!ImplD->isInvalidDecl())
709 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000710
Argyrios Kyrtzidis0f6d5ca2013-05-30 18:53:21 +0000711 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
712 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
713 if (!ImplD->isInvalidDecl())
714 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000715
Argyrios Kyrtzidis0f6d5ca2013-05-30 18:53:21 +0000716 } else if (ObjCImplementationDecl *ImplD =
717 dyn_cast<ObjCImplementationDecl>(CtxD)) {
718 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
719 if (!IFD->isInvalidDecl())
720 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
Argyrios Kyrtzidisa56fa192009-07-28 05:11:05 +0000721
Argyrios Kyrtzidis0f6d5ca2013-05-30 18:53:21 +0000722 } else if (ObjCCategoryImplDecl *CImplD =
723 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
724 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
725 if (!CatD->isInvalidDecl())
726 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
727 }
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000728 }
729
Argyrios Kyrtzidisdcaaa212011-10-14 08:02:31 +0000730 if (!Redecl && isRedeclaration()) {
731 // This is the last redeclaration, go back to the first method.
732 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
733 isInstanceMethod());
734 }
735
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000736 return Redecl ? Redecl : this;
737}
738
Argyrios Kyrtzidisf390c432009-07-28 05:11:17 +0000739ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
740 Decl *CtxD = cast<Decl>(getDeclContext());
741
742 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
743 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
744 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
745 isInstanceMethod()))
746 return MD;
747
748 } else if (ObjCCategoryImplDecl *CImplD =
749 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
Steve Narofff406f4d2009-10-29 21:11:04 +0000750 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
Argyrios Kyrtzidisf390c432009-07-28 05:11:17 +0000751 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
752 isInstanceMethod()))
753 return MD;
754 }
755
Argyrios Kyrtzidis690dccd2011-10-17 19:48:09 +0000756 if (isRedeclaration())
757 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
758 isInstanceMethod());
759
Argyrios Kyrtzidisf390c432009-07-28 05:11:17 +0000760 return this;
761}
762
Argyrios Kyrtzidis33b4bfc2012-06-16 00:46:02 +0000763SourceLocation ObjCMethodDecl::getLocEnd() const {
764 if (Stmt *Body = getBody())
765 return Body->getLocEnd();
766 return DeclEndLoc;
767}
768
John McCallb4526252011-03-02 01:50:55 +0000769ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
770 ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
John McCallfb55f852011-03-02 21:01:41 +0000771 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
John McCallb4526252011-03-02 01:50:55 +0000772 return family;
773
John McCall86bc21f2011-03-02 11:33:24 +0000774 // Check for an explicit attribute.
775 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
776 // The unfortunate necessity of mapping between enums here is due
777 // to the attributes framework.
778 switch (attr->getFamily()) {
779 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
780 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
781 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
782 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
783 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
784 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
785 }
786 Family = static_cast<unsigned>(family);
787 return family;
788 }
789
John McCallb4526252011-03-02 01:50:55 +0000790 family = getSelector().getMethodFamily();
791 switch (family) {
792 case OMF_None: break;
793
794 // init only has a conventional meaning for an instance method, and
795 // it has to return an object.
796 case OMF_init:
Alp Toker314cc812014-01-25 16:55:45 +0000797 if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
John McCallb4526252011-03-02 01:50:55 +0000798 family = OMF_None;
799 break;
800
801 // alloc/copy/new have a conventional meaning for both class and
802 // instance methods, but they require an object return.
803 case OMF_alloc:
804 case OMF_copy:
805 case OMF_mutableCopy:
806 case OMF_new:
Alp Toker314cc812014-01-25 16:55:45 +0000807 if (!getReturnType()->isObjCObjectPointerType())
John McCallb4526252011-03-02 01:50:55 +0000808 family = OMF_None;
809 break;
810
811 // These selectors have a conventional meaning only for instance methods.
812 case OMF_dealloc:
Nico Weber1fb82662011-08-28 22:35:17 +0000813 case OMF_finalize:
John McCallb4526252011-03-02 01:50:55 +0000814 case OMF_retain:
815 case OMF_release:
816 case OMF_autorelease:
817 case OMF_retainCount:
Douglas Gregor33823722011-06-11 01:09:30 +0000818 case OMF_self:
John McCallb4526252011-03-02 01:50:55 +0000819 if (!isInstanceMethod())
820 family = OMF_None;
821 break;
Fariborz Jahanianb7a77362011-07-05 22:38:59 +0000822
823 case OMF_performSelector:
Alp Toker314cc812014-01-25 16:55:45 +0000824 if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
Fariborz Jahanianb7a77362011-07-05 22:38:59 +0000825 family = OMF_None;
826 else {
827 unsigned noParams = param_size();
828 if (noParams < 1 || noParams > 3)
829 family = OMF_None;
830 else {
Alp Toker1f307f42014-01-25 17:32:04 +0000831 ObjCMethodDecl::param_type_iterator it = param_type_begin();
Fariborz Jahanianb7a77362011-07-05 22:38:59 +0000832 QualType ArgT = (*it);
833 if (!ArgT->isObjCSelType()) {
834 family = OMF_None;
835 break;
836 }
837 while (--noParams) {
838 it++;
839 ArgT = (*it);
840 if (!ArgT->isObjCIdType()) {
841 family = OMF_None;
842 break;
843 }
844 }
845 }
846 }
847 break;
848
John McCallb4526252011-03-02 01:50:55 +0000849 }
850
851 // Cache the result.
852 Family = static_cast<unsigned>(family);
853 return family;
854}
855
Mike Stump11289f42009-09-09 15:08:12 +0000856void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000857 const ObjCInterfaceDecl *OID) {
858 QualType selfTy;
859 if (isInstanceMethod()) {
860 // There may be no interface context due to error in declaration
861 // of the interface (which has been reported). Recover gracefully.
862 if (OID) {
Daniel Dunbaraefc2b92009-04-22 04:34:53 +0000863 selfTy = Context.getObjCInterfaceType(OID);
Steve Naroff7cae42b2009-07-10 23:34:53 +0000864 selfTy = Context.getObjCObjectPointerType(selfTy);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000865 } else {
866 selfTy = Context.getObjCIdType();
867 }
868 } else // we have a factory method.
869 selfTy = Context.getObjCClassType();
870
John McCalld4631322011-06-17 06:42:21 +0000871 bool selfIsPseudoStrong = false;
John McCall31168b02011-06-15 23:02:42 +0000872 bool selfIsConsumed = false;
Ted Kremenek1fcdaa92011-11-14 21:59:25 +0000873
David Blaikiebbafb8a2012-03-11 07:00:24 +0000874 if (Context.getLangOpts().ObjCAutoRefCount) {
Ted Kremenek1fcdaa92011-11-14 21:59:25 +0000875 if (isInstanceMethod()) {
876 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
John McCall31168b02011-06-15 23:02:42 +0000877
Ted Kremenek1fcdaa92011-11-14 21:59:25 +0000878 // 'self' is always __strong. It's actually pseudo-strong except
879 // in init methods (or methods labeled ns_consumes_self), though.
880 Qualifiers qs;
881 qs.setObjCLifetime(Qualifiers::OCL_Strong);
882 selfTy = Context.getQualifiedType(selfTy, qs);
John McCall31168b02011-06-15 23:02:42 +0000883
Ted Kremenek1fcdaa92011-11-14 21:59:25 +0000884 // In addition, 'self' is const unless this is an init method.
885 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
886 selfTy = selfTy.withConst();
887 selfIsPseudoStrong = true;
888 }
889 }
890 else {
891 assert(isClassMethod());
892 // 'self' is always const in class methods.
John McCall31168b02011-06-15 23:02:42 +0000893 selfTy = selfTy.withConst();
John McCalld4631322011-06-17 06:42:21 +0000894 selfIsPseudoStrong = true;
895 }
John McCall31168b02011-06-15 23:02:42 +0000896 }
897
898 ImplicitParamDecl *self
899 = ImplicitParamDecl::Create(Context, this, SourceLocation(),
900 &Context.Idents.get("self"), selfTy);
901 setSelfDecl(self);
902
903 if (selfIsConsumed)
Aaron Ballman36a53502014-01-16 13:03:14 +0000904 self->addAttr(NSConsumedAttr::CreateImplicit(Context));
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000905
John McCalld4631322011-06-17 06:42:21 +0000906 if (selfIsPseudoStrong)
907 self->setARCPseudoStrong(true);
908
Mike Stump11289f42009-09-09 15:08:12 +0000909 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
910 &Context.Idents.get("_cmd"),
Steve Naroff04f2d142009-04-20 15:06:07 +0000911 Context.getObjCSelType()));
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000912}
913
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000914ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
915 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
916 return ID;
917 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
918 return CD->getClassInterface();
Argyrios Kyrtzidis2cee40d2009-07-28 05:10:52 +0000919 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000920 return IMD->getClassInterface();
Fariborz Jahanian7a583022014-03-04 22:57:32 +0000921 if (isa<ObjCProtocolDecl>(getDeclContext()))
922 return 0;
David Blaikie83d382b2011-09-23 05:06:16 +0000923 llvm_unreachable("unknown method context");
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000924}
925
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +0000926static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
927 const ObjCMethodDecl *Method,
928 SmallVectorImpl<const ObjCMethodDecl *> &Methods,
929 bool MovedToSuper) {
930 if (!Container)
931 return;
932
933 // In categories look for overriden methods from protocols. A method from
934 // category is not "overriden" since it is considered as the "same" method
935 // (same USR) as the one from the interface.
936 if (const ObjCCategoryDecl *
937 Category = dyn_cast<ObjCCategoryDecl>(Container)) {
938 // Check whether we have a matching method at this category but only if we
939 // are at the super class level.
940 if (MovedToSuper)
941 if (ObjCMethodDecl *
942 Overridden = Container->getMethod(Method->getSelector(),
Argyrios Kyrtzidisbd8cd3e2013-03-29 21:51:48 +0000943 Method->isInstanceMethod(),
944 /*AllowHidden=*/true))
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +0000945 if (Method != Overridden) {
946 // We found an override at this category; there is no need to look
947 // into its protocols.
948 Methods.push_back(Overridden);
949 return;
950 }
951
952 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
953 PEnd = Category->protocol_end();
954 P != PEnd; ++P)
955 CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
956 return;
957 }
958
959 // Check whether we have a matching method at this level.
960 if (const ObjCMethodDecl *
961 Overridden = Container->getMethod(Method->getSelector(),
Argyrios Kyrtzidisbd8cd3e2013-03-29 21:51:48 +0000962 Method->isInstanceMethod(),
963 /*AllowHidden=*/true))
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +0000964 if (Method != Overridden) {
965 // We found an override at this level; there is no need to look
966 // into other protocols or categories.
967 Methods.push_back(Overridden);
968 return;
969 }
970
971 if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
972 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
973 PEnd = Protocol->protocol_end();
974 P != PEnd; ++P)
975 CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
976 }
977
978 if (const ObjCInterfaceDecl *
979 Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
Aaron Ballmana49c5062014-03-13 20:29:09 +0000980 for (const auto *P : Interface->protocols())
981 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +0000982
Argyrios Kyrtzidisbd8cd3e2013-03-29 21:51:48 +0000983 for (ObjCInterfaceDecl::known_categories_iterator
984 Cat = Interface->known_categories_begin(),
985 CatEnd = Interface->known_categories_end();
Douglas Gregor048fbfa2013-01-16 23:00:23 +0000986 Cat != CatEnd; ++Cat) {
987 CollectOverriddenMethodsRecurse(*Cat, Method, Methods,
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +0000988 MovedToSuper);
Douglas Gregor048fbfa2013-01-16 23:00:23 +0000989 }
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +0000990
991 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
992 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
993 /*MovedToSuper=*/true);
994 }
995}
996
997static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
998 const ObjCMethodDecl *Method,
999 SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
1000 CollectOverriddenMethodsRecurse(Container, Method, Methods,
1001 /*MovedToSuper=*/false);
1002}
1003
1004static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
1005 SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
1006 assert(Method->isOverriding());
1007
1008 if (const ObjCProtocolDecl *
1009 ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1010 CollectOverriddenMethods(ProtD, Method, overridden);
1011
1012 } else if (const ObjCImplDecl *
1013 IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1014 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1015 if (!ID)
1016 return;
1017 // Start searching for overridden methods using the method from the
1018 // interface as starting point.
1019 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
Argyrios Kyrtzidisbd8cd3e2013-03-29 21:51:48 +00001020 Method->isInstanceMethod(),
1021 /*AllowHidden=*/true))
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +00001022 Method = IFaceMeth;
1023 CollectOverriddenMethods(ID, Method, overridden);
1024
1025 } else if (const ObjCCategoryDecl *
1026 CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1027 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1028 if (!ID)
1029 return;
1030 // Start searching for overridden methods using the method from the
1031 // interface as starting point.
1032 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
Argyrios Kyrtzidisbd8cd3e2013-03-29 21:51:48 +00001033 Method->isInstanceMethod(),
1034 /*AllowHidden=*/true))
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +00001035 Method = IFaceMeth;
1036 CollectOverriddenMethods(ID, Method, overridden);
1037
1038 } else {
1039 CollectOverriddenMethods(
1040 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1041 Method, overridden);
1042 }
1043}
1044
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +00001045void ObjCMethodDecl::getOverriddenMethods(
1046 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1047 const ObjCMethodDecl *Method = this;
1048
1049 if (Method->isRedeclaration()) {
1050 Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
1051 getMethod(Method->getSelector(), Method->isInstanceMethod());
1052 }
1053
Argyrios Kyrtzidisc2091d52013-04-17 00:09:08 +00001054 if (Method->isOverriding()) {
Argyrios Kyrtzidis353f6a42012-10-09 18:19:01 +00001055 collectOverriddenMethodsSlow(Method, Overridden);
1056 assert(!Overridden.empty() &&
1057 "ObjCMethodDecl's overriding bit is not as expected");
1058 }
1059}
1060
Jordan Rose2bd991a2012-10-10 16:42:54 +00001061const ObjCPropertyDecl *
1062ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
1063 Selector Sel = getSelector();
1064 unsigned NumArgs = Sel.getNumArgs();
1065 if (NumArgs > 1)
1066 return 0;
1067
Jordan Rose59e34ec2012-10-11 16:02:02 +00001068 if (!isInstanceMethod() || getMethodFamily() != OMF_None)
Jordan Rose2bd991a2012-10-10 16:42:54 +00001069 return 0;
1070
1071 if (isPropertyAccessor()) {
1072 const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
Fariborz Jahanian37494a12013-01-12 00:28:34 +00001073 // If container is class extension, find its primary class.
1074 if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(Container))
1075 if (CatDecl->IsClassExtension())
1076 Container = CatDecl->getClassInterface();
1077
Jordan Rose2bd991a2012-10-10 16:42:54 +00001078 bool IsGetter = (NumArgs == 0);
1079
Aaron Ballmand174edf2014-03-13 19:11:50 +00001080 for (const auto *I : Container->properties()) {
Aaron Ballmandc4bea42014-03-13 18:47:37 +00001081 Selector NextSel = IsGetter ? I->getGetterName()
1082 : I->getSetterName();
Jordan Rose2bd991a2012-10-10 16:42:54 +00001083 if (NextSel == Sel)
Aaron Ballmandc4bea42014-03-13 18:47:37 +00001084 return I;
Jordan Rose2bd991a2012-10-10 16:42:54 +00001085 }
1086
1087 llvm_unreachable("Marked as a property accessor but no property found!");
1088 }
1089
1090 if (!CheckOverrides)
1091 return 0;
1092
1093 typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
1094 OverridesTy Overrides;
1095 getOverriddenMethods(Overrides);
1096 for (OverridesTy::const_iterator I = Overrides.begin(), E = Overrides.end();
1097 I != E; ++I) {
1098 if (const ObjCPropertyDecl *Prop = (*I)->findPropertyDecl(false))
1099 return Prop;
1100 }
1101
1102 return 0;
1103
1104}
1105
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001106//===----------------------------------------------------------------------===//
1107// ObjCInterfaceDecl
1108//===----------------------------------------------------------------------===//
1109
Douglas Gregord53ae832012-01-17 18:09:05 +00001110ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001111 DeclContext *DC,
1112 SourceLocation atLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001113 IdentifierInfo *Id,
Douglas Gregorab1ec82e2011-12-16 03:12:41 +00001114 ObjCInterfaceDecl *PrevDecl,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001115 SourceLocation ClassLoc,
Douglas Gregordc9166c2011-12-15 20:29:51 +00001116 bool isInternal){
Richard Smithf7981722013-11-22 09:01:48 +00001117 ObjCInterfaceDecl *Result = new (C, DC)
1118 ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, PrevDecl, isInternal);
Douglas Gregor7dab26b2013-02-09 01:35:03 +00001119 Result->Data.setInt(!C.getLangOpts().Modules);
Douglas Gregorab1ec82e2011-12-16 03:12:41 +00001120 C.getObjCInterfaceType(Result, PrevDecl);
Douglas Gregorab1ec82e2011-12-16 03:12:41 +00001121 return Result;
1122}
1123
Richard Smithf7981722013-11-22 09:01:48 +00001124ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +00001125 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001126 ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(0, SourceLocation(),
1127 0, SourceLocation(),
1128 0, false);
Douglas Gregor7dab26b2013-02-09 01:35:03 +00001129 Result->Data.setInt(!C.getLangOpts().Modules);
1130 return Result;
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001131}
1132
1133ObjCInterfaceDecl::
1134ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
Douglas Gregor81252352011-12-16 22:37:11 +00001135 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
1136 bool isInternal)
Argyrios Kyrtzidis52f53fb2011-10-04 04:48:02 +00001137 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
Douglas Gregordc9166c2011-12-15 20:29:51 +00001138 TypeForDecl(0), Data()
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001139{
Rafael Espindola8db352d2013-10-17 15:37:26 +00001140 setPreviousDecl(PrevDecl);
Douglas Gregor81252352011-12-16 22:37:11 +00001141
1142 // Copy the 'data' pointer over.
1143 if (PrevDecl)
1144 Data = PrevDecl->Data;
1145
Argyrios Kyrtzidisae8e7922011-11-15 06:20:21 +00001146 setImplicit(isInternal);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001147}
1148
Douglas Gregor73693022010-12-01 23:49:52 +00001149void ObjCInterfaceDecl::LoadExternalDefinition() const {
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001150 assert(data().ExternallyCompleted && "Class is not externally completed");
1151 data().ExternallyCompleted = false;
Douglas Gregor73693022010-12-01 23:49:52 +00001152 getASTContext().getExternalSource()->CompleteType(
1153 const_cast<ObjCInterfaceDecl *>(this));
1154}
1155
1156void ObjCInterfaceDecl::setExternallyCompleted() {
1157 assert(getASTContext().getExternalSource() &&
1158 "Class can't be externally completed without an external source");
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001159 assert(hasDefinition() &&
Douglas Gregor73693022010-12-01 23:49:52 +00001160 "Forward declarations can't be externally completed");
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001161 data().ExternallyCompleted = true;
Douglas Gregor73693022010-12-01 23:49:52 +00001162}
1163
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +00001164void ObjCInterfaceDecl::setHasDesignatedInitializers() {
Fariborz Jahanian0c325312014-03-11 18:56:18 +00001165 // Check for a complete definition and recover if not so.
1166 if (!isThisDeclarationADefinition())
1167 return;
Argyrios Kyrtzidis9ed9e5f2013-12-03 21:11:30 +00001168 data().HasDesignatedInitializers = true;
1169}
1170
Argyrios Kyrtzidisb66d3cf2013-12-03 21:11:49 +00001171bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
Fariborz Jahanian0c325312014-03-11 18:56:18 +00001172 // Check for a complete definition and recover if not so.
1173 if (!isThisDeclarationADefinition())
1174 return false;
Argyrios Kyrtzidisb66d3cf2013-12-03 21:11:49 +00001175 if (data().ExternallyCompleted)
1176 LoadExternalDefinition();
1177
1178 return data().HasDesignatedInitializers;
1179}
1180
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +00001181ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
Douglas Gregordc9166c2011-12-15 20:29:51 +00001182 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1183 if (data().ExternallyCompleted)
1184 LoadExternalDefinition();
1185
1186 return getASTContext().getObjCImplementation(
1187 const_cast<ObjCInterfaceDecl*>(Def));
1188 }
1189
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001190 // FIXME: Should make sure no callers ever do this.
Douglas Gregordc9166c2011-12-15 20:29:51 +00001191 return 0;
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +00001192}
1193
1194void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
Douglas Gregordc9166c2011-12-15 20:29:51 +00001195 getASTContext().setObjCImplementation(getDefinition(), ImplD);
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +00001196}
1197
Fariborz Jahanian3c822042013-02-13 22:50:36 +00001198namespace {
1199 struct SynthesizeIvarChunk {
1200 uint64_t Size;
1201 ObjCIvarDecl *Ivar;
1202 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1203 : Size(size), Ivar(ivar) {}
1204 };
1205
1206 bool operator<(const SynthesizeIvarChunk & LHS,
1207 const SynthesizeIvarChunk &RHS) {
1208 return LHS.Size < RHS.Size;
1209 }
1210}
1211
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001212/// all_declared_ivar_begin - return first ivar declared in this class,
1213/// its extensions and its implementation. Lazily build the list on first
1214/// access.
Adrian Prantla03a85a2013-03-06 22:03:30 +00001215///
1216/// Caveat: The list returned by this method reflects the current
1217/// state of the parser. The cache will be updated for every ivar
1218/// added by an extension or the implementation when they are
1219/// encountered.
1220/// See also ObjCIvarDecl::Create().
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001221ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001222 // FIXME: Should make sure no callers ever do this.
1223 if (!hasDefinition())
1224 return 0;
1225
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001226 ObjCIvarDecl *curIvar = 0;
Adrian Prantla03a85a2013-03-06 22:03:30 +00001227 if (!data().IvarList) {
1228 if (!ivar_empty()) {
1229 ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
1230 data().IvarList = *I; ++I;
1231 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
Adrian Prantl68a57502013-02-27 01:31:55 +00001232 curIvar->setNextIvar(*I);
1233 }
Adrian Prantla03a85a2013-03-06 22:03:30 +00001234
1235 for (ObjCInterfaceDecl::known_extensions_iterator
1236 Ext = known_extensions_begin(),
1237 ExtEnd = known_extensions_end();
1238 Ext != ExtEnd; ++Ext) {
1239 if (!Ext->ivar_empty()) {
1240 ObjCCategoryDecl::ivar_iterator
1241 I = Ext->ivar_begin(),
1242 E = Ext->ivar_end();
1243 if (!data().IvarList) {
1244 data().IvarList = *I; ++I;
1245 curIvar = data().IvarList;
1246 }
1247 for ( ;I != E; curIvar = *I, ++I)
1248 curIvar->setNextIvar(*I);
1249 }
1250 }
1251 data().IvarListMissingImplementation = true;
Adrian Prantl68a57502013-02-27 01:31:55 +00001252 }
Adrian Prantla03a85a2013-03-06 22:03:30 +00001253
1254 // cached and complete!
1255 if (!data().IvarListMissingImplementation)
1256 return data().IvarList;
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001257
1258 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
Adrian Prantla03a85a2013-03-06 22:03:30 +00001259 data().IvarListMissingImplementation = false;
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001260 if (!ImplDecl->ivar_empty()) {
Fariborz Jahanian3c822042013-02-13 22:50:36 +00001261 SmallVector<SynthesizeIvarChunk, 16> layout;
1262 for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
1263 E = ImplDecl->ivar_end(); I != E; ++I) {
1264 ObjCIvarDecl *IV = *I;
1265 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1266 layout.push_back(SynthesizeIvarChunk(
1267 IV->getASTContext().getTypeSize(IV->getType()), IV));
1268 continue;
1269 }
1270 if (!data().IvarList)
1271 data().IvarList = *I;
1272 else
1273 curIvar->setNextIvar(*I);
1274 curIvar = *I;
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001275 }
Fariborz Jahanian3c822042013-02-13 22:50:36 +00001276
1277 if (!layout.empty()) {
1278 // Order synthesized ivars by their size.
1279 std::stable_sort(layout.begin(), layout.end());
1280 unsigned Ix = 0, EIx = layout.size();
1281 if (!data().IvarList) {
1282 data().IvarList = layout[0].Ivar; Ix++;
1283 curIvar = data().IvarList;
1284 }
1285 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1286 curIvar->setNextIvar(layout[Ix].Ivar);
1287 }
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001288 }
1289 }
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001290 return data().IvarList;
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001291}
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001292
1293/// FindCategoryDeclaration - Finds category declaration in the list of
1294/// categories for this class and returns it. Name of the category is passed
1295/// in 'CategoryId'. If category not found, return 0;
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +00001296///
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001297ObjCCategoryDecl *
1298ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
Argyrios Kyrtzidis4af2cb32012-03-02 19:14:29 +00001299 // FIXME: Should make sure no callers ever do this.
1300 if (!hasDefinition())
1301 return 0;
1302
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001303 if (data().ExternallyCompleted)
Douglas Gregor73693022010-12-01 23:49:52 +00001304 LoadExternalDefinition();
1305
Aaron Ballman3fe486a2014-03-13 21:23:55 +00001306 for (auto *Cat : visible_categories())
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001307 if (Cat->getIdentifier() == CategoryId)
Aaron Ballman3fe486a2014-03-13 21:23:55 +00001308 return Cat;
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001309
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +00001310 return 0;
1311}
1312
Argyrios Kyrtzidis1559d67b2009-07-21 00:06:20 +00001313ObjCMethodDecl *
1314ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
Aaron Ballman3fe486a2014-03-13 21:23:55 +00001315 for (const auto *Cat : visible_categories()) {
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001316 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
Argyrios Kyrtzidis1559d67b2009-07-21 00:06:20 +00001317 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1318 return MD;
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001319 }
1320
Argyrios Kyrtzidis1559d67b2009-07-21 00:06:20 +00001321 return 0;
1322}
1323
1324ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
Aaron Ballman3fe486a2014-03-13 21:23:55 +00001325 for (const auto *Cat : visible_categories()) {
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001326 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
Argyrios Kyrtzidis1559d67b2009-07-21 00:06:20 +00001327 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1328 return MD;
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001329 }
1330
Argyrios Kyrtzidis1559d67b2009-07-21 00:06:20 +00001331 return 0;
1332}
1333
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001334/// ClassImplementsProtocol - Checks that 'lProto' protocol
1335/// has been implemented in IDecl class, its super class or categories (if
1336/// lookupCategory is true).
1337bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1338 bool lookupCategory,
1339 bool RHSIsQualifiedID) {
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001340 if (!hasDefinition())
1341 return false;
1342
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001343 ObjCInterfaceDecl *IDecl = this;
1344 // 1st, look up the class.
Aaron Ballmana49c5062014-03-13 20:29:09 +00001345 for (auto *PI : IDecl->protocols()){
1346 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001347 return true;
1348 // This is dubious and is added to be compatible with gcc. In gcc, it is
1349 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1350 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1351 // object. This IMO, should be a bug.
1352 // FIXME: Treat this as an extension, and flag this as an error when GCC
1353 // extensions are not enabled.
Mike Stump11289f42009-09-09 15:08:12 +00001354 if (RHSIsQualifiedID &&
Aaron Ballmana49c5062014-03-13 20:29:09 +00001355 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001356 return true;
1357 }
Mike Stump11289f42009-09-09 15:08:12 +00001358
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001359 // 2nd, look up the category.
1360 if (lookupCategory)
Aaron Ballman3fe486a2014-03-13 21:23:55 +00001361 for (const auto *Cat : visible_categories()) {
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001362 for (ObjCCategoryDecl::protocol_iterator PI = Cat->protocol_begin(),
1363 E = Cat->protocol_end();
1364 PI != E; ++PI)
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001365 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
1366 return true;
1367 }
Mike Stump11289f42009-09-09 15:08:12 +00001368
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001369 // 3rd, look up the super class(s)
1370 if (IDecl->getSuperClass())
1371 return
1372 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1373 RHSIsQualifiedID);
Mike Stump11289f42009-09-09 15:08:12 +00001374
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +00001375 return false;
1376}
1377
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001378//===----------------------------------------------------------------------===//
1379// ObjCIvarDecl
1380//===----------------------------------------------------------------------===//
1381
David Blaikie68e081d2011-12-20 02:48:34 +00001382void ObjCIvarDecl::anchor() { }
1383
Daniel Dunbarfe3ead72010-04-02 20:10:03 +00001384ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +00001385 SourceLocation StartLoc,
1386 SourceLocation IdLoc, IdentifierInfo *Id,
John McCallbcd03502009-12-07 02:54:59 +00001387 QualType T, TypeSourceInfo *TInfo,
Fariborz Jahanian18722982010-07-17 00:59:30 +00001388 AccessControl ac, Expr *BW,
Argyrios Kyrtzidis2080d902014-01-03 18:32:18 +00001389 bool synthesized) {
Daniel Dunbarfe3ead72010-04-02 20:10:03 +00001390 if (DC) {
1391 // Ivar's can only appear in interfaces, implementations (via synthesized
1392 // properties), and class extensions (via direct declaration, or synthesized
1393 // properties).
1394 //
1395 // FIXME: This should really be asserting this:
1396 // (isa<ObjCCategoryDecl>(DC) &&
1397 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1398 // but unfortunately we sometimes place ivars into non-class extension
1399 // categories on error. This breaks an AST invariant, and should not be
1400 // fixed.
1401 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1402 isa<ObjCCategoryDecl>(DC)) &&
1403 "Invalid ivar decl context!");
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001404 // Once a new ivar is created in any of class/class-extension/implementation
1405 // decl contexts, the previously built IvarList must be rebuilt.
1406 ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1407 if (!ID) {
Eric Christopherf8378ca2012-07-19 22:22:55 +00001408 if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001409 ID = IM->getClassInterface();
Eric Christopherf8378ca2012-07-19 22:22:55 +00001410 else
1411 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
Fariborz Jahaniana50b3a22010-08-20 21:21:08 +00001412 }
1413 ID->setIvarList(0);
Daniel Dunbarfe3ead72010-04-02 20:10:03 +00001414 }
1415
Richard Smithf7981722013-11-22 09:01:48 +00001416 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
Argyrios Kyrtzidis2080d902014-01-03 18:32:18 +00001417 synthesized);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001418}
1419
Douglas Gregor72172e92012-01-05 21:55:30 +00001420ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001421 return new (C, ID) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
Argyrios Kyrtzidis2080d902014-01-03 18:32:18 +00001422 QualType(), 0, ObjCIvarDecl::None, 0, false);
Douglas Gregor72172e92012-01-05 21:55:30 +00001423}
1424
Daniel Dunbar89947ea2010-04-02 21:13:59 +00001425const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
1426 const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001427
Daniel Dunbar89947ea2010-04-02 21:13:59 +00001428 switch (DC->getKind()) {
1429 default:
1430 case ObjCCategoryImpl:
1431 case ObjCProtocol:
David Blaikie83d382b2011-09-23 05:06:16 +00001432 llvm_unreachable("invalid ivar container!");
Daniel Dunbar89947ea2010-04-02 21:13:59 +00001433
1434 // Ivars can only appear in class extension categories.
1435 case ObjCCategory: {
1436 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
1437 assert(CD->IsClassExtension() && "invalid container for ivar!");
1438 return CD->getClassInterface();
1439 }
1440
1441 case ObjCImplementation:
1442 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1443
1444 case ObjCInterface:
1445 return cast<ObjCInterfaceDecl>(DC);
1446 }
1447}
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001448
1449//===----------------------------------------------------------------------===//
1450// ObjCAtDefsFieldDecl
1451//===----------------------------------------------------------------------===//
1452
David Blaikie68e081d2011-12-20 02:48:34 +00001453void ObjCAtDefsFieldDecl::anchor() { }
1454
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001455ObjCAtDefsFieldDecl
Abramo Bagnaradff19302011-03-08 08:55:46 +00001456*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1457 SourceLocation StartLoc, SourceLocation IdLoc,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001458 IdentifierInfo *Id, QualType T, Expr *BW) {
Richard Smithf7981722013-11-22 09:01:48 +00001459 return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001460}
1461
Richard Smithf7981722013-11-22 09:01:48 +00001462ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +00001463 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001464 return new (C, ID) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
1465 0, QualType(), 0);
Douglas Gregor72172e92012-01-05 21:55:30 +00001466}
1467
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001468//===----------------------------------------------------------------------===//
1469// ObjCProtocolDecl
1470//===----------------------------------------------------------------------===//
1471
David Blaikie68e081d2011-12-20 02:48:34 +00001472void ObjCProtocolDecl::anchor() { }
1473
Douglas Gregor32c17572012-01-01 20:30:41 +00001474ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1475 SourceLocation nameLoc,
1476 SourceLocation atStartLoc,
Douglas Gregor05a1f4d2012-01-01 22:06:18 +00001477 ObjCProtocolDecl *PrevDecl)
1478 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
Douglas Gregor32c17572012-01-01 20:30:41 +00001479{
Rafael Espindola8db352d2013-10-17 15:37:26 +00001480 setPreviousDecl(PrevDecl);
Douglas Gregor32c17572012-01-01 20:30:41 +00001481 if (PrevDecl)
1482 Data = PrevDecl->Data;
1483}
1484
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001485ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Argyrios Kyrtzidis52f53fb2011-10-04 04:48:02 +00001486 IdentifierInfo *Id,
1487 SourceLocation nameLoc,
Argyrios Kyrtzidis1f4bee52011-10-17 19:48:06 +00001488 SourceLocation atStartLoc,
Douglas Gregor05a1f4d2012-01-01 22:06:18 +00001489 ObjCProtocolDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +00001490 ObjCProtocolDecl *Result =
1491 new (C, DC) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +00001492 Result->Data.setInt(!C.getLangOpts().Modules);
Douglas Gregor32c17572012-01-01 20:30:41 +00001493 return Result;
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001494}
1495
Richard Smithf7981722013-11-22 09:01:48 +00001496ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +00001497 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001498 ObjCProtocolDecl *Result =
1499 new (C, ID) ObjCProtocolDecl(0, 0, SourceLocation(), SourceLocation(), 0);
Douglas Gregor7dab26b2013-02-09 01:35:03 +00001500 Result->Data.setInt(!C.getLangOpts().Modules);
1501 return Result;
Douglas Gregor72172e92012-01-05 21:55:30 +00001502}
1503
Steve Naroff114aecb2009-03-01 16:12:44 +00001504ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1505 ObjCProtocolDecl *PDecl = this;
1506
1507 if (Name == getIdentifier())
1508 return PDecl;
1509
1510 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1511 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
1512 return PDecl;
Mike Stump11289f42009-09-09 15:08:12 +00001513
Steve Naroff114aecb2009-03-01 16:12:44 +00001514 return NULL;
1515}
1516
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +00001517// lookupMethod - Lookup a instance/class method in the protocol and protocols
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001518// it inherited.
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +00001519ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1520 bool isInstance) const {
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001521 ObjCMethodDecl *MethodDecl = NULL;
Mike Stump11289f42009-09-09 15:08:12 +00001522
Douglas Gregoreed49792013-01-17 00:38:46 +00001523 // If there is no definition or the definition is hidden, we don't find
1524 // anything.
1525 const ObjCProtocolDecl *Def = getDefinition();
1526 if (!Def || Def->isHidden())
1527 return NULL;
1528
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +00001529 if ((MethodDecl = getMethod(Sel, isInstance)))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001530 return MethodDecl;
Mike Stump11289f42009-09-09 15:08:12 +00001531
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001532 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +00001533 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001534 return MethodDecl;
1535 return NULL;
1536}
1537
Douglas Gregore6e48b12012-01-01 19:29:29 +00001538void ObjCProtocolDecl::allocateDefinitionData() {
Douglas Gregor7dab26b2013-02-09 01:35:03 +00001539 assert(!Data.getPointer() && "Protocol already has a definition!");
1540 Data.setPointer(new (getASTContext()) DefinitionData);
1541 Data.getPointer()->Definition = this;
Douglas Gregore6e48b12012-01-01 19:29:29 +00001542}
1543
1544void ObjCProtocolDecl::startDefinition() {
1545 allocateDefinitionData();
Douglas Gregora715bff2012-01-01 19:51:50 +00001546
1547 // Update all of the declarations with a pointer to the definition.
Aaron Ballman86c93902014-03-06 23:45:36 +00001548 for (auto RD : redecls())
Douglas Gregora715bff2012-01-01 19:51:50 +00001549 RD->Data = this->Data;
Argyrios Kyrtzidisb97a4022011-11-12 21:07:46 +00001550}
1551
Fariborz Jahanianaedaaa42013-02-14 22:33:34 +00001552void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
1553 PropertyDeclOrder &PO) const {
Fariborz Jahanian0a17f592013-01-07 21:31:08 +00001554
1555 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
Aaron Ballmand174edf2014-03-13 19:11:50 +00001556 for (auto *Prop : PDecl->properties()) {
Fariborz Jahanian0a17f592013-01-07 21:31:08 +00001557 // Insert into PM if not there already.
1558 PM.insert(std::make_pair(Prop->getIdentifier(), Prop));
Fariborz Jahanianaedaaa42013-02-14 22:33:34 +00001559 PO.push_back(Prop);
Fariborz Jahanian0a17f592013-01-07 21:31:08 +00001560 }
1561 // Scan through protocol's protocols.
1562 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
1563 E = PDecl->protocol_end(); PI != E; ++PI)
Fariborz Jahanianaedaaa42013-02-14 22:33:34 +00001564 (*PI)->collectPropertiesToImplement(PM, PO);
Anna Zaks673d76b2012-10-18 19:17:53 +00001565 }
Anna Zaks673d76b2012-10-18 19:17:53 +00001566}
1567
Fariborz Jahanian0ebf8792013-05-20 21:20:24 +00001568
1569void ObjCProtocolDecl::collectInheritedProtocolProperties(
1570 const ObjCPropertyDecl *Property,
1571 ProtocolPropertyMap &PM) const {
1572 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
1573 bool MatchFound = false;
Aaron Ballmand174edf2014-03-13 19:11:50 +00001574 for (auto *Prop : PDecl->properties()) {
Fariborz Jahanian0ebf8792013-05-20 21:20:24 +00001575 if (Prop == Property)
1576 continue;
1577 if (Prop->getIdentifier() == Property->getIdentifier()) {
1578 PM[PDecl] = Prop;
1579 MatchFound = true;
1580 break;
1581 }
1582 }
1583 // Scan through protocol's protocols which did not have a matching property.
1584 if (!MatchFound)
1585 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
1586 E = PDecl->protocol_end(); PI != E; ++PI)
1587 (*PI)->collectInheritedProtocolProperties(Property, PM);
1588 }
1589}
Anna Zaks673d76b2012-10-18 19:17:53 +00001590
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001591//===----------------------------------------------------------------------===//
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001592// ObjCCategoryDecl
1593//===----------------------------------------------------------------------===//
1594
David Blaikie68e081d2011-12-20 02:48:34 +00001595void ObjCCategoryDecl::anchor() { }
1596
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001597ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Richard Smithf7981722013-11-22 09:01:48 +00001598 SourceLocation AtLoc,
Douglas Gregor071676f2010-01-16 16:38:58 +00001599 SourceLocation ClassNameLoc,
1600 SourceLocation CategoryNameLoc,
Argyrios Kyrtzidis3a5094b2011-08-30 19:43:26 +00001601 IdentifierInfo *Id,
Fariborz Jahaniana7765fe2012-02-20 20:09:20 +00001602 ObjCInterfaceDecl *IDecl,
1603 SourceLocation IvarLBraceLoc,
1604 SourceLocation IvarRBraceLoc) {
Richard Smithf7981722013-11-22 09:01:48 +00001605 ObjCCategoryDecl *CatDecl =
1606 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
1607 IDecl, IvarLBraceLoc, IvarRBraceLoc);
Argyrios Kyrtzidis3a5094b2011-08-30 19:43:26 +00001608 if (IDecl) {
1609 // Link this category into its class's category list.
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001610 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001611 if (IDecl->hasDefinition()) {
Douglas Gregor048fbfa2013-01-16 23:00:23 +00001612 IDecl->setCategoryListRaw(CatDecl);
Douglas Gregorc0ac7d62011-12-15 05:27:12 +00001613 if (ASTMutationListener *L = C.getASTMutationListener())
1614 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
1615 }
Argyrios Kyrtzidis3a5094b2011-08-30 19:43:26 +00001616 }
1617
1618 return CatDecl;
1619}
1620
Richard Smithf7981722013-11-22 09:01:48 +00001621ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +00001622 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001623 return new (C, ID) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
1624 SourceLocation(), 0, 0);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001625}
1626
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +00001627ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
1628 return getASTContext().getObjCImplementation(
1629 const_cast<ObjCCategoryDecl*>(this));
1630}
1631
1632void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
1633 getASTContext().setObjCImplementation(this, ImplD);
1634}
1635
1636
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001637//===----------------------------------------------------------------------===//
1638// ObjCCategoryImplDecl
1639//===----------------------------------------------------------------------===//
1640
David Blaikie68e081d2011-12-20 02:48:34 +00001641void ObjCCategoryImplDecl::anchor() { }
1642
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001643ObjCCategoryImplDecl *
1644ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Argyrios Kyrtzidis52f53fb2011-10-04 04:48:02 +00001645 IdentifierInfo *Id,
1646 ObjCInterfaceDecl *ClassInterface,
1647 SourceLocation nameLoc,
Argyrios Kyrtzidis4996f5f2011-12-09 00:31:40 +00001648 SourceLocation atStartLoc,
1649 SourceLocation CategoryNameLoc) {
Fariborz Jahanian87b4ae6c2011-12-23 00:31:02 +00001650 if (ClassInterface && ClassInterface->hasDefinition())
1651 ClassInterface = ClassInterface->getDefinition();
Richard Smithf7981722013-11-22 09:01:48 +00001652 return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
1653 atStartLoc, CategoryNameLoc);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001654}
1655
Douglas Gregor72172e92012-01-05 21:55:30 +00001656ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
1657 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001658 return new (C, ID) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(),
1659 SourceLocation(), SourceLocation());
Douglas Gregor72172e92012-01-05 21:55:30 +00001660}
1661
Steve Narofff406f4d2009-10-29 21:11:04 +00001662ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
Ted Kremeneke184ac52010-03-19 20:39:03 +00001663 // The class interface might be NULL if we are working with invalid code.
1664 if (const ObjCInterfaceDecl *ID = getClassInterface())
1665 return ID->FindCategoryDeclaration(getIdentifier());
1666 return 0;
Argyrios Kyrtzidisa56fa192009-07-28 05:11:05 +00001667}
1668
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001669
David Blaikie68e081d2011-12-20 02:48:34 +00001670void ObjCImplDecl::anchor() { }
1671
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00001672void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
Douglas Gregor9a13efd2009-04-23 02:42:49 +00001673 // FIXME: The context should be correct before we get here.
Douglas Gregor29bd76f2009-04-23 01:02:12 +00001674 property->setLexicalDeclContext(this);
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00001675 addDecl(property);
Douglas Gregor29bd76f2009-04-23 01:02:12 +00001676}
1677
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +00001678void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
1679 ASTContext &Ctx = getASTContext();
1680
1681 if (ObjCImplementationDecl *ImplD
Duncan Sands49c29ee2009-07-21 07:56:29 +00001682 = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +00001683 if (IFace)
1684 Ctx.setObjCImplementation(IFace, ImplD);
1685
Duncan Sands49c29ee2009-07-21 07:56:29 +00001686 } else if (ObjCCategoryImplDecl *ImplD =
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +00001687 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
1688 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
1689 Ctx.setObjCImplementation(CD, ImplD);
1690 }
1691
1692 ClassInterface = IFace;
1693}
1694
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +00001695/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahaniane92f54a2013-03-12 17:43:00 +00001696/// properties implemented in this \@implementation block and returns
Chris Lattneraab70d22009-02-16 19:24:31 +00001697/// the implemented property that uses it.
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +00001698///
Chris Lattnera9ca0522009-02-28 18:42:10 +00001699ObjCPropertyImplDecl *ObjCImplDecl::
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00001700FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
1701 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
David Blaikie40ed2972012-06-06 20:45:41 +00001702 ObjCPropertyImplDecl *PID = *i;
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +00001703 if (PID->getPropertyIvarDecl() &&
1704 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
1705 return PID;
1706 }
1707 return 0;
1708}
1709
1710/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
James Dennett5207a1c2012-06-15 22:30:14 +00001711/// added to the list of those properties \@synthesized/\@dynamic in this
1712/// category \@implementation block.
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +00001713///
Chris Lattnera9ca0522009-02-28 18:42:10 +00001714ObjCPropertyImplDecl *ObjCImplDecl::
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00001715FindPropertyImplDecl(IdentifierInfo *Id) const {
1716 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
David Blaikie40ed2972012-06-06 20:45:41 +00001717 ObjCPropertyImplDecl *PID = *i;
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +00001718 if (PID->getPropertyDecl()->getIdentifier() == Id)
1719 return PID;
1720 }
1721 return 0;
1722}
1723
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001724raw_ostream &clang::operator<<(raw_ostream &OS,
Benjamin Kramer2f569922012-02-07 11:57:45 +00001725 const ObjCCategoryImplDecl &CID) {
1726 OS << CID.getName();
Benjamin Kramerb11416d2010-04-17 09:33:03 +00001727 return OS;
1728}
1729
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001730//===----------------------------------------------------------------------===//
1731// ObjCImplementationDecl
1732//===----------------------------------------------------------------------===//
1733
David Blaikie68e081d2011-12-20 02:48:34 +00001734void ObjCImplementationDecl::anchor() { }
1735
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001736ObjCImplementationDecl *
Mike Stump11289f42009-09-09 15:08:12 +00001737ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001738 ObjCInterfaceDecl *ClassInterface,
Argyrios Kyrtzidis52f53fb2011-10-04 04:48:02 +00001739 ObjCInterfaceDecl *SuperDecl,
1740 SourceLocation nameLoc,
Fariborz Jahaniana7765fe2012-02-20 20:09:20 +00001741 SourceLocation atStartLoc,
Argyrios Kyrtzidisfac31622013-05-03 18:05:44 +00001742 SourceLocation superLoc,
Fariborz Jahaniana7765fe2012-02-20 20:09:20 +00001743 SourceLocation IvarLBraceLoc,
1744 SourceLocation IvarRBraceLoc) {
Fariborz Jahanian87b4ae6c2011-12-23 00:31:02 +00001745 if (ClassInterface && ClassInterface->hasDefinition())
1746 ClassInterface = ClassInterface->getDefinition();
Richard Smithf7981722013-11-22 09:01:48 +00001747 return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
1748 nameLoc, atStartLoc, superLoc,
1749 IvarLBraceLoc, IvarRBraceLoc);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001750}
1751
Douglas Gregor72172e92012-01-05 21:55:30 +00001752ObjCImplementationDecl *
1753ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001754 return new (C, ID) ObjCImplementationDecl(0, 0, 0, SourceLocation(),
1755 SourceLocation());
Douglas Gregor72172e92012-01-05 21:55:30 +00001756}
1757
John McCall0410e572011-07-22 04:15:06 +00001758void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
1759 CXXCtorInitializer ** initializers,
1760 unsigned numInitializers) {
1761 if (numInitializers > 0) {
1762 NumIvarInitializers = numInitializers;
1763 CXXCtorInitializer **ivarInitializers =
1764 new (C) CXXCtorInitializer*[NumIvarInitializers];
1765 memcpy(ivarInitializers, initializers,
1766 numInitializers * sizeof(CXXCtorInitializer*));
1767 IvarInitializers = ivarInitializers;
1768 }
1769}
1770
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001771raw_ostream &clang::operator<<(raw_ostream &OS,
Benjamin Kramer2f569922012-02-07 11:57:45 +00001772 const ObjCImplementationDecl &ID) {
1773 OS << ID.getName();
Benjamin Kramerb11416d2010-04-17 09:33:03 +00001774 return OS;
1775}
1776
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001777//===----------------------------------------------------------------------===//
1778// ObjCCompatibleAliasDecl
1779//===----------------------------------------------------------------------===//
1780
David Blaikie68e081d2011-12-20 02:48:34 +00001781void ObjCCompatibleAliasDecl::anchor() { }
1782
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001783ObjCCompatibleAliasDecl *
1784ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
1785 SourceLocation L,
Mike Stump11289f42009-09-09 15:08:12 +00001786 IdentifierInfo *Id,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001787 ObjCInterfaceDecl* AliasedClass) {
Richard Smithf7981722013-11-22 09:01:48 +00001788 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001789}
1790
Douglas Gregor72172e92012-01-05 21:55:30 +00001791ObjCCompatibleAliasDecl *
1792ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001793 return new (C, ID) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
Douglas Gregor72172e92012-01-05 21:55:30 +00001794}
1795
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001796//===----------------------------------------------------------------------===//
1797// ObjCPropertyDecl
1798//===----------------------------------------------------------------------===//
1799
David Blaikie68e081d2011-12-20 02:48:34 +00001800void ObjCPropertyDecl::anchor() { }
1801
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001802ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
1803 SourceLocation L,
1804 IdentifierInfo *Id,
Fariborz Jahanianda8ec2b2010-01-21 17:36:00 +00001805 SourceLocation AtLoc,
Fariborz Jahanian86c2f5c2012-02-29 22:18:55 +00001806 SourceLocation LParenLoc,
John McCall339bb662010-06-04 20:50:08 +00001807 TypeSourceInfo *T,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001808 PropertyControl propControl) {
Richard Smithf7981722013-11-22 09:01:48 +00001809 return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001810}
1811
Richard Smithf7981722013-11-22 09:01:48 +00001812ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +00001813 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001814 return new (C, ID) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
1815 SourceLocation(), 0);
Douglas Gregor72172e92012-01-05 21:55:30 +00001816}
1817
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +00001818//===----------------------------------------------------------------------===//
1819// ObjCPropertyImplDecl
1820//===----------------------------------------------------------------------===//
1821
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +00001822ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregorc25d7a72009-01-09 00:49:46 +00001823 DeclContext *DC,
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +00001824 SourceLocation atLoc,
1825 SourceLocation L,
1826 ObjCPropertyDecl *property,
Daniel Dunbar3b4fdb02008-08-26 04:47:31 +00001827 Kind PK,
Douglas Gregorb1b71e52010-11-17 01:03:52 +00001828 ObjCIvarDecl *ivar,
1829 SourceLocation ivarLoc) {
Richard Smithf7981722013-11-22 09:01:48 +00001830 return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
1831 ivarLoc);
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +00001832}
Chris Lattnered0e1642008-03-17 01:19:02 +00001833
Richard Smithf7981722013-11-22 09:01:48 +00001834ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +00001835 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +00001836 return new (C, ID) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
1837 0, Dynamic, 0, SourceLocation());
Douglas Gregor72172e92012-01-05 21:55:30 +00001838}
1839
Douglas Gregorb1b71e52010-11-17 01:03:52 +00001840SourceRange ObjCPropertyImplDecl::getSourceRange() const {
1841 SourceLocation EndLoc = getLocation();
1842 if (IvarLoc.isValid())
1843 EndLoc = IvarLoc;
Chris Lattnerc5ffed42008-04-04 06:12:32 +00001844
Douglas Gregorb1b71e52010-11-17 01:03:52 +00001845 return SourceRange(AtLoc, EndLoc);
1846}