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