1 //===--- 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"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/Attr.h"
18 #include "clang/AST/Stmt.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallString.h"
21 using namespace clang;
22
23 //===----------------------------------------------------------------------===//
24 // ObjCListBase
25 //===----------------------------------------------------------------------===//
26
set(void * const * InList,unsigned Elts,ASTContext & Ctx)27 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
28 List = 0;
29 if (Elts == 0) return; // Setting to an empty list is a noop.
30
31
32 List = new (Ctx) void*[Elts];
33 NumElts = Elts;
34 memcpy(List, InList, sizeof(void*)*Elts);
35 }
36
set(ObjCProtocolDecl * const * InList,unsigned Elts,const SourceLocation * Locs,ASTContext & Ctx)37 void 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
47 //===----------------------------------------------------------------------===//
48 // ObjCInterfaceDecl
49 //===----------------------------------------------------------------------===//
50
anchor()51 void ObjCContainerDecl::anchor() { }
52
53 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
54 ///
55 ObjCIvarDecl *
getIvarDecl(IdentifierInfo * Id) const56 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
57 lookup_const_result R = lookup(Id);
58 for (lookup_const_iterator Ivar = R.begin(), IvarEnd = R.end();
59 Ivar != IvarEnd; ++Ivar) {
60 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
61 return ivar;
62 }
63 return 0;
64 }
65
66 // Get the local instance/class method declared in this interface.
67 ObjCMethodDecl *
getMethod(Selector Sel,bool isInstance) const68 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
69 // If this context is a hidden protocol definition, don't find any
70 // methods there.
71 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
72 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
73 if (Def->isHidden())
74 return 0;
75 }
76
77 // Since instance & class methods can have the same name, the loop below
78 // ensures we get the correct method.
79 //
80 // @interface Whatever
81 // - (int) class_method;
82 // + (float) class_method;
83 // @end
84 //
85 lookup_const_result R = lookup(Sel);
86 for (lookup_const_iterator Meth = R.begin(), MethEnd = R.end();
87 Meth != MethEnd; ++Meth) {
88 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
89 if (MD && MD->isInstanceMethod() == isInstance)
90 return MD;
91 }
92 return 0;
93 }
94
95 ObjCPropertyDecl *
findPropertyDecl(const DeclContext * DC,IdentifierInfo * propertyID)96 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
97 IdentifierInfo *propertyID) {
98 // If this context is a hidden protocol definition, don't find any
99 // property.
100 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
101 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
102 if (Def->isHidden())
103 return 0;
104 }
105
106 DeclContext::lookup_const_result R = DC->lookup(propertyID);
107 for (DeclContext::lookup_const_iterator I = R.begin(), E = R.end(); I != E;
108 ++I)
109 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
110 return PD;
111
112 return 0;
113 }
114
115 IdentifierInfo *
getDefaultSynthIvarName(ASTContext & Ctx) const116 ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
117 SmallString<128> ivarName;
118 {
119 llvm::raw_svector_ostream os(ivarName);
120 os << '_' << getIdentifier()->getName();
121 }
122 return &Ctx.Idents.get(ivarName.str());
123 }
124
125 /// FindPropertyDeclaration - Finds declaration of the property given its name
126 /// in 'PropertyId' and returns it. It returns 0, if not found.
127 ObjCPropertyDecl *
FindPropertyDeclaration(IdentifierInfo * PropertyId) const128 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
129 // Don't find properties within hidden protocol definitions.
130 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
131 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
132 if (Def->isHidden())
133 return 0;
134 }
135
136 if (ObjCPropertyDecl *PD =
137 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
138 return PD;
139
140 switch (getKind()) {
141 default:
142 break;
143 case Decl::ObjCProtocol: {
144 const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
145 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
146 E = PID->protocol_end(); I != E; ++I)
147 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
148 return P;
149 break;
150 }
151 case Decl::ObjCInterface: {
152 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
153 // Look through categories (but not extensions).
154 for (ObjCInterfaceDecl::visible_categories_iterator
155 Cat = OID->visible_categories_begin(),
156 CatEnd = OID->visible_categories_end();
157 Cat != CatEnd; ++Cat) {
158 if (!Cat->IsClassExtension())
159 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
160 return P;
161 }
162
163 // Look through protocols.
164 for (ObjCInterfaceDecl::all_protocol_iterator
165 I = OID->all_referenced_protocol_begin(),
166 E = OID->all_referenced_protocol_end(); I != E; ++I)
167 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
168 return P;
169
170 // Finally, check the super class.
171 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
172 return superClass->FindPropertyDeclaration(PropertyId);
173 break;
174 }
175 case Decl::ObjCCategory: {
176 const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
177 // Look through protocols.
178 if (!OCD->IsClassExtension())
179 for (ObjCCategoryDecl::protocol_iterator
180 I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
181 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
182 return P;
183
184 break;
185 }
186 }
187 return 0;
188 }
189
anchor()190 void ObjCInterfaceDecl::anchor() { }
191
192 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
193 /// with name 'PropertyId' in the primary class; including those in protocols
194 /// (direct or indirect) used by the primary class.
195 ///
196 ObjCPropertyDecl *
FindPropertyVisibleInPrimaryClass(IdentifierInfo * PropertyId) const197 ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
198 IdentifierInfo *PropertyId) const {
199 // FIXME: Should make sure no callers ever do this.
200 if (!hasDefinition())
201 return 0;
202
203 if (data().ExternallyCompleted)
204 LoadExternalDefinition();
205
206 if (ObjCPropertyDecl *PD =
207 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
208 return PD;
209
210 // Look through protocols.
211 for (ObjCInterfaceDecl::all_protocol_iterator
212 I = all_referenced_protocol_begin(),
213 E = all_referenced_protocol_end(); I != E; ++I)
214 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
215 return P;
216
217 return 0;
218 }
219
collectPropertiesToImplement(PropertyMap & PM,PropertyDeclOrder & PO) const220 void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
221 PropertyDeclOrder &PO) const {
222 for (ObjCContainerDecl::prop_iterator P = prop_begin(),
223 E = prop_end(); P != E; ++P) {
224 ObjCPropertyDecl *Prop = *P;
225 PM[Prop->getIdentifier()] = Prop;
226 PO.push_back(Prop);
227 }
228 for (ObjCInterfaceDecl::all_protocol_iterator
229 PI = all_referenced_protocol_begin(),
230 E = all_referenced_protocol_end(); PI != E; ++PI)
231 (*PI)->collectPropertiesToImplement(PM, PO);
232 // Note, the properties declared only in class extensions are still copied
233 // into the main @interface's property list, and therefore we don't
234 // explicitly, have to search class extension properties.
235 }
236
isArcWeakrefUnavailable() const237 bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {
238 const ObjCInterfaceDecl *Class = this;
239 while (Class) {
240 if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
241 return true;
242 Class = Class->getSuperClass();
243 }
244 return false;
245 }
246
isObjCRequiresPropertyDefs() const247 const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
248 const ObjCInterfaceDecl *Class = this;
249 while (Class) {
250 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
251 return Class;
252 Class = Class->getSuperClass();
253 }
254 return 0;
255 }
256
mergeClassExtensionProtocolList(ObjCProtocolDecl * const * ExtList,unsigned ExtNum,ASTContext & C)257 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
258 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
259 ASTContext &C)
260 {
261 if (data().ExternallyCompleted)
262 LoadExternalDefinition();
263
264 if (data().AllReferencedProtocols.empty() &&
265 data().ReferencedProtocols.empty()) {
266 data().AllReferencedProtocols.set(ExtList, ExtNum, C);
267 return;
268 }
269
270 // Check for duplicate protocol in class's protocol list.
271 // This is O(n*m). But it is extremely rare and number of protocols in
272 // class or its extension are very few.
273 SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
274 for (unsigned i = 0; i < ExtNum; i++) {
275 bool protocolExists = false;
276 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
277 for (all_protocol_iterator
278 p = all_referenced_protocol_begin(),
279 e = all_referenced_protocol_end(); p != e; ++p) {
280 ObjCProtocolDecl *Proto = (*p);
281 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
282 protocolExists = true;
283 break;
284 }
285 }
286 // Do we want to warn on a protocol in extension class which
287 // already exist in the class? Probably not.
288 if (!protocolExists)
289 ProtocolRefs.push_back(ProtoInExtension);
290 }
291
292 if (ProtocolRefs.empty())
293 return;
294
295 // Merge ProtocolRefs into class's protocol list;
296 for (all_protocol_iterator p = all_referenced_protocol_begin(),
297 e = all_referenced_protocol_end(); p != e; ++p) {
298 ProtocolRefs.push_back(*p);
299 }
300
301 data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
302 }
303
allocateDefinitionData()304 void ObjCInterfaceDecl::allocateDefinitionData() {
305 assert(!hasDefinition() && "ObjC class already has a definition");
306 Data.setPointer(new (getASTContext()) DefinitionData());
307 Data.getPointer()->Definition = this;
308
309 // Make the type point at the definition, now that we have one.
310 if (TypeForDecl)
311 cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
312 }
313
startDefinition()314 void ObjCInterfaceDecl::startDefinition() {
315 allocateDefinitionData();
316
317 // Update all of the declarations with a pointer to the definition.
318 for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
319 RD != RDEnd; ++RD) {
320 if (*RD != this)
321 RD->Data = Data;
322 }
323 }
324
lookupInstanceVariable(IdentifierInfo * ID,ObjCInterfaceDecl * & clsDeclared)325 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
326 ObjCInterfaceDecl *&clsDeclared) {
327 // FIXME: Should make sure no callers ever do this.
328 if (!hasDefinition())
329 return 0;
330
331 if (data().ExternallyCompleted)
332 LoadExternalDefinition();
333
334 ObjCInterfaceDecl* ClassDecl = this;
335 while (ClassDecl != NULL) {
336 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
337 clsDeclared = ClassDecl;
338 return I;
339 }
340
341 for (ObjCInterfaceDecl::visible_extensions_iterator
342 Ext = ClassDecl->visible_extensions_begin(),
343 ExtEnd = ClassDecl->visible_extensions_end();
344 Ext != ExtEnd; ++Ext) {
345 if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
346 clsDeclared = ClassDecl;
347 return I;
348 }
349 }
350
351 ClassDecl = ClassDecl->getSuperClass();
352 }
353 return NULL;
354 }
355
356 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
357 /// class whose name is passed as argument. If it is not one of the super classes
358 /// the it returns NULL.
lookupInheritedClass(const IdentifierInfo * ICName)359 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
360 const IdentifierInfo*ICName) {
361 // FIXME: Should make sure no callers ever do this.
362 if (!hasDefinition())
363 return 0;
364
365 if (data().ExternallyCompleted)
366 LoadExternalDefinition();
367
368 ObjCInterfaceDecl* ClassDecl = this;
369 while (ClassDecl != NULL) {
370 if (ClassDecl->getIdentifier() == ICName)
371 return ClassDecl;
372 ClassDecl = ClassDecl->getSuperClass();
373 }
374 return NULL;
375 }
376
377 /// lookupMethod - This method returns an instance/class method by looking in
378 /// the class, its categories, and its super classes (using a linear search).
lookupMethod(Selector Sel,bool isInstance,bool shallowCategoryLookup) const379 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
380 bool isInstance,
381 bool shallowCategoryLookup) const {
382 // FIXME: Should make sure no callers ever do this.
383 if (!hasDefinition())
384 return 0;
385
386 const ObjCInterfaceDecl* ClassDecl = this;
387 ObjCMethodDecl *MethodDecl = 0;
388
389 if (data().ExternallyCompleted)
390 LoadExternalDefinition();
391
392 while (ClassDecl != NULL) {
393 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
394 return MethodDecl;
395
396 // Didn't find one yet - look through protocols.
397 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
398 E = ClassDecl->protocol_end();
399 I != E; ++I)
400 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
401 return MethodDecl;
402
403 // Didn't find one yet - now look through categories.
404 for (ObjCInterfaceDecl::visible_categories_iterator
405 Cat = ClassDecl->visible_categories_begin(),
406 CatEnd = ClassDecl->visible_categories_end();
407 Cat != CatEnd; ++Cat) {
408 if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
409 return MethodDecl;
410
411 if (!shallowCategoryLookup) {
412 // Didn't find one yet - look through protocols.
413 const ObjCList<ObjCProtocolDecl> &Protocols =
414 Cat->getReferencedProtocols();
415 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
416 E = Protocols.end(); I != E; ++I)
417 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
418 return MethodDecl;
419 }
420 }
421
422 ClassDecl = ClassDecl->getSuperClass();
423 }
424 return NULL;
425 }
426
427 // Will search "local" class/category implementations for a method decl.
428 // If failed, then we search in class's root for an instance method.
429 // Returns 0 if no method is found.
lookupPrivateMethod(const Selector & Sel,bool Instance) const430 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
431 const Selector &Sel,
432 bool Instance) const {
433 // FIXME: Should make sure no callers ever do this.
434 if (!hasDefinition())
435 return 0;
436
437 if (data().ExternallyCompleted)
438 LoadExternalDefinition();
439
440 ObjCMethodDecl *Method = 0;
441 if (ObjCImplementationDecl *ImpDecl = getImplementation())
442 Method = Instance ? ImpDecl->getInstanceMethod(Sel)
443 : ImpDecl->getClassMethod(Sel);
444
445 // Look through local category implementations associated with the class.
446 if (!Method)
447 Method = Instance ? getCategoryInstanceMethod(Sel)
448 : getCategoryClassMethod(Sel);
449
450 // Before we give up, check if the selector is an instance method.
451 // But only in the root. This matches gcc's behavior and what the
452 // runtime expects.
453 if (!Instance && !Method && !getSuperClass()) {
454 Method = lookupInstanceMethod(Sel);
455 // Look through local category implementations associated
456 // with the root class.
457 if (!Method)
458 Method = lookupPrivateMethod(Sel, true);
459 }
460
461 if (!Method && getSuperClass())
462 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
463 return Method;
464 }
465
466 //===----------------------------------------------------------------------===//
467 // ObjCMethodDecl
468 //===----------------------------------------------------------------------===//
469
Create(ASTContext & C,SourceLocation beginLoc,SourceLocation endLoc,Selector SelInfo,QualType T,TypeSourceInfo * ResultTInfo,DeclContext * contextDecl,bool isInstance,bool isVariadic,bool isPropertyAccessor,bool isImplicitlyDeclared,bool isDefined,ImplementationControl impControl,bool HasRelatedResultType)470 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
471 SourceLocation beginLoc,
472 SourceLocation endLoc,
473 Selector SelInfo, QualType T,
474 TypeSourceInfo *ResultTInfo,
475 DeclContext *contextDecl,
476 bool isInstance,
477 bool isVariadic,
478 bool isPropertyAccessor,
479 bool isImplicitlyDeclared,
480 bool isDefined,
481 ImplementationControl impControl,
482 bool HasRelatedResultType) {
483 return new (C) ObjCMethodDecl(beginLoc, endLoc,
484 SelInfo, T, ResultTInfo, contextDecl,
485 isInstance, isVariadic, isPropertyAccessor,
486 isImplicitlyDeclared, isDefined,
487 impControl,
488 HasRelatedResultType);
489 }
490
CreateDeserialized(ASTContext & C,unsigned ID)491 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
492 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCMethodDecl));
493 return new (Mem) ObjCMethodDecl(SourceLocation(), SourceLocation(),
494 Selector(), QualType(), 0, 0);
495 }
496
getBody() const497 Stmt *ObjCMethodDecl::getBody() const {
498 return Body.get(getASTContext().getExternalSource());
499 }
500
setAsRedeclaration(const ObjCMethodDecl * PrevMethod)501 void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
502 assert(PrevMethod);
503 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
504 IsRedeclaration = true;
505 PrevMethod->HasRedeclaration = true;
506 }
507
setParamsAndSelLocs(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)508 void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
509 ArrayRef<ParmVarDecl*> Params,
510 ArrayRef<SourceLocation> SelLocs) {
511 ParamsAndSelLocs = 0;
512 NumParams = Params.size();
513 if (Params.empty() && SelLocs.empty())
514 return;
515
516 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
517 sizeof(SourceLocation) * SelLocs.size();
518 ParamsAndSelLocs = C.Allocate(Size);
519 std::copy(Params.begin(), Params.end(), getParams());
520 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
521 }
522
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const523 void ObjCMethodDecl::getSelectorLocs(
524 SmallVectorImpl<SourceLocation> &SelLocs) const {
525 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
526 SelLocs.push_back(getSelectorLoc(i));
527 }
528
setMethodParams(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)529 void ObjCMethodDecl::setMethodParams(ASTContext &C,
530 ArrayRef<ParmVarDecl*> Params,
531 ArrayRef<SourceLocation> SelLocs) {
532 assert((!SelLocs.empty() || isImplicit()) &&
533 "No selector locs for non-implicit method");
534 if (isImplicit())
535 return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
536
537 SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
538 DeclEndLoc);
539 if (SelLocsKind != SelLoc_NonStandard)
540 return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
541
542 setParamsAndSelLocs(C, Params, SelLocs);
543 }
544
545 /// \brief A definition will return its interface declaration.
546 /// An interface declaration will return its definition.
547 /// Otherwise it will return itself.
getNextRedeclaration()548 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
549 ASTContext &Ctx = getASTContext();
550 ObjCMethodDecl *Redecl = 0;
551 if (HasRedeclaration)
552 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
553 if (Redecl)
554 return Redecl;
555
556 Decl *CtxD = cast<Decl>(getDeclContext());
557
558 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
559 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
560 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
561
562 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
563 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
564 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
565
566 } else if (ObjCImplementationDecl *ImplD =
567 dyn_cast<ObjCImplementationDecl>(CtxD)) {
568 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
569 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
570
571 } else if (ObjCCategoryImplDecl *CImplD =
572 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
573 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
574 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
575 }
576
577 if (!Redecl && isRedeclaration()) {
578 // This is the last redeclaration, go back to the first method.
579 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
580 isInstanceMethod());
581 }
582
583 return Redecl ? Redecl : this;
584 }
585
getCanonicalDecl()586 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
587 Decl *CtxD = cast<Decl>(getDeclContext());
588
589 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
590 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
591 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
592 isInstanceMethod()))
593 return MD;
594
595 } else if (ObjCCategoryImplDecl *CImplD =
596 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
597 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
598 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
599 isInstanceMethod()))
600 return MD;
601 }
602
603 if (isRedeclaration())
604 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
605 isInstanceMethod());
606
607 return this;
608 }
609
getLocEnd() const610 SourceLocation ObjCMethodDecl::getLocEnd() const {
611 if (Stmt *Body = getBody())
612 return Body->getLocEnd();
613 return DeclEndLoc;
614 }
615
getMethodFamily() const616 ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
617 ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
618 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
619 return family;
620
621 // Check for an explicit attribute.
622 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
623 // The unfortunate necessity of mapping between enums here is due
624 // to the attributes framework.
625 switch (attr->getFamily()) {
626 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
627 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
628 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
629 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
630 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
631 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
632 }
633 Family = static_cast<unsigned>(family);
634 return family;
635 }
636
637 family = getSelector().getMethodFamily();
638 switch (family) {
639 case OMF_None: break;
640
641 // init only has a conventional meaning for an instance method, and
642 // it has to return an object.
643 case OMF_init:
644 if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
645 family = OMF_None;
646 break;
647
648 // alloc/copy/new have a conventional meaning for both class and
649 // instance methods, but they require an object return.
650 case OMF_alloc:
651 case OMF_copy:
652 case OMF_mutableCopy:
653 case OMF_new:
654 if (!getResultType()->isObjCObjectPointerType())
655 family = OMF_None;
656 break;
657
658 // These selectors have a conventional meaning only for instance methods.
659 case OMF_dealloc:
660 case OMF_finalize:
661 case OMF_retain:
662 case OMF_release:
663 case OMF_autorelease:
664 case OMF_retainCount:
665 case OMF_self:
666 if (!isInstanceMethod())
667 family = OMF_None;
668 break;
669
670 case OMF_performSelector:
671 if (!isInstanceMethod() ||
672 !getResultType()->isObjCIdType())
673 family = OMF_None;
674 else {
675 unsigned noParams = param_size();
676 if (noParams < 1 || noParams > 3)
677 family = OMF_None;
678 else {
679 ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
680 QualType ArgT = (*it);
681 if (!ArgT->isObjCSelType()) {
682 family = OMF_None;
683 break;
684 }
685 while (--noParams) {
686 it++;
687 ArgT = (*it);
688 if (!ArgT->isObjCIdType()) {
689 family = OMF_None;
690 break;
691 }
692 }
693 }
694 }
695 break;
696
697 }
698
699 // Cache the result.
700 Family = static_cast<unsigned>(family);
701 return family;
702 }
703
createImplicitParams(ASTContext & Context,const ObjCInterfaceDecl * OID)704 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
705 const ObjCInterfaceDecl *OID) {
706 QualType selfTy;
707 if (isInstanceMethod()) {
708 // There may be no interface context due to error in declaration
709 // of the interface (which has been reported). Recover gracefully.
710 if (OID) {
711 selfTy = Context.getObjCInterfaceType(OID);
712 selfTy = Context.getObjCObjectPointerType(selfTy);
713 } else {
714 selfTy = Context.getObjCIdType();
715 }
716 } else // we have a factory method.
717 selfTy = Context.getObjCClassType();
718
719 bool selfIsPseudoStrong = false;
720 bool selfIsConsumed = false;
721
722 if (Context.getLangOpts().ObjCAutoRefCount) {
723 if (isInstanceMethod()) {
724 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
725
726 // 'self' is always __strong. It's actually pseudo-strong except
727 // in init methods (or methods labeled ns_consumes_self), though.
728 Qualifiers qs;
729 qs.setObjCLifetime(Qualifiers::OCL_Strong);
730 selfTy = Context.getQualifiedType(selfTy, qs);
731
732 // In addition, 'self' is const unless this is an init method.
733 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
734 selfTy = selfTy.withConst();
735 selfIsPseudoStrong = true;
736 }
737 }
738 else {
739 assert(isClassMethod());
740 // 'self' is always const in class methods.
741 selfTy = selfTy.withConst();
742 selfIsPseudoStrong = true;
743 }
744 }
745
746 ImplicitParamDecl *self
747 = ImplicitParamDecl::Create(Context, this, SourceLocation(),
748 &Context.Idents.get("self"), selfTy);
749 setSelfDecl(self);
750
751 if (selfIsConsumed)
752 self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
753
754 if (selfIsPseudoStrong)
755 self->setARCPseudoStrong(true);
756
757 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
758 &Context.Idents.get("_cmd"),
759 Context.getObjCSelType()));
760 }
761
getClassInterface()762 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
763 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
764 return ID;
765 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
766 return CD->getClassInterface();
767 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
768 return IMD->getClassInterface();
769
770 assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
771 llvm_unreachable("unknown method context");
772 }
773
CollectOverriddenMethodsRecurse(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods,bool MovedToSuper)774 static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
775 const ObjCMethodDecl *Method,
776 SmallVectorImpl<const ObjCMethodDecl *> &Methods,
777 bool MovedToSuper) {
778 if (!Container)
779 return;
780
781 // In categories look for overriden methods from protocols. A method from
782 // category is not "overriden" since it is considered as the "same" method
783 // (same USR) as the one from the interface.
784 if (const ObjCCategoryDecl *
785 Category = dyn_cast<ObjCCategoryDecl>(Container)) {
786 // Check whether we have a matching method at this category but only if we
787 // are at the super class level.
788 if (MovedToSuper)
789 if (ObjCMethodDecl *
790 Overridden = Container->getMethod(Method->getSelector(),
791 Method->isInstanceMethod()))
792 if (Method != Overridden) {
793 // We found an override at this category; there is no need to look
794 // into its protocols.
795 Methods.push_back(Overridden);
796 return;
797 }
798
799 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
800 PEnd = Category->protocol_end();
801 P != PEnd; ++P)
802 CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
803 return;
804 }
805
806 // Check whether we have a matching method at this level.
807 if (const ObjCMethodDecl *
808 Overridden = Container->getMethod(Method->getSelector(),
809 Method->isInstanceMethod()))
810 if (Method != Overridden) {
811 // We found an override at this level; there is no need to look
812 // into other protocols or categories.
813 Methods.push_back(Overridden);
814 return;
815 }
816
817 if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
818 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
819 PEnd = Protocol->protocol_end();
820 P != PEnd; ++P)
821 CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
822 }
823
824 if (const ObjCInterfaceDecl *
825 Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
826 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
827 PEnd = Interface->protocol_end();
828 P != PEnd; ++P)
829 CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
830
831 for (ObjCInterfaceDecl::visible_categories_iterator
832 Cat = Interface->visible_categories_begin(),
833 CatEnd = Interface->visible_categories_end();
834 Cat != CatEnd; ++Cat) {
835 CollectOverriddenMethodsRecurse(*Cat, Method, Methods,
836 MovedToSuper);
837 }
838
839 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
840 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
841 /*MovedToSuper=*/true);
842 }
843 }
844
CollectOverriddenMethods(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)845 static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
846 const ObjCMethodDecl *Method,
847 SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
848 CollectOverriddenMethodsRecurse(Container, Method, Methods,
849 /*MovedToSuper=*/false);
850 }
851
collectOverriddenMethodsSlow(const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & overridden)852 static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
853 SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
854 assert(Method->isOverriding());
855
856 if (const ObjCProtocolDecl *
857 ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
858 CollectOverriddenMethods(ProtD, Method, overridden);
859
860 } else if (const ObjCImplDecl *
861 IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
862 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
863 if (!ID)
864 return;
865 // Start searching for overridden methods using the method from the
866 // interface as starting point.
867 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
868 Method->isInstanceMethod()))
869 Method = IFaceMeth;
870 CollectOverriddenMethods(ID, Method, overridden);
871
872 } else if (const ObjCCategoryDecl *
873 CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
874 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
875 if (!ID)
876 return;
877 // Start searching for overridden methods using the method from the
878 // interface as starting point.
879 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
880 Method->isInstanceMethod()))
881 Method = IFaceMeth;
882 CollectOverriddenMethods(ID, Method, overridden);
883
884 } else {
885 CollectOverriddenMethods(
886 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
887 Method, overridden);
888 }
889 }
890
collectOnCategoriesAfterLocation(SourceLocation Loc,const ObjCInterfaceDecl * Class,SourceManager & SM,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)891 static void collectOnCategoriesAfterLocation(SourceLocation Loc,
892 const ObjCInterfaceDecl *Class,
893 SourceManager &SM,
894 const ObjCMethodDecl *Method,
895 SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
896 if (!Class)
897 return;
898
899 for (ObjCInterfaceDecl::visible_categories_iterator
900 Cat = Class->visible_categories_begin(),
901 CatEnd = Class->visible_categories_end();
902 Cat != CatEnd; ++Cat) {
903 if (SM.isBeforeInTranslationUnit(Loc, Cat->getLocation()))
904 CollectOverriddenMethodsRecurse(*Cat, Method, Methods, true);
905 }
906
907 collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,
908 Method, Methods);
909 }
910
911 /// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
912 /// returns false.
913 /// You'd think that in that case there are no overrides but categories can
914 /// "introduce" new overridden methods that are missed by Sema because the
915 /// overrides lookup that it does for methods, inside implementations, will
916 /// stop at the interface level (if there is a method there) and not look
917 /// further in super classes.
918 /// Methods in an implementation can overide methods in super class's category
919 /// but not in current class's category. But, such methods
collectOverriddenMethodsFast(SourceManager & SM,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)920 static void collectOverriddenMethodsFast(SourceManager &SM,
921 const ObjCMethodDecl *Method,
922 SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
923 assert(!Method->isOverriding());
924
925 const ObjCContainerDecl *
926 ContD = cast<ObjCContainerDecl>(Method->getDeclContext());
927 if (isa<ObjCInterfaceDecl>(ContD) || isa<ObjCProtocolDecl>(ContD))
928 return;
929 const ObjCInterfaceDecl *Class = Method->getClassInterface();
930 if (!Class)
931 return;
932
933 collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
934 SM, Method, Methods);
935 }
936
getOverriddenMethods(SmallVectorImpl<const ObjCMethodDecl * > & Overridden) const937 void ObjCMethodDecl::getOverriddenMethods(
938 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
939 const ObjCMethodDecl *Method = this;
940
941 if (Method->isRedeclaration()) {
942 Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
943 getMethod(Method->getSelector(), Method->isInstanceMethod());
944 }
945
946 if (!Method->isOverriding()) {
947 collectOverriddenMethodsFast(getASTContext().getSourceManager(),
948 Method, Overridden);
949 } else {
950 collectOverriddenMethodsSlow(Method, Overridden);
951 assert(!Overridden.empty() &&
952 "ObjCMethodDecl's overriding bit is not as expected");
953 }
954 }
955
956 const ObjCPropertyDecl *
findPropertyDecl(bool CheckOverrides) const957 ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
958 Selector Sel = getSelector();
959 unsigned NumArgs = Sel.getNumArgs();
960 if (NumArgs > 1)
961 return 0;
962
963 if (!isInstanceMethod() || getMethodFamily() != OMF_None)
964 return 0;
965
966 if (isPropertyAccessor()) {
967 const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
968 // If container is class extension, find its primary class.
969 if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(Container))
970 if (CatDecl->IsClassExtension())
971 Container = CatDecl->getClassInterface();
972
973 bool IsGetter = (NumArgs == 0);
974
975 for (ObjCContainerDecl::prop_iterator I = Container->prop_begin(),
976 E = Container->prop_end();
977 I != E; ++I) {
978 Selector NextSel = IsGetter ? (*I)->getGetterName()
979 : (*I)->getSetterName();
980 if (NextSel == Sel)
981 return *I;
982 }
983
984 llvm_unreachable("Marked as a property accessor but no property found!");
985 }
986
987 if (!CheckOverrides)
988 return 0;
989
990 typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
991 OverridesTy Overrides;
992 getOverriddenMethods(Overrides);
993 for (OverridesTy::const_iterator I = Overrides.begin(), E = Overrides.end();
994 I != E; ++I) {
995 if (const ObjCPropertyDecl *Prop = (*I)->findPropertyDecl(false))
996 return Prop;
997 }
998
999 return 0;
1000
1001 }
1002
1003 //===----------------------------------------------------------------------===//
1004 // ObjCInterfaceDecl
1005 //===----------------------------------------------------------------------===//
1006
Create(const ASTContext & C,DeclContext * DC,SourceLocation atLoc,IdentifierInfo * Id,ObjCInterfaceDecl * PrevDecl,SourceLocation ClassLoc,bool isInternal)1007 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
1008 DeclContext *DC,
1009 SourceLocation atLoc,
1010 IdentifierInfo *Id,
1011 ObjCInterfaceDecl *PrevDecl,
1012 SourceLocation ClassLoc,
1013 bool isInternal){
1014 ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
1015 PrevDecl, isInternal);
1016 Result->Data.setInt(!C.getLangOpts().Modules);
1017 C.getObjCInterfaceType(Result, PrevDecl);
1018 return Result;
1019 }
1020
CreateDeserialized(ASTContext & C,unsigned ID)1021 ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C,
1022 unsigned ID) {
1023 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCInterfaceDecl));
1024 ObjCInterfaceDecl *Result = new (Mem) ObjCInterfaceDecl(0, SourceLocation(),
1025 0, SourceLocation(),
1026 0, false);
1027 Result->Data.setInt(!C.getLangOpts().Modules);
1028 return Result;
1029 }
1030
1031 ObjCInterfaceDecl::
ObjCInterfaceDecl(DeclContext * DC,SourceLocation atLoc,IdentifierInfo * Id,SourceLocation CLoc,ObjCInterfaceDecl * PrevDecl,bool isInternal)1032 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
1033 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
1034 bool isInternal)
1035 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
1036 TypeForDecl(0), Data()
1037 {
1038 setPreviousDeclaration(PrevDecl);
1039
1040 // Copy the 'data' pointer over.
1041 if (PrevDecl)
1042 Data = PrevDecl->Data;
1043
1044 setImplicit(isInternal);
1045 }
1046
LoadExternalDefinition() const1047 void ObjCInterfaceDecl::LoadExternalDefinition() const {
1048 assert(data().ExternallyCompleted && "Class is not externally completed");
1049 data().ExternallyCompleted = false;
1050 getASTContext().getExternalSource()->CompleteType(
1051 const_cast<ObjCInterfaceDecl *>(this));
1052 }
1053
setExternallyCompleted()1054 void ObjCInterfaceDecl::setExternallyCompleted() {
1055 assert(getASTContext().getExternalSource() &&
1056 "Class can't be externally completed without an external source");
1057 assert(hasDefinition() &&
1058 "Forward declarations can't be externally completed");
1059 data().ExternallyCompleted = true;
1060 }
1061
getImplementation() const1062 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
1063 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1064 if (data().ExternallyCompleted)
1065 LoadExternalDefinition();
1066
1067 return getASTContext().getObjCImplementation(
1068 const_cast<ObjCInterfaceDecl*>(Def));
1069 }
1070
1071 // FIXME: Should make sure no callers ever do this.
1072 return 0;
1073 }
1074
setImplementation(ObjCImplementationDecl * ImplD)1075 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
1076 getASTContext().setObjCImplementation(getDefinition(), ImplD);
1077 }
1078
1079 namespace {
1080 struct SynthesizeIvarChunk {
1081 uint64_t Size;
1082 ObjCIvarDecl *Ivar;
SynthesizeIvarChunk__anoneed1ec6f0111::SynthesizeIvarChunk1083 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1084 : Size(size), Ivar(ivar) {}
1085 };
1086
operator <(const SynthesizeIvarChunk & LHS,const SynthesizeIvarChunk & RHS)1087 bool operator<(const SynthesizeIvarChunk & LHS,
1088 const SynthesizeIvarChunk &RHS) {
1089 return LHS.Size < RHS.Size;
1090 }
1091 }
1092
1093 /// all_declared_ivar_begin - return first ivar declared in this class,
1094 /// its extensions and its implementation. Lazily build the list on first
1095 /// access.
1096 ///
1097 /// Caveat: The list returned by this method reflects the current
1098 /// state of the parser. The cache will be updated for every ivar
1099 /// added by an extension or the implementation when they are
1100 /// encountered.
1101 /// See also ObjCIvarDecl::Create().
all_declared_ivar_begin()1102 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
1103 // FIXME: Should make sure no callers ever do this.
1104 if (!hasDefinition())
1105 return 0;
1106
1107 ObjCIvarDecl *curIvar = 0;
1108 if (!data().IvarList) {
1109 if (!ivar_empty()) {
1110 ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
1111 data().IvarList = *I; ++I;
1112 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1113 curIvar->setNextIvar(*I);
1114 }
1115
1116 for (ObjCInterfaceDecl::known_extensions_iterator
1117 Ext = known_extensions_begin(),
1118 ExtEnd = known_extensions_end();
1119 Ext != ExtEnd; ++Ext) {
1120 if (!Ext->ivar_empty()) {
1121 ObjCCategoryDecl::ivar_iterator
1122 I = Ext->ivar_begin(),
1123 E = Ext->ivar_end();
1124 if (!data().IvarList) {
1125 data().IvarList = *I; ++I;
1126 curIvar = data().IvarList;
1127 }
1128 for ( ;I != E; curIvar = *I, ++I)
1129 curIvar->setNextIvar(*I);
1130 }
1131 }
1132 data().IvarListMissingImplementation = true;
1133 }
1134
1135 // cached and complete!
1136 if (!data().IvarListMissingImplementation)
1137 return data().IvarList;
1138
1139 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1140 data().IvarListMissingImplementation = false;
1141 if (!ImplDecl->ivar_empty()) {
1142 SmallVector<SynthesizeIvarChunk, 16> layout;
1143 for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
1144 E = ImplDecl->ivar_end(); I != E; ++I) {
1145 ObjCIvarDecl *IV = *I;
1146 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1147 layout.push_back(SynthesizeIvarChunk(
1148 IV->getASTContext().getTypeSize(IV->getType()), IV));
1149 continue;
1150 }
1151 if (!data().IvarList)
1152 data().IvarList = *I;
1153 else
1154 curIvar->setNextIvar(*I);
1155 curIvar = *I;
1156 }
1157
1158 if (!layout.empty()) {
1159 // Order synthesized ivars by their size.
1160 std::stable_sort(layout.begin(), layout.end());
1161 unsigned Ix = 0, EIx = layout.size();
1162 if (!data().IvarList) {
1163 data().IvarList = layout[0].Ivar; Ix++;
1164 curIvar = data().IvarList;
1165 }
1166 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1167 curIvar->setNextIvar(layout[Ix].Ivar);
1168 }
1169 }
1170 }
1171 return data().IvarList;
1172 }
1173
1174 /// FindCategoryDeclaration - Finds category declaration in the list of
1175 /// categories for this class and returns it. Name of the category is passed
1176 /// in 'CategoryId'. If category not found, return 0;
1177 ///
1178 ObjCCategoryDecl *
FindCategoryDeclaration(IdentifierInfo * CategoryId) const1179 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
1180 // FIXME: Should make sure no callers ever do this.
1181 if (!hasDefinition())
1182 return 0;
1183
1184 if (data().ExternallyCompleted)
1185 LoadExternalDefinition();
1186
1187 for (visible_categories_iterator Cat = visible_categories_begin(),
1188 CatEnd = visible_categories_end();
1189 Cat != CatEnd;
1190 ++Cat) {
1191 if (Cat->getIdentifier() == CategoryId)
1192 return *Cat;
1193 }
1194
1195 return 0;
1196 }
1197
1198 ObjCMethodDecl *
getCategoryInstanceMethod(Selector Sel) const1199 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
1200 for (visible_categories_iterator Cat = visible_categories_begin(),
1201 CatEnd = visible_categories_end();
1202 Cat != CatEnd;
1203 ++Cat) {
1204 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1205 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1206 return MD;
1207 }
1208
1209 return 0;
1210 }
1211
getCategoryClassMethod(Selector Sel) const1212 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
1213 for (visible_categories_iterator Cat = visible_categories_begin(),
1214 CatEnd = visible_categories_end();
1215 Cat != CatEnd;
1216 ++Cat) {
1217 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1218 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1219 return MD;
1220 }
1221
1222 return 0;
1223 }
1224
1225 /// ClassImplementsProtocol - Checks that 'lProto' protocol
1226 /// has been implemented in IDecl class, its super class or categories (if
1227 /// lookupCategory is true).
ClassImplementsProtocol(ObjCProtocolDecl * lProto,bool lookupCategory,bool RHSIsQualifiedID)1228 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1229 bool lookupCategory,
1230 bool RHSIsQualifiedID) {
1231 if (!hasDefinition())
1232 return false;
1233
1234 ObjCInterfaceDecl *IDecl = this;
1235 // 1st, look up the class.
1236 for (ObjCInterfaceDecl::protocol_iterator
1237 PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
1238 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
1239 return true;
1240 // This is dubious and is added to be compatible with gcc. In gcc, it is
1241 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1242 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1243 // object. This IMO, should be a bug.
1244 // FIXME: Treat this as an extension, and flag this as an error when GCC
1245 // extensions are not enabled.
1246 if (RHSIsQualifiedID &&
1247 getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
1248 return true;
1249 }
1250
1251 // 2nd, look up the category.
1252 if (lookupCategory)
1253 for (visible_categories_iterator Cat = visible_categories_begin(),
1254 CatEnd = visible_categories_end();
1255 Cat != CatEnd;
1256 ++Cat) {
1257 for (ObjCCategoryDecl::protocol_iterator PI = Cat->protocol_begin(),
1258 E = Cat->protocol_end();
1259 PI != E; ++PI)
1260 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
1261 return true;
1262 }
1263
1264 // 3rd, look up the super class(s)
1265 if (IDecl->getSuperClass())
1266 return
1267 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1268 RHSIsQualifiedID);
1269
1270 return false;
1271 }
1272
1273 //===----------------------------------------------------------------------===//
1274 // ObjCIvarDecl
1275 //===----------------------------------------------------------------------===//
1276
anchor()1277 void ObjCIvarDecl::anchor() { }
1278
Create(ASTContext & C,ObjCContainerDecl * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,AccessControl ac,Expr * BW,bool synthesized)1279 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
1280 SourceLocation StartLoc,
1281 SourceLocation IdLoc, IdentifierInfo *Id,
1282 QualType T, TypeSourceInfo *TInfo,
1283 AccessControl ac, Expr *BW,
1284 bool synthesized) {
1285 if (DC) {
1286 // Ivar's can only appear in interfaces, implementations (via synthesized
1287 // properties), and class extensions (via direct declaration, or synthesized
1288 // properties).
1289 //
1290 // FIXME: This should really be asserting this:
1291 // (isa<ObjCCategoryDecl>(DC) &&
1292 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1293 // but unfortunately we sometimes place ivars into non-class extension
1294 // categories on error. This breaks an AST invariant, and should not be
1295 // fixed.
1296 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1297 isa<ObjCCategoryDecl>(DC)) &&
1298 "Invalid ivar decl context!");
1299 // Once a new ivar is created in any of class/class-extension/implementation
1300 // decl contexts, the previously built IvarList must be rebuilt.
1301 ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1302 if (!ID) {
1303 if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
1304 ID = IM->getClassInterface();
1305 else
1306 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1307 }
1308 ID->setIvarList(0);
1309 }
1310
1311 return new (C) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo,
1312 ac, BW, synthesized);
1313 }
1314
CreateDeserialized(ASTContext & C,unsigned ID)1315 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1316 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCIvarDecl));
1317 return new (Mem) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
1318 QualType(), 0, ObjCIvarDecl::None, 0, false);
1319 }
1320
getContainingInterface() const1321 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
1322 const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
1323
1324 switch (DC->getKind()) {
1325 default:
1326 case ObjCCategoryImpl:
1327 case ObjCProtocol:
1328 llvm_unreachable("invalid ivar container!");
1329
1330 // Ivars can only appear in class extension categories.
1331 case ObjCCategory: {
1332 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
1333 assert(CD->IsClassExtension() && "invalid container for ivar!");
1334 return CD->getClassInterface();
1335 }
1336
1337 case ObjCImplementation:
1338 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1339
1340 case ObjCInterface:
1341 return cast<ObjCInterfaceDecl>(DC);
1342 }
1343 }
1344
1345 //===----------------------------------------------------------------------===//
1346 // ObjCAtDefsFieldDecl
1347 //===----------------------------------------------------------------------===//
1348
anchor()1349 void ObjCAtDefsFieldDecl::anchor() { }
1350
1351 ObjCAtDefsFieldDecl
Create(ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,Expr * BW)1352 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1353 SourceLocation StartLoc, SourceLocation IdLoc,
1354 IdentifierInfo *Id, QualType T, Expr *BW) {
1355 return new (C) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1356 }
1357
CreateDeserialized(ASTContext & C,unsigned ID)1358 ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
1359 unsigned ID) {
1360 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCAtDefsFieldDecl));
1361 return new (Mem) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
1362 0, QualType(), 0);
1363 }
1364
1365 //===----------------------------------------------------------------------===//
1366 // ObjCProtocolDecl
1367 //===----------------------------------------------------------------------===//
1368
anchor()1369 void ObjCProtocolDecl::anchor() { }
1370
ObjCProtocolDecl(DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1371 ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1372 SourceLocation nameLoc,
1373 SourceLocation atStartLoc,
1374 ObjCProtocolDecl *PrevDecl)
1375 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
1376 {
1377 setPreviousDeclaration(PrevDecl);
1378 if (PrevDecl)
1379 Data = PrevDecl->Data;
1380 }
1381
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1382 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
1383 IdentifierInfo *Id,
1384 SourceLocation nameLoc,
1385 SourceLocation atStartLoc,
1386 ObjCProtocolDecl *PrevDecl) {
1387 ObjCProtocolDecl *Result
1388 = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
1389 Result->Data.setInt(!C.getLangOpts().Modules);
1390 return Result;
1391 }
1392
CreateDeserialized(ASTContext & C,unsigned ID)1393 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
1394 unsigned ID) {
1395 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCProtocolDecl));
1396 ObjCProtocolDecl *Result = new (Mem) ObjCProtocolDecl(0, 0, SourceLocation(),
1397 SourceLocation(), 0);
1398 Result->Data.setInt(!C.getLangOpts().Modules);
1399 return Result;
1400 }
1401
lookupProtocolNamed(IdentifierInfo * Name)1402 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1403 ObjCProtocolDecl *PDecl = this;
1404
1405 if (Name == getIdentifier())
1406 return PDecl;
1407
1408 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1409 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
1410 return PDecl;
1411
1412 return NULL;
1413 }
1414
1415 // lookupMethod - Lookup a instance/class method in the protocol and protocols
1416 // it inherited.
lookupMethod(Selector Sel,bool isInstance) const1417 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1418 bool isInstance) const {
1419 ObjCMethodDecl *MethodDecl = NULL;
1420
1421 // If there is no definition or the definition is hidden, we don't find
1422 // anything.
1423 const ObjCProtocolDecl *Def = getDefinition();
1424 if (!Def || Def->isHidden())
1425 return NULL;
1426
1427 if ((MethodDecl = getMethod(Sel, isInstance)))
1428 return MethodDecl;
1429
1430 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1431 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
1432 return MethodDecl;
1433 return NULL;
1434 }
1435
allocateDefinitionData()1436 void ObjCProtocolDecl::allocateDefinitionData() {
1437 assert(!Data.getPointer() && "Protocol already has a definition!");
1438 Data.setPointer(new (getASTContext()) DefinitionData);
1439 Data.getPointer()->Definition = this;
1440 }
1441
startDefinition()1442 void ObjCProtocolDecl::startDefinition() {
1443 allocateDefinitionData();
1444
1445 // Update all of the declarations with a pointer to the definition.
1446 for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
1447 RD != RDEnd; ++RD)
1448 RD->Data = this->Data;
1449 }
1450
collectPropertiesToImplement(PropertyMap & PM,PropertyDeclOrder & PO) const1451 void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
1452 PropertyDeclOrder &PO) const {
1453
1454 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
1455 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
1456 E = PDecl->prop_end(); P != E; ++P) {
1457 ObjCPropertyDecl *Prop = *P;
1458 // Insert into PM if not there already.
1459 PM.insert(std::make_pair(Prop->getIdentifier(), Prop));
1460 PO.push_back(Prop);
1461 }
1462 // Scan through protocol's protocols.
1463 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
1464 E = PDecl->protocol_end(); PI != E; ++PI)
1465 (*PI)->collectPropertiesToImplement(PM, PO);
1466 }
1467 }
1468
1469
1470 //===----------------------------------------------------------------------===//
1471 // ObjCCategoryDecl
1472 //===----------------------------------------------------------------------===//
1473
anchor()1474 void ObjCCategoryDecl::anchor() { }
1475
Create(ASTContext & C,DeclContext * DC,SourceLocation AtLoc,SourceLocation ClassNameLoc,SourceLocation CategoryNameLoc,IdentifierInfo * Id,ObjCInterfaceDecl * IDecl,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1476 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
1477 SourceLocation AtLoc,
1478 SourceLocation ClassNameLoc,
1479 SourceLocation CategoryNameLoc,
1480 IdentifierInfo *Id,
1481 ObjCInterfaceDecl *IDecl,
1482 SourceLocation IvarLBraceLoc,
1483 SourceLocation IvarRBraceLoc) {
1484 ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
1485 CategoryNameLoc, Id,
1486 IDecl,
1487 IvarLBraceLoc, IvarRBraceLoc);
1488 if (IDecl) {
1489 // Link this category into its class's category list.
1490 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
1491 if (IDecl->hasDefinition()) {
1492 IDecl->setCategoryListRaw(CatDecl);
1493 if (ASTMutationListener *L = C.getASTMutationListener())
1494 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
1495 }
1496 }
1497
1498 return CatDecl;
1499 }
1500
CreateDeserialized(ASTContext & C,unsigned ID)1501 ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
1502 unsigned ID) {
1503 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryDecl));
1504 return new (Mem) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
1505 SourceLocation(), 0, 0);
1506 }
1507
getImplementation() const1508 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
1509 return getASTContext().getObjCImplementation(
1510 const_cast<ObjCCategoryDecl*>(this));
1511 }
1512
setImplementation(ObjCCategoryImplDecl * ImplD)1513 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
1514 getASTContext().setObjCImplementation(this, ImplD);
1515 }
1516
1517
1518 //===----------------------------------------------------------------------===//
1519 // ObjCCategoryImplDecl
1520 //===----------------------------------------------------------------------===//
1521
anchor()1522 void ObjCCategoryImplDecl::anchor() { }
1523
1524 ObjCCategoryImplDecl *
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,ObjCInterfaceDecl * ClassInterface,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation CategoryNameLoc)1525 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
1526 IdentifierInfo *Id,
1527 ObjCInterfaceDecl *ClassInterface,
1528 SourceLocation nameLoc,
1529 SourceLocation atStartLoc,
1530 SourceLocation CategoryNameLoc) {
1531 if (ClassInterface && ClassInterface->hasDefinition())
1532 ClassInterface = ClassInterface->getDefinition();
1533 return new (C) ObjCCategoryImplDecl(DC, Id, ClassInterface,
1534 nameLoc, atStartLoc, CategoryNameLoc);
1535 }
1536
CreateDeserialized(ASTContext & C,unsigned ID)1537 ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
1538 unsigned ID) {
1539 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryImplDecl));
1540 return new (Mem) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(),
1541 SourceLocation(), SourceLocation());
1542 }
1543
getCategoryDecl() const1544 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
1545 // The class interface might be NULL if we are working with invalid code.
1546 if (const ObjCInterfaceDecl *ID = getClassInterface())
1547 return ID->FindCategoryDeclaration(getIdentifier());
1548 return 0;
1549 }
1550
1551
anchor()1552 void ObjCImplDecl::anchor() { }
1553
addPropertyImplementation(ObjCPropertyImplDecl * property)1554 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
1555 // FIXME: The context should be correct before we get here.
1556 property->setLexicalDeclContext(this);
1557 addDecl(property);
1558 }
1559
setClassInterface(ObjCInterfaceDecl * IFace)1560 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
1561 ASTContext &Ctx = getASTContext();
1562
1563 if (ObjCImplementationDecl *ImplD
1564 = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
1565 if (IFace)
1566 Ctx.setObjCImplementation(IFace, ImplD);
1567
1568 } else if (ObjCCategoryImplDecl *ImplD =
1569 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
1570 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
1571 Ctx.setObjCImplementation(CD, ImplD);
1572 }
1573
1574 ClassInterface = IFace;
1575 }
1576
1577 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
1578 /// properties implemented in this \@implementation block and returns
1579 /// the implemented property that uses it.
1580 ///
1581 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo * ivarId) const1582 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
1583 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1584 ObjCPropertyImplDecl *PID = *i;
1585 if (PID->getPropertyIvarDecl() &&
1586 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
1587 return PID;
1588 }
1589 return 0;
1590 }
1591
1592 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
1593 /// added to the list of those properties \@synthesized/\@dynamic in this
1594 /// category \@implementation block.
1595 ///
1596 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo * Id) const1597 FindPropertyImplDecl(IdentifierInfo *Id) const {
1598 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1599 ObjCPropertyImplDecl *PID = *i;
1600 if (PID->getPropertyDecl()->getIdentifier() == Id)
1601 return PID;
1602 }
1603 return 0;
1604 }
1605
operator <<(raw_ostream & OS,const ObjCCategoryImplDecl & CID)1606 raw_ostream &clang::operator<<(raw_ostream &OS,
1607 const ObjCCategoryImplDecl &CID) {
1608 OS << CID.getName();
1609 return OS;
1610 }
1611
1612 //===----------------------------------------------------------------------===//
1613 // ObjCImplementationDecl
1614 //===----------------------------------------------------------------------===//
1615
anchor()1616 void ObjCImplementationDecl::anchor() { }
1617
1618 ObjCImplementationDecl *
Create(ASTContext & C,DeclContext * DC,ObjCInterfaceDecl * ClassInterface,ObjCInterfaceDecl * SuperDecl,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1619 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
1620 ObjCInterfaceDecl *ClassInterface,
1621 ObjCInterfaceDecl *SuperDecl,
1622 SourceLocation nameLoc,
1623 SourceLocation atStartLoc,
1624 SourceLocation IvarLBraceLoc,
1625 SourceLocation IvarRBraceLoc) {
1626 if (ClassInterface && ClassInterface->hasDefinition())
1627 ClassInterface = ClassInterface->getDefinition();
1628 return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
1629 nameLoc, atStartLoc,
1630 IvarLBraceLoc, IvarRBraceLoc);
1631 }
1632
1633 ObjCImplementationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1634 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1635 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCImplementationDecl));
1636 return new (Mem) ObjCImplementationDecl(0, 0, 0, SourceLocation(),
1637 SourceLocation());
1638 }
1639
setIvarInitializers(ASTContext & C,CXXCtorInitializer ** initializers,unsigned numInitializers)1640 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
1641 CXXCtorInitializer ** initializers,
1642 unsigned numInitializers) {
1643 if (numInitializers > 0) {
1644 NumIvarInitializers = numInitializers;
1645 CXXCtorInitializer **ivarInitializers =
1646 new (C) CXXCtorInitializer*[NumIvarInitializers];
1647 memcpy(ivarInitializers, initializers,
1648 numInitializers * sizeof(CXXCtorInitializer*));
1649 IvarInitializers = ivarInitializers;
1650 }
1651 }
1652
operator <<(raw_ostream & OS,const ObjCImplementationDecl & ID)1653 raw_ostream &clang::operator<<(raw_ostream &OS,
1654 const ObjCImplementationDecl &ID) {
1655 OS << ID.getName();
1656 return OS;
1657 }
1658
1659 //===----------------------------------------------------------------------===//
1660 // ObjCCompatibleAliasDecl
1661 //===----------------------------------------------------------------------===//
1662
anchor()1663 void ObjCCompatibleAliasDecl::anchor() { }
1664
1665 ObjCCompatibleAliasDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,ObjCInterfaceDecl * AliasedClass)1666 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
1667 SourceLocation L,
1668 IdentifierInfo *Id,
1669 ObjCInterfaceDecl* AliasedClass) {
1670 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
1671 }
1672
1673 ObjCCompatibleAliasDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1674 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1675 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCompatibleAliasDecl));
1676 return new (Mem) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
1677 }
1678
1679 //===----------------------------------------------------------------------===//
1680 // ObjCPropertyDecl
1681 //===----------------------------------------------------------------------===//
1682
anchor()1683 void ObjCPropertyDecl::anchor() { }
1684
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,SourceLocation AtLoc,SourceLocation LParenLoc,TypeSourceInfo * T,PropertyControl propControl)1685 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
1686 SourceLocation L,
1687 IdentifierInfo *Id,
1688 SourceLocation AtLoc,
1689 SourceLocation LParenLoc,
1690 TypeSourceInfo *T,
1691 PropertyControl propControl) {
1692 return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
1693 }
1694
CreateDeserialized(ASTContext & C,unsigned ID)1695 ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
1696 unsigned ID) {
1697 void * Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyDecl));
1698 return new (Mem) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
1699 SourceLocation(),
1700 0);
1701 }
1702
1703 //===----------------------------------------------------------------------===//
1704 // ObjCPropertyImplDecl
1705 //===----------------------------------------------------------------------===//
1706
Create(ASTContext & C,DeclContext * DC,SourceLocation atLoc,SourceLocation L,ObjCPropertyDecl * property,Kind PK,ObjCIvarDecl * ivar,SourceLocation ivarLoc)1707 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
1708 DeclContext *DC,
1709 SourceLocation atLoc,
1710 SourceLocation L,
1711 ObjCPropertyDecl *property,
1712 Kind PK,
1713 ObjCIvarDecl *ivar,
1714 SourceLocation ivarLoc) {
1715 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
1716 ivarLoc);
1717 }
1718
CreateDeserialized(ASTContext & C,unsigned ID)1719 ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
1720 unsigned ID) {
1721 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyImplDecl));
1722 return new (Mem) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
1723 0, Dynamic, 0, SourceLocation());
1724 }
1725
getSourceRange() const1726 SourceRange ObjCPropertyImplDecl::getSourceRange() const {
1727 SourceLocation EndLoc = getLocation();
1728 if (IvarLoc.isValid())
1729 EndLoc = IvarLoc;
1730
1731 return SourceRange(AtLoc, EndLoc);
1732 }
1733