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