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
39using namespace clang;
40
41//===----------------------------------------------------------------------===//
42// ObjCListBase
43//===----------------------------------------------------------------------===//
44
45void 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(dest: List, src: InList, n: sizeof(void*)*Elts);
52}
53
54void 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(dest: Locations, src: Locs, n: sizeof(SourceLocation) * Elts);
61 set(InList, Elts, Ctx);
62}
63
64//===----------------------------------------------------------------------===//
65// ObjCInterfaceDecl
66//===----------------------------------------------------------------------===//
67
68ObjCContainerDecl::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
76void ObjCContainerDecl::anchor() {}
77
78/// getIvarDecl - This method looks up an ivar in this ContextDecl.
79///
80ObjCIvarDecl *
81ObjCContainerDecl::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.
92ObjCMethodDecl *
93ObjCContainerDecl::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>(Val: 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>(Val: *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.
125bool 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>(Val: *Meth);
132 if (MD && MD->isInstanceMethod() && !MD->isImplicit())
133 return true;
134 }
135
136 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(Val: 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>(Val: this))
172 for (const auto *PI : PD->protocols())
173 if (PI->HasUserDeclaredSetterMethod(Property))
174 return true;
175 return false;
176}
177
178ObjCPropertyDecl *
179ObjCPropertyDecl::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>(Val: 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>(Val: 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(Name: 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>(Val: *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
226IdentifierInfo *
227ObjCPropertyDecl::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(Name: ivarName.str());
234}
235
236ObjCPropertyDecl *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.
250ObjCPropertyDecl *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>(Val: 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>(Val: 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(DC: cast<DeclContext>(Val: this), propertyID: PropertyId,
271 queryKind: QueryKind))
272 return PD;
273
274 switch (getKind()) {
275 default:
276 break;
277 case Decl::ObjCProtocol: {
278 const auto *PID = cast<ObjCProtocolDecl>(Val: 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>(Val: 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>(Val: 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
320void ObjCInterfaceDecl::anchor() {}
321
322ObjCTypeParamList *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
343void 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
352ObjCInterfaceDecl *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
372SourceLocation 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.
382ObjCPropertyDecl *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(DC: cast<DeclContext>(Val: this), propertyID: PropertyId,
393 queryKind: 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
405void 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
422bool 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
432const 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
442void 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(InList: ExtList, Elts: ExtNum, Ctx&: 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(lProto: ProtoInExtension, rProto: 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(Elt: ProtoInExtension);
471 }
472
473 if (ProtocolRefs.empty())
474 return;
475
476 // Merge ProtocolRefs into class's protocol list;
477 ProtocolRefs.append(in_start: all_referenced_protocol_begin(),
478 in_end: all_referenced_protocol_end());
479
480 data().AllReferencedProtocols.set(InList: ProtocolRefs.data(), Elts: ProtocolRefs.size(),Ctx&: C);
481}
482
483const ObjCInterfaceDecl *
484ObjCInterfaceDecl::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
496static 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
516bool 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(D: 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
548void 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
570bool 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
610void ObjCInterfaceDecl::allocateDefinitionData() {
611 assert(!hasDefinition() && "ObjC class already has a definition");
612 Data.setPointer(new (getASTContext()) DefinitionData());
613 Data.getPointer()->Definition = this;
614}
615
616void 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
626void ObjCInterfaceDecl::startDuplicateDefinitionForComparison() {
627 Data.setPointer(nullptr);
628 allocateDefinitionData();
629 // Don't propagate data to other redeclarations.
630}
631
632void ObjCInterfaceDecl::mergeDuplicateDefinitionWithCommon(
633 const ObjCInterfaceDecl *Definition) {
634 Data = Definition->Data;
635}
636
637ObjCIvarDecl *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.
668ObjCInterfaceDecl *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
686ObjCProtocolDecl *
687ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
688 for (auto *P : all_referenced_protocols())
689 if (P->lookupProtocolNamed(PName: 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.
699ObjCMethodDecl *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.
756ObjCMethodDecl *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, isInstance: 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, Instance: true);
784 }
785
786 if (!Method && getSuperClass())
787 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
788 return Method;
789}
790
791unsigned 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(Record: getDefinition());
801 data().ODRHash = Hasher.CalculateHash();
802 setHasODRHash(true);
803
804 return data().ODRHash;
805}
806
807bool ObjCInterfaceDecl::hasODRHash() const {
808 if (!hasDefinition())
809 return false;
810 return data().HasODRHash;
811}
812
813void ObjCInterfaceDecl::setHasODRHash(bool HasHash) {
814 assert(hasDefinition() && "Cannot set ODRHash without definition");
815 data().HasODRHash = HasHash;
816}
817
818//===----------------------------------------------------------------------===//
819// ObjCMethodDecl
820//===----------------------------------------------------------------------===//
821
822ObjCMethodDecl::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
852ObjCMethodDecl *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
865ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) {
866 return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
867 Selector(), QualType(), nullptr, nullptr);
868}
869
870bool ObjCMethodDecl::isDirectMethod() const {
871 return hasAttr<ObjCDirectAttr>() &&
872 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
873}
874
875bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
876 return getMethodFamily() == OMF_init &&
877 hasAttr<ObjCDesignatedInitializerAttr>();
878}
879
880bool ObjCMethodDecl::definedInNSObject(const ASTContext &Ctx) const {
881 if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext()))
882 return PD->getIdentifier() == Ctx.getNSObjectName();
883 if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext()))
884 return ID->getIdentifier() == Ctx.getNSObjectName();
885 return false;
886}
887
888bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
889 const ObjCMethodDecl **InitMethod) const {
890 if (getMethodFamily() != OMF_init)
891 return false;
892 const DeclContext *DC = getDeclContext();
893 if (isa<ObjCProtocolDecl>(Val: DC))
894 return false;
895 if (const ObjCInterfaceDecl *ID = getClassInterface())
896 return ID->isDesignatedInitializer(Sel: getSelector(), InitMethod);
897 return false;
898}
899
900bool ObjCMethodDecl::hasParamDestroyedInCallee() const {
901 for (auto *param : parameters()) {
902 if (param->isDestroyedInCallee())
903 return true;
904 }
905 return false;
906}
907
908Stmt *ObjCMethodDecl::getBody() const {
909 return Body.get(Source: getASTContext().getExternalSource());
910}
911
912void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
913 assert(PrevMethod);
914 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
915 setIsRedeclaration(true);
916 PrevMethod->setHasRedeclaration(true);
917}
918
919void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
920 ArrayRef<ParmVarDecl*> Params,
921 ArrayRef<SourceLocation> SelLocs) {
922 ParamsAndSelLocs = nullptr;
923 NumParams = Params.size();
924 if (Params.empty() && SelLocs.empty())
925 return;
926
927 static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation),
928 "Alignment not sufficient for SourceLocation");
929
930 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
931 sizeof(SourceLocation) * SelLocs.size();
932 ParamsAndSelLocs = C.Allocate(Size);
933 std::uninitialized_copy(first: Params.begin(), last: Params.end(), result: getParams());
934 std::uninitialized_copy(first: SelLocs.begin(), last: SelLocs.end(), result: getStoredSelLocs());
935}
936
937void ObjCMethodDecl::getSelectorLocs(
938 SmallVectorImpl<SourceLocation> &SelLocs) const {
939 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
940 SelLocs.push_back(Elt: getSelectorLoc(Index: i));
941}
942
943void ObjCMethodDecl::setMethodParams(ASTContext &C,
944 ArrayRef<ParmVarDecl*> Params,
945 ArrayRef<SourceLocation> SelLocs) {
946 assert((!SelLocs.empty() || isImplicit()) &&
947 "No selector locs for non-implicit method");
948 if (isImplicit())
949 return setParamsAndSelLocs(C, Params, SelLocs: std::nullopt);
950
951 setSelLocsKind(hasStandardSelectorLocs(Sel: getSelector(), SelLocs, Args: Params,
952 EndLoc: DeclEndLoc));
953 if (getSelLocsKind() != SelLoc_NonStandard)
954 return setParamsAndSelLocs(C, Params, SelLocs: std::nullopt);
955
956 setParamsAndSelLocs(C, Params, SelLocs);
957}
958
959/// A definition will return its interface declaration.
960/// An interface declaration will return its definition.
961/// Otherwise it will return itself.
962ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
963 ASTContext &Ctx = getASTContext();
964 ObjCMethodDecl *Redecl = nullptr;
965 if (hasRedeclaration())
966 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(MD: this));
967 if (Redecl)
968 return Redecl;
969
970 auto *CtxD = cast<Decl>(getDeclContext());
971
972 if (!CtxD->isInvalidDecl()) {
973 if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
974 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
975 if (!ImplD->isInvalidDecl())
976 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
977
978 } else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
979 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
980 if (!ImplD->isInvalidDecl())
981 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
982
983 } else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
984 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
985 if (!IFD->isInvalidDecl())
986 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
987
988 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
989 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
990 if (!CatD->isInvalidDecl())
991 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
992 }
993 }
994
995 // Ensure that the discovered method redeclaration has a valid declaration
996 // context. Used to prevent infinite loops when iterating redeclarations in
997 // a partially invalid AST.
998 if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl())
999 Redecl = nullptr;
1000
1001 if (!Redecl && isRedeclaration()) {
1002 // This is the last redeclaration, go back to the first method.
1003 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
1004 isInstanceMethod(),
1005 /*AllowHidden=*/true);
1006 }
1007
1008 return Redecl ? Redecl : this;
1009}
1010
1011ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
1012 auto *CtxD = cast<Decl>(getDeclContext());
1013 const auto &Sel = getSelector();
1014
1015 if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
1016 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) {
1017 // When the container is the ObjCImplementationDecl (the primary
1018 // @implementation), then the canonical Decl is either in
1019 // the class Interface, or in any of its extension.
1020 //
1021 // So when we don't find it in the ObjCInterfaceDecl,
1022 // sift through extensions too.
1023 if (ObjCMethodDecl *MD = IFD->getMethod(Sel, isInstanceMethod()))
1024 return MD;
1025 for (auto *Ext : IFD->known_extensions())
1026 if (ObjCMethodDecl *MD = Ext->getMethod(Sel, isInstanceMethod()))
1027 return MD;
1028 }
1029 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
1030 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
1031 if (ObjCMethodDecl *MD = CatD->getMethod(Sel, isInstanceMethod()))
1032 return MD;
1033 }
1034
1035 if (isRedeclaration()) {
1036 // It is possible that we have not done deserializing the ObjCMethod yet.
1037 ObjCMethodDecl *MD =
1038 cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
1039 /*AllowHidden=*/true);
1040 return MD ? MD : this;
1041 }
1042
1043 return this;
1044}
1045
1046SourceLocation ObjCMethodDecl::getEndLoc() const {
1047 if (Stmt *Body = getBody())
1048 return Body->getEndLoc();
1049 return DeclEndLoc;
1050}
1051
1052ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
1053 auto family = static_cast<ObjCMethodFamily>(ObjCMethodDeclBits.Family);
1054 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
1055 return family;
1056
1057 // Check for an explicit attribute.
1058 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
1059 // The unfortunate necessity of mapping between enums here is due
1060 // to the attributes framework.
1061 switch (attr->getFamily()) {
1062 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
1063 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
1064 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
1065 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
1066 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
1067 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
1068 }
1069 ObjCMethodDeclBits.Family = family;
1070 return family;
1071 }
1072
1073 family = getSelector().getMethodFamily();
1074 switch (family) {
1075 case OMF_None: break;
1076
1077 // init only has a conventional meaning for an instance method, and
1078 // it has to return an object.
1079 case OMF_init:
1080 if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
1081 family = OMF_None;
1082 break;
1083
1084 // alloc/copy/new have a conventional meaning for both class and
1085 // instance methods, but they require an object return.
1086 case OMF_alloc:
1087 case OMF_copy:
1088 case OMF_mutableCopy:
1089 case OMF_new:
1090 if (!getReturnType()->isObjCObjectPointerType())
1091 family = OMF_None;
1092 break;
1093
1094 // These selectors have a conventional meaning only for instance methods.
1095 case OMF_dealloc:
1096 case OMF_finalize:
1097 case OMF_retain:
1098 case OMF_release:
1099 case OMF_autorelease:
1100 case OMF_retainCount:
1101 case OMF_self:
1102 if (!isInstanceMethod())
1103 family = OMF_None;
1104 break;
1105
1106 case OMF_initialize:
1107 if (isInstanceMethod() || !getReturnType()->isVoidType())
1108 family = OMF_None;
1109 break;
1110
1111 case OMF_performSelector:
1112 if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
1113 family = OMF_None;
1114 else {
1115 unsigned noParams = param_size();
1116 if (noParams < 1 || noParams > 3)
1117 family = OMF_None;
1118 else {
1119 ObjCMethodDecl::param_type_iterator it = param_type_begin();
1120 QualType ArgT = (*it);
1121 if (!ArgT->isObjCSelType()) {
1122 family = OMF_None;
1123 break;
1124 }
1125 while (--noParams) {
1126 it++;
1127 ArgT = (*it);
1128 if (!ArgT->isObjCIdType()) {
1129 family = OMF_None;
1130 break;
1131 }
1132 }
1133 }
1134 }
1135 break;
1136
1137 }
1138
1139 // Cache the result.
1140 ObjCMethodDeclBits.Family = family;
1141 return family;
1142}
1143
1144QualType ObjCMethodDecl::getSelfType(ASTContext &Context,
1145 const ObjCInterfaceDecl *OID,
1146 bool &selfIsPseudoStrong,
1147 bool &selfIsConsumed) const {
1148 QualType selfTy;
1149 selfIsPseudoStrong = false;
1150 selfIsConsumed = false;
1151 if (isInstanceMethod()) {
1152 // There may be no interface context due to error in declaration
1153 // of the interface (which has been reported). Recover gracefully.
1154 if (OID) {
1155 selfTy = Context.getObjCInterfaceType(Decl: OID);
1156 selfTy = Context.getObjCObjectPointerType(OIT: selfTy);
1157 } else {
1158 selfTy = Context.getObjCIdType();
1159 }
1160 } else // we have a factory method.
1161 selfTy = Context.getObjCClassType();
1162
1163 if (Context.getLangOpts().ObjCAutoRefCount) {
1164 if (isInstanceMethod()) {
1165 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
1166
1167 // 'self' is always __strong. It's actually pseudo-strong except
1168 // in init methods (or methods labeled ns_consumes_self), though.
1169 Qualifiers qs;
1170 qs.setObjCLifetime(Qualifiers::OCL_Strong);
1171 selfTy = Context.getQualifiedType(T: selfTy, Qs: qs);
1172
1173 // In addition, 'self' is const unless this is an init method.
1174 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
1175 selfTy = selfTy.withConst();
1176 selfIsPseudoStrong = true;
1177 }
1178 }
1179 else {
1180 assert(isClassMethod());
1181 // 'self' is always const in class methods.
1182 selfTy = selfTy.withConst();
1183 selfIsPseudoStrong = true;
1184 }
1185 }
1186 return selfTy;
1187}
1188
1189void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
1190 const ObjCInterfaceDecl *OID) {
1191 bool selfIsPseudoStrong, selfIsConsumed;
1192 QualType selfTy =
1193 getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
1194 auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),
1195 &Context.Idents.get(Name: "self"), selfTy,
1196 ImplicitParamKind::ObjCSelf);
1197 setSelfDecl(Self);
1198
1199 if (selfIsConsumed)
1200 Self->addAttr(NSConsumedAttr::CreateImplicit(Context));
1201
1202 if (selfIsPseudoStrong)
1203 Self->setARCPseudoStrong(true);
1204
1205 setCmdDecl(ImplicitParamDecl::Create(
1206 Context, this, SourceLocation(), &Context.Idents.get(Name: "_cmd"),
1207 Context.getObjCSelType(), ImplicitParamKind::ObjCCmd));
1208}
1209
1210ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
1211 if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
1212 return ID;
1213 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1214 return CD->getClassInterface();
1215 if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
1216 return IMD->getClassInterface();
1217 if (isa<ObjCProtocolDecl>(getDeclContext()))
1218 return nullptr;
1219 llvm_unreachable("unknown method context");
1220}
1221
1222ObjCCategoryDecl *ObjCMethodDecl::getCategory() {
1223 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1224 return CD;
1225 if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
1226 return IMD->getCategoryDecl();
1227 return nullptr;
1228}
1229
1230SourceRange ObjCMethodDecl::getReturnTypeSourceRange() const {
1231 const auto *TSI = getReturnTypeSourceInfo();
1232 if (TSI)
1233 return TSI->getTypeLoc().getSourceRange();
1234 return SourceRange();
1235}
1236
1237QualType ObjCMethodDecl::getSendResultType() const {
1238 ASTContext &Ctx = getASTContext();
1239 return getReturnType().getNonLValueExprType(Context: Ctx)
1240 .substObjCTypeArgs(ctx&: Ctx, typeArgs: {}, context: ObjCSubstitutionContext::Result);
1241}
1242
1243QualType ObjCMethodDecl::getSendResultType(QualType receiverType) const {
1244 // FIXME: Handle related result types here.
1245
1246 return getReturnType().getNonLValueExprType(Context: getASTContext())
1247 .substObjCMemberType(receiverType, getDeclContext(),
1248 ObjCSubstitutionContext::Result);
1249}
1250
1251static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
1252 const ObjCMethodDecl *Method,
1253 SmallVectorImpl<const ObjCMethodDecl *> &Methods,
1254 bool MovedToSuper) {
1255 if (!Container)
1256 return;
1257
1258 // In categories look for overridden methods from protocols. A method from
1259 // category is not "overridden" since it is considered as the "same" method
1260 // (same USR) as the one from the interface.
1261 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Val: Container)) {
1262 // Check whether we have a matching method at this category but only if we
1263 // are at the super class level.
1264 if (MovedToSuper)
1265 if (ObjCMethodDecl *
1266 Overridden = Container->getMethod(Sel: Method->getSelector(),
1267 isInstance: Method->isInstanceMethod(),
1268 /*AllowHidden=*/true))
1269 if (Method != Overridden) {
1270 // We found an override at this category; there is no need to look
1271 // into its protocols.
1272 Methods.push_back(Elt: Overridden);
1273 return;
1274 }
1275
1276 for (const auto *P : Category->protocols())
1277 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1278 return;
1279 }
1280
1281 // Check whether we have a matching method at this level.
1282 if (const ObjCMethodDecl *
1283 Overridden = Container->getMethod(Sel: Method->getSelector(),
1284 isInstance: Method->isInstanceMethod(),
1285 /*AllowHidden=*/true))
1286 if (Method != Overridden) {
1287 // We found an override at this level; there is no need to look
1288 // into other protocols or categories.
1289 Methods.push_back(Elt: Overridden);
1290 return;
1291 }
1292
1293 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Val: Container)){
1294 for (const auto *P : Protocol->protocols())
1295 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1296 }
1297
1298 if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Val: Container)) {
1299 for (const auto *P : Interface->protocols())
1300 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1301
1302 for (const auto *Cat : Interface->known_categories())
1303 CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
1304
1305 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
1306 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
1307 /*MovedToSuper=*/true);
1308 }
1309}
1310
1311static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
1312 const ObjCMethodDecl *Method,
1313 SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
1314 CollectOverriddenMethodsRecurse(Container, Method, Methods,
1315 /*MovedToSuper=*/false);
1316}
1317
1318static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
1319 SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
1320 assert(Method->isOverriding());
1321
1322 if (const auto *ProtD =
1323 dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1324 CollectOverriddenMethods(ProtD, Method, overridden);
1325
1326 } else if (const auto *IMD =
1327 dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1328 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1329 if (!ID)
1330 return;
1331 // Start searching for overridden methods using the method from the
1332 // interface as starting point.
1333 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1334 Method->isInstanceMethod(),
1335 /*AllowHidden=*/true))
1336 Method = IFaceMeth;
1337 CollectOverriddenMethods(ID, Method, overridden);
1338
1339 } else if (const auto *CatD =
1340 dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1341 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1342 if (!ID)
1343 return;
1344 // Start searching for overridden methods using the method from the
1345 // interface as starting point.
1346 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1347 Method->isInstanceMethod(),
1348 /*AllowHidden=*/true))
1349 Method = IFaceMeth;
1350 CollectOverriddenMethods(ID, Method, overridden);
1351
1352 } else {
1353 CollectOverriddenMethods(
1354 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1355 Method, overridden);
1356 }
1357}
1358
1359void ObjCMethodDecl::getOverriddenMethods(
1360 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1361 const ObjCMethodDecl *Method = this;
1362
1363 if (Method->isRedeclaration()) {
1364 Method = cast<ObjCContainerDecl>(Method->getDeclContext())
1365 ->getMethod(Method->getSelector(), Method->isInstanceMethod(),
1366 /*AllowHidden=*/true);
1367 }
1368
1369 if (Method->isOverriding()) {
1370 collectOverriddenMethodsSlow(Method, overridden&: Overridden);
1371 assert(!Overridden.empty() &&
1372 "ObjCMethodDecl's overriding bit is not as expected");
1373 }
1374}
1375
1376const ObjCPropertyDecl *
1377ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
1378 Selector Sel = getSelector();
1379 unsigned NumArgs = Sel.getNumArgs();
1380 if (NumArgs > 1)
1381 return nullptr;
1382
1383 if (isPropertyAccessor()) {
1384 const auto *Container = cast<ObjCContainerDecl>(getParent());
1385 // For accessor stubs, go back to the interface.
1386 if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container))
1387 if (isSynthesizedAccessorStub())
1388 Container = ImplDecl->getClassInterface();
1389
1390 bool IsGetter = (NumArgs == 0);
1391 bool IsInstance = isInstanceMethod();
1392
1393 /// Local function that attempts to find a matching property within the
1394 /// given Objective-C container.
1395 auto findMatchingProperty =
1396 [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
1397 if (IsInstance) {
1398 for (const auto *I : Container->instance_properties()) {
1399 Selector NextSel = IsGetter ? I->getGetterName()
1400 : I->getSetterName();
1401 if (NextSel == Sel)
1402 return I;
1403 }
1404 } else {
1405 for (const auto *I : Container->class_properties()) {
1406 Selector NextSel = IsGetter ? I->getGetterName()
1407 : I->getSetterName();
1408 if (NextSel == Sel)
1409 return I;
1410 }
1411 }
1412
1413 return nullptr;
1414 };
1415
1416 // Look in the container we were given.
1417 if (const auto *Found = findMatchingProperty(Container))
1418 return Found;
1419
1420 // If we're in a category or extension, look in the main class.
1421 const ObjCInterfaceDecl *ClassDecl = nullptr;
1422 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1423 ClassDecl = Category->getClassInterface();
1424 if (const auto *Found = findMatchingProperty(ClassDecl))
1425 return Found;
1426 } else {
1427 // Determine whether the container is a class.
1428 ClassDecl = cast<ObjCInterfaceDecl>(Container);
1429 }
1430 assert(ClassDecl && "Failed to find main class");
1431
1432 // If we have a class, check its visible extensions.
1433 for (const auto *Ext : ClassDecl->visible_extensions()) {
1434 if (Ext == Container)
1435 continue;
1436 if (const auto *Found = findMatchingProperty(Ext))
1437 return Found;
1438 }
1439
1440 assert(isSynthesizedAccessorStub() && "expected an accessor stub");
1441
1442 for (const auto *Cat : ClassDecl->known_categories()) {
1443 if (Cat == Container)
1444 continue;
1445 if (const auto *Found = findMatchingProperty(Cat))
1446 return Found;
1447 }
1448
1449 llvm_unreachable("Marked as a property accessor but no property found!");
1450 }
1451
1452 if (!CheckOverrides)
1453 return nullptr;
1454
1455 using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;
1456
1457 OverridesTy Overrides;
1458 getOverriddenMethods(Overridden&: Overrides);
1459 for (const auto *Override : Overrides)
1460 if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(CheckOverrides: false))
1461 return Prop;
1462
1463 return nullptr;
1464}
1465
1466//===----------------------------------------------------------------------===//
1467// ObjCTypeParamDecl
1468//===----------------------------------------------------------------------===//
1469
1470void ObjCTypeParamDecl::anchor() {}
1471
1472ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc,
1473 ObjCTypeParamVariance variance,
1474 SourceLocation varianceLoc,
1475 unsigned index,
1476 SourceLocation nameLoc,
1477 IdentifierInfo *name,
1478 SourceLocation colonLoc,
1479 TypeSourceInfo *boundInfo) {
1480 auto *TPDecl =
1481 new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
1482 nameLoc, name, colonLoc, boundInfo);
1483 QualType TPType = ctx.getObjCTypeParamType(Decl: TPDecl, protocols: {});
1484 TPDecl->setTypeForDecl(TPType.getTypePtr());
1485 return TPDecl;
1486}
1487
1488ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx,
1489 Decl::DeclID ID) {
1490 return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,
1491 ObjCTypeParamVariance::Invariant,
1492 SourceLocation(), 0, SourceLocation(),
1493 nullptr, SourceLocation(), nullptr);
1494}
1495
1496SourceRange ObjCTypeParamDecl::getSourceRange() const {
1497 SourceLocation startLoc = VarianceLoc;
1498 if (startLoc.isInvalid())
1499 startLoc = getLocation();
1500
1501 if (hasExplicitBound()) {
1502 return SourceRange(startLoc,
1503 getTypeSourceInfo()->getTypeLoc().getEndLoc());
1504 }
1505
1506 return SourceRange(startLoc);
1507}
1508
1509//===----------------------------------------------------------------------===//
1510// ObjCTypeParamList
1511//===----------------------------------------------------------------------===//
1512ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,
1513 ArrayRef<ObjCTypeParamDecl *> typeParams,
1514 SourceLocation rAngleLoc)
1515 : Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) {
1516 std::copy(first: typeParams.begin(), last: typeParams.end(), result: begin());
1517}
1518
1519ObjCTypeParamList *ObjCTypeParamList::create(
1520 ASTContext &ctx,
1521 SourceLocation lAngleLoc,
1522 ArrayRef<ObjCTypeParamDecl *> typeParams,
1523 SourceLocation rAngleLoc) {
1524 void *mem =
1525 ctx.Allocate(Size: totalSizeToAlloc<ObjCTypeParamDecl *>(Counts: typeParams.size()),
1526 Align: alignof(ObjCTypeParamList));
1527 return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
1528}
1529
1530void ObjCTypeParamList::gatherDefaultTypeArgs(
1531 SmallVectorImpl<QualType> &typeArgs) const {
1532 typeArgs.reserve(N: size());
1533 for (auto *typeParam : *this)
1534 typeArgs.push_back(Elt: typeParam->getUnderlyingType());
1535}
1536
1537//===----------------------------------------------------------------------===//
1538// ObjCInterfaceDecl
1539//===----------------------------------------------------------------------===//
1540
1541ObjCInterfaceDecl *ObjCInterfaceDecl::Create(
1542 const ASTContext &C, DeclContext *DC, SourceLocation atLoc,
1543 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1544 ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal) {
1545 auto *Result = new (C, DC)
1546 ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
1547 isInternal);
1548 Result->Data.setInt(!C.getLangOpts().Modules);
1549 C.getObjCInterfaceType(Decl: Result, PrevDecl);
1550 return Result;
1551}
1552
1553ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
1554 Decl::DeclID ID) {
1555 auto *Result = new (C, ID)
1556 ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,
1557 SourceLocation(), nullptr, false);
1558 Result->Data.setInt(!C.getLangOpts().Modules);
1559 return Result;
1560}
1561
1562ObjCInterfaceDecl::ObjCInterfaceDecl(
1563 const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
1564 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1565 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal)
1566 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
1567 redeclarable_base(C) {
1568 setPreviousDecl(PrevDecl);
1569
1570 // Copy the 'data' pointer over.
1571 if (PrevDecl)
1572 Data = PrevDecl->Data;
1573
1574 setImplicit(IsInternal);
1575
1576 setTypeParamList(typeParamList);
1577}
1578
1579void ObjCInterfaceDecl::LoadExternalDefinition() const {
1580 assert(data().ExternallyCompleted && "Class is not externally completed");
1581 data().ExternallyCompleted = false;
1582 getASTContext().getExternalSource()->CompleteType(
1583 const_cast<ObjCInterfaceDecl *>(this));
1584}
1585
1586void ObjCInterfaceDecl::setExternallyCompleted() {
1587 assert(getASTContext().getExternalSource() &&
1588 "Class can't be externally completed without an external source");
1589 assert(hasDefinition() &&
1590 "Forward declarations can't be externally completed");
1591 data().ExternallyCompleted = true;
1592}
1593
1594void ObjCInterfaceDecl::setHasDesignatedInitializers() {
1595 // Check for a complete definition and recover if not so.
1596 if (!isThisDeclarationADefinition())
1597 return;
1598 data().HasDesignatedInitializers = true;
1599}
1600
1601bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
1602 // Check for a complete definition and recover if not so.
1603 if (!isThisDeclarationADefinition())
1604 return false;
1605 if (data().ExternallyCompleted)
1606 LoadExternalDefinition();
1607
1608 return data().HasDesignatedInitializers;
1609}
1610
1611StringRef
1612ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
1613 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1614 return ObjCRTName->getMetadataName();
1615
1616 return getName();
1617}
1618
1619StringRef
1620ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
1621 if (ObjCInterfaceDecl *ID =
1622 const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
1623 return ID->getObjCRuntimeNameAsString();
1624
1625 return getName();
1626}
1627
1628ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
1629 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1630 if (data().ExternallyCompleted)
1631 LoadExternalDefinition();
1632
1633 return getASTContext().getObjCImplementation(
1634 const_cast<ObjCInterfaceDecl*>(Def));
1635 }
1636
1637 // FIXME: Should make sure no callers ever do this.
1638 return nullptr;
1639}
1640
1641void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
1642 getASTContext().setObjCImplementation(getDefinition(), ImplD);
1643}
1644
1645namespace {
1646
1647struct SynthesizeIvarChunk {
1648 uint64_t Size;
1649 ObjCIvarDecl *Ivar;
1650
1651 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1652 : Size(size), Ivar(ivar) {}
1653};
1654
1655bool operator<(const SynthesizeIvarChunk & LHS,
1656 const SynthesizeIvarChunk &RHS) {
1657 return LHS.Size < RHS.Size;
1658}
1659
1660} // namespace
1661
1662/// all_declared_ivar_begin - return first ivar declared in this class,
1663/// its extensions and its implementation. Lazily build the list on first
1664/// access.
1665///
1666/// Caveat: The list returned by this method reflects the current
1667/// state of the parser. The cache will be updated for every ivar
1668/// added by an extension or the implementation when they are
1669/// encountered.
1670/// See also ObjCIvarDecl::Create().
1671ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
1672 // FIXME: Should make sure no callers ever do this.
1673 if (!hasDefinition())
1674 return nullptr;
1675
1676 ObjCIvarDecl *curIvar = nullptr;
1677 if (!data().IvarList) {
1678 // Force ivar deserialization upfront, before building IvarList.
1679 (void)ivar_empty();
1680 for (const auto *Ext : known_extensions()) {
1681 (void)Ext->ivar_empty();
1682 }
1683 if (!ivar_empty()) {
1684 ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
1685 data().IvarList = *I; ++I;
1686 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1687 curIvar->setNextIvar(*I);
1688 }
1689
1690 for (const auto *Ext : known_extensions()) {
1691 if (!Ext->ivar_empty()) {
1692 ObjCCategoryDecl::ivar_iterator
1693 I = Ext->ivar_begin(),
1694 E = Ext->ivar_end();
1695 if (!data().IvarList) {
1696 data().IvarList = *I; ++I;
1697 curIvar = data().IvarList;
1698 }
1699 for ( ;I != E; curIvar = *I, ++I)
1700 curIvar->setNextIvar(*I);
1701 }
1702 }
1703 data().IvarListMissingImplementation = true;
1704 }
1705
1706 // cached and complete!
1707 if (!data().IvarListMissingImplementation)
1708 return data().IvarList;
1709
1710 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1711 data().IvarListMissingImplementation = false;
1712 if (!ImplDecl->ivar_empty()) {
1713 SmallVector<SynthesizeIvarChunk, 16> layout;
1714 for (auto *IV : ImplDecl->ivars()) {
1715 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1716 layout.push_back(Elt: SynthesizeIvarChunk(
1717 IV->getASTContext().getTypeSize(IV->getType()), IV));
1718 continue;
1719 }
1720 if (!data().IvarList)
1721 data().IvarList = IV;
1722 else
1723 curIvar->setNextIvar(IV);
1724 curIvar = IV;
1725 }
1726
1727 if (!layout.empty()) {
1728 // Order synthesized ivars by their size.
1729 llvm::stable_sort(Range&: layout);
1730 unsigned Ix = 0, EIx = layout.size();
1731 if (!data().IvarList) {
1732 data().IvarList = layout[0].Ivar; Ix++;
1733 curIvar = data().IvarList;
1734 }
1735 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1736 curIvar->setNextIvar(layout[Ix].Ivar);
1737 }
1738 }
1739 }
1740 return data().IvarList;
1741}
1742
1743/// FindCategoryDeclaration - Finds category declaration in the list of
1744/// categories for this class and returns it. Name of the category is passed
1745/// in 'CategoryId'. If category not found, return 0;
1746///
1747ObjCCategoryDecl *ObjCInterfaceDecl::FindCategoryDeclaration(
1748 const IdentifierInfo *CategoryId) const {
1749 // FIXME: Should make sure no callers ever do this.
1750 if (!hasDefinition())
1751 return nullptr;
1752
1753 if (data().ExternallyCompleted)
1754 LoadExternalDefinition();
1755
1756 for (auto *Cat : visible_categories())
1757 if (Cat->getIdentifier() == CategoryId)
1758 return Cat;
1759
1760 return nullptr;
1761}
1762
1763ObjCMethodDecl *
1764ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
1765 for (const auto *Cat : visible_categories()) {
1766 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1767 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1768 return MD;
1769 }
1770
1771 return nullptr;
1772}
1773
1774ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
1775 for (const auto *Cat : visible_categories()) {
1776 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1777 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1778 return MD;
1779 }
1780
1781 return nullptr;
1782}
1783
1784/// ClassImplementsProtocol - Checks that 'lProto' protocol
1785/// has been implemented in IDecl class, its super class or categories (if
1786/// lookupCategory is true).
1787bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1788 bool lookupCategory,
1789 bool RHSIsQualifiedID) {
1790 if (!hasDefinition())
1791 return false;
1792
1793 ObjCInterfaceDecl *IDecl = this;
1794 // 1st, look up the class.
1795 for (auto *PI : IDecl->protocols()){
1796 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1797 return true;
1798 // This is dubious and is added to be compatible with gcc. In gcc, it is
1799 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1800 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1801 // object. This IMO, should be a bug.
1802 // FIXME: Treat this as an extension, and flag this as an error when GCC
1803 // extensions are not enabled.
1804 if (RHSIsQualifiedID &&
1805 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
1806 return true;
1807 }
1808
1809 // 2nd, look up the category.
1810 if (lookupCategory)
1811 for (const auto *Cat : visible_categories()) {
1812 for (auto *PI : Cat->protocols())
1813 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1814 return true;
1815 }
1816
1817 // 3rd, look up the super class(s)
1818 if (IDecl->getSuperClass())
1819 return
1820 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1821 RHSIsQualifiedID);
1822
1823 return false;
1824}
1825
1826//===----------------------------------------------------------------------===//
1827// ObjCIvarDecl
1828//===----------------------------------------------------------------------===//
1829
1830void ObjCIvarDecl::anchor() {}
1831
1832ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
1833 SourceLocation StartLoc,
1834 SourceLocation IdLoc,
1835 const IdentifierInfo *Id, QualType T,
1836 TypeSourceInfo *TInfo, AccessControl ac,
1837 Expr *BW, bool synthesized) {
1838 if (DC) {
1839 // Ivar's can only appear in interfaces, implementations (via synthesized
1840 // properties), and class extensions (via direct declaration, or synthesized
1841 // properties).
1842 //
1843 // FIXME: This should really be asserting this:
1844 // (isa<ObjCCategoryDecl>(DC) &&
1845 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1846 // but unfortunately we sometimes place ivars into non-class extension
1847 // categories on error. This breaks an AST invariant, and should not be
1848 // fixed.
1849 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1850 isa<ObjCCategoryDecl>(DC)) &&
1851 "Invalid ivar decl context!");
1852 // Once a new ivar is created in any of class/class-extension/implementation
1853 // decl contexts, the previously built IvarList must be rebuilt.
1854 auto *ID = dyn_cast<ObjCInterfaceDecl>(Val: DC);
1855 if (!ID) {
1856 if (auto *IM = dyn_cast<ObjCImplementationDecl>(Val: DC))
1857 ID = IM->getClassInterface();
1858 else
1859 ID = cast<ObjCCategoryDecl>(Val: DC)->getClassInterface();
1860 }
1861 ID->setIvarList(nullptr);
1862 }
1863
1864 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1865 synthesized);
1866}
1867
1868ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) {
1869 return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1870 nullptr, QualType(), nullptr,
1871 ObjCIvarDecl::None, nullptr, false);
1872}
1873
1874ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() {
1875 auto *DC = cast<ObjCContainerDecl>(getDeclContext());
1876
1877 switch (DC->getKind()) {
1878 default:
1879 case ObjCCategoryImpl:
1880 case ObjCProtocol:
1881 llvm_unreachable("invalid ivar container!");
1882
1883 // Ivars can only appear in class extension categories.
1884 case ObjCCategory: {
1885 auto *CD = cast<ObjCCategoryDecl>(DC);
1886 assert(CD->IsClassExtension() && "invalid container for ivar!");
1887 return CD->getClassInterface();
1888 }
1889
1890 case ObjCImplementation:
1891 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1892
1893 case ObjCInterface:
1894 return cast<ObjCInterfaceDecl>(DC);
1895 }
1896}
1897
1898QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
1899 return getType().substObjCMemberType(objectType, getDeclContext(),
1900 ObjCSubstitutionContext::Property);
1901}
1902
1903//===----------------------------------------------------------------------===//
1904// ObjCAtDefsFieldDecl
1905//===----------------------------------------------------------------------===//
1906
1907void ObjCAtDefsFieldDecl::anchor() {}
1908
1909ObjCAtDefsFieldDecl
1910*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1911 SourceLocation StartLoc, SourceLocation IdLoc,
1912 IdentifierInfo *Id, QualType T, Expr *BW) {
1913 return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1914}
1915
1916ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
1917 Decl::DeclID ID) {
1918 return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
1919 SourceLocation(), nullptr, QualType(),
1920 nullptr);
1921}
1922
1923//===----------------------------------------------------------------------===//
1924// ObjCProtocolDecl
1925//===----------------------------------------------------------------------===//
1926
1927void ObjCProtocolDecl::anchor() {}
1928
1929ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
1930 IdentifierInfo *Id, SourceLocation nameLoc,
1931 SourceLocation atStartLoc,
1932 ObjCProtocolDecl *PrevDecl)
1933 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
1934 redeclarable_base(C) {
1935 setPreviousDecl(PrevDecl);
1936 if (PrevDecl)
1937 Data = PrevDecl->Data;
1938}
1939
1940ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
1941 IdentifierInfo *Id,
1942 SourceLocation nameLoc,
1943 SourceLocation atStartLoc,
1944 ObjCProtocolDecl *PrevDecl) {
1945 auto *Result =
1946 new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
1947 Result->Data.setInt(!C.getLangOpts().Modules);
1948 return Result;
1949}
1950
1951ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
1952 Decl::DeclID ID) {
1953 ObjCProtocolDecl *Result =
1954 new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
1955 SourceLocation(), nullptr);
1956 Result->Data.setInt(!C.getLangOpts().Modules);
1957 return Result;
1958}
1959
1960bool ObjCProtocolDecl::isNonRuntimeProtocol() const {
1961 return hasAttr<ObjCNonRuntimeProtocolAttr>();
1962}
1963
1964void ObjCProtocolDecl::getImpliedProtocols(
1965 llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const {
1966 std::queue<const ObjCProtocolDecl *> WorkQueue;
1967 WorkQueue.push(x: this);
1968
1969 while (!WorkQueue.empty()) {
1970 const auto *PD = WorkQueue.front();
1971 WorkQueue.pop();
1972 for (const auto *Parent : PD->protocols()) {
1973 const auto *Can = Parent->getCanonicalDecl();
1974 auto Result = IPs.insert(V: Can);
1975 if (Result.second)
1976 WorkQueue.push(x: Parent);
1977 }
1978 }
1979}
1980
1981ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1982 ObjCProtocolDecl *PDecl = this;
1983
1984 if (Name == getIdentifier())
1985 return PDecl;
1986
1987 for (auto *I : protocols())
1988 if ((PDecl = I->lookupProtocolNamed(Name)))
1989 return PDecl;
1990
1991 return nullptr;
1992}
1993
1994// lookupMethod - Lookup a instance/class method in the protocol and protocols
1995// it inherited.
1996ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1997 bool isInstance) const {
1998 ObjCMethodDecl *MethodDecl = nullptr;
1999
2000 // If there is no definition or the definition is hidden, we don't find
2001 // anything.
2002 const ObjCProtocolDecl *Def = getDefinition();
2003 if (!Def || !Def->isUnconditionallyVisible())
2004 return nullptr;
2005
2006 if ((MethodDecl = getMethod(Sel, isInstance)))
2007 return MethodDecl;
2008
2009 for (const auto *I : protocols())
2010 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
2011 return MethodDecl;
2012 return nullptr;
2013}
2014
2015void ObjCProtocolDecl::allocateDefinitionData() {
2016 assert(!Data.getPointer() && "Protocol already has a definition!");
2017 Data.setPointer(new (getASTContext()) DefinitionData);
2018 Data.getPointer()->Definition = this;
2019 Data.getPointer()->HasODRHash = false;
2020}
2021
2022void ObjCProtocolDecl::startDefinition() {
2023 allocateDefinitionData();
2024
2025 // Update all of the declarations with a pointer to the definition.
2026 for (auto *RD : redecls())
2027 RD->Data = this->Data;
2028}
2029
2030void ObjCProtocolDecl::startDuplicateDefinitionForComparison() {
2031 Data.setPointer(nullptr);
2032 allocateDefinitionData();
2033 // Don't propagate data to other redeclarations.
2034}
2035
2036void ObjCProtocolDecl::mergeDuplicateDefinitionWithCommon(
2037 const ObjCProtocolDecl *Definition) {
2038 Data = Definition->Data;
2039}
2040
2041void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM) const {
2042 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2043 for (auto *Prop : PDecl->properties()) {
2044 // Insert into PM if not there already.
2045 PM.insert(std::make_pair(
2046 std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
2047 Prop));
2048 }
2049 // Scan through protocol's protocols.
2050 for (const auto *PI : PDecl->protocols())
2051 PI->collectPropertiesToImplement(PM);
2052 }
2053}
2054
2055void ObjCProtocolDecl::collectInheritedProtocolProperties(
2056 const ObjCPropertyDecl *Property, ProtocolPropertySet &PS,
2057 PropertyDeclOrder &PO) const {
2058 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2059 if (!PS.insert(V: PDecl).second)
2060 return;
2061 for (auto *Prop : PDecl->properties()) {
2062 if (Prop == Property)
2063 continue;
2064 if (Prop->getIdentifier() == Property->getIdentifier()) {
2065 PO.push_back(Prop);
2066 return;
2067 }
2068 }
2069 // Scan through protocol's protocols which did not have a matching property.
2070 for (const auto *PI : PDecl->protocols())
2071 PI->collectInheritedProtocolProperties(Property, PS, PO);
2072 }
2073}
2074
2075StringRef
2076ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
2077 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
2078 return ObjCRTName->getMetadataName();
2079
2080 return getName();
2081}
2082
2083unsigned ObjCProtocolDecl::getODRHash() {
2084 assert(hasDefinition() && "ODRHash only for records with definitions");
2085
2086 // Previously calculated hash is stored in DefinitionData.
2087 if (hasODRHash())
2088 return data().ODRHash;
2089
2090 // Only calculate hash on first call of getODRHash per record.
2091 ODRHash Hasher;
2092 Hasher.AddObjCProtocolDecl(P: getDefinition());
2093 data().ODRHash = Hasher.CalculateHash();
2094 setHasODRHash(true);
2095
2096 return data().ODRHash;
2097}
2098
2099bool ObjCProtocolDecl::hasODRHash() const {
2100 if (!hasDefinition())
2101 return false;
2102 return data().HasODRHash;
2103}
2104
2105void ObjCProtocolDecl::setHasODRHash(bool HasHash) {
2106 assert(hasDefinition() && "Cannot set ODRHash without definition");
2107 data().HasODRHash = HasHash;
2108}
2109
2110//===----------------------------------------------------------------------===//
2111// ObjCCategoryDecl
2112//===----------------------------------------------------------------------===//
2113
2114void ObjCCategoryDecl::anchor() {}
2115
2116ObjCCategoryDecl::ObjCCategoryDecl(
2117 DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc,
2118 SourceLocation CategoryNameLoc, const IdentifierInfo *Id,
2119 ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList,
2120 SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc)
2121 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
2122 ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
2123 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
2124 setTypeParamList(typeParamList);
2125}
2126
2127ObjCCategoryDecl *ObjCCategoryDecl::Create(
2128 ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
2129 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
2130 const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
2131 ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,
2132 SourceLocation IvarRBraceLoc) {
2133 auto *CatDecl =
2134 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
2135 IDecl, typeParamList, IvarLBraceLoc,
2136 IvarRBraceLoc);
2137 if (IDecl) {
2138 // Link this category into its class's category list.
2139 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
2140 if (IDecl->hasDefinition()) {
2141 IDecl->setCategoryListRaw(CatDecl);
2142 if (ASTMutationListener *L = C.getASTMutationListener())
2143 L->AddedObjCCategoryToInterface(CatD: CatDecl, IFD: IDecl);
2144 }
2145 }
2146
2147 return CatDecl;
2148}
2149
2150ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
2151 Decl::DeclID ID) {
2152 return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
2153 SourceLocation(), SourceLocation(),
2154 nullptr, nullptr, nullptr);
2155}
2156
2157ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
2158 return getASTContext().getObjCImplementation(
2159 const_cast<ObjCCategoryDecl*>(this));
2160}
2161
2162void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
2163 getASTContext().setObjCImplementation(this, ImplD);
2164}
2165
2166void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) {
2167 TypeParamList = TPL;
2168 if (!TPL)
2169 return;
2170 // Set the declaration context of each of the type parameters.
2171 for (auto *typeParam : *TypeParamList)
2172 typeParam->setDeclContext(this);
2173}
2174
2175//===----------------------------------------------------------------------===//
2176// ObjCCategoryImplDecl
2177//===----------------------------------------------------------------------===//
2178
2179void ObjCCategoryImplDecl::anchor() {}
2180
2181ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create(
2182 ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,
2183 ObjCInterfaceDecl *ClassInterface, SourceLocation nameLoc,
2184 SourceLocation atStartLoc, SourceLocation CategoryNameLoc) {
2185 if (ClassInterface && ClassInterface->hasDefinition())
2186 ClassInterface = ClassInterface->getDefinition();
2187 return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
2188 atStartLoc, CategoryNameLoc);
2189}
2190
2191ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
2192 Decl::DeclID ID) {
2193 return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
2194 SourceLocation(), SourceLocation(),
2195 SourceLocation());
2196}
2197
2198ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
2199 // The class interface might be NULL if we are working with invalid code.
2200 if (const ObjCInterfaceDecl *ID = getClassInterface())
2201 return ID->FindCategoryDeclaration(CategoryId: getIdentifier());
2202 return nullptr;
2203}
2204
2205void ObjCImplDecl::anchor() {}
2206
2207void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
2208 // FIXME: The context should be correct before we get here.
2209 property->setLexicalDeclContext(this);
2210 addDecl(property);
2211}
2212
2213void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
2214 ASTContext &Ctx = getASTContext();
2215
2216 if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(Val: this)) {
2217 if (IFace)
2218 Ctx.setObjCImplementation(IFaceD: IFace, ImplD);
2219
2220 } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(Val: this)) {
2221 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(CategoryId: getIdentifier()))
2222 Ctx.setObjCImplementation(CatD: CD, ImplD);
2223 }
2224
2225 ClassInterface = IFace;
2226}
2227
2228/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
2229/// properties implemented in this \@implementation block and returns
2230/// the implemented property that uses it.
2231ObjCPropertyImplDecl *ObjCImplDecl::
2232FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
2233 for (auto *PID : property_impls())
2234 if (PID->getPropertyIvarDecl() &&
2235 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
2236 return PID;
2237 return nullptr;
2238}
2239
2240/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
2241/// added to the list of those properties \@synthesized/\@dynamic in this
2242/// category \@implementation block.
2243ObjCPropertyImplDecl *ObjCImplDecl::
2244FindPropertyImplDecl(IdentifierInfo *Id,
2245 ObjCPropertyQueryKind QueryKind) const {
2246 ObjCPropertyImplDecl *ClassPropImpl = nullptr;
2247 for (auto *PID : property_impls())
2248 // If queryKind is unknown, we return the instance property if one
2249 // exists; otherwise we return the class property.
2250 if (PID->getPropertyDecl()->getIdentifier() == Id) {
2251 if ((QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown &&
2252 !PID->getPropertyDecl()->isClassProperty()) ||
2253 (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_class &&
2254 PID->getPropertyDecl()->isClassProperty()) ||
2255 (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance &&
2256 !PID->getPropertyDecl()->isClassProperty()))
2257 return PID;
2258
2259 if (PID->getPropertyDecl()->isClassProperty())
2260 ClassPropImpl = PID;
2261 }
2262
2263 if (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown)
2264 // We can't find the instance property, return the class property.
2265 return ClassPropImpl;
2266
2267 return nullptr;
2268}
2269
2270raw_ostream &clang::operator<<(raw_ostream &OS,
2271 const ObjCCategoryImplDecl &CID) {
2272 OS << CID.getName();
2273 return OS;
2274}
2275
2276//===----------------------------------------------------------------------===//
2277// ObjCImplementationDecl
2278//===----------------------------------------------------------------------===//
2279
2280void ObjCImplementationDecl::anchor() {}
2281
2282ObjCImplementationDecl *
2283ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
2284 ObjCInterfaceDecl *ClassInterface,
2285 ObjCInterfaceDecl *SuperDecl,
2286 SourceLocation nameLoc,
2287 SourceLocation atStartLoc,
2288 SourceLocation superLoc,
2289 SourceLocation IvarLBraceLoc,
2290 SourceLocation IvarRBraceLoc) {
2291 if (ClassInterface && ClassInterface->hasDefinition())
2292 ClassInterface = ClassInterface->getDefinition();
2293 return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
2294 nameLoc, atStartLoc, superLoc,
2295 IvarLBraceLoc, IvarRBraceLoc);
2296}
2297
2298ObjCImplementationDecl *
2299ObjCImplementationDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) {
2300 return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
2301 SourceLocation(), SourceLocation());
2302}
2303
2304void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
2305 CXXCtorInitializer ** initializers,
2306 unsigned numInitializers) {
2307 if (numInitializers > 0) {
2308 NumIvarInitializers = numInitializers;
2309 auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];
2310 memcpy(dest: ivarInitializers, src: initializers,
2311 n: numInitializers * sizeof(CXXCtorInitializer*));
2312 IvarInitializers = ivarInitializers;
2313 }
2314}
2315
2316ObjCImplementationDecl::init_const_iterator
2317ObjCImplementationDecl::init_begin() const {
2318 return IvarInitializers.get(Source: getASTContext().getExternalSource());
2319}
2320
2321raw_ostream &clang::operator<<(raw_ostream &OS,
2322 const ObjCImplementationDecl &ID) {
2323 OS << ID.getName();
2324 return OS;
2325}
2326
2327//===----------------------------------------------------------------------===//
2328// ObjCCompatibleAliasDecl
2329//===----------------------------------------------------------------------===//
2330
2331void ObjCCompatibleAliasDecl::anchor() {}
2332
2333ObjCCompatibleAliasDecl *
2334ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
2335 SourceLocation L,
2336 IdentifierInfo *Id,
2337 ObjCInterfaceDecl* AliasedClass) {
2338 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
2339}
2340
2341ObjCCompatibleAliasDecl *
2342ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) {
2343 return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
2344 nullptr, nullptr);
2345}
2346
2347//===----------------------------------------------------------------------===//
2348// ObjCPropertyDecl
2349//===----------------------------------------------------------------------===//
2350
2351void ObjCPropertyDecl::anchor() {}
2352
2353ObjCPropertyDecl *
2354ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
2355 const IdentifierInfo *Id, SourceLocation AtLoc,
2356 SourceLocation LParenLoc, QualType T,
2357 TypeSourceInfo *TSI, PropertyControl propControl) {
2358 return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
2359 propControl);
2360}
2361
2362ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
2363 Decl::DeclID ID) {
2364 return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
2365 SourceLocation(), SourceLocation(),
2366 QualType(), nullptr, None);
2367}
2368
2369QualType ObjCPropertyDecl::getUsageType(QualType objectType) const {
2370 return DeclType.substObjCMemberType(objectType, getDeclContext(),
2371 ObjCSubstitutionContext::Property);
2372}
2373
2374bool ObjCPropertyDecl::isDirectProperty() const {
2375 return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
2376 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
2377}
2378
2379//===----------------------------------------------------------------------===//
2380// ObjCPropertyImplDecl
2381//===----------------------------------------------------------------------===//
2382
2383ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
2384 DeclContext *DC,
2385 SourceLocation atLoc,
2386 SourceLocation L,
2387 ObjCPropertyDecl *property,
2388 Kind PK,
2389 ObjCIvarDecl *ivar,
2390 SourceLocation ivarLoc) {
2391 return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
2392 ivarLoc);
2393}
2394
2395ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
2396 Decl::DeclID ID) {
2397 return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
2398 SourceLocation(), nullptr, Dynamic,
2399 nullptr, SourceLocation());
2400}
2401
2402SourceRange ObjCPropertyImplDecl::getSourceRange() const {
2403 SourceLocation EndLoc = getLocation();
2404 if (IvarLoc.isValid())
2405 EndLoc = IvarLoc;
2406
2407 return SourceRange(AtLoc, EndLoc);
2408}
2409

source code of clang/lib/AST/DeclObjC.cpp