1 //===- DeclObjC.cpp - ObjC Declaration AST Node Implementation ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Objective-C related Decl classes.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/AST/DeclObjC.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/Attr.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/DeclBase.h"
19 #include "clang/AST/ODRHash.h"
20 #include "clang/AST/Stmt.h"
21 #include "clang/AST/Type.h"
22 #include "clang/AST/TypeLoc.h"
23 #include "clang/Basic/IdentifierTable.h"
24 #include "clang/Basic/LLVM.h"
25 #include "clang/Basic/LangOptions.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include <algorithm>
33 #include <cassert>
34 #include <cstdint>
35 #include <cstring>
36 #include <queue>
37 #include <utility>
38
39 using namespace clang;
40
41 //===----------------------------------------------------------------------===//
42 // ObjCListBase
43 //===----------------------------------------------------------------------===//
44
set(void * const * InList,unsigned Elts,ASTContext & Ctx)45 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
46 List = nullptr;
47 if (Elts == 0) return; // Setting to an empty list is a noop.
48
49 List = new (Ctx) void*[Elts];
50 NumElts = Elts;
51 memcpy(List, InList, sizeof(void*)*Elts);
52 }
53
set(ObjCProtocolDecl * const * InList,unsigned Elts,const SourceLocation * Locs,ASTContext & Ctx)54 void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
55 const SourceLocation *Locs, ASTContext &Ctx) {
56 if (Elts == 0)
57 return;
58
59 Locations = new (Ctx) SourceLocation[Elts];
60 memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
61 set(InList, Elts, Ctx);
62 }
63
64 //===----------------------------------------------------------------------===//
65 // ObjCInterfaceDecl
66 //===----------------------------------------------------------------------===//
67
ObjCContainerDecl(Kind DK,DeclContext * DC,const IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc)68 ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,
69 const IdentifierInfo *Id,
70 SourceLocation nameLoc,
71 SourceLocation atStartLoc)
72 : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
73 setAtStartLoc(atStartLoc);
74 }
75
anchor()76 void ObjCContainerDecl::anchor() {}
77
78 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
79 ///
80 ObjCIvarDecl *
getIvarDecl(IdentifierInfo * Id) const81 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
82 lookup_result R = lookup(Id);
83 for (lookup_iterator Ivar = R.begin(), IvarEnd = R.end();
84 Ivar != IvarEnd; ++Ivar) {
85 if (auto *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
86 return ivar;
87 }
88 return nullptr;
89 }
90
91 // Get the local instance/class method declared in this interface.
92 ObjCMethodDecl *
getMethod(Selector Sel,bool isInstance,bool AllowHidden) const93 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
94 bool AllowHidden) const {
95 // If this context is a hidden protocol definition, don't find any
96 // methods there.
97 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
98 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
99 if (!Def->isUnconditionallyVisible() && !AllowHidden)
100 return nullptr;
101 }
102
103 // Since instance & class methods can have the same name, the loop below
104 // ensures we get the correct method.
105 //
106 // @interface Whatever
107 // - (int) class_method;
108 // + (float) class_method;
109 // @end
110 lookup_result R = lookup(Sel);
111 for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
112 Meth != MethEnd; ++Meth) {
113 auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
114 if (MD && MD->isInstanceMethod() == isInstance)
115 return MD;
116 }
117 return nullptr;
118 }
119
120 /// This routine returns 'true' if a user declared setter method was
121 /// found in the class, its protocols, its super classes or categories.
122 /// It also returns 'true' if one of its categories has declared a 'readwrite'
123 /// property. This is because, user must provide a setter method for the
124 /// category's 'readwrite' property.
HasUserDeclaredSetterMethod(const ObjCPropertyDecl * Property) const125 bool ObjCContainerDecl::HasUserDeclaredSetterMethod(
126 const ObjCPropertyDecl *Property) const {
127 Selector Sel = Property->getSetterName();
128 lookup_result R = lookup(Sel);
129 for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
130 Meth != MethEnd; ++Meth) {
131 auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
132 if (MD && MD->isInstanceMethod() && !MD->isImplicit())
133 return true;
134 }
135
136 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
137 // Also look into categories, including class extensions, looking
138 // for a user declared instance method.
139 for (const auto *Cat : ID->visible_categories()) {
140 if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
141 if (!MD->isImplicit())
142 return true;
143 if (Cat->IsClassExtension())
144 continue;
145 // Also search through the categories looking for a 'readwrite'
146 // declaration of this property. If one found, presumably a setter will
147 // be provided (properties declared in categories will not get
148 // auto-synthesized).
149 for (const auto *P : Cat->properties())
150 if (P->getIdentifier() == Property->getIdentifier()) {
151 if (P->getPropertyAttributes() &
152 ObjCPropertyAttribute::kind_readwrite)
153 return true;
154 break;
155 }
156 }
157
158 // Also look into protocols, for a user declared instance method.
159 for (const auto *Proto : ID->all_referenced_protocols())
160 if (Proto->HasUserDeclaredSetterMethod(Property))
161 return true;
162
163 // And in its super class.
164 ObjCInterfaceDecl *OSC = ID->getSuperClass();
165 while (OSC) {
166 if (OSC->HasUserDeclaredSetterMethod(Property))
167 return true;
168 OSC = OSC->getSuperClass();
169 }
170 }
171 if (const auto *PD = dyn_cast<ObjCProtocolDecl>(this))
172 for (const auto *PI : PD->protocols())
173 if (PI->HasUserDeclaredSetterMethod(Property))
174 return true;
175 return false;
176 }
177
178 ObjCPropertyDecl *
findPropertyDecl(const DeclContext * DC,const IdentifierInfo * propertyID,ObjCPropertyQueryKind queryKind)179 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
180 const IdentifierInfo *propertyID,
181 ObjCPropertyQueryKind queryKind) {
182 // If this context is a hidden protocol definition, don't find any
183 // property.
184 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
185 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
186 if (!Def->isUnconditionallyVisible())
187 return nullptr;
188 }
189
190 // If context is class, then lookup property in its visible extensions.
191 // This comes before property is looked up in primary class.
192 if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
193 for (const auto *Ext : IDecl->visible_extensions())
194 if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,
195 propertyID,
196 queryKind))
197 return PD;
198 }
199
200 DeclContext::lookup_result R = DC->lookup(propertyID);
201 ObjCPropertyDecl *classProp = nullptr;
202 for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
203 ++I)
204 if (auto *PD = dyn_cast<ObjCPropertyDecl>(*I)) {
205 // If queryKind is unknown, we return the instance property if one
206 // exists; otherwise we return the class property.
207 if ((queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown &&
208 !PD->isClassProperty()) ||
209 (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_class &&
210 PD->isClassProperty()) ||
211 (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance &&
212 !PD->isClassProperty()))
213 return PD;
214
215 if (PD->isClassProperty())
216 classProp = PD;
217 }
218
219 if (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown)
220 // We can't find the instance property, return the class property.
221 return classProp;
222
223 return nullptr;
224 }
225
226 IdentifierInfo *
getDefaultSynthIvarName(ASTContext & Ctx) const227 ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
228 SmallString<128> ivarName;
229 {
230 llvm::raw_svector_ostream os(ivarName);
231 os << '_' << getIdentifier()->getName();
232 }
233 return &Ctx.Idents.get(ivarName.str());
234 }
235
getProperty(const IdentifierInfo * Id,bool IsInstance) const236 ObjCPropertyDecl *ObjCContainerDecl::getProperty(const IdentifierInfo *Id,
237 bool IsInstance) const {
238 for (auto *LookupResult : lookup(Id)) {
239 if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) {
240 if (Prop->isInstanceProperty() == IsInstance) {
241 return Prop;
242 }
243 }
244 }
245 return nullptr;
246 }
247
248 /// FindPropertyDeclaration - Finds declaration of the property given its name
249 /// in 'PropertyId' and returns it. It returns 0, if not found.
FindPropertyDeclaration(const IdentifierInfo * PropertyId,ObjCPropertyQueryKind QueryKind) const250 ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
251 const IdentifierInfo *PropertyId,
252 ObjCPropertyQueryKind QueryKind) const {
253 // Don't find properties within hidden protocol definitions.
254 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
255 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
256 if (!Def->isUnconditionallyVisible())
257 return nullptr;
258 }
259
260 // Search the extensions of a class first; they override what's in
261 // the class itself.
262 if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) {
263 for (const auto *Ext : ClassDecl->visible_extensions()) {
264 if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind))
265 return P;
266 }
267 }
268
269 if (ObjCPropertyDecl *PD =
270 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
271 QueryKind))
272 return PD;
273
274 switch (getKind()) {
275 default:
276 break;
277 case Decl::ObjCProtocol: {
278 const auto *PID = cast<ObjCProtocolDecl>(this);
279 for (const auto *I : PID->protocols())
280 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
281 QueryKind))
282 return P;
283 break;
284 }
285 case Decl::ObjCInterface: {
286 const auto *OID = cast<ObjCInterfaceDecl>(this);
287 // Look through categories (but not extensions; they were handled above).
288 for (const auto *Cat : OID->visible_categories()) {
289 if (!Cat->IsClassExtension())
290 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(
291 PropertyId, QueryKind))
292 return P;
293 }
294
295 // Look through protocols.
296 for (const auto *I : OID->all_referenced_protocols())
297 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
298 QueryKind))
299 return P;
300
301 // Finally, check the super class.
302 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
303 return superClass->FindPropertyDeclaration(PropertyId, QueryKind);
304 break;
305 }
306 case Decl::ObjCCategory: {
307 const auto *OCD = cast<ObjCCategoryDecl>(this);
308 // Look through protocols.
309 if (!OCD->IsClassExtension())
310 for (const auto *I : OCD->protocols())
311 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
312 QueryKind))
313 return P;
314 break;
315 }
316 }
317 return nullptr;
318 }
319
anchor()320 void ObjCInterfaceDecl::anchor() {}
321
getTypeParamList() const322 ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const {
323 // If this particular declaration has a type parameter list, return it.
324 if (ObjCTypeParamList *written = getTypeParamListAsWritten())
325 return written;
326
327 // If there is a definition, return its type parameter list.
328 if (const ObjCInterfaceDecl *def = getDefinition())
329 return def->getTypeParamListAsWritten();
330
331 // Otherwise, look at previous declarations to determine whether any
332 // of them has a type parameter list, skipping over those
333 // declarations that do not.
334 for (const ObjCInterfaceDecl *decl = getMostRecentDecl(); decl;
335 decl = decl->getPreviousDecl()) {
336 if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten())
337 return written;
338 }
339
340 return nullptr;
341 }
342
setTypeParamList(ObjCTypeParamList * TPL)343 void ObjCInterfaceDecl::setTypeParamList(ObjCTypeParamList *TPL) {
344 TypeParamList = TPL;
345 if (!TPL)
346 return;
347 // Set the declaration context of each of the type parameters.
348 for (auto *typeParam : *TypeParamList)
349 typeParam->setDeclContext(this);
350 }
351
getSuperClass() const352 ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const {
353 // FIXME: Should make sure no callers ever do this.
354 if (!hasDefinition())
355 return nullptr;
356
357 if (data().ExternallyCompleted)
358 LoadExternalDefinition();
359
360 if (const ObjCObjectType *superType = getSuperClassType()) {
361 if (ObjCInterfaceDecl *superDecl = superType->getInterface()) {
362 if (ObjCInterfaceDecl *superDef = superDecl->getDefinition())
363 return superDef;
364
365 return superDecl;
366 }
367 }
368
369 return nullptr;
370 }
371
getSuperClassLoc() const372 SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const {
373 if (TypeSourceInfo *superTInfo = getSuperClassTInfo())
374 return superTInfo->getTypeLoc().getBeginLoc();
375
376 return SourceLocation();
377 }
378
379 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
380 /// with name 'PropertyId' in the primary class; including those in protocols
381 /// (direct or indirect) used by the primary class.
FindPropertyVisibleInPrimaryClass(const IdentifierInfo * PropertyId,ObjCPropertyQueryKind QueryKind) const382 ObjCPropertyDecl *ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
383 const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const {
384 // FIXME: Should make sure no callers ever do this.
385 if (!hasDefinition())
386 return nullptr;
387
388 if (data().ExternallyCompleted)
389 LoadExternalDefinition();
390
391 if (ObjCPropertyDecl *PD =
392 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
393 QueryKind))
394 return PD;
395
396 // Look through protocols.
397 for (const auto *I : all_referenced_protocols())
398 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
399 QueryKind))
400 return P;
401
402 return nullptr;
403 }
404
collectPropertiesToImplement(PropertyMap & PM) const405 void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM) const {
406 for (auto *Prop : properties()) {
407 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
408 }
409 for (const auto *Ext : known_extensions()) {
410 const ObjCCategoryDecl *ClassExt = Ext;
411 for (auto *Prop : ClassExt->properties()) {
412 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
413 }
414 }
415 for (const auto *PI : all_referenced_protocols())
416 PI->collectPropertiesToImplement(PM);
417 // Note, the properties declared only in class extensions are still copied
418 // into the main @interface's property list, and therefore we don't
419 // explicitly, have to search class extension properties.
420 }
421
isArcWeakrefUnavailable() const422 bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {
423 const ObjCInterfaceDecl *Class = this;
424 while (Class) {
425 if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
426 return true;
427 Class = Class->getSuperClass();
428 }
429 return false;
430 }
431
isObjCRequiresPropertyDefs() const432 const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
433 const ObjCInterfaceDecl *Class = this;
434 while (Class) {
435 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
436 return Class;
437 Class = Class->getSuperClass();
438 }
439 return nullptr;
440 }
441
mergeClassExtensionProtocolList(ObjCProtocolDecl * const * ExtList,unsigned ExtNum,ASTContext & C)442 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
443 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
444 ASTContext &C) {
445 if (data().ExternallyCompleted)
446 LoadExternalDefinition();
447
448 if (data().AllReferencedProtocols.empty() &&
449 data().ReferencedProtocols.empty()) {
450 data().AllReferencedProtocols.set(ExtList, ExtNum, C);
451 return;
452 }
453
454 // Check for duplicate protocol in class's protocol list.
455 // This is O(n*m). But it is extremely rare and number of protocols in
456 // class or its extension are very few.
457 SmallVector<ObjCProtocolDecl *, 8> ProtocolRefs;
458 for (unsigned i = 0; i < ExtNum; i++) {
459 bool protocolExists = false;
460 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
461 for (auto *Proto : all_referenced_protocols()) {
462 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
463 protocolExists = true;
464 break;
465 }
466 }
467 // Do we want to warn on a protocol in extension class which
468 // already exist in the class? Probably not.
469 if (!protocolExists)
470 ProtocolRefs.push_back(ProtoInExtension);
471 }
472
473 if (ProtocolRefs.empty())
474 return;
475
476 // Merge ProtocolRefs into class's protocol list;
477 ProtocolRefs.append(all_referenced_protocol_begin(),
478 all_referenced_protocol_end());
479
480 data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
481 }
482
483 const ObjCInterfaceDecl *
findInterfaceWithDesignatedInitializers() const484 ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
485 const ObjCInterfaceDecl *IFace = this;
486 while (IFace) {
487 if (IFace->hasDesignatedInitializers())
488 return IFace;
489 if (!IFace->inheritsDesignatedInitializers())
490 break;
491 IFace = IFace->getSuperClass();
492 }
493 return nullptr;
494 }
495
isIntroducingInitializers(const ObjCInterfaceDecl * D)496 static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {
497 for (const auto *MD : D->instance_methods()) {
498 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
499 return true;
500 }
501 for (const auto *Ext : D->visible_extensions()) {
502 for (const auto *MD : Ext->instance_methods()) {
503 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
504 return true;
505 }
506 }
507 if (const auto *ImplD = D->getImplementation()) {
508 for (const auto *MD : ImplD->instance_methods()) {
509 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
510 return true;
511 }
512 }
513 return false;
514 }
515
inheritsDesignatedInitializers() const516 bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
517 switch (data().InheritedDesignatedInitializers) {
518 case DefinitionData::IDI_Inherited:
519 return true;
520 case DefinitionData::IDI_NotInherited:
521 return false;
522 case DefinitionData::IDI_Unknown:
523 // If the class introduced initializers we conservatively assume that we
524 // don't know if any of them is a designated initializer to avoid possible
525 // misleading warnings.
526 if (isIntroducingInitializers(this)) {
527 data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
528 } else {
529 if (auto SuperD = getSuperClass()) {
530 data().InheritedDesignatedInitializers =
531 SuperD->declaresOrInheritsDesignatedInitializers() ?
532 DefinitionData::IDI_Inherited :
533 DefinitionData::IDI_NotInherited;
534 } else {
535 data().InheritedDesignatedInitializers =
536 DefinitionData::IDI_NotInherited;
537 }
538 }
539 assert(data().InheritedDesignatedInitializers
540 != DefinitionData::IDI_Unknown);
541 return data().InheritedDesignatedInitializers ==
542 DefinitionData::IDI_Inherited;
543 }
544
545 llvm_unreachable("unexpected InheritedDesignatedInitializers value");
546 }
547
getDesignatedInitializers(llvm::SmallVectorImpl<const ObjCMethodDecl * > & Methods) const548 void ObjCInterfaceDecl::getDesignatedInitializers(
549 llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
550 // Check for a complete definition and recover if not so.
551 if (!isThisDeclarationADefinition())
552 return;
553 if (data().ExternallyCompleted)
554 LoadExternalDefinition();
555
556 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
557 if (!IFace)
558 return;
559
560 for (const auto *MD : IFace->instance_methods())
561 if (MD->isThisDeclarationADesignatedInitializer())
562 Methods.push_back(MD);
563 for (const auto *Ext : IFace->visible_extensions()) {
564 for (const auto *MD : Ext->instance_methods())
565 if (MD->isThisDeclarationADesignatedInitializer())
566 Methods.push_back(MD);
567 }
568 }
569
isDesignatedInitializer(Selector Sel,const ObjCMethodDecl ** InitMethod) const570 bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
571 const ObjCMethodDecl **InitMethod) const {
572 bool HasCompleteDef = isThisDeclarationADefinition();
573 // During deserialization the data record for the ObjCInterfaceDecl could
574 // be made invariant by reusing the canonical decl. Take this into account
575 // when checking for the complete definition.
576 if (!HasCompleteDef && getCanonicalDecl()->hasDefinition() &&
577 getCanonicalDecl()->getDefinition() == getDefinition())
578 HasCompleteDef = true;
579
580 // Check for a complete definition and recover if not so.
581 if (!HasCompleteDef)
582 return false;
583
584 if (data().ExternallyCompleted)
585 LoadExternalDefinition();
586
587 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
588 if (!IFace)
589 return false;
590
591 if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
592 if (MD->isThisDeclarationADesignatedInitializer()) {
593 if (InitMethod)
594 *InitMethod = MD;
595 return true;
596 }
597 }
598 for (const auto *Ext : IFace->visible_extensions()) {
599 if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
600 if (MD->isThisDeclarationADesignatedInitializer()) {
601 if (InitMethod)
602 *InitMethod = MD;
603 return true;
604 }
605 }
606 }
607 return false;
608 }
609
allocateDefinitionData()610 void ObjCInterfaceDecl::allocateDefinitionData() {
611 assert(!hasDefinition() && "ObjC class already has a definition");
612 Data.setPointer(new (getASTContext()) DefinitionData());
613 Data.getPointer()->Definition = this;
614 }
615
startDefinition()616 void ObjCInterfaceDecl::startDefinition() {
617 allocateDefinitionData();
618
619 // Update all of the declarations with a pointer to the definition.
620 for (auto *RD : redecls()) {
621 if (RD != this)
622 RD->Data = Data;
623 }
624 }
625
startDuplicateDefinitionForComparison()626 void ObjCInterfaceDecl::startDuplicateDefinitionForComparison() {
627 Data.setPointer(nullptr);
628 allocateDefinitionData();
629 // Don't propagate data to other redeclarations.
630 }
631
mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl * Definition)632 void ObjCInterfaceDecl::mergeDuplicateDefinitionWithCommon(
633 const ObjCInterfaceDecl *Definition) {
634 Data = Definition->Data;
635 }
636
lookupInstanceVariable(IdentifierInfo * ID,ObjCInterfaceDecl * & clsDeclared)637 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
638 ObjCInterfaceDecl *&clsDeclared) {
639 // FIXME: Should make sure no callers ever do this.
640 if (!hasDefinition())
641 return nullptr;
642
643 if (data().ExternallyCompleted)
644 LoadExternalDefinition();
645
646 ObjCInterfaceDecl* ClassDecl = this;
647 while (ClassDecl != nullptr) {
648 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
649 clsDeclared = ClassDecl;
650 return I;
651 }
652
653 for (const auto *Ext : ClassDecl->visible_extensions()) {
654 if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
655 clsDeclared = ClassDecl;
656 return I;
657 }
658 }
659
660 ClassDecl = ClassDecl->getSuperClass();
661 }
662 return nullptr;
663 }
664
665 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
666 /// class whose name is passed as argument. If it is not one of the super classes
667 /// the it returns NULL.
lookupInheritedClass(const IdentifierInfo * ICName)668 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
669 const IdentifierInfo*ICName) {
670 // FIXME: Should make sure no callers ever do this.
671 if (!hasDefinition())
672 return nullptr;
673
674 if (data().ExternallyCompleted)
675 LoadExternalDefinition();
676
677 ObjCInterfaceDecl* ClassDecl = this;
678 while (ClassDecl != nullptr) {
679 if (ClassDecl->getIdentifier() == ICName)
680 return ClassDecl;
681 ClassDecl = ClassDecl->getSuperClass();
682 }
683 return nullptr;
684 }
685
686 ObjCProtocolDecl *
lookupNestedProtocol(IdentifierInfo * Name)687 ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
688 for (auto *P : all_referenced_protocols())
689 if (P->lookupProtocolNamed(Name))
690 return P;
691 ObjCInterfaceDecl *SuperClass = getSuperClass();
692 return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
693 }
694
695 /// lookupMethod - This method returns an instance/class method by looking in
696 /// the class, its categories, and its super classes (using a linear search).
697 /// When argument category "C" is specified, any implicit method found
698 /// in this category is ignored.
lookupMethod(Selector Sel,bool isInstance,bool shallowCategoryLookup,bool followSuper,const ObjCCategoryDecl * C) const699 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
700 bool isInstance,
701 bool shallowCategoryLookup,
702 bool followSuper,
703 const ObjCCategoryDecl *C) const
704 {
705 // FIXME: Should make sure no callers ever do this.
706 if (!hasDefinition())
707 return nullptr;
708
709 const ObjCInterfaceDecl* ClassDecl = this;
710 ObjCMethodDecl *MethodDecl = nullptr;
711
712 if (data().ExternallyCompleted)
713 LoadExternalDefinition();
714
715 while (ClassDecl) {
716 // 1. Look through primary class.
717 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
718 return MethodDecl;
719
720 // 2. Didn't find one yet - now look through categories.
721 for (const auto *Cat : ClassDecl->visible_categories())
722 if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
723 if (C != Cat || !MethodDecl->isImplicit())
724 return MethodDecl;
725
726 // 3. Didn't find one yet - look through primary class's protocols.
727 for (const auto *I : ClassDecl->protocols())
728 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
729 return MethodDecl;
730
731 // 4. Didn't find one yet - now look through categories' protocols
732 if (!shallowCategoryLookup)
733 for (const auto *Cat : ClassDecl->visible_categories()) {
734 // Didn't find one yet - look through protocols.
735 const ObjCList<ObjCProtocolDecl> &Protocols =
736 Cat->getReferencedProtocols();
737 for (auto *Protocol : Protocols)
738 if ((MethodDecl = Protocol->lookupMethod(Sel, isInstance)))
739 if (C != Cat || !MethodDecl->isImplicit())
740 return MethodDecl;
741 }
742
743
744 if (!followSuper)
745 return nullptr;
746
747 // 5. Get to the super class (if any).
748 ClassDecl = ClassDecl->getSuperClass();
749 }
750 return nullptr;
751 }
752
753 // Will search "local" class/category implementations for a method decl.
754 // If failed, then we search in class's root for an instance method.
755 // Returns 0 if no method is found.
lookupPrivateMethod(const Selector & Sel,bool Instance) const756 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
757 const Selector &Sel,
758 bool Instance) const {
759 // FIXME: Should make sure no callers ever do this.
760 if (!hasDefinition())
761 return nullptr;
762
763 if (data().ExternallyCompleted)
764 LoadExternalDefinition();
765
766 ObjCMethodDecl *Method = nullptr;
767 if (ObjCImplementationDecl *ImpDecl = getImplementation())
768 Method = Instance ? ImpDecl->getInstanceMethod(Sel)
769 : ImpDecl->getClassMethod(Sel);
770
771 // Look through local category implementations associated with the class.
772 if (!Method)
773 Method = getCategoryMethod(Sel, Instance);
774
775 // Before we give up, check if the selector is an instance method.
776 // But only in the root. This matches gcc's behavior and what the
777 // runtime expects.
778 if (!Instance && !Method && !getSuperClass()) {
779 Method = lookupInstanceMethod(Sel);
780 // Look through local category implementations associated
781 // with the root class.
782 if (!Method)
783 Method = lookupPrivateMethod(Sel, true);
784 }
785
786 if (!Method && getSuperClass())
787 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
788 return Method;
789 }
790
getODRHash()791 unsigned ObjCInterfaceDecl::getODRHash() {
792 assert(hasDefinition() && "ODRHash only for records with definitions");
793
794 // Previously calculated hash is stored in DefinitionData.
795 if (hasODRHash())
796 return data().ODRHash;
797
798 // Only calculate hash on first call of getODRHash per record.
799 ODRHash Hasher;
800 Hasher.AddObjCInterfaceDecl(getDefinition());
801 data().ODRHash = Hasher.CalculateHash();
802 setHasODRHash(true);
803
804 return data().ODRHash;
805 }
806
hasODRHash() const807 bool ObjCInterfaceDecl::hasODRHash() const {
808 if (!hasDefinition())
809 return false;
810 return data().HasODRHash;
811 }
812
setHasODRHash(bool HasHash)813 void ObjCInterfaceDecl::setHasODRHash(bool HasHash) {
814 assert(hasDefinition() && "Cannot set ODRHash without definition");
815 data().HasODRHash = HasHash;
816 }
817
818 //===----------------------------------------------------------------------===//
819 // ObjCMethodDecl
820 //===----------------------------------------------------------------------===//
821
ObjCMethodDecl(SourceLocation beginLoc,SourceLocation endLoc,Selector SelInfo,QualType T,TypeSourceInfo * ReturnTInfo,DeclContext * contextDecl,bool isInstance,bool isVariadic,bool isPropertyAccessor,bool isSynthesizedAccessorStub,bool isImplicitlyDeclared,bool isDefined,ObjCImplementationControl impControl,bool HasRelatedResultType)822 ObjCMethodDecl::ObjCMethodDecl(
823 SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo,
824 QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl,
825 bool isInstance, bool isVariadic, bool isPropertyAccessor,
826 bool isSynthesizedAccessorStub, bool isImplicitlyDeclared, bool isDefined,
827 ObjCImplementationControl impControl, bool HasRelatedResultType)
828 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
829 DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),
830 DeclEndLoc(endLoc) {
831
832 // Initialized the bits stored in DeclContext.
833 ObjCMethodDeclBits.Family =
834 static_cast<ObjCMethodFamily>(InvalidObjCMethodFamily);
835 setInstanceMethod(isInstance);
836 setVariadic(isVariadic);
837 setPropertyAccessor(isPropertyAccessor);
838 setSynthesizedAccessorStub(isSynthesizedAccessorStub);
839 setDefined(isDefined);
840 setIsRedeclaration(false);
841 setHasRedeclaration(false);
842 setDeclImplementation(impControl);
843 setObjCDeclQualifier(OBJC_TQ_None);
844 setRelatedResultType(HasRelatedResultType);
845 setSelLocsKind(SelLoc_StandardNoSpace);
846 setOverriding(false);
847 setHasSkippedBody(false);
848
849 setImplicit(isImplicitlyDeclared);
850 }
851
Create(ASTContext & C,SourceLocation beginLoc,SourceLocation endLoc,Selector SelInfo,QualType T,TypeSourceInfo * ReturnTInfo,DeclContext * contextDecl,bool isInstance,bool isVariadic,bool isPropertyAccessor,bool isSynthesizedAccessorStub,bool isImplicitlyDeclared,bool isDefined,ObjCImplementationControl impControl,bool HasRelatedResultType)852 ObjCMethodDecl *ObjCMethodDecl::Create(
853 ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
854 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
855 DeclContext *contextDecl, bool isInstance, bool isVariadic,
856 bool isPropertyAccessor, bool isSynthesizedAccessorStub,
857 bool isImplicitlyDeclared, bool isDefined,
858 ObjCImplementationControl impControl, bool HasRelatedResultType) {
859 return new (C, contextDecl) ObjCMethodDecl(
860 beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
861 isVariadic, isPropertyAccessor, isSynthesizedAccessorStub,
862 isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);
863 }
864
CreateDeserialized(ASTContext & C,GlobalDeclID ID)865 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C,
866 GlobalDeclID ID) {
867 return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
868 Selector(), QualType(), nullptr, nullptr);
869 }
870
isDirectMethod() const871 bool ObjCMethodDecl::isDirectMethod() const {
872 return hasAttr<ObjCDirectAttr>() &&
873 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
874 }
875
isThisDeclarationADesignatedInitializer() const876 bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
877 return getMethodFamily() == OMF_init &&
878 hasAttr<ObjCDesignatedInitializerAttr>();
879 }
880
definedInNSObject(const ASTContext & Ctx) const881 bool ObjCMethodDecl::definedInNSObject(const ASTContext &Ctx) const {
882 if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext()))
883 return PD->getIdentifier() == Ctx.getNSObjectName();
884 if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext()))
885 return ID->getIdentifier() == Ctx.getNSObjectName();
886 return false;
887 }
888
isDesignatedInitializerForTheInterface(const ObjCMethodDecl ** InitMethod) const889 bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
890 const ObjCMethodDecl **InitMethod) const {
891 if (getMethodFamily() != OMF_init)
892 return false;
893 const DeclContext *DC = getDeclContext();
894 if (isa<ObjCProtocolDecl>(DC))
895 return false;
896 if (const ObjCInterfaceDecl *ID = getClassInterface())
897 return ID->isDesignatedInitializer(getSelector(), InitMethod);
898 return false;
899 }
900
hasParamDestroyedInCallee() const901 bool ObjCMethodDecl::hasParamDestroyedInCallee() const {
902 for (auto *param : parameters()) {
903 if (param->isDestroyedInCallee())
904 return true;
905 }
906 return false;
907 }
908
getBody() const909 Stmt *ObjCMethodDecl::getBody() const {
910 return Body.get(getASTContext().getExternalSource());
911 }
912
setAsRedeclaration(const ObjCMethodDecl * PrevMethod)913 void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
914 assert(PrevMethod);
915 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
916 setIsRedeclaration(true);
917 PrevMethod->setHasRedeclaration(true);
918 }
919
setParamsAndSelLocs(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)920 void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
921 ArrayRef<ParmVarDecl*> Params,
922 ArrayRef<SourceLocation> SelLocs) {
923 ParamsAndSelLocs = nullptr;
924 NumParams = Params.size();
925 if (Params.empty() && SelLocs.empty())
926 return;
927
928 static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation),
929 "Alignment not sufficient for SourceLocation");
930
931 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
932 sizeof(SourceLocation) * SelLocs.size();
933 ParamsAndSelLocs = C.Allocate(Size);
934 std::uninitialized_copy(Params.begin(), Params.end(), getParams());
935 std::uninitialized_copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
936 }
937
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const938 void ObjCMethodDecl::getSelectorLocs(
939 SmallVectorImpl<SourceLocation> &SelLocs) const {
940 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
941 SelLocs.push_back(getSelectorLoc(i));
942 }
943
setMethodParams(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)944 void ObjCMethodDecl::setMethodParams(ASTContext &C,
945 ArrayRef<ParmVarDecl*> Params,
946 ArrayRef<SourceLocation> SelLocs) {
947 assert((!SelLocs.empty() || isImplicit()) &&
948 "No selector locs for non-implicit method");
949 if (isImplicit())
950 return setParamsAndSelLocs(C, Params, std::nullopt);
951
952 setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params,
953 DeclEndLoc));
954 if (getSelLocsKind() != SelLoc_NonStandard)
955 return setParamsAndSelLocs(C, Params, std::nullopt);
956
957 setParamsAndSelLocs(C, Params, SelLocs);
958 }
959
960 /// A definition will return its interface declaration.
961 /// An interface declaration will return its definition.
962 /// Otherwise it will return itself.
getNextRedeclarationImpl()963 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
964 ASTContext &Ctx = getASTContext();
965 ObjCMethodDecl *Redecl = nullptr;
966 if (hasRedeclaration())
967 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
968 if (Redecl)
969 return Redecl;
970
971 auto *CtxD = cast<Decl>(getDeclContext());
972
973 if (!CtxD->isInvalidDecl()) {
974 if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
975 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
976 if (!ImplD->isInvalidDecl())
977 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
978
979 } else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
980 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
981 if (!ImplD->isInvalidDecl())
982 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
983
984 } else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
985 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
986 if (!IFD->isInvalidDecl())
987 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
988
989 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
990 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
991 if (!CatD->isInvalidDecl())
992 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
993 }
994 }
995
996 // Ensure that the discovered method redeclaration has a valid declaration
997 // context. Used to prevent infinite loops when iterating redeclarations in
998 // a partially invalid AST.
999 if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl())
1000 Redecl = nullptr;
1001
1002 if (!Redecl && isRedeclaration()) {
1003 // This is the last redeclaration, go back to the first method.
1004 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
1005 isInstanceMethod(),
1006 /*AllowHidden=*/true);
1007 }
1008
1009 return Redecl ? Redecl : this;
1010 }
1011
getCanonicalDecl()1012 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
1013 auto *CtxD = cast<Decl>(getDeclContext());
1014 const auto &Sel = getSelector();
1015
1016 if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
1017 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) {
1018 // When the container is the ObjCImplementationDecl (the primary
1019 // @implementation), then the canonical Decl is either in
1020 // the class Interface, or in any of its extension.
1021 //
1022 // So when we don't find it in the ObjCInterfaceDecl,
1023 // sift through extensions too.
1024 if (ObjCMethodDecl *MD = IFD->getMethod(Sel, isInstanceMethod()))
1025 return MD;
1026 for (auto *Ext : IFD->known_extensions())
1027 if (ObjCMethodDecl *MD = Ext->getMethod(Sel, isInstanceMethod()))
1028 return MD;
1029 }
1030 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
1031 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
1032 if (ObjCMethodDecl *MD = CatD->getMethod(Sel, isInstanceMethod()))
1033 return MD;
1034 }
1035
1036 if (isRedeclaration()) {
1037 // It is possible that we have not done deserializing the ObjCMethod yet.
1038 ObjCMethodDecl *MD =
1039 cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
1040 /*AllowHidden=*/true);
1041 return MD ? MD : this;
1042 }
1043
1044 return this;
1045 }
1046
getEndLoc() const1047 SourceLocation ObjCMethodDecl::getEndLoc() const {
1048 if (Stmt *Body = getBody())
1049 return Body->getEndLoc();
1050 return DeclEndLoc;
1051 }
1052
getMethodFamily() const1053 ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
1054 auto family = static_cast<ObjCMethodFamily>(ObjCMethodDeclBits.Family);
1055 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
1056 return family;
1057
1058 // Check for an explicit attribute.
1059 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
1060 // The unfortunate necessity of mapping between enums here is due
1061 // to the attributes framework.
1062 switch (attr->getFamily()) {
1063 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
1064 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
1065 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
1066 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
1067 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
1068 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
1069 }
1070 ObjCMethodDeclBits.Family = family;
1071 return family;
1072 }
1073
1074 family = getSelector().getMethodFamily();
1075 switch (family) {
1076 case OMF_None: break;
1077
1078 // init only has a conventional meaning for an instance method, and
1079 // it has to return an object.
1080 case OMF_init:
1081 if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
1082 family = OMF_None;
1083 break;
1084
1085 // alloc/copy/new have a conventional meaning for both class and
1086 // instance methods, but they require an object return.
1087 case OMF_alloc:
1088 case OMF_copy:
1089 case OMF_mutableCopy:
1090 case OMF_new:
1091 if (!getReturnType()->isObjCObjectPointerType())
1092 family = OMF_None;
1093 break;
1094
1095 // These selectors have a conventional meaning only for instance methods.
1096 case OMF_dealloc:
1097 case OMF_finalize:
1098 case OMF_retain:
1099 case OMF_release:
1100 case OMF_autorelease:
1101 case OMF_retainCount:
1102 case OMF_self:
1103 if (!isInstanceMethod())
1104 family = OMF_None;
1105 break;
1106
1107 case OMF_initialize:
1108 if (isInstanceMethod() || !getReturnType()->isVoidType())
1109 family = OMF_None;
1110 break;
1111
1112 case OMF_performSelector:
1113 if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
1114 family = OMF_None;
1115 else {
1116 unsigned noParams = param_size();
1117 if (noParams < 1 || noParams > 3)
1118 family = OMF_None;
1119 else {
1120 ObjCMethodDecl::param_type_iterator it = param_type_begin();
1121 QualType ArgT = (*it);
1122 if (!ArgT->isObjCSelType()) {
1123 family = OMF_None;
1124 break;
1125 }
1126 while (--noParams) {
1127 it++;
1128 ArgT = (*it);
1129 if (!ArgT->isObjCIdType()) {
1130 family = OMF_None;
1131 break;
1132 }
1133 }
1134 }
1135 }
1136 break;
1137
1138 }
1139
1140 // Cache the result.
1141 ObjCMethodDeclBits.Family = family;
1142 return family;
1143 }
1144
getSelfType(ASTContext & Context,const ObjCInterfaceDecl * OID,bool & selfIsPseudoStrong,bool & selfIsConsumed) const1145 QualType ObjCMethodDecl::getSelfType(ASTContext &Context,
1146 const ObjCInterfaceDecl *OID,
1147 bool &selfIsPseudoStrong,
1148 bool &selfIsConsumed) const {
1149 QualType selfTy;
1150 selfIsPseudoStrong = false;
1151 selfIsConsumed = false;
1152 if (isInstanceMethod()) {
1153 // There may be no interface context due to error in declaration
1154 // of the interface (which has been reported). Recover gracefully.
1155 if (OID) {
1156 selfTy = Context.getObjCInterfaceType(OID);
1157 selfTy = Context.getObjCObjectPointerType(selfTy);
1158 } else {
1159 selfTy = Context.getObjCIdType();
1160 }
1161 } else // we have a factory method.
1162 selfTy = Context.getObjCClassType();
1163
1164 if (Context.getLangOpts().ObjCAutoRefCount) {
1165 if (isInstanceMethod()) {
1166 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
1167
1168 // 'self' is always __strong. It's actually pseudo-strong except
1169 // in init methods (or methods labeled ns_consumes_self), though.
1170 Qualifiers qs;
1171 qs.setObjCLifetime(Qualifiers::OCL_Strong);
1172 selfTy = Context.getQualifiedType(selfTy, qs);
1173
1174 // In addition, 'self' is const unless this is an init method.
1175 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
1176 selfTy = selfTy.withConst();
1177 selfIsPseudoStrong = true;
1178 }
1179 }
1180 else {
1181 assert(isClassMethod());
1182 // 'self' is always const in class methods.
1183 selfTy = selfTy.withConst();
1184 selfIsPseudoStrong = true;
1185 }
1186 }
1187 return selfTy;
1188 }
1189
createImplicitParams(ASTContext & Context,const ObjCInterfaceDecl * OID)1190 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
1191 const ObjCInterfaceDecl *OID) {
1192 bool selfIsPseudoStrong, selfIsConsumed;
1193 QualType selfTy =
1194 getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
1195 auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),
1196 &Context.Idents.get("self"), selfTy,
1197 ImplicitParamKind::ObjCSelf);
1198 setSelfDecl(Self);
1199
1200 if (selfIsConsumed)
1201 Self->addAttr(NSConsumedAttr::CreateImplicit(Context));
1202
1203 if (selfIsPseudoStrong)
1204 Self->setARCPseudoStrong(true);
1205
1206 setCmdDecl(ImplicitParamDecl::Create(
1207 Context, this, SourceLocation(), &Context.Idents.get("_cmd"),
1208 Context.getObjCSelType(), ImplicitParamKind::ObjCCmd));
1209 }
1210
getClassInterface()1211 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
1212 if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
1213 return ID;
1214 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1215 return CD->getClassInterface();
1216 if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
1217 return IMD->getClassInterface();
1218 if (isa<ObjCProtocolDecl>(getDeclContext()))
1219 return nullptr;
1220 llvm_unreachable("unknown method context");
1221 }
1222
getCategory()1223 ObjCCategoryDecl *ObjCMethodDecl::getCategory() {
1224 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1225 return CD;
1226 if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
1227 return IMD->getCategoryDecl();
1228 return nullptr;
1229 }
1230
getReturnTypeSourceRange() const1231 SourceRange ObjCMethodDecl::getReturnTypeSourceRange() const {
1232 const auto *TSI = getReturnTypeSourceInfo();
1233 if (TSI)
1234 return TSI->getTypeLoc().getSourceRange();
1235 return SourceRange();
1236 }
1237
getSendResultType() const1238 QualType ObjCMethodDecl::getSendResultType() const {
1239 ASTContext &Ctx = getASTContext();
1240 return getReturnType().getNonLValueExprType(Ctx)
1241 .substObjCTypeArgs(Ctx, {}, ObjCSubstitutionContext::Result);
1242 }
1243
getSendResultType(QualType receiverType) const1244 QualType ObjCMethodDecl::getSendResultType(QualType receiverType) const {
1245 // FIXME: Handle related result types here.
1246
1247 return getReturnType().getNonLValueExprType(getASTContext())
1248 .substObjCMemberType(receiverType, getDeclContext(),
1249 ObjCSubstitutionContext::Result);
1250 }
1251
CollectOverriddenMethodsRecurse(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods,bool MovedToSuper)1252 static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
1253 const ObjCMethodDecl *Method,
1254 SmallVectorImpl<const ObjCMethodDecl *> &Methods,
1255 bool MovedToSuper) {
1256 if (!Container)
1257 return;
1258
1259 // In categories look for overridden methods from protocols. A method from
1260 // category is not "overridden" since it is considered as the "same" method
1261 // (same USR) as the one from the interface.
1262 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1263 // Check whether we have a matching method at this category but only if we
1264 // are at the super class level.
1265 if (MovedToSuper)
1266 if (ObjCMethodDecl *
1267 Overridden = Container->getMethod(Method->getSelector(),
1268 Method->isInstanceMethod(),
1269 /*AllowHidden=*/true))
1270 if (Method != Overridden) {
1271 // We found an override at this category; there is no need to look
1272 // into its protocols.
1273 Methods.push_back(Overridden);
1274 return;
1275 }
1276
1277 for (const auto *P : Category->protocols())
1278 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1279 return;
1280 }
1281
1282 // Check whether we have a matching method at this level.
1283 if (const ObjCMethodDecl *
1284 Overridden = Container->getMethod(Method->getSelector(),
1285 Method->isInstanceMethod(),
1286 /*AllowHidden=*/true))
1287 if (Method != Overridden) {
1288 // We found an override at this level; there is no need to look
1289 // into other protocols or categories.
1290 Methods.push_back(Overridden);
1291 return;
1292 }
1293
1294 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
1295 for (const auto *P : Protocol->protocols())
1296 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1297 }
1298
1299 if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
1300 for (const auto *P : Interface->protocols())
1301 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1302
1303 for (const auto *Cat : Interface->known_categories())
1304 CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
1305
1306 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
1307 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
1308 /*MovedToSuper=*/true);
1309 }
1310 }
1311
CollectOverriddenMethods(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)1312 static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
1313 const ObjCMethodDecl *Method,
1314 SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
1315 CollectOverriddenMethodsRecurse(Container, Method, Methods,
1316 /*MovedToSuper=*/false);
1317 }
1318
collectOverriddenMethodsSlow(const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & overridden)1319 static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
1320 SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
1321 assert(Method->isOverriding());
1322
1323 if (const auto *ProtD =
1324 dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1325 CollectOverriddenMethods(ProtD, Method, overridden);
1326
1327 } else if (const auto *IMD =
1328 dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1329 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1330 if (!ID)
1331 return;
1332 // Start searching for overridden methods using the method from the
1333 // interface as starting point.
1334 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1335 Method->isInstanceMethod(),
1336 /*AllowHidden=*/true))
1337 Method = IFaceMeth;
1338 CollectOverriddenMethods(ID, Method, overridden);
1339
1340 } else if (const auto *CatD =
1341 dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1342 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1343 if (!ID)
1344 return;
1345 // Start searching for overridden methods using the method from the
1346 // interface as starting point.
1347 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1348 Method->isInstanceMethod(),
1349 /*AllowHidden=*/true))
1350 Method = IFaceMeth;
1351 CollectOverriddenMethods(ID, Method, overridden);
1352
1353 } else {
1354 CollectOverriddenMethods(
1355 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1356 Method, overridden);
1357 }
1358 }
1359
getOverriddenMethods(SmallVectorImpl<const ObjCMethodDecl * > & Overridden) const1360 void ObjCMethodDecl::getOverriddenMethods(
1361 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1362 const ObjCMethodDecl *Method = this;
1363
1364 if (Method->isRedeclaration()) {
1365 Method = cast<ObjCContainerDecl>(Method->getDeclContext())
1366 ->getMethod(Method->getSelector(), Method->isInstanceMethod(),
1367 /*AllowHidden=*/true);
1368 }
1369
1370 if (Method->isOverriding()) {
1371 collectOverriddenMethodsSlow(Method, Overridden);
1372 assert(!Overridden.empty() &&
1373 "ObjCMethodDecl's overriding bit is not as expected");
1374 }
1375 }
1376
1377 const ObjCPropertyDecl *
findPropertyDecl(bool CheckOverrides) const1378 ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
1379 Selector Sel = getSelector();
1380 unsigned NumArgs = Sel.getNumArgs();
1381 if (NumArgs > 1)
1382 return nullptr;
1383
1384 if (isPropertyAccessor()) {
1385 const auto *Container = cast<ObjCContainerDecl>(getParent());
1386 // For accessor stubs, go back to the interface.
1387 if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container))
1388 if (isSynthesizedAccessorStub())
1389 Container = ImplDecl->getClassInterface();
1390
1391 bool IsGetter = (NumArgs == 0);
1392 bool IsInstance = isInstanceMethod();
1393
1394 /// Local function that attempts to find a matching property within the
1395 /// given Objective-C container.
1396 auto findMatchingProperty =
1397 [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
1398 if (IsInstance) {
1399 for (const auto *I : Container->instance_properties()) {
1400 Selector NextSel = IsGetter ? I->getGetterName()
1401 : I->getSetterName();
1402 if (NextSel == Sel)
1403 return I;
1404 }
1405 } else {
1406 for (const auto *I : Container->class_properties()) {
1407 Selector NextSel = IsGetter ? I->getGetterName()
1408 : I->getSetterName();
1409 if (NextSel == Sel)
1410 return I;
1411 }
1412 }
1413
1414 return nullptr;
1415 };
1416
1417 // Look in the container we were given.
1418 if (const auto *Found = findMatchingProperty(Container))
1419 return Found;
1420
1421 // If we're in a category or extension, look in the main class.
1422 const ObjCInterfaceDecl *ClassDecl = nullptr;
1423 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1424 ClassDecl = Category->getClassInterface();
1425 if (const auto *Found = findMatchingProperty(ClassDecl))
1426 return Found;
1427 } else {
1428 // Determine whether the container is a class.
1429 ClassDecl = cast<ObjCInterfaceDecl>(Container);
1430 }
1431 assert(ClassDecl && "Failed to find main class");
1432
1433 // If we have a class, check its visible extensions.
1434 for (const auto *Ext : ClassDecl->visible_extensions()) {
1435 if (Ext == Container)
1436 continue;
1437 if (const auto *Found = findMatchingProperty(Ext))
1438 return Found;
1439 }
1440
1441 assert(isSynthesizedAccessorStub() && "expected an accessor stub");
1442
1443 for (const auto *Cat : ClassDecl->known_categories()) {
1444 if (Cat == Container)
1445 continue;
1446 if (const auto *Found = findMatchingProperty(Cat))
1447 return Found;
1448 }
1449
1450 llvm_unreachable("Marked as a property accessor but no property found!");
1451 }
1452
1453 if (!CheckOverrides)
1454 return nullptr;
1455
1456 using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;
1457
1458 OverridesTy Overrides;
1459 getOverriddenMethods(Overrides);
1460 for (const auto *Override : Overrides)
1461 if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(false))
1462 return Prop;
1463
1464 return nullptr;
1465 }
1466
1467 //===----------------------------------------------------------------------===//
1468 // ObjCTypeParamDecl
1469 //===----------------------------------------------------------------------===//
1470
anchor()1471 void ObjCTypeParamDecl::anchor() {}
1472
Create(ASTContext & ctx,DeclContext * dc,ObjCTypeParamVariance variance,SourceLocation varianceLoc,unsigned index,SourceLocation nameLoc,IdentifierInfo * name,SourceLocation colonLoc,TypeSourceInfo * boundInfo)1473 ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc,
1474 ObjCTypeParamVariance variance,
1475 SourceLocation varianceLoc,
1476 unsigned index,
1477 SourceLocation nameLoc,
1478 IdentifierInfo *name,
1479 SourceLocation colonLoc,
1480 TypeSourceInfo *boundInfo) {
1481 auto *TPDecl =
1482 new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
1483 nameLoc, name, colonLoc, boundInfo);
1484 QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});
1485 TPDecl->setTypeForDecl(TPType.getTypePtr());
1486 return TPDecl;
1487 }
1488
CreateDeserialized(ASTContext & ctx,GlobalDeclID ID)1489 ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx,
1490 GlobalDeclID ID) {
1491 return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,
1492 ObjCTypeParamVariance::Invariant,
1493 SourceLocation(), 0, SourceLocation(),
1494 nullptr, SourceLocation(), nullptr);
1495 }
1496
getSourceRange() const1497 SourceRange ObjCTypeParamDecl::getSourceRange() const {
1498 SourceLocation startLoc = VarianceLoc;
1499 if (startLoc.isInvalid())
1500 startLoc = getLocation();
1501
1502 if (hasExplicitBound()) {
1503 return SourceRange(startLoc,
1504 getTypeSourceInfo()->getTypeLoc().getEndLoc());
1505 }
1506
1507 return SourceRange(startLoc);
1508 }
1509
1510 //===----------------------------------------------------------------------===//
1511 // ObjCTypeParamList
1512 //===----------------------------------------------------------------------===//
ObjCTypeParamList(SourceLocation lAngleLoc,ArrayRef<ObjCTypeParamDecl * > typeParams,SourceLocation rAngleLoc)1513 ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,
1514 ArrayRef<ObjCTypeParamDecl *> typeParams,
1515 SourceLocation rAngleLoc)
1516 : Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) {
1517 std::copy(typeParams.begin(), typeParams.end(), begin());
1518 }
1519
create(ASTContext & ctx,SourceLocation lAngleLoc,ArrayRef<ObjCTypeParamDecl * > typeParams,SourceLocation rAngleLoc)1520 ObjCTypeParamList *ObjCTypeParamList::create(
1521 ASTContext &ctx,
1522 SourceLocation lAngleLoc,
1523 ArrayRef<ObjCTypeParamDecl *> typeParams,
1524 SourceLocation rAngleLoc) {
1525 void *mem =
1526 ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),
1527 alignof(ObjCTypeParamList));
1528 return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
1529 }
1530
gatherDefaultTypeArgs(SmallVectorImpl<QualType> & typeArgs) const1531 void ObjCTypeParamList::gatherDefaultTypeArgs(
1532 SmallVectorImpl<QualType> &typeArgs) const {
1533 typeArgs.reserve(size());
1534 for (auto *typeParam : *this)
1535 typeArgs.push_back(typeParam->getUnderlyingType());
1536 }
1537
1538 //===----------------------------------------------------------------------===//
1539 // ObjCInterfaceDecl
1540 //===----------------------------------------------------------------------===//
1541
Create(const ASTContext & C,DeclContext * DC,SourceLocation atLoc,const IdentifierInfo * Id,ObjCTypeParamList * typeParamList,ObjCInterfaceDecl * PrevDecl,SourceLocation ClassLoc,bool isInternal)1542 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(
1543 const ASTContext &C, DeclContext *DC, SourceLocation atLoc,
1544 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1545 ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal) {
1546 auto *Result = new (C, DC)
1547 ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
1548 isInternal);
1549 Result->Data.setInt(!C.getLangOpts().Modules);
1550 C.getObjCInterfaceType(Result, PrevDecl);
1551 return Result;
1552 }
1553
CreateDeserialized(const ASTContext & C,GlobalDeclID ID)1554 ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
1555 GlobalDeclID ID) {
1556 auto *Result = new (C, ID)
1557 ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,
1558 SourceLocation(), nullptr, false);
1559 Result->Data.setInt(!C.getLangOpts().Modules);
1560 return Result;
1561 }
1562
ObjCInterfaceDecl(const ASTContext & C,DeclContext * DC,SourceLocation AtLoc,const IdentifierInfo * Id,ObjCTypeParamList * typeParamList,SourceLocation CLoc,ObjCInterfaceDecl * PrevDecl,bool IsInternal)1563 ObjCInterfaceDecl::ObjCInterfaceDecl(
1564 const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
1565 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1566 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal)
1567 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
1568 redeclarable_base(C) {
1569 setPreviousDecl(PrevDecl);
1570
1571 // Copy the 'data' pointer over.
1572 if (PrevDecl)
1573 Data = PrevDecl->Data;
1574
1575 setImplicit(IsInternal);
1576
1577 setTypeParamList(typeParamList);
1578 }
1579
LoadExternalDefinition() const1580 void ObjCInterfaceDecl::LoadExternalDefinition() const {
1581 assert(data().ExternallyCompleted && "Class is not externally completed");
1582 data().ExternallyCompleted = false;
1583 getASTContext().getExternalSource()->CompleteType(
1584 const_cast<ObjCInterfaceDecl *>(this));
1585 }
1586
setExternallyCompleted()1587 void ObjCInterfaceDecl::setExternallyCompleted() {
1588 assert(getASTContext().getExternalSource() &&
1589 "Class can't be externally completed without an external source");
1590 assert(hasDefinition() &&
1591 "Forward declarations can't be externally completed");
1592 data().ExternallyCompleted = true;
1593 }
1594
setHasDesignatedInitializers()1595 void ObjCInterfaceDecl::setHasDesignatedInitializers() {
1596 // Check for a complete definition and recover if not so.
1597 if (!isThisDeclarationADefinition())
1598 return;
1599 data().HasDesignatedInitializers = true;
1600 }
1601
hasDesignatedInitializers() const1602 bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
1603 // Check for a complete definition and recover if not so.
1604 if (!isThisDeclarationADefinition())
1605 return false;
1606 if (data().ExternallyCompleted)
1607 LoadExternalDefinition();
1608
1609 return data().HasDesignatedInitializers;
1610 }
1611
1612 StringRef
getObjCRuntimeNameAsString() const1613 ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
1614 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1615 return ObjCRTName->getMetadataName();
1616
1617 return getName();
1618 }
1619
1620 StringRef
getObjCRuntimeNameAsString() const1621 ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
1622 if (ObjCInterfaceDecl *ID =
1623 const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
1624 return ID->getObjCRuntimeNameAsString();
1625
1626 return getName();
1627 }
1628
getImplementation() const1629 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
1630 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1631 if (data().ExternallyCompleted)
1632 LoadExternalDefinition();
1633
1634 return getASTContext().getObjCImplementation(
1635 const_cast<ObjCInterfaceDecl*>(Def));
1636 }
1637
1638 // FIXME: Should make sure no callers ever do this.
1639 return nullptr;
1640 }
1641
setImplementation(ObjCImplementationDecl * ImplD)1642 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
1643 getASTContext().setObjCImplementation(getDefinition(), ImplD);
1644 }
1645
1646 namespace {
1647
1648 struct SynthesizeIvarChunk {
1649 uint64_t Size;
1650 ObjCIvarDecl *Ivar;
1651
SynthesizeIvarChunk__anon43dd50270211::SynthesizeIvarChunk1652 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1653 : Size(size), Ivar(ivar) {}
1654 };
1655
operator <(const SynthesizeIvarChunk & LHS,const SynthesizeIvarChunk & RHS)1656 bool operator<(const SynthesizeIvarChunk & LHS,
1657 const SynthesizeIvarChunk &RHS) {
1658 return LHS.Size < RHS.Size;
1659 }
1660
1661 } // namespace
1662
1663 /// all_declared_ivar_begin - return first ivar declared in this class,
1664 /// its extensions and its implementation. Lazily build the list on first
1665 /// access.
1666 ///
1667 /// Caveat: The list returned by this method reflects the current
1668 /// state of the parser. The cache will be updated for every ivar
1669 /// added by an extension or the implementation when they are
1670 /// encountered.
1671 /// See also ObjCIvarDecl::Create().
all_declared_ivar_begin()1672 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
1673 // FIXME: Should make sure no callers ever do this.
1674 if (!hasDefinition())
1675 return nullptr;
1676
1677 ObjCIvarDecl *curIvar = nullptr;
1678 if (!data().IvarList) {
1679 // Force ivar deserialization upfront, before building IvarList.
1680 (void)ivar_empty();
1681 for (const auto *Ext : known_extensions()) {
1682 (void)Ext->ivar_empty();
1683 }
1684 if (!ivar_empty()) {
1685 ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
1686 data().IvarList = *I; ++I;
1687 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1688 curIvar->setNextIvar(*I);
1689 }
1690
1691 for (const auto *Ext : known_extensions()) {
1692 if (!Ext->ivar_empty()) {
1693 ObjCCategoryDecl::ivar_iterator
1694 I = Ext->ivar_begin(),
1695 E = Ext->ivar_end();
1696 if (!data().IvarList) {
1697 data().IvarList = *I; ++I;
1698 curIvar = data().IvarList;
1699 }
1700 for ( ;I != E; curIvar = *I, ++I)
1701 curIvar->setNextIvar(*I);
1702 }
1703 }
1704 data().IvarListMissingImplementation = true;
1705 }
1706
1707 // cached and complete!
1708 if (!data().IvarListMissingImplementation)
1709 return data().IvarList;
1710
1711 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1712 data().IvarListMissingImplementation = false;
1713 if (!ImplDecl->ivar_empty()) {
1714 SmallVector<SynthesizeIvarChunk, 16> layout;
1715 for (auto *IV : ImplDecl->ivars()) {
1716 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1717 layout.push_back(SynthesizeIvarChunk(
1718 IV->getASTContext().getTypeSize(IV->getType()), IV));
1719 continue;
1720 }
1721 if (!data().IvarList)
1722 data().IvarList = IV;
1723 else
1724 curIvar->setNextIvar(IV);
1725 curIvar = IV;
1726 }
1727
1728 if (!layout.empty()) {
1729 // Order synthesized ivars by their size.
1730 llvm::stable_sort(layout);
1731 unsigned Ix = 0, EIx = layout.size();
1732 if (!data().IvarList) {
1733 data().IvarList = layout[0].Ivar; Ix++;
1734 curIvar = data().IvarList;
1735 }
1736 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1737 curIvar->setNextIvar(layout[Ix].Ivar);
1738 }
1739 }
1740 }
1741 return data().IvarList;
1742 }
1743
1744 /// FindCategoryDeclaration - Finds category declaration in the list of
1745 /// categories for this class and returns it. Name of the category is passed
1746 /// in 'CategoryId'. If category not found, return 0;
1747 ///
FindCategoryDeclaration(const IdentifierInfo * CategoryId) const1748 ObjCCategoryDecl *ObjCInterfaceDecl::FindCategoryDeclaration(
1749 const IdentifierInfo *CategoryId) const {
1750 // FIXME: Should make sure no callers ever do this.
1751 if (!hasDefinition())
1752 return nullptr;
1753
1754 if (data().ExternallyCompleted)
1755 LoadExternalDefinition();
1756
1757 for (auto *Cat : visible_categories())
1758 if (Cat->getIdentifier() == CategoryId)
1759 return Cat;
1760
1761 return nullptr;
1762 }
1763
1764 ObjCMethodDecl *
getCategoryInstanceMethod(Selector Sel) const1765 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
1766 for (const auto *Cat : visible_categories()) {
1767 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1768 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1769 return MD;
1770 }
1771
1772 return nullptr;
1773 }
1774
getCategoryClassMethod(Selector Sel) const1775 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
1776 for (const auto *Cat : visible_categories()) {
1777 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1778 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1779 return MD;
1780 }
1781
1782 return nullptr;
1783 }
1784
1785 /// ClassImplementsProtocol - Checks that 'lProto' protocol
1786 /// has been implemented in IDecl class, its super class or categories (if
1787 /// lookupCategory is true).
ClassImplementsProtocol(ObjCProtocolDecl * lProto,bool lookupCategory,bool RHSIsQualifiedID)1788 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1789 bool lookupCategory,
1790 bool RHSIsQualifiedID) {
1791 if (!hasDefinition())
1792 return false;
1793
1794 ObjCInterfaceDecl *IDecl = this;
1795 // 1st, look up the class.
1796 for (auto *PI : IDecl->protocols()){
1797 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1798 return true;
1799 // This is dubious and is added to be compatible with gcc. In gcc, it is
1800 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1801 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1802 // object. This IMO, should be a bug.
1803 // FIXME: Treat this as an extension, and flag this as an error when GCC
1804 // extensions are not enabled.
1805 if (RHSIsQualifiedID &&
1806 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
1807 return true;
1808 }
1809
1810 // 2nd, look up the category.
1811 if (lookupCategory)
1812 for (const auto *Cat : visible_categories()) {
1813 for (auto *PI : Cat->protocols())
1814 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1815 return true;
1816 }
1817
1818 // 3rd, look up the super class(s)
1819 if (IDecl->getSuperClass())
1820 return
1821 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1822 RHSIsQualifiedID);
1823
1824 return false;
1825 }
1826
1827 //===----------------------------------------------------------------------===//
1828 // ObjCIvarDecl
1829 //===----------------------------------------------------------------------===//
1830
anchor()1831 void ObjCIvarDecl::anchor() {}
1832
Create(ASTContext & C,ObjCContainerDecl * DC,SourceLocation StartLoc,SourceLocation IdLoc,const IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,AccessControl ac,Expr * BW,bool synthesized)1833 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
1834 SourceLocation StartLoc,
1835 SourceLocation IdLoc,
1836 const IdentifierInfo *Id, QualType T,
1837 TypeSourceInfo *TInfo, AccessControl ac,
1838 Expr *BW, bool synthesized) {
1839 if (DC) {
1840 // Ivar's can only appear in interfaces, implementations (via synthesized
1841 // properties), and class extensions (via direct declaration, or synthesized
1842 // properties).
1843 //
1844 // FIXME: This should really be asserting this:
1845 // (isa<ObjCCategoryDecl>(DC) &&
1846 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1847 // but unfortunately we sometimes place ivars into non-class extension
1848 // categories on error. This breaks an AST invariant, and should not be
1849 // fixed.
1850 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1851 isa<ObjCCategoryDecl>(DC)) &&
1852 "Invalid ivar decl context!");
1853 // Once a new ivar is created in any of class/class-extension/implementation
1854 // decl contexts, the previously built IvarList must be rebuilt.
1855 auto *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1856 if (!ID) {
1857 if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC))
1858 ID = IM->getClassInterface();
1859 else
1860 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1861 }
1862 ID->setIvarList(nullptr);
1863 }
1864
1865 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1866 synthesized);
1867 }
1868
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1869 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1870 return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1871 nullptr, QualType(), nullptr,
1872 ObjCIvarDecl::None, nullptr, false);
1873 }
1874
getContainingInterface()1875 ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() {
1876 auto *DC = cast<ObjCContainerDecl>(getDeclContext());
1877
1878 switch (DC->getKind()) {
1879 default:
1880 case ObjCCategoryImpl:
1881 case ObjCProtocol:
1882 llvm_unreachable("invalid ivar container!");
1883
1884 // Ivars can only appear in class extension categories.
1885 case ObjCCategory: {
1886 auto *CD = cast<ObjCCategoryDecl>(DC);
1887 assert(CD->IsClassExtension() && "invalid container for ivar!");
1888 return CD->getClassInterface();
1889 }
1890
1891 case ObjCImplementation:
1892 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1893
1894 case ObjCInterface:
1895 return cast<ObjCInterfaceDecl>(DC);
1896 }
1897 }
1898
getUsageType(QualType objectType) const1899 QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
1900 return getType().substObjCMemberType(objectType, getDeclContext(),
1901 ObjCSubstitutionContext::Property);
1902 }
1903
1904 //===----------------------------------------------------------------------===//
1905 // ObjCAtDefsFieldDecl
1906 //===----------------------------------------------------------------------===//
1907
anchor()1908 void ObjCAtDefsFieldDecl::anchor() {}
1909
1910 ObjCAtDefsFieldDecl
Create(ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,Expr * BW)1911 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1912 SourceLocation StartLoc, SourceLocation IdLoc,
1913 IdentifierInfo *Id, QualType T, Expr *BW) {
1914 return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1915 }
1916
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1917 ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
1918 GlobalDeclID ID) {
1919 return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
1920 SourceLocation(), nullptr, QualType(),
1921 nullptr);
1922 }
1923
1924 //===----------------------------------------------------------------------===//
1925 // ObjCProtocolDecl
1926 //===----------------------------------------------------------------------===//
1927
anchor()1928 void ObjCProtocolDecl::anchor() {}
1929
ObjCProtocolDecl(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1930 ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
1931 IdentifierInfo *Id, SourceLocation nameLoc,
1932 SourceLocation atStartLoc,
1933 ObjCProtocolDecl *PrevDecl)
1934 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
1935 redeclarable_base(C) {
1936 setPreviousDecl(PrevDecl);
1937 if (PrevDecl)
1938 Data = PrevDecl->Data;
1939 }
1940
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1941 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
1942 IdentifierInfo *Id,
1943 SourceLocation nameLoc,
1944 SourceLocation atStartLoc,
1945 ObjCProtocolDecl *PrevDecl) {
1946 auto *Result =
1947 new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
1948 Result->Data.setInt(!C.getLangOpts().Modules);
1949 return Result;
1950 }
1951
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1952 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
1953 GlobalDeclID ID) {
1954 ObjCProtocolDecl *Result =
1955 new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
1956 SourceLocation(), nullptr);
1957 Result->Data.setInt(!C.getLangOpts().Modules);
1958 return Result;
1959 }
1960
isNonRuntimeProtocol() const1961 bool ObjCProtocolDecl::isNonRuntimeProtocol() const {
1962 return hasAttr<ObjCNonRuntimeProtocolAttr>();
1963 }
1964
getImpliedProtocols(llvm::DenseSet<const ObjCProtocolDecl * > & IPs) const1965 void ObjCProtocolDecl::getImpliedProtocols(
1966 llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const {
1967 std::queue<const ObjCProtocolDecl *> WorkQueue;
1968 WorkQueue.push(this);
1969
1970 while (!WorkQueue.empty()) {
1971 const auto *PD = WorkQueue.front();
1972 WorkQueue.pop();
1973 for (const auto *Parent : PD->protocols()) {
1974 const auto *Can = Parent->getCanonicalDecl();
1975 auto Result = IPs.insert(Can);
1976 if (Result.second)
1977 WorkQueue.push(Parent);
1978 }
1979 }
1980 }
1981
lookupProtocolNamed(IdentifierInfo * Name)1982 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1983 ObjCProtocolDecl *PDecl = this;
1984
1985 if (Name == getIdentifier())
1986 return PDecl;
1987
1988 for (auto *I : protocols())
1989 if ((PDecl = I->lookupProtocolNamed(Name)))
1990 return PDecl;
1991
1992 return nullptr;
1993 }
1994
1995 // lookupMethod - Lookup a instance/class method in the protocol and protocols
1996 // it inherited.
lookupMethod(Selector Sel,bool isInstance) const1997 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1998 bool isInstance) const {
1999 ObjCMethodDecl *MethodDecl = nullptr;
2000
2001 // If there is no definition or the definition is hidden, we don't find
2002 // anything.
2003 const ObjCProtocolDecl *Def = getDefinition();
2004 if (!Def || !Def->isUnconditionallyVisible())
2005 return nullptr;
2006
2007 if ((MethodDecl = getMethod(Sel, isInstance)))
2008 return MethodDecl;
2009
2010 for (const auto *I : protocols())
2011 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
2012 return MethodDecl;
2013 return nullptr;
2014 }
2015
allocateDefinitionData()2016 void ObjCProtocolDecl::allocateDefinitionData() {
2017 assert(!Data.getPointer() && "Protocol already has a definition!");
2018 Data.setPointer(new (getASTContext()) DefinitionData);
2019 Data.getPointer()->Definition = this;
2020 Data.getPointer()->HasODRHash = false;
2021 }
2022
startDefinition()2023 void ObjCProtocolDecl::startDefinition() {
2024 allocateDefinitionData();
2025
2026 // Update all of the declarations with a pointer to the definition.
2027 for (auto *RD : redecls())
2028 RD->Data = this->Data;
2029 }
2030
startDuplicateDefinitionForComparison()2031 void ObjCProtocolDecl::startDuplicateDefinitionForComparison() {
2032 Data.setPointer(nullptr);
2033 allocateDefinitionData();
2034 // Don't propagate data to other redeclarations.
2035 }
2036
mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl * Definition)2037 void ObjCProtocolDecl::mergeDuplicateDefinitionWithCommon(
2038 const ObjCProtocolDecl *Definition) {
2039 Data = Definition->Data;
2040 }
2041
collectPropertiesToImplement(PropertyMap & PM) const2042 void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM) const {
2043 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2044 for (auto *Prop : PDecl->properties()) {
2045 // Insert into PM if not there already.
2046 PM.insert(std::make_pair(
2047 std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
2048 Prop));
2049 }
2050 // Scan through protocol's protocols.
2051 for (const auto *PI : PDecl->protocols())
2052 PI->collectPropertiesToImplement(PM);
2053 }
2054 }
2055
collectInheritedProtocolProperties(const ObjCPropertyDecl * Property,ProtocolPropertySet & PS,PropertyDeclOrder & PO) const2056 void ObjCProtocolDecl::collectInheritedProtocolProperties(
2057 const ObjCPropertyDecl *Property, ProtocolPropertySet &PS,
2058 PropertyDeclOrder &PO) const {
2059 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2060 if (!PS.insert(PDecl).second)
2061 return;
2062 for (auto *Prop : PDecl->properties()) {
2063 if (Prop == Property)
2064 continue;
2065 if (Prop->getIdentifier() == Property->getIdentifier()) {
2066 PO.push_back(Prop);
2067 return;
2068 }
2069 }
2070 // Scan through protocol's protocols which did not have a matching property.
2071 for (const auto *PI : PDecl->protocols())
2072 PI->collectInheritedProtocolProperties(Property, PS, PO);
2073 }
2074 }
2075
2076 StringRef
getObjCRuntimeNameAsString() const2077 ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
2078 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
2079 return ObjCRTName->getMetadataName();
2080
2081 return getName();
2082 }
2083
getODRHash()2084 unsigned ObjCProtocolDecl::getODRHash() {
2085 assert(hasDefinition() && "ODRHash only for records with definitions");
2086
2087 // Previously calculated hash is stored in DefinitionData.
2088 if (hasODRHash())
2089 return data().ODRHash;
2090
2091 // Only calculate hash on first call of getODRHash per record.
2092 ODRHash Hasher;
2093 Hasher.AddObjCProtocolDecl(getDefinition());
2094 data().ODRHash = Hasher.CalculateHash();
2095 setHasODRHash(true);
2096
2097 return data().ODRHash;
2098 }
2099
hasODRHash() const2100 bool ObjCProtocolDecl::hasODRHash() const {
2101 if (!hasDefinition())
2102 return false;
2103 return data().HasODRHash;
2104 }
2105
setHasODRHash(bool HasHash)2106 void ObjCProtocolDecl::setHasODRHash(bool HasHash) {
2107 assert(hasDefinition() && "Cannot set ODRHash without definition");
2108 data().HasODRHash = HasHash;
2109 }
2110
2111 //===----------------------------------------------------------------------===//
2112 // ObjCCategoryDecl
2113 //===----------------------------------------------------------------------===//
2114
anchor()2115 void ObjCCategoryDecl::anchor() {}
2116
ObjCCategoryDecl(DeclContext * DC,SourceLocation AtLoc,SourceLocation ClassNameLoc,SourceLocation CategoryNameLoc,const IdentifierInfo * Id,ObjCInterfaceDecl * IDecl,ObjCTypeParamList * typeParamList,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)2117 ObjCCategoryDecl::ObjCCategoryDecl(
2118 DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc,
2119 SourceLocation CategoryNameLoc, const IdentifierInfo *Id,
2120 ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList,
2121 SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc)
2122 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
2123 ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
2124 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
2125 setTypeParamList(typeParamList);
2126 }
2127
Create(ASTContext & C,DeclContext * DC,SourceLocation AtLoc,SourceLocation ClassNameLoc,SourceLocation CategoryNameLoc,const IdentifierInfo * Id,ObjCInterfaceDecl * IDecl,ObjCTypeParamList * typeParamList,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)2128 ObjCCategoryDecl *ObjCCategoryDecl::Create(
2129 ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
2130 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
2131 const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
2132 ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,
2133 SourceLocation IvarRBraceLoc) {
2134 auto *CatDecl =
2135 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
2136 IDecl, typeParamList, IvarLBraceLoc,
2137 IvarRBraceLoc);
2138 if (IDecl) {
2139 // Link this category into its class's category list.
2140 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
2141 if (IDecl->hasDefinition()) {
2142 IDecl->setCategoryListRaw(CatDecl);
2143 if (ASTMutationListener *L = C.getASTMutationListener())
2144 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
2145 }
2146 }
2147
2148 return CatDecl;
2149 }
2150
CreateDeserialized(ASTContext & C,GlobalDeclID ID)2151 ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
2152 GlobalDeclID ID) {
2153 return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
2154 SourceLocation(), SourceLocation(),
2155 nullptr, nullptr, nullptr);
2156 }
2157
getImplementation() const2158 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
2159 return getASTContext().getObjCImplementation(
2160 const_cast<ObjCCategoryDecl*>(this));
2161 }
2162
setImplementation(ObjCCategoryImplDecl * ImplD)2163 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
2164 getASTContext().setObjCImplementation(this, ImplD);
2165 }
2166
setTypeParamList(ObjCTypeParamList * TPL)2167 void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) {
2168 TypeParamList = TPL;
2169 if (!TPL)
2170 return;
2171 // Set the declaration context of each of the type parameters.
2172 for (auto *typeParam : *TypeParamList)
2173 typeParam->setDeclContext(this);
2174 }
2175
2176 //===----------------------------------------------------------------------===//
2177 // ObjCCategoryImplDecl
2178 //===----------------------------------------------------------------------===//
2179
anchor()2180 void ObjCCategoryImplDecl::anchor() {}
2181
Create(ASTContext & C,DeclContext * DC,const IdentifierInfo * Id,ObjCInterfaceDecl * ClassInterface,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation CategoryNameLoc)2182 ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create(
2183 ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,
2184 ObjCInterfaceDecl *ClassInterface, SourceLocation nameLoc,
2185 SourceLocation atStartLoc, SourceLocation CategoryNameLoc) {
2186 if (ClassInterface && ClassInterface->hasDefinition())
2187 ClassInterface = ClassInterface->getDefinition();
2188 return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
2189 atStartLoc, CategoryNameLoc);
2190 }
2191
2192 ObjCCategoryImplDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)2193 ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
2194 return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
2195 SourceLocation(), SourceLocation(),
2196 SourceLocation());
2197 }
2198
getCategoryDecl() const2199 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
2200 // The class interface might be NULL if we are working with invalid code.
2201 if (const ObjCInterfaceDecl *ID = getClassInterface())
2202 return ID->FindCategoryDeclaration(getIdentifier());
2203 return nullptr;
2204 }
2205
anchor()2206 void ObjCImplDecl::anchor() {}
2207
addPropertyImplementation(ObjCPropertyImplDecl * property)2208 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
2209 // FIXME: The context should be correct before we get here.
2210 property->setLexicalDeclContext(this);
2211 addDecl(property);
2212 }
2213
setClassInterface(ObjCInterfaceDecl * IFace)2214 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
2215 ASTContext &Ctx = getASTContext();
2216
2217 if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
2218 if (IFace)
2219 Ctx.setObjCImplementation(IFace, ImplD);
2220
2221 } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
2222 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
2223 Ctx.setObjCImplementation(CD, ImplD);
2224 }
2225
2226 ClassInterface = IFace;
2227 }
2228
2229 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
2230 /// properties implemented in this \@implementation block and returns
2231 /// the implemented property that uses it.
2232 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo * ivarId) const2233 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
2234 for (auto *PID : property_impls())
2235 if (PID->getPropertyIvarDecl() &&
2236 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
2237 return PID;
2238 return nullptr;
2239 }
2240
2241 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
2242 /// added to the list of those properties \@synthesized/\@dynamic in this
2243 /// category \@implementation block.
2244 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo * Id,ObjCPropertyQueryKind QueryKind) const2245 FindPropertyImplDecl(IdentifierInfo *Id,
2246 ObjCPropertyQueryKind QueryKind) const {
2247 ObjCPropertyImplDecl *ClassPropImpl = nullptr;
2248 for (auto *PID : property_impls())
2249 // If queryKind is unknown, we return the instance property if one
2250 // exists; otherwise we return the class property.
2251 if (PID->getPropertyDecl()->getIdentifier() == Id) {
2252 if ((QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown &&
2253 !PID->getPropertyDecl()->isClassProperty()) ||
2254 (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_class &&
2255 PID->getPropertyDecl()->isClassProperty()) ||
2256 (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance &&
2257 !PID->getPropertyDecl()->isClassProperty()))
2258 return PID;
2259
2260 if (PID->getPropertyDecl()->isClassProperty())
2261 ClassPropImpl = PID;
2262 }
2263
2264 if (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown)
2265 // We can't find the instance property, return the class property.
2266 return ClassPropImpl;
2267
2268 return nullptr;
2269 }
2270
operator <<(raw_ostream & OS,const ObjCCategoryImplDecl & CID)2271 raw_ostream &clang::operator<<(raw_ostream &OS,
2272 const ObjCCategoryImplDecl &CID) {
2273 OS << CID.getName();
2274 return OS;
2275 }
2276
2277 //===----------------------------------------------------------------------===//
2278 // ObjCImplementationDecl
2279 //===----------------------------------------------------------------------===//
2280
anchor()2281 void ObjCImplementationDecl::anchor() {}
2282
2283 ObjCImplementationDecl *
Create(ASTContext & C,DeclContext * DC,ObjCInterfaceDecl * ClassInterface,ObjCInterfaceDecl * SuperDecl,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation superLoc,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)2284 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
2285 ObjCInterfaceDecl *ClassInterface,
2286 ObjCInterfaceDecl *SuperDecl,
2287 SourceLocation nameLoc,
2288 SourceLocation atStartLoc,
2289 SourceLocation superLoc,
2290 SourceLocation IvarLBraceLoc,
2291 SourceLocation IvarRBraceLoc) {
2292 if (ClassInterface && ClassInterface->hasDefinition())
2293 ClassInterface = ClassInterface->getDefinition();
2294 return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
2295 nameLoc, atStartLoc, superLoc,
2296 IvarLBraceLoc, IvarRBraceLoc);
2297 }
2298
2299 ObjCImplementationDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)2300 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
2301 return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
2302 SourceLocation(), SourceLocation());
2303 }
2304
setIvarInitializers(ASTContext & C,CXXCtorInitializer ** initializers,unsigned numInitializers)2305 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
2306 CXXCtorInitializer ** initializers,
2307 unsigned numInitializers) {
2308 if (numInitializers > 0) {
2309 NumIvarInitializers = numInitializers;
2310 auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];
2311 memcpy(ivarInitializers, initializers,
2312 numInitializers * sizeof(CXXCtorInitializer*));
2313 IvarInitializers = ivarInitializers;
2314 }
2315 }
2316
2317 ObjCImplementationDecl::init_const_iterator
init_begin() const2318 ObjCImplementationDecl::init_begin() const {
2319 return IvarInitializers.get(getASTContext().getExternalSource());
2320 }
2321
operator <<(raw_ostream & OS,const ObjCImplementationDecl & ID)2322 raw_ostream &clang::operator<<(raw_ostream &OS,
2323 const ObjCImplementationDecl &ID) {
2324 OS << ID.getName();
2325 return OS;
2326 }
2327
2328 //===----------------------------------------------------------------------===//
2329 // ObjCCompatibleAliasDecl
2330 //===----------------------------------------------------------------------===//
2331
anchor()2332 void ObjCCompatibleAliasDecl::anchor() {}
2333
2334 ObjCCompatibleAliasDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,ObjCInterfaceDecl * AliasedClass)2335 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
2336 SourceLocation L,
2337 IdentifierInfo *Id,
2338 ObjCInterfaceDecl* AliasedClass) {
2339 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
2340 }
2341
2342 ObjCCompatibleAliasDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)2343 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
2344 return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
2345 nullptr, nullptr);
2346 }
2347
2348 //===----------------------------------------------------------------------===//
2349 // ObjCPropertyDecl
2350 //===----------------------------------------------------------------------===//
2351
anchor()2352 void ObjCPropertyDecl::anchor() {}
2353
2354 ObjCPropertyDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,const IdentifierInfo * Id,SourceLocation AtLoc,SourceLocation LParenLoc,QualType T,TypeSourceInfo * TSI,PropertyControl propControl)2355 ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
2356 const IdentifierInfo *Id, SourceLocation AtLoc,
2357 SourceLocation LParenLoc, QualType T,
2358 TypeSourceInfo *TSI, PropertyControl propControl) {
2359 return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
2360 propControl);
2361 }
2362
CreateDeserialized(ASTContext & C,GlobalDeclID ID)2363 ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
2364 GlobalDeclID ID) {
2365 return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
2366 SourceLocation(), SourceLocation(),
2367 QualType(), nullptr, None);
2368 }
2369
getUsageType(QualType objectType) const2370 QualType ObjCPropertyDecl::getUsageType(QualType objectType) const {
2371 return DeclType.substObjCMemberType(objectType, getDeclContext(),
2372 ObjCSubstitutionContext::Property);
2373 }
2374
isDirectProperty() const2375 bool ObjCPropertyDecl::isDirectProperty() const {
2376 return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
2377 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
2378 }
2379
2380 //===----------------------------------------------------------------------===//
2381 // ObjCPropertyImplDecl
2382 //===----------------------------------------------------------------------===//
2383
Create(ASTContext & C,DeclContext * DC,SourceLocation atLoc,SourceLocation L,ObjCPropertyDecl * property,Kind PK,ObjCIvarDecl * ivar,SourceLocation ivarLoc)2384 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
2385 DeclContext *DC,
2386 SourceLocation atLoc,
2387 SourceLocation L,
2388 ObjCPropertyDecl *property,
2389 Kind PK,
2390 ObjCIvarDecl *ivar,
2391 SourceLocation ivarLoc) {
2392 return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
2393 ivarLoc);
2394 }
2395
2396 ObjCPropertyImplDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)2397 ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
2398 return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
2399 SourceLocation(), nullptr, Dynamic,
2400 nullptr, SourceLocation());
2401 }
2402
getSourceRange() const2403 SourceRange ObjCPropertyImplDecl::getSourceRange() const {
2404 SourceLocation EndLoc = getLocation();
2405 if (IvarLoc.isValid())
2406 EndLoc = IvarLoc;
2407
2408 return SourceRange(AtLoc, EndLoc);
2409 }
2410