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 = nullptr;
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_result R = lookup(Id);
58 for (lookup_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 nullptr;
64 }
65
66 // Get the local instance/class method declared in this interface.
67 ObjCMethodDecl *
getMethod(Selector Sel,bool isInstance,bool AllowHidden) const68 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
69 bool AllowHidden) const {
70 // 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())
74 if (Def->isHidden() && !AllowHidden)
75 return nullptr;
76 }
77
78 // 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 //
86 lookup_result R = lookup(Sel);
87 for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
88 Meth != MethEnd; ++Meth) {
89 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
90 if (MD && MD->isInstanceMethod() == isInstance)
91 return MD;
92 }
93 return nullptr;
94 }
95
96 /// \brief This routine returns 'true' if a user declared setter method was
97 /// 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'
99 /// property. This is because, user must provide a setter method for the
100 /// category's 'readwrite' property.
HasUserDeclaredSetterMethod(const ObjCPropertyDecl * Property) const101 bool ObjCContainerDecl::HasUserDeclaredSetterMethod(
102 const ObjCPropertyDecl *Property) const {
103 Selector Sel = Property->getSetterName();
104 lookup_result R = lookup(Sel);
105 for (lookup_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.
115 for (const auto *Cat : ID->visible_categories()) {
116 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'
122 // declaration of this property. If one found, presumably a setter will
123 // be provided (properties declared in categories will not get
124 // auto-synthesized).
125 for (const auto *P : Cat->properties())
126 if (P->getIdentifier() == Property->getIdentifier()) {
127 if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite)
128 return true;
129 break;
130 }
131 }
132
133 // Also look into protocols, for a user declared instance method.
134 for (const auto *Proto : ID->all_referenced_protocols())
135 if (Proto->HasUserDeclaredSetterMethod(Property))
136 return true;
137
138 // And in its super class.
139 ObjCInterfaceDecl *OSC = ID->getSuperClass();
140 while (OSC) {
141 if (OSC->HasUserDeclaredSetterMethod(Property))
142 return true;
143 OSC = OSC->getSuperClass();
144 }
145 }
146 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(this))
147 for (const auto *PI : PD->protocols())
148 if (PI->HasUserDeclaredSetterMethod(Property))
149 return true;
150 return false;
151 }
152
153 ObjCPropertyDecl *
findPropertyDecl(const DeclContext * DC,const IdentifierInfo * propertyID)154 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
155 const IdentifierInfo *propertyID) {
156 // If this context is a hidden protocol definition, don't find any
157 // property.
158 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
159 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
160 if (Def->isHidden())
161 return nullptr;
162 }
163
164 // If context is class, then lookup property in its extensions.
165 // This comes before property is looked up in primary class.
166 if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
167 for (const auto *Ext : IDecl->known_extensions())
168 if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,
169 propertyID))
170 return PD;
171 }
172
173 DeclContext::lookup_result R = DC->lookup(propertyID);
174 for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
175 ++I)
176 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
177 return PD;
178
179 return nullptr;
180 }
181
182 IdentifierInfo *
getDefaultSynthIvarName(ASTContext & Ctx) const183 ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
184 SmallString<128> ivarName;
185 {
186 llvm::raw_svector_ostream os(ivarName);
187 os << '_' << getIdentifier()->getName();
188 }
189 return &Ctx.Idents.get(ivarName.str());
190 }
191
192 /// FindPropertyDeclaration - Finds declaration of the property given its name
193 /// in 'PropertyId' and returns it. It returns 0, if not found.
FindPropertyDeclaration(const IdentifierInfo * PropertyId) const194 ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
195 const IdentifierInfo *PropertyId) const {
196 // Don't find properties within hidden protocol definitions.
197 if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
198 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
199 if (Def->isHidden())
200 return nullptr;
201 }
202
203 // Search the extensions of a class first; they override what's in
204 // the class itself.
205 if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) {
206 for (const auto *Ext : ClassDecl->visible_extensions()) {
207 if (auto *P = Ext->FindPropertyDeclaration(PropertyId))
208 return P;
209 }
210 }
211
212 if (ObjCPropertyDecl *PD =
213 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
214 return PD;
215
216 switch (getKind()) {
217 default:
218 break;
219 case Decl::ObjCProtocol: {
220 const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
221 for (const auto *I : PID->protocols())
222 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
223 return P;
224 break;
225 }
226 case Decl::ObjCInterface: {
227 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
228 // Look through categories (but not extensions; they were handled above).
229 for (const auto *Cat : OID->visible_categories()) {
230 if (!Cat->IsClassExtension())
231 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
232 return P;
233 }
234
235 // Look through protocols.
236 for (const auto *I : OID->all_referenced_protocols())
237 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
238 return P;
239
240 // Finally, check the super class.
241 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
242 return superClass->FindPropertyDeclaration(PropertyId);
243 break;
244 }
245 case Decl::ObjCCategory: {
246 const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
247 // Look through protocols.
248 if (!OCD->IsClassExtension())
249 for (const auto *I : OCD->protocols())
250 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
251 return P;
252 break;
253 }
254 }
255 return nullptr;
256 }
257
anchor()258 void ObjCInterfaceDecl::anchor() { }
259
getTypeParamList() const260 ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const {
261 // If this particular declaration has a type parameter list, return it.
262 if (ObjCTypeParamList *written = getTypeParamListAsWritten())
263 return written;
264
265 // If there is a definition, return its type parameter list.
266 if (const ObjCInterfaceDecl *def = getDefinition())
267 return def->getTypeParamListAsWritten();
268
269 // Otherwise, look at previous declarations to determine whether any
270 // of them has a type parameter list, skipping over those
271 // declarations that do not.
272 for (auto decl = getMostRecentDecl(); decl; decl = decl->getPreviousDecl()) {
273 if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten())
274 return written;
275 }
276
277 return nullptr;
278 }
279
setTypeParamList(ObjCTypeParamList * TPL)280 void ObjCInterfaceDecl::setTypeParamList(ObjCTypeParamList *TPL) {
281 TypeParamList = TPL;
282 if (!TPL)
283 return;
284 // Set the declaration context of each of the type parameters.
285 for (auto typeParam : *TypeParamList)
286 typeParam->setDeclContext(this);
287 }
288
getSuperClass() const289 ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const {
290 // FIXME: Should make sure no callers ever do this.
291 if (!hasDefinition())
292 return nullptr;
293
294 if (data().ExternallyCompleted)
295 LoadExternalDefinition();
296
297 if (const ObjCObjectType *superType = getSuperClassType()) {
298 if (ObjCInterfaceDecl *superDecl = superType->getInterface()) {
299 if (ObjCInterfaceDecl *superDef = superDecl->getDefinition())
300 return superDef;
301
302 return superDecl;
303 }
304 }
305
306 return nullptr;
307 }
308
getSuperClassLoc() const309 SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const {
310 if (TypeSourceInfo *superTInfo = getSuperClassTInfo())
311 return superTInfo->getTypeLoc().getLocStart();
312
313 return SourceLocation();
314 }
315
316 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
317 /// with name 'PropertyId' in the primary class; including those in protocols
318 /// (direct or indirect) used by the primary class.
319 ///
320 ObjCPropertyDecl *
FindPropertyVisibleInPrimaryClass(IdentifierInfo * PropertyId) const321 ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
322 IdentifierInfo *PropertyId) const {
323 // FIXME: Should make sure no callers ever do this.
324 if (!hasDefinition())
325 return nullptr;
326
327 if (data().ExternallyCompleted)
328 LoadExternalDefinition();
329
330 if (ObjCPropertyDecl *PD =
331 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
332 return PD;
333
334 // Look through protocols.
335 for (const auto *I : all_referenced_protocols())
336 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
337 return P;
338
339 return nullptr;
340 }
341
collectPropertiesToImplement(PropertyMap & PM,PropertyDeclOrder & PO) const342 void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
343 PropertyDeclOrder &PO) const {
344 for (auto *Prop : properties()) {
345 PM[Prop->getIdentifier()] = Prop;
346 PO.push_back(Prop);
347 }
348 for (const auto *Ext : known_extensions()) {
349 const ObjCCategoryDecl *ClassExt = Ext;
350 for (auto *Prop : ClassExt->properties()) {
351 PM[Prop->getIdentifier()] = Prop;
352 PO.push_back(Prop);
353 }
354 }
355 for (const auto *PI : all_referenced_protocols())
356 PI->collectPropertiesToImplement(PM, PO);
357 // Note, the properties declared only in class extensions are still copied
358 // into the main @interface's property list, and therefore we don't
359 // explicitly, have to search class extension properties.
360 }
361
isArcWeakrefUnavailable() const362 bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {
363 const ObjCInterfaceDecl *Class = this;
364 while (Class) {
365 if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
366 return true;
367 Class = Class->getSuperClass();
368 }
369 return false;
370 }
371
isObjCRequiresPropertyDefs() const372 const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
373 const ObjCInterfaceDecl *Class = this;
374 while (Class) {
375 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
376 return Class;
377 Class = Class->getSuperClass();
378 }
379 return nullptr;
380 }
381
mergeClassExtensionProtocolList(ObjCProtocolDecl * const * ExtList,unsigned ExtNum,ASTContext & C)382 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
383 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
384 ASTContext &C)
385 {
386 if (data().ExternallyCompleted)
387 LoadExternalDefinition();
388
389 if (data().AllReferencedProtocols.empty() &&
390 data().ReferencedProtocols.empty()) {
391 data().AllReferencedProtocols.set(ExtList, ExtNum, C);
392 return;
393 }
394
395 // Check for duplicate protocol in class's protocol list.
396 // This is O(n*m). But it is extremely rare and number of protocols in
397 // class or its extension are very few.
398 SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
399 for (unsigned i = 0; i < ExtNum; i++) {
400 bool protocolExists = false;
401 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
402 for (auto *Proto : all_referenced_protocols()) {
403 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
404 protocolExists = true;
405 break;
406 }
407 }
408 // Do we want to warn on a protocol in extension class which
409 // already exist in the class? Probably not.
410 if (!protocolExists)
411 ProtocolRefs.push_back(ProtoInExtension);
412 }
413
414 if (ProtocolRefs.empty())
415 return;
416
417 // Merge ProtocolRefs into class's protocol list;
418 ProtocolRefs.append(all_referenced_protocol_begin(),
419 all_referenced_protocol_end());
420
421 data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
422 }
423
424 const ObjCInterfaceDecl *
findInterfaceWithDesignatedInitializers() const425 ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
426 const ObjCInterfaceDecl *IFace = this;
427 while (IFace) {
428 if (IFace->hasDesignatedInitializers())
429 return IFace;
430 if (!IFace->inheritsDesignatedInitializers())
431 break;
432 IFace = IFace->getSuperClass();
433 }
434 return nullptr;
435 }
436
isIntroducingInitializers(const ObjCInterfaceDecl * D)437 static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {
438 for (const auto *MD : D->instance_methods()) {
439 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
440 return true;
441 }
442 for (const auto *Ext : D->visible_extensions()) {
443 for (const auto *MD : Ext->instance_methods()) {
444 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
445 return true;
446 }
447 }
448 if (const auto *ImplD = D->getImplementation()) {
449 for (const auto *MD : ImplD->instance_methods()) {
450 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
451 return true;
452 }
453 }
454 return false;
455 }
456
inheritsDesignatedInitializers() const457 bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
458 switch (data().InheritedDesignatedInitializers) {
459 case DefinitionData::IDI_Inherited:
460 return true;
461 case DefinitionData::IDI_NotInherited:
462 return false;
463 case DefinitionData::IDI_Unknown: {
464 // If the class introduced initializers we conservatively assume that we
465 // don't know if any of them is a designated initializer to avoid possible
466 // misleading warnings.
467 if (isIntroducingInitializers(this)) {
468 data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
469 } else {
470 if (auto SuperD = getSuperClass()) {
471 data().InheritedDesignatedInitializers =
472 SuperD->declaresOrInheritsDesignatedInitializers() ?
473 DefinitionData::IDI_Inherited :
474 DefinitionData::IDI_NotInherited;
475 } else {
476 data().InheritedDesignatedInitializers =
477 DefinitionData::IDI_NotInherited;
478 }
479 }
480 assert(data().InheritedDesignatedInitializers
481 != DefinitionData::IDI_Unknown);
482 return data().InheritedDesignatedInitializers ==
483 DefinitionData::IDI_Inherited;
484 }
485 }
486
487 llvm_unreachable("unexpected InheritedDesignatedInitializers value");
488 }
489
getDesignatedInitializers(llvm::SmallVectorImpl<const ObjCMethodDecl * > & Methods) const490 void ObjCInterfaceDecl::getDesignatedInitializers(
491 llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
492 // Check for a complete definition and recover if not so.
493 if (!isThisDeclarationADefinition())
494 return;
495 if (data().ExternallyCompleted)
496 LoadExternalDefinition();
497
498 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
499 if (!IFace)
500 return;
501
502 for (const auto *MD : IFace->instance_methods())
503 if (MD->isThisDeclarationADesignatedInitializer())
504 Methods.push_back(MD);
505 for (const auto *Ext : IFace->visible_extensions()) {
506 for (const auto *MD : Ext->instance_methods())
507 if (MD->isThisDeclarationADesignatedInitializer())
508 Methods.push_back(MD);
509 }
510 }
511
isDesignatedInitializer(Selector Sel,const ObjCMethodDecl ** InitMethod) const512 bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
513 const ObjCMethodDecl **InitMethod) const {
514 // Check for a complete definition and recover if not so.
515 if (!isThisDeclarationADefinition())
516 return false;
517 if (data().ExternallyCompleted)
518 LoadExternalDefinition();
519
520 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
521 if (!IFace)
522 return false;
523
524 if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
525 if (MD->isThisDeclarationADesignatedInitializer()) {
526 if (InitMethod)
527 *InitMethod = MD;
528 return true;
529 }
530 }
531 for (const auto *Ext : IFace->visible_extensions()) {
532 if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
533 if (MD->isThisDeclarationADesignatedInitializer()) {
534 if (InitMethod)
535 *InitMethod = MD;
536 return true;
537 }
538 }
539 }
540 return false;
541 }
542
allocateDefinitionData()543 void ObjCInterfaceDecl::allocateDefinitionData() {
544 assert(!hasDefinition() && "ObjC class already has a definition");
545 Data.setPointer(new (getASTContext()) DefinitionData());
546 Data.getPointer()->Definition = this;
547
548 // Make the type point at the definition, now that we have one.
549 if (TypeForDecl)
550 cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
551 }
552
startDefinition()553 void ObjCInterfaceDecl::startDefinition() {
554 allocateDefinitionData();
555
556 // Update all of the declarations with a pointer to the definition.
557 for (auto RD : redecls()) {
558 if (RD != this)
559 RD->Data = Data;
560 }
561 }
562
lookupInstanceVariable(IdentifierInfo * ID,ObjCInterfaceDecl * & clsDeclared)563 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
564 ObjCInterfaceDecl *&clsDeclared) {
565 // FIXME: Should make sure no callers ever do this.
566 if (!hasDefinition())
567 return nullptr;
568
569 if (data().ExternallyCompleted)
570 LoadExternalDefinition();
571
572 ObjCInterfaceDecl* ClassDecl = this;
573 while (ClassDecl != nullptr) {
574 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
575 clsDeclared = ClassDecl;
576 return I;
577 }
578
579 for (const auto *Ext : ClassDecl->visible_extensions()) {
580 if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
581 clsDeclared = ClassDecl;
582 return I;
583 }
584 }
585
586 ClassDecl = ClassDecl->getSuperClass();
587 }
588 return nullptr;
589 }
590
591 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
592 /// class whose name is passed as argument. If it is not one of the super classes
593 /// the it returns NULL.
lookupInheritedClass(const IdentifierInfo * ICName)594 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
595 const IdentifierInfo*ICName) {
596 // FIXME: Should make sure no callers ever do this.
597 if (!hasDefinition())
598 return nullptr;
599
600 if (data().ExternallyCompleted)
601 LoadExternalDefinition();
602
603 ObjCInterfaceDecl* ClassDecl = this;
604 while (ClassDecl != nullptr) {
605 if (ClassDecl->getIdentifier() == ICName)
606 return ClassDecl;
607 ClassDecl = ClassDecl->getSuperClass();
608 }
609 return nullptr;
610 }
611
612 ObjCProtocolDecl *
lookupNestedProtocol(IdentifierInfo * Name)613 ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
614 for (auto *P : all_referenced_protocols())
615 if (P->lookupProtocolNamed(Name))
616 return P;
617 ObjCInterfaceDecl *SuperClass = getSuperClass();
618 return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
619 }
620
621 /// lookupMethod - This method returns an instance/class method by looking in
622 /// the class, its categories, and its super classes (using a linear search).
623 /// When argument category "C" is specified, any implicit method found
624 /// in this category is ignored.
lookupMethod(Selector Sel,bool isInstance,bool shallowCategoryLookup,bool followSuper,const ObjCCategoryDecl * C) const625 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
626 bool isInstance,
627 bool shallowCategoryLookup,
628 bool followSuper,
629 const ObjCCategoryDecl *C) const
630 {
631 // FIXME: Should make sure no callers ever do this.
632 if (!hasDefinition())
633 return nullptr;
634
635 const ObjCInterfaceDecl* ClassDecl = this;
636 ObjCMethodDecl *MethodDecl = nullptr;
637
638 if (data().ExternallyCompleted)
639 LoadExternalDefinition();
640
641 while (ClassDecl) {
642 // 1. Look through primary class.
643 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
644 return MethodDecl;
645
646 // 2. Didn't find one yet - now look through categories.
647 for (const auto *Cat : ClassDecl->visible_categories())
648 if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
649 if (C != Cat || !MethodDecl->isImplicit())
650 return MethodDecl;
651
652 // 3. Didn't find one yet - look through primary class's protocols.
653 for (const auto *I : ClassDecl->protocols())
654 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
655 return MethodDecl;
656
657 // 4. Didn't find one yet - now look through categories' protocols
658 if (!shallowCategoryLookup)
659 for (const auto *Cat : ClassDecl->visible_categories()) {
660 // Didn't find one yet - look through protocols.
661 const ObjCList<ObjCProtocolDecl> &Protocols =
662 Cat->getReferencedProtocols();
663 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
664 E = Protocols.end(); I != E; ++I)
665 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
666 if (C != Cat || !MethodDecl->isImplicit())
667 return MethodDecl;
668 }
669
670
671 if (!followSuper)
672 return nullptr;
673
674 // 5. Get to the super class (if any).
675 ClassDecl = ClassDecl->getSuperClass();
676 }
677 return nullptr;
678 }
679
680 // Will search "local" class/category implementations for a method decl.
681 // If failed, then we search in class's root for an instance method.
682 // Returns 0 if no method is found.
lookupPrivateMethod(const Selector & Sel,bool Instance) const683 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
684 const Selector &Sel,
685 bool Instance) const {
686 // FIXME: Should make sure no callers ever do this.
687 if (!hasDefinition())
688 return nullptr;
689
690 if (data().ExternallyCompleted)
691 LoadExternalDefinition();
692
693 ObjCMethodDecl *Method = nullptr;
694 if (ObjCImplementationDecl *ImpDecl = getImplementation())
695 Method = Instance ? ImpDecl->getInstanceMethod(Sel)
696 : ImpDecl->getClassMethod(Sel);
697
698 // Look through local category implementations associated with the class.
699 if (!Method)
700 Method = getCategoryMethod(Sel, Instance);
701
702 // Before we give up, check if the selector is an instance method.
703 // But only in the root. This matches gcc's behavior and what the
704 // runtime expects.
705 if (!Instance && !Method && !getSuperClass()) {
706 Method = lookupInstanceMethod(Sel);
707 // Look through local category implementations associated
708 // with the root class.
709 if (!Method)
710 Method = lookupPrivateMethod(Sel, true);
711 }
712
713 if (!Method && getSuperClass())
714 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
715 return Method;
716 }
717
718 //===----------------------------------------------------------------------===//
719 // ObjCMethodDecl
720 //===----------------------------------------------------------------------===//
721
Create(ASTContext & C,SourceLocation beginLoc,SourceLocation endLoc,Selector SelInfo,QualType T,TypeSourceInfo * ReturnTInfo,DeclContext * contextDecl,bool isInstance,bool isVariadic,bool isPropertyAccessor,bool isImplicitlyDeclared,bool isDefined,ImplementationControl impControl,bool HasRelatedResultType)722 ObjCMethodDecl *ObjCMethodDecl::Create(
723 ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
724 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
725 DeclContext *contextDecl, bool isInstance, bool isVariadic,
726 bool isPropertyAccessor, bool isImplicitlyDeclared, bool isDefined,
727 ImplementationControl impControl, bool HasRelatedResultType) {
728 return new (C, contextDecl) ObjCMethodDecl(
729 beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
730 isVariadic, isPropertyAccessor, isImplicitlyDeclared, isDefined,
731 impControl, HasRelatedResultType);
732 }
733
CreateDeserialized(ASTContext & C,unsigned ID)734 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
735 return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
736 Selector(), QualType(), nullptr, nullptr);
737 }
738
isThisDeclarationADesignatedInitializer() const739 bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
740 return getMethodFamily() == OMF_init &&
741 hasAttr<ObjCDesignatedInitializerAttr>();
742 }
743
isDesignatedInitializerForTheInterface(const ObjCMethodDecl ** InitMethod) const744 bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
745 const ObjCMethodDecl **InitMethod) const {
746 if (getMethodFamily() != OMF_init)
747 return false;
748 const DeclContext *DC = getDeclContext();
749 if (isa<ObjCProtocolDecl>(DC))
750 return false;
751 if (const ObjCInterfaceDecl *ID = getClassInterface())
752 return ID->isDesignatedInitializer(getSelector(), InitMethod);
753 return false;
754 }
755
getBody() const756 Stmt *ObjCMethodDecl::getBody() const {
757 return Body.get(getASTContext().getExternalSource());
758 }
759
setAsRedeclaration(const ObjCMethodDecl * PrevMethod)760 void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
761 assert(PrevMethod);
762 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
763 IsRedeclaration = true;
764 PrevMethod->HasRedeclaration = true;
765 }
766
setParamsAndSelLocs(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)767 void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
768 ArrayRef<ParmVarDecl*> Params,
769 ArrayRef<SourceLocation> SelLocs) {
770 ParamsAndSelLocs = nullptr;
771 NumParams = Params.size();
772 if (Params.empty() && SelLocs.empty())
773 return;
774
775 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
776 sizeof(SourceLocation) * SelLocs.size();
777 ParamsAndSelLocs = C.Allocate(Size);
778 std::copy(Params.begin(), Params.end(), getParams());
779 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
780 }
781
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const782 void ObjCMethodDecl::getSelectorLocs(
783 SmallVectorImpl<SourceLocation> &SelLocs) const {
784 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
785 SelLocs.push_back(getSelectorLoc(i));
786 }
787
setMethodParams(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)788 void ObjCMethodDecl::setMethodParams(ASTContext &C,
789 ArrayRef<ParmVarDecl*> Params,
790 ArrayRef<SourceLocation> SelLocs) {
791 assert((!SelLocs.empty() || isImplicit()) &&
792 "No selector locs for non-implicit method");
793 if (isImplicit())
794 return setParamsAndSelLocs(C, Params, llvm::None);
795
796 SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
797 DeclEndLoc);
798 if (SelLocsKind != SelLoc_NonStandard)
799 return setParamsAndSelLocs(C, Params, llvm::None);
800
801 setParamsAndSelLocs(C, Params, SelLocs);
802 }
803
804 /// \brief A definition will return its interface declaration.
805 /// An interface declaration will return its definition.
806 /// Otherwise it will return itself.
getNextRedeclarationImpl()807 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
808 ASTContext &Ctx = getASTContext();
809 ObjCMethodDecl *Redecl = nullptr;
810 if (HasRedeclaration)
811 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
812 if (Redecl)
813 return Redecl;
814
815 Decl *CtxD = cast<Decl>(getDeclContext());
816
817 if (!CtxD->isInvalidDecl()) {
818 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
819 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
820 if (!ImplD->isInvalidDecl())
821 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
822
823 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
824 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
825 if (!ImplD->isInvalidDecl())
826 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
827
828 } else if (ObjCImplementationDecl *ImplD =
829 dyn_cast<ObjCImplementationDecl>(CtxD)) {
830 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
831 if (!IFD->isInvalidDecl())
832 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
833
834 } else if (ObjCCategoryImplDecl *CImplD =
835 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
836 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
837 if (!CatD->isInvalidDecl())
838 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
839 }
840 }
841
842 if (!Redecl && isRedeclaration()) {
843 // This is the last redeclaration, go back to the first method.
844 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
845 isInstanceMethod());
846 }
847
848 return Redecl ? Redecl : this;
849 }
850
getCanonicalDecl()851 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
852 Decl *CtxD = cast<Decl>(getDeclContext());
853
854 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
855 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
856 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
857 isInstanceMethod()))
858 return MD;
859
860 } else if (ObjCCategoryImplDecl *CImplD =
861 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
862 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
863 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
864 isInstanceMethod()))
865 return MD;
866 }
867
868 if (isRedeclaration())
869 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
870 isInstanceMethod());
871
872 return this;
873 }
874
getLocEnd() const875 SourceLocation ObjCMethodDecl::getLocEnd() const {
876 if (Stmt *Body = getBody())
877 return Body->getLocEnd();
878 return DeclEndLoc;
879 }
880
getMethodFamily() const881 ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
882 ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
883 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
884 return family;
885
886 // Check for an explicit attribute.
887 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
888 // The unfortunate necessity of mapping between enums here is due
889 // to the attributes framework.
890 switch (attr->getFamily()) {
891 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
892 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
893 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
894 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
895 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
896 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
897 }
898 Family = static_cast<unsigned>(family);
899 return family;
900 }
901
902 family = getSelector().getMethodFamily();
903 switch (family) {
904 case OMF_None: break;
905
906 // init only has a conventional meaning for an instance method, and
907 // it has to return an object.
908 case OMF_init:
909 if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
910 family = OMF_None;
911 break;
912
913 // alloc/copy/new have a conventional meaning for both class and
914 // instance methods, but they require an object return.
915 case OMF_alloc:
916 case OMF_copy:
917 case OMF_mutableCopy:
918 case OMF_new:
919 if (!getReturnType()->isObjCObjectPointerType())
920 family = OMF_None;
921 break;
922
923 // These selectors have a conventional meaning only for instance methods.
924 case OMF_dealloc:
925 case OMF_finalize:
926 case OMF_retain:
927 case OMF_release:
928 case OMF_autorelease:
929 case OMF_retainCount:
930 case OMF_self:
931 if (!isInstanceMethod())
932 family = OMF_None;
933 break;
934
935 case OMF_initialize:
936 if (isInstanceMethod() || !getReturnType()->isVoidType())
937 family = OMF_None;
938 break;
939
940 case OMF_performSelector:
941 if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
942 family = OMF_None;
943 else {
944 unsigned noParams = param_size();
945 if (noParams < 1 || noParams > 3)
946 family = OMF_None;
947 else {
948 ObjCMethodDecl::param_type_iterator it = param_type_begin();
949 QualType ArgT = (*it);
950 if (!ArgT->isObjCSelType()) {
951 family = OMF_None;
952 break;
953 }
954 while (--noParams) {
955 it++;
956 ArgT = (*it);
957 if (!ArgT->isObjCIdType()) {
958 family = OMF_None;
959 break;
960 }
961 }
962 }
963 }
964 break;
965
966 }
967
968 // Cache the result.
969 Family = static_cast<unsigned>(family);
970 return family;
971 }
972
getSelfType(ASTContext & Context,const ObjCInterfaceDecl * OID,bool & selfIsPseudoStrong,bool & selfIsConsumed)973 QualType ObjCMethodDecl::getSelfType(ASTContext &Context,
974 const ObjCInterfaceDecl *OID,
975 bool &selfIsPseudoStrong,
976 bool &selfIsConsumed) {
977 QualType selfTy;
978 selfIsPseudoStrong = false;
979 selfIsConsumed = false;
980 if (isInstanceMethod()) {
981 // There may be no interface context due to error in declaration
982 // of the interface (which has been reported). Recover gracefully.
983 if (OID) {
984 selfTy = Context.getObjCInterfaceType(OID);
985 selfTy = Context.getObjCObjectPointerType(selfTy);
986 } else {
987 selfTy = Context.getObjCIdType();
988 }
989 } else // we have a factory method.
990 selfTy = Context.getObjCClassType();
991
992 if (Context.getLangOpts().ObjCAutoRefCount) {
993 if (isInstanceMethod()) {
994 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
995
996 // 'self' is always __strong. It's actually pseudo-strong except
997 // in init methods (or methods labeled ns_consumes_self), though.
998 Qualifiers qs;
999 qs.setObjCLifetime(Qualifiers::OCL_Strong);
1000 selfTy = Context.getQualifiedType(selfTy, qs);
1001
1002 // In addition, 'self' is const unless this is an init method.
1003 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
1004 selfTy = selfTy.withConst();
1005 selfIsPseudoStrong = true;
1006 }
1007 }
1008 else {
1009 assert(isClassMethod());
1010 // 'self' is always const in class methods.
1011 selfTy = selfTy.withConst();
1012 selfIsPseudoStrong = true;
1013 }
1014 }
1015 return selfTy;
1016 }
1017
createImplicitParams(ASTContext & Context,const ObjCInterfaceDecl * OID)1018 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
1019 const ObjCInterfaceDecl *OID) {
1020 bool selfIsPseudoStrong, selfIsConsumed;
1021 QualType selfTy =
1022 getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
1023 ImplicitParamDecl *self
1024 = ImplicitParamDecl::Create(Context, this, SourceLocation(),
1025 &Context.Idents.get("self"), selfTy);
1026 setSelfDecl(self);
1027
1028 if (selfIsConsumed)
1029 self->addAttr(NSConsumedAttr::CreateImplicit(Context));
1030
1031 if (selfIsPseudoStrong)
1032 self->setARCPseudoStrong(true);
1033
1034 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
1035 &Context.Idents.get("_cmd"),
1036 Context.getObjCSelType()));
1037 }
1038
getClassInterface()1039 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
1040 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
1041 return ID;
1042 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1043 return CD->getClassInterface();
1044 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
1045 return IMD->getClassInterface();
1046 if (isa<ObjCProtocolDecl>(getDeclContext()))
1047 return nullptr;
1048 llvm_unreachable("unknown method context");
1049 }
1050
getReturnTypeSourceRange() const1051 SourceRange ObjCMethodDecl::getReturnTypeSourceRange() const {
1052 const auto *TSI = getReturnTypeSourceInfo();
1053 if (TSI)
1054 return TSI->getTypeLoc().getSourceRange();
1055 return SourceRange();
1056 }
1057
getSendResultType() const1058 QualType ObjCMethodDecl::getSendResultType() const {
1059 ASTContext &Ctx = getASTContext();
1060 return getReturnType().getNonLValueExprType(Ctx)
1061 .substObjCTypeArgs(Ctx, {}, ObjCSubstitutionContext::Result);
1062 }
1063
getSendResultType(QualType receiverType) const1064 QualType ObjCMethodDecl::getSendResultType(QualType receiverType) const {
1065 // FIXME: Handle related result types here.
1066
1067 return getReturnType().getNonLValueExprType(getASTContext())
1068 .substObjCMemberType(receiverType, getDeclContext(),
1069 ObjCSubstitutionContext::Result);
1070 }
1071
CollectOverriddenMethodsRecurse(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods,bool MovedToSuper)1072 static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
1073 const ObjCMethodDecl *Method,
1074 SmallVectorImpl<const ObjCMethodDecl *> &Methods,
1075 bool MovedToSuper) {
1076 if (!Container)
1077 return;
1078
1079 // In categories look for overriden methods from protocols. A method from
1080 // category is not "overriden" since it is considered as the "same" method
1081 // (same USR) as the one from the interface.
1082 if (const ObjCCategoryDecl *
1083 Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1084 // Check whether we have a matching method at this category but only if we
1085 // are at the super class level.
1086 if (MovedToSuper)
1087 if (ObjCMethodDecl *
1088 Overridden = Container->getMethod(Method->getSelector(),
1089 Method->isInstanceMethod(),
1090 /*AllowHidden=*/true))
1091 if (Method != Overridden) {
1092 // We found an override at this category; there is no need to look
1093 // into its protocols.
1094 Methods.push_back(Overridden);
1095 return;
1096 }
1097
1098 for (const auto *P : Category->protocols())
1099 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1100 return;
1101 }
1102
1103 // Check whether we have a matching method at this level.
1104 if (const ObjCMethodDecl *
1105 Overridden = Container->getMethod(Method->getSelector(),
1106 Method->isInstanceMethod(),
1107 /*AllowHidden=*/true))
1108 if (Method != Overridden) {
1109 // We found an override at this level; there is no need to look
1110 // into other protocols or categories.
1111 Methods.push_back(Overridden);
1112 return;
1113 }
1114
1115 if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
1116 for (const auto *P : Protocol->protocols())
1117 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1118 }
1119
1120 if (const ObjCInterfaceDecl *
1121 Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
1122 for (const auto *P : Interface->protocols())
1123 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1124
1125 for (const auto *Cat : Interface->known_categories())
1126 CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
1127
1128 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
1129 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
1130 /*MovedToSuper=*/true);
1131 }
1132 }
1133
CollectOverriddenMethods(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)1134 static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
1135 const ObjCMethodDecl *Method,
1136 SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
1137 CollectOverriddenMethodsRecurse(Container, Method, Methods,
1138 /*MovedToSuper=*/false);
1139 }
1140
collectOverriddenMethodsSlow(const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & overridden)1141 static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
1142 SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
1143 assert(Method->isOverriding());
1144
1145 if (const ObjCProtocolDecl *
1146 ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1147 CollectOverriddenMethods(ProtD, Method, overridden);
1148
1149 } else if (const ObjCImplDecl *
1150 IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1151 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1152 if (!ID)
1153 return;
1154 // Start searching for overridden methods using the method from the
1155 // interface as starting point.
1156 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1157 Method->isInstanceMethod(),
1158 /*AllowHidden=*/true))
1159 Method = IFaceMeth;
1160 CollectOverriddenMethods(ID, Method, overridden);
1161
1162 } else if (const ObjCCategoryDecl *
1163 CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1164 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1165 if (!ID)
1166 return;
1167 // Start searching for overridden methods using the method from the
1168 // interface as starting point.
1169 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1170 Method->isInstanceMethod(),
1171 /*AllowHidden=*/true))
1172 Method = IFaceMeth;
1173 CollectOverriddenMethods(ID, Method, overridden);
1174
1175 } else {
1176 CollectOverriddenMethods(
1177 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1178 Method, overridden);
1179 }
1180 }
1181
getOverriddenMethods(SmallVectorImpl<const ObjCMethodDecl * > & Overridden) const1182 void ObjCMethodDecl::getOverriddenMethods(
1183 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1184 const ObjCMethodDecl *Method = this;
1185
1186 if (Method->isRedeclaration()) {
1187 Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
1188 getMethod(Method->getSelector(), Method->isInstanceMethod());
1189 }
1190
1191 if (Method->isOverriding()) {
1192 collectOverriddenMethodsSlow(Method, Overridden);
1193 assert(!Overridden.empty() &&
1194 "ObjCMethodDecl's overriding bit is not as expected");
1195 }
1196 }
1197
1198 const ObjCPropertyDecl *
findPropertyDecl(bool CheckOverrides) const1199 ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
1200 Selector Sel = getSelector();
1201 unsigned NumArgs = Sel.getNumArgs();
1202 if (NumArgs > 1)
1203 return nullptr;
1204
1205 if (!isInstanceMethod())
1206 return nullptr;
1207
1208 if (isPropertyAccessor()) {
1209 const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
1210 bool IsGetter = (NumArgs == 0);
1211
1212 /// Local function that attempts to find a matching property within the
1213 /// given Objective-C container.
1214 auto findMatchingProperty =
1215 [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
1216
1217 for (const auto *I : Container->properties()) {
1218 Selector NextSel = IsGetter ? I->getGetterName()
1219 : I->getSetterName();
1220 if (NextSel == Sel)
1221 return I;
1222 }
1223
1224 return nullptr;
1225 };
1226
1227 // Look in the container we were given.
1228 if (const auto *Found = findMatchingProperty(Container))
1229 return Found;
1230
1231 // If we're in a category or extension, look in the main class.
1232 const ObjCInterfaceDecl *ClassDecl = nullptr;
1233 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1234 ClassDecl = Category->getClassInterface();
1235 if (const auto *Found = findMatchingProperty(ClassDecl))
1236 return Found;
1237 } else {
1238 // Determine whether the container is a class.
1239 ClassDecl = dyn_cast<ObjCInterfaceDecl>(Container);
1240 }
1241
1242 // If we have a class, check its visible extensions.
1243 if (ClassDecl) {
1244 for (const auto *Ext : ClassDecl->visible_extensions()) {
1245 if (Ext == Container)
1246 continue;
1247
1248 if (const auto *Found = findMatchingProperty(Ext))
1249 return Found;
1250 }
1251 }
1252
1253 llvm_unreachable("Marked as a property accessor but no property found!");
1254 }
1255
1256 if (!CheckOverrides)
1257 return nullptr;
1258
1259 typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
1260 OverridesTy Overrides;
1261 getOverriddenMethods(Overrides);
1262 for (OverridesTy::const_iterator I = Overrides.begin(), E = Overrides.end();
1263 I != E; ++I) {
1264 if (const ObjCPropertyDecl *Prop = (*I)->findPropertyDecl(false))
1265 return Prop;
1266 }
1267
1268 return nullptr;
1269 }
1270
1271 //===----------------------------------------------------------------------===//
1272 // ObjCTypeParamDecl
1273 //===----------------------------------------------------------------------===//
1274
anchor()1275 void ObjCTypeParamDecl::anchor() { }
1276
Create(ASTContext & ctx,DeclContext * dc,ObjCTypeParamVariance variance,SourceLocation varianceLoc,unsigned index,SourceLocation nameLoc,IdentifierInfo * name,SourceLocation colonLoc,TypeSourceInfo * boundInfo)1277 ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc,
1278 ObjCTypeParamVariance variance,
1279 SourceLocation varianceLoc,
1280 unsigned index,
1281 SourceLocation nameLoc,
1282 IdentifierInfo *name,
1283 SourceLocation colonLoc,
1284 TypeSourceInfo *boundInfo) {
1285 return new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
1286 nameLoc, name, colonLoc, boundInfo);
1287 }
1288
CreateDeserialized(ASTContext & ctx,unsigned ID)1289 ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx,
1290 unsigned ID) {
1291 return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,
1292 ObjCTypeParamVariance::Invariant,
1293 SourceLocation(), 0, SourceLocation(),
1294 nullptr, SourceLocation(), nullptr);
1295 }
1296
getSourceRange() const1297 SourceRange ObjCTypeParamDecl::getSourceRange() const {
1298 SourceLocation startLoc = VarianceLoc;
1299 if (startLoc.isInvalid())
1300 startLoc = getLocation();
1301
1302 if (hasExplicitBound()) {
1303 return SourceRange(startLoc,
1304 getTypeSourceInfo()->getTypeLoc().getEndLoc());
1305 }
1306
1307 return SourceRange(startLoc);
1308 }
1309
1310 //===----------------------------------------------------------------------===//
1311 // ObjCTypeParamList
1312 //===----------------------------------------------------------------------===//
ObjCTypeParamList(SourceLocation lAngleLoc,ArrayRef<ObjCTypeParamDecl * > typeParams,SourceLocation rAngleLoc)1313 ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,
1314 ArrayRef<ObjCTypeParamDecl *> typeParams,
1315 SourceLocation rAngleLoc)
1316 : NumParams(typeParams.size())
1317 {
1318 Brackets.Begin = lAngleLoc.getRawEncoding();
1319 Brackets.End = rAngleLoc.getRawEncoding();
1320 std::copy(typeParams.begin(), typeParams.end(), begin());
1321 }
1322
1323
create(ASTContext & ctx,SourceLocation lAngleLoc,ArrayRef<ObjCTypeParamDecl * > typeParams,SourceLocation rAngleLoc)1324 ObjCTypeParamList *ObjCTypeParamList::create(
1325 ASTContext &ctx,
1326 SourceLocation lAngleLoc,
1327 ArrayRef<ObjCTypeParamDecl *> typeParams,
1328 SourceLocation rAngleLoc) {
1329 unsigned size = sizeof(ObjCTypeParamList)
1330 + sizeof(ObjCTypeParamDecl *) * typeParams.size();
1331 static_assert(llvm::AlignOf<ObjCTypeParamList>::Alignment >=
1332 llvm::AlignOf<ObjCTypeParamDecl *>::Alignment,
1333 "type parameter list needs greater alignment");
1334 unsigned align = llvm::alignOf<ObjCTypeParamList>();
1335 void *mem = ctx.Allocate(size, align);
1336 return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
1337 }
1338
gatherDefaultTypeArgs(SmallVectorImpl<QualType> & typeArgs) const1339 void ObjCTypeParamList::gatherDefaultTypeArgs(
1340 SmallVectorImpl<QualType> &typeArgs) const {
1341 typeArgs.reserve(size());
1342 for (auto typeParam : *this)
1343 typeArgs.push_back(typeParam->getUnderlyingType());
1344 }
1345
1346 //===----------------------------------------------------------------------===//
1347 // ObjCInterfaceDecl
1348 //===----------------------------------------------------------------------===//
1349
Create(const ASTContext & C,DeclContext * DC,SourceLocation atLoc,IdentifierInfo * Id,ObjCTypeParamList * typeParamList,ObjCInterfaceDecl * PrevDecl,SourceLocation ClassLoc,bool isInternal)1350 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
1351 DeclContext *DC,
1352 SourceLocation atLoc,
1353 IdentifierInfo *Id,
1354 ObjCTypeParamList *typeParamList,
1355 ObjCInterfaceDecl *PrevDecl,
1356 SourceLocation ClassLoc,
1357 bool isInternal){
1358 ObjCInterfaceDecl *Result = new (C, DC)
1359 ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
1360 isInternal);
1361 Result->Data.setInt(!C.getLangOpts().Modules);
1362 C.getObjCInterfaceType(Result, PrevDecl);
1363 return Result;
1364 }
1365
CreateDeserialized(const ASTContext & C,unsigned ID)1366 ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
1367 unsigned ID) {
1368 ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr,
1369 SourceLocation(),
1370 nullptr,
1371 nullptr,
1372 SourceLocation(),
1373 nullptr, false);
1374 Result->Data.setInt(!C.getLangOpts().Modules);
1375 return Result;
1376 }
1377
ObjCInterfaceDecl(const ASTContext & C,DeclContext * DC,SourceLocation AtLoc,IdentifierInfo * Id,ObjCTypeParamList * typeParamList,SourceLocation CLoc,ObjCInterfaceDecl * PrevDecl,bool IsInternal)1378 ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
1379 SourceLocation AtLoc, IdentifierInfo *Id,
1380 ObjCTypeParamList *typeParamList,
1381 SourceLocation CLoc,
1382 ObjCInterfaceDecl *PrevDecl,
1383 bool IsInternal)
1384 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
1385 redeclarable_base(C), TypeForDecl(nullptr), TypeParamList(nullptr),
1386 Data() {
1387 setPreviousDecl(PrevDecl);
1388
1389 // Copy the 'data' pointer over.
1390 if (PrevDecl)
1391 Data = PrevDecl->Data;
1392
1393 setImplicit(IsInternal);
1394
1395 setTypeParamList(typeParamList);
1396 }
1397
LoadExternalDefinition() const1398 void ObjCInterfaceDecl::LoadExternalDefinition() const {
1399 assert(data().ExternallyCompleted && "Class is not externally completed");
1400 data().ExternallyCompleted = false;
1401 getASTContext().getExternalSource()->CompleteType(
1402 const_cast<ObjCInterfaceDecl *>(this));
1403 }
1404
setExternallyCompleted()1405 void ObjCInterfaceDecl::setExternallyCompleted() {
1406 assert(getASTContext().getExternalSource() &&
1407 "Class can't be externally completed without an external source");
1408 assert(hasDefinition() &&
1409 "Forward declarations can't be externally completed");
1410 data().ExternallyCompleted = true;
1411 }
1412
setHasDesignatedInitializers()1413 void ObjCInterfaceDecl::setHasDesignatedInitializers() {
1414 // Check for a complete definition and recover if not so.
1415 if (!isThisDeclarationADefinition())
1416 return;
1417 data().HasDesignatedInitializers = true;
1418 }
1419
hasDesignatedInitializers() const1420 bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
1421 // Check for a complete definition and recover if not so.
1422 if (!isThisDeclarationADefinition())
1423 return false;
1424 if (data().ExternallyCompleted)
1425 LoadExternalDefinition();
1426
1427 return data().HasDesignatedInitializers;
1428 }
1429
1430 StringRef
getObjCRuntimeNameAsString() const1431 ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
1432 if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1433 return ObjCRTName->getMetadataName();
1434
1435 return getName();
1436 }
1437
1438 StringRef
getObjCRuntimeNameAsString() const1439 ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
1440 if (ObjCInterfaceDecl *ID =
1441 const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
1442 return ID->getObjCRuntimeNameAsString();
1443
1444 return getName();
1445 }
1446
getImplementation() const1447 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
1448 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1449 if (data().ExternallyCompleted)
1450 LoadExternalDefinition();
1451
1452 return getASTContext().getObjCImplementation(
1453 const_cast<ObjCInterfaceDecl*>(Def));
1454 }
1455
1456 // FIXME: Should make sure no callers ever do this.
1457 return nullptr;
1458 }
1459
setImplementation(ObjCImplementationDecl * ImplD)1460 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
1461 getASTContext().setObjCImplementation(getDefinition(), ImplD);
1462 }
1463
1464 namespace {
1465 struct SynthesizeIvarChunk {
1466 uint64_t Size;
1467 ObjCIvarDecl *Ivar;
SynthesizeIvarChunk__anon5bbbbf6e0211::SynthesizeIvarChunk1468 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1469 : Size(size), Ivar(ivar) {}
1470 };
1471
operator <(const SynthesizeIvarChunk & LHS,const SynthesizeIvarChunk & RHS)1472 bool operator<(const SynthesizeIvarChunk & LHS,
1473 const SynthesizeIvarChunk &RHS) {
1474 return LHS.Size < RHS.Size;
1475 }
1476 }
1477
1478 /// all_declared_ivar_begin - return first ivar declared in this class,
1479 /// its extensions and its implementation. Lazily build the list on first
1480 /// access.
1481 ///
1482 /// Caveat: The list returned by this method reflects the current
1483 /// state of the parser. The cache will be updated for every ivar
1484 /// added by an extension or the implementation when they are
1485 /// encountered.
1486 /// See also ObjCIvarDecl::Create().
all_declared_ivar_begin()1487 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
1488 // FIXME: Should make sure no callers ever do this.
1489 if (!hasDefinition())
1490 return nullptr;
1491
1492 ObjCIvarDecl *curIvar = nullptr;
1493 if (!data().IvarList) {
1494 if (!ivar_empty()) {
1495 ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
1496 data().IvarList = *I; ++I;
1497 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1498 curIvar->setNextIvar(*I);
1499 }
1500
1501 for (const auto *Ext : known_extensions()) {
1502 if (!Ext->ivar_empty()) {
1503 ObjCCategoryDecl::ivar_iterator
1504 I = Ext->ivar_begin(),
1505 E = Ext->ivar_end();
1506 if (!data().IvarList) {
1507 data().IvarList = *I; ++I;
1508 curIvar = data().IvarList;
1509 }
1510 for ( ;I != E; curIvar = *I, ++I)
1511 curIvar->setNextIvar(*I);
1512 }
1513 }
1514 data().IvarListMissingImplementation = true;
1515 }
1516
1517 // cached and complete!
1518 if (!data().IvarListMissingImplementation)
1519 return data().IvarList;
1520
1521 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1522 data().IvarListMissingImplementation = false;
1523 if (!ImplDecl->ivar_empty()) {
1524 SmallVector<SynthesizeIvarChunk, 16> layout;
1525 for (auto *IV : ImplDecl->ivars()) {
1526 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1527 layout.push_back(SynthesizeIvarChunk(
1528 IV->getASTContext().getTypeSize(IV->getType()), IV));
1529 continue;
1530 }
1531 if (!data().IvarList)
1532 data().IvarList = IV;
1533 else
1534 curIvar->setNextIvar(IV);
1535 curIvar = IV;
1536 }
1537
1538 if (!layout.empty()) {
1539 // Order synthesized ivars by their size.
1540 std::stable_sort(layout.begin(), layout.end());
1541 unsigned Ix = 0, EIx = layout.size();
1542 if (!data().IvarList) {
1543 data().IvarList = layout[0].Ivar; Ix++;
1544 curIvar = data().IvarList;
1545 }
1546 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1547 curIvar->setNextIvar(layout[Ix].Ivar);
1548 }
1549 }
1550 }
1551 return data().IvarList;
1552 }
1553
1554 /// FindCategoryDeclaration - Finds category declaration in the list of
1555 /// categories for this class and returns it. Name of the category is passed
1556 /// in 'CategoryId'. If category not found, return 0;
1557 ///
1558 ObjCCategoryDecl *
FindCategoryDeclaration(IdentifierInfo * CategoryId) const1559 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
1560 // FIXME: Should make sure no callers ever do this.
1561 if (!hasDefinition())
1562 return nullptr;
1563
1564 if (data().ExternallyCompleted)
1565 LoadExternalDefinition();
1566
1567 for (auto *Cat : visible_categories())
1568 if (Cat->getIdentifier() == CategoryId)
1569 return Cat;
1570
1571 return nullptr;
1572 }
1573
1574 ObjCMethodDecl *
getCategoryInstanceMethod(Selector Sel) const1575 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
1576 for (const auto *Cat : visible_categories()) {
1577 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1578 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1579 return MD;
1580 }
1581
1582 return nullptr;
1583 }
1584
getCategoryClassMethod(Selector Sel) const1585 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
1586 for (const auto *Cat : visible_categories()) {
1587 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1588 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1589 return MD;
1590 }
1591
1592 return nullptr;
1593 }
1594
1595 /// ClassImplementsProtocol - Checks that 'lProto' protocol
1596 /// has been implemented in IDecl class, its super class or categories (if
1597 /// lookupCategory is true).
ClassImplementsProtocol(ObjCProtocolDecl * lProto,bool lookupCategory,bool RHSIsQualifiedID)1598 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1599 bool lookupCategory,
1600 bool RHSIsQualifiedID) {
1601 if (!hasDefinition())
1602 return false;
1603
1604 ObjCInterfaceDecl *IDecl = this;
1605 // 1st, look up the class.
1606 for (auto *PI : IDecl->protocols()){
1607 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1608 return true;
1609 // This is dubious and is added to be compatible with gcc. In gcc, it is
1610 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1611 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1612 // object. This IMO, should be a bug.
1613 // FIXME: Treat this as an extension, and flag this as an error when GCC
1614 // extensions are not enabled.
1615 if (RHSIsQualifiedID &&
1616 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
1617 return true;
1618 }
1619
1620 // 2nd, look up the category.
1621 if (lookupCategory)
1622 for (const auto *Cat : visible_categories()) {
1623 for (auto *PI : Cat->protocols())
1624 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1625 return true;
1626 }
1627
1628 // 3rd, look up the super class(s)
1629 if (IDecl->getSuperClass())
1630 return
1631 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1632 RHSIsQualifiedID);
1633
1634 return false;
1635 }
1636
1637 //===----------------------------------------------------------------------===//
1638 // ObjCIvarDecl
1639 //===----------------------------------------------------------------------===//
1640
anchor()1641 void ObjCIvarDecl::anchor() { }
1642
Create(ASTContext & C,ObjCContainerDecl * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,AccessControl ac,Expr * BW,bool synthesized)1643 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
1644 SourceLocation StartLoc,
1645 SourceLocation IdLoc, IdentifierInfo *Id,
1646 QualType T, TypeSourceInfo *TInfo,
1647 AccessControl ac, Expr *BW,
1648 bool synthesized) {
1649 if (DC) {
1650 // Ivar's can only appear in interfaces, implementations (via synthesized
1651 // properties), and class extensions (via direct declaration, or synthesized
1652 // properties).
1653 //
1654 // FIXME: This should really be asserting this:
1655 // (isa<ObjCCategoryDecl>(DC) &&
1656 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1657 // but unfortunately we sometimes place ivars into non-class extension
1658 // categories on error. This breaks an AST invariant, and should not be
1659 // fixed.
1660 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1661 isa<ObjCCategoryDecl>(DC)) &&
1662 "Invalid ivar decl context!");
1663 // Once a new ivar is created in any of class/class-extension/implementation
1664 // decl contexts, the previously built IvarList must be rebuilt.
1665 ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1666 if (!ID) {
1667 if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
1668 ID = IM->getClassInterface();
1669 else
1670 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1671 }
1672 ID->setIvarList(nullptr);
1673 }
1674
1675 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1676 synthesized);
1677 }
1678
CreateDeserialized(ASTContext & C,unsigned ID)1679 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1680 return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1681 nullptr, QualType(), nullptr,
1682 ObjCIvarDecl::None, nullptr, false);
1683 }
1684
getContainingInterface() const1685 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
1686 const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
1687
1688 switch (DC->getKind()) {
1689 default:
1690 case ObjCCategoryImpl:
1691 case ObjCProtocol:
1692 llvm_unreachable("invalid ivar container!");
1693
1694 // Ivars can only appear in class extension categories.
1695 case ObjCCategory: {
1696 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
1697 assert(CD->IsClassExtension() && "invalid container for ivar!");
1698 return CD->getClassInterface();
1699 }
1700
1701 case ObjCImplementation:
1702 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1703
1704 case ObjCInterface:
1705 return cast<ObjCInterfaceDecl>(DC);
1706 }
1707 }
1708
getUsageType(QualType objectType) const1709 QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
1710 return getType().substObjCMemberType(objectType, getDeclContext(),
1711 ObjCSubstitutionContext::Property);
1712 }
1713
1714 //===----------------------------------------------------------------------===//
1715 // ObjCAtDefsFieldDecl
1716 //===----------------------------------------------------------------------===//
1717
anchor()1718 void ObjCAtDefsFieldDecl::anchor() { }
1719
1720 ObjCAtDefsFieldDecl
Create(ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,Expr * BW)1721 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1722 SourceLocation StartLoc, SourceLocation IdLoc,
1723 IdentifierInfo *Id, QualType T, Expr *BW) {
1724 return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1725 }
1726
CreateDeserialized(ASTContext & C,unsigned ID)1727 ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
1728 unsigned ID) {
1729 return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
1730 SourceLocation(), nullptr, QualType(),
1731 nullptr);
1732 }
1733
1734 //===----------------------------------------------------------------------===//
1735 // ObjCProtocolDecl
1736 //===----------------------------------------------------------------------===//
1737
anchor()1738 void ObjCProtocolDecl::anchor() { }
1739
ObjCProtocolDecl(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1740 ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
1741 IdentifierInfo *Id, SourceLocation nameLoc,
1742 SourceLocation atStartLoc,
1743 ObjCProtocolDecl *PrevDecl)
1744 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
1745 redeclarable_base(C), Data() {
1746 setPreviousDecl(PrevDecl);
1747 if (PrevDecl)
1748 Data = PrevDecl->Data;
1749 }
1750
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1751 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
1752 IdentifierInfo *Id,
1753 SourceLocation nameLoc,
1754 SourceLocation atStartLoc,
1755 ObjCProtocolDecl *PrevDecl) {
1756 ObjCProtocolDecl *Result =
1757 new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
1758 Result->Data.setInt(!C.getLangOpts().Modules);
1759 return Result;
1760 }
1761
CreateDeserialized(ASTContext & C,unsigned ID)1762 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
1763 unsigned ID) {
1764 ObjCProtocolDecl *Result =
1765 new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
1766 SourceLocation(), nullptr);
1767 Result->Data.setInt(!C.getLangOpts().Modules);
1768 return Result;
1769 }
1770
lookupProtocolNamed(IdentifierInfo * Name)1771 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1772 ObjCProtocolDecl *PDecl = this;
1773
1774 if (Name == getIdentifier())
1775 return PDecl;
1776
1777 for (auto *I : protocols())
1778 if ((PDecl = I->lookupProtocolNamed(Name)))
1779 return PDecl;
1780
1781 return nullptr;
1782 }
1783
1784 // lookupMethod - Lookup a instance/class method in the protocol and protocols
1785 // it inherited.
lookupMethod(Selector Sel,bool isInstance) const1786 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1787 bool isInstance) const {
1788 ObjCMethodDecl *MethodDecl = nullptr;
1789
1790 // If there is no definition or the definition is hidden, we don't find
1791 // anything.
1792 const ObjCProtocolDecl *Def = getDefinition();
1793 if (!Def || Def->isHidden())
1794 return nullptr;
1795
1796 if ((MethodDecl = getMethod(Sel, isInstance)))
1797 return MethodDecl;
1798
1799 for (const auto *I : protocols())
1800 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
1801 return MethodDecl;
1802 return nullptr;
1803 }
1804
allocateDefinitionData()1805 void ObjCProtocolDecl::allocateDefinitionData() {
1806 assert(!Data.getPointer() && "Protocol already has a definition!");
1807 Data.setPointer(new (getASTContext()) DefinitionData);
1808 Data.getPointer()->Definition = this;
1809 }
1810
startDefinition()1811 void ObjCProtocolDecl::startDefinition() {
1812 allocateDefinitionData();
1813
1814 // Update all of the declarations with a pointer to the definition.
1815 for (auto RD : redecls())
1816 RD->Data = this->Data;
1817 }
1818
collectPropertiesToImplement(PropertyMap & PM,PropertyDeclOrder & PO) const1819 void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
1820 PropertyDeclOrder &PO) const {
1821
1822 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
1823 for (auto *Prop : PDecl->properties()) {
1824 // Insert into PM if not there already.
1825 PM.insert(std::make_pair(Prop->getIdentifier(), Prop));
1826 PO.push_back(Prop);
1827 }
1828 // Scan through protocol's protocols.
1829 for (const auto *PI : PDecl->protocols())
1830 PI->collectPropertiesToImplement(PM, PO);
1831 }
1832 }
1833
1834
collectInheritedProtocolProperties(const ObjCPropertyDecl * Property,ProtocolPropertyMap & PM) const1835 void ObjCProtocolDecl::collectInheritedProtocolProperties(
1836 const ObjCPropertyDecl *Property,
1837 ProtocolPropertyMap &PM) const {
1838 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
1839 bool MatchFound = false;
1840 for (auto *Prop : PDecl->properties()) {
1841 if (Prop == Property)
1842 continue;
1843 if (Prop->getIdentifier() == Property->getIdentifier()) {
1844 PM[PDecl] = Prop;
1845 MatchFound = true;
1846 break;
1847 }
1848 }
1849 // Scan through protocol's protocols which did not have a matching property.
1850 if (!MatchFound)
1851 for (const auto *PI : PDecl->protocols())
1852 PI->collectInheritedProtocolProperties(Property, PM);
1853 }
1854 }
1855
1856 StringRef
getObjCRuntimeNameAsString() const1857 ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
1858 if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1859 return ObjCRTName->getMetadataName();
1860
1861 return getName();
1862 }
1863
1864 //===----------------------------------------------------------------------===//
1865 // ObjCCategoryDecl
1866 //===----------------------------------------------------------------------===//
1867
anchor()1868 void ObjCCategoryDecl::anchor() { }
1869
ObjCCategoryDecl(DeclContext * DC,SourceLocation AtLoc,SourceLocation ClassNameLoc,SourceLocation CategoryNameLoc,IdentifierInfo * Id,ObjCInterfaceDecl * IDecl,ObjCTypeParamList * typeParamList,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1870 ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
1871 SourceLocation ClassNameLoc,
1872 SourceLocation CategoryNameLoc,
1873 IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
1874 ObjCTypeParamList *typeParamList,
1875 SourceLocation IvarLBraceLoc,
1876 SourceLocation IvarRBraceLoc)
1877 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
1878 ClassInterface(IDecl), TypeParamList(nullptr),
1879 NextClassCategory(nullptr), CategoryNameLoc(CategoryNameLoc),
1880 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc)
1881 {
1882 setTypeParamList(typeParamList);
1883 }
1884
Create(ASTContext & C,DeclContext * DC,SourceLocation AtLoc,SourceLocation ClassNameLoc,SourceLocation CategoryNameLoc,IdentifierInfo * Id,ObjCInterfaceDecl * IDecl,ObjCTypeParamList * typeParamList,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1885 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
1886 SourceLocation AtLoc,
1887 SourceLocation ClassNameLoc,
1888 SourceLocation CategoryNameLoc,
1889 IdentifierInfo *Id,
1890 ObjCInterfaceDecl *IDecl,
1891 ObjCTypeParamList *typeParamList,
1892 SourceLocation IvarLBraceLoc,
1893 SourceLocation IvarRBraceLoc) {
1894 ObjCCategoryDecl *CatDecl =
1895 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
1896 IDecl, typeParamList, IvarLBraceLoc,
1897 IvarRBraceLoc);
1898 if (IDecl) {
1899 // Link this category into its class's category list.
1900 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
1901 if (IDecl->hasDefinition()) {
1902 IDecl->setCategoryListRaw(CatDecl);
1903 if (ASTMutationListener *L = C.getASTMutationListener())
1904 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
1905 }
1906 }
1907
1908 return CatDecl;
1909 }
1910
CreateDeserialized(ASTContext & C,unsigned ID)1911 ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
1912 unsigned ID) {
1913 return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
1914 SourceLocation(), SourceLocation(),
1915 nullptr, nullptr, nullptr);
1916 }
1917
getImplementation() const1918 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
1919 return getASTContext().getObjCImplementation(
1920 const_cast<ObjCCategoryDecl*>(this));
1921 }
1922
setImplementation(ObjCCategoryImplDecl * ImplD)1923 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
1924 getASTContext().setObjCImplementation(this, ImplD);
1925 }
1926
setTypeParamList(ObjCTypeParamList * TPL)1927 void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) {
1928 TypeParamList = TPL;
1929 if (!TPL)
1930 return;
1931 // Set the declaration context of each of the type parameters.
1932 for (auto typeParam : *TypeParamList)
1933 typeParam->setDeclContext(this);
1934 }
1935
1936
1937 //===----------------------------------------------------------------------===//
1938 // ObjCCategoryImplDecl
1939 //===----------------------------------------------------------------------===//
1940
anchor()1941 void ObjCCategoryImplDecl::anchor() { }
1942
1943 ObjCCategoryImplDecl *
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,ObjCInterfaceDecl * ClassInterface,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation CategoryNameLoc)1944 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
1945 IdentifierInfo *Id,
1946 ObjCInterfaceDecl *ClassInterface,
1947 SourceLocation nameLoc,
1948 SourceLocation atStartLoc,
1949 SourceLocation CategoryNameLoc) {
1950 if (ClassInterface && ClassInterface->hasDefinition())
1951 ClassInterface = ClassInterface->getDefinition();
1952 return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
1953 atStartLoc, CategoryNameLoc);
1954 }
1955
CreateDeserialized(ASTContext & C,unsigned ID)1956 ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
1957 unsigned ID) {
1958 return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
1959 SourceLocation(), SourceLocation(),
1960 SourceLocation());
1961 }
1962
getCategoryDecl() const1963 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
1964 // The class interface might be NULL if we are working with invalid code.
1965 if (const ObjCInterfaceDecl *ID = getClassInterface())
1966 return ID->FindCategoryDeclaration(getIdentifier());
1967 return nullptr;
1968 }
1969
1970
anchor()1971 void ObjCImplDecl::anchor() { }
1972
addPropertyImplementation(ObjCPropertyImplDecl * property)1973 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
1974 // FIXME: The context should be correct before we get here.
1975 property->setLexicalDeclContext(this);
1976 addDecl(property);
1977 }
1978
setClassInterface(ObjCInterfaceDecl * IFace)1979 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
1980 ASTContext &Ctx = getASTContext();
1981
1982 if (ObjCImplementationDecl *ImplD
1983 = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
1984 if (IFace)
1985 Ctx.setObjCImplementation(IFace, ImplD);
1986
1987 } else if (ObjCCategoryImplDecl *ImplD =
1988 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
1989 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
1990 Ctx.setObjCImplementation(CD, ImplD);
1991 }
1992
1993 ClassInterface = IFace;
1994 }
1995
1996 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
1997 /// properties implemented in this \@implementation block and returns
1998 /// the implemented property that uses it.
1999 ///
2000 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo * ivarId) const2001 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
2002 for (auto *PID : property_impls())
2003 if (PID->getPropertyIvarDecl() &&
2004 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
2005 return PID;
2006 return nullptr;
2007 }
2008
2009 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
2010 /// added to the list of those properties \@synthesized/\@dynamic in this
2011 /// category \@implementation block.
2012 ///
2013 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo * Id) const2014 FindPropertyImplDecl(IdentifierInfo *Id) const {
2015 for (auto *PID : property_impls())
2016 if (PID->getPropertyDecl()->getIdentifier() == Id)
2017 return PID;
2018 return nullptr;
2019 }
2020
operator <<(raw_ostream & OS,const ObjCCategoryImplDecl & CID)2021 raw_ostream &clang::operator<<(raw_ostream &OS,
2022 const ObjCCategoryImplDecl &CID) {
2023 OS << CID.getName();
2024 return OS;
2025 }
2026
2027 //===----------------------------------------------------------------------===//
2028 // ObjCImplementationDecl
2029 //===----------------------------------------------------------------------===//
2030
anchor()2031 void ObjCImplementationDecl::anchor() { }
2032
2033 ObjCImplementationDecl *
Create(ASTContext & C,DeclContext * DC,ObjCInterfaceDecl * ClassInterface,ObjCInterfaceDecl * SuperDecl,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation superLoc,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)2034 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
2035 ObjCInterfaceDecl *ClassInterface,
2036 ObjCInterfaceDecl *SuperDecl,
2037 SourceLocation nameLoc,
2038 SourceLocation atStartLoc,
2039 SourceLocation superLoc,
2040 SourceLocation IvarLBraceLoc,
2041 SourceLocation IvarRBraceLoc) {
2042 if (ClassInterface && ClassInterface->hasDefinition())
2043 ClassInterface = ClassInterface->getDefinition();
2044 return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
2045 nameLoc, atStartLoc, superLoc,
2046 IvarLBraceLoc, IvarRBraceLoc);
2047 }
2048
2049 ObjCImplementationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)2050 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2051 return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
2052 SourceLocation(), SourceLocation());
2053 }
2054
setIvarInitializers(ASTContext & C,CXXCtorInitializer ** initializers,unsigned numInitializers)2055 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
2056 CXXCtorInitializer ** initializers,
2057 unsigned numInitializers) {
2058 if (numInitializers > 0) {
2059 NumIvarInitializers = numInitializers;
2060 CXXCtorInitializer **ivarInitializers =
2061 new (C) CXXCtorInitializer*[NumIvarInitializers];
2062 memcpy(ivarInitializers, initializers,
2063 numInitializers * sizeof(CXXCtorInitializer*));
2064 IvarInitializers = ivarInitializers;
2065 }
2066 }
2067
2068 ObjCImplementationDecl::init_const_iterator
init_begin() const2069 ObjCImplementationDecl::init_begin() const {
2070 return IvarInitializers.get(getASTContext().getExternalSource());
2071 }
2072
operator <<(raw_ostream & OS,const ObjCImplementationDecl & ID)2073 raw_ostream &clang::operator<<(raw_ostream &OS,
2074 const ObjCImplementationDecl &ID) {
2075 OS << ID.getName();
2076 return OS;
2077 }
2078
2079 //===----------------------------------------------------------------------===//
2080 // ObjCCompatibleAliasDecl
2081 //===----------------------------------------------------------------------===//
2082
anchor()2083 void ObjCCompatibleAliasDecl::anchor() { }
2084
2085 ObjCCompatibleAliasDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,ObjCInterfaceDecl * AliasedClass)2086 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
2087 SourceLocation L,
2088 IdentifierInfo *Id,
2089 ObjCInterfaceDecl* AliasedClass) {
2090 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
2091 }
2092
2093 ObjCCompatibleAliasDecl *
CreateDeserialized(ASTContext & C,unsigned ID)2094 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
2095 return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
2096 nullptr, nullptr);
2097 }
2098
2099 //===----------------------------------------------------------------------===//
2100 // ObjCPropertyDecl
2101 //===----------------------------------------------------------------------===//
2102
anchor()2103 void ObjCPropertyDecl::anchor() { }
2104
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,SourceLocation AtLoc,SourceLocation LParenLoc,QualType T,TypeSourceInfo * TSI,PropertyControl propControl)2105 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
2106 SourceLocation L,
2107 IdentifierInfo *Id,
2108 SourceLocation AtLoc,
2109 SourceLocation LParenLoc,
2110 QualType T,
2111 TypeSourceInfo *TSI,
2112 PropertyControl propControl) {
2113 return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
2114 propControl);
2115 }
2116
CreateDeserialized(ASTContext & C,unsigned ID)2117 ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
2118 unsigned ID) {
2119 return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
2120 SourceLocation(), SourceLocation(),
2121 QualType(), nullptr, None);
2122 }
2123
getUsageType(QualType objectType) const2124 QualType ObjCPropertyDecl::getUsageType(QualType objectType) const {
2125 return DeclType.substObjCMemberType(objectType, getDeclContext(),
2126 ObjCSubstitutionContext::Property);
2127 }
2128
2129 //===----------------------------------------------------------------------===//
2130 // ObjCPropertyImplDecl
2131 //===----------------------------------------------------------------------===//
2132
Create(ASTContext & C,DeclContext * DC,SourceLocation atLoc,SourceLocation L,ObjCPropertyDecl * property,Kind PK,ObjCIvarDecl * ivar,SourceLocation ivarLoc)2133 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
2134 DeclContext *DC,
2135 SourceLocation atLoc,
2136 SourceLocation L,
2137 ObjCPropertyDecl *property,
2138 Kind PK,
2139 ObjCIvarDecl *ivar,
2140 SourceLocation ivarLoc) {
2141 return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
2142 ivarLoc);
2143 }
2144
CreateDeserialized(ASTContext & C,unsigned ID)2145 ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
2146 unsigned ID) {
2147 return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
2148 SourceLocation(), nullptr, Dynamic,
2149 nullptr, SourceLocation());
2150 }
2151
getSourceRange() const2152 SourceRange ObjCPropertyImplDecl::getSourceRange() const {
2153 SourceLocation EndLoc = getLocation();
2154 if (IvarLoc.isValid())
2155 EndLoc = IvarLoc;
2156
2157 return SourceRange(AtLoc, EndLoc);
2158 }
2159