clang 20.0.0git
DeclObjC.cpp
Go to the documentation of this file.
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"
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"
24#include "clang/Basic/LLVM.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(List, InList, 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(Locations, Locs, sizeof(SourceLocation) * Elts);
61 set(InList, Elts, Ctx);
62}
63
64//===----------------------------------------------------------------------===//
65// ObjCInterfaceDecl
66//===----------------------------------------------------------------------===//
67
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///
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.
94 bool AllowHidden) const {
95 // If this context is a hidden protocol definition, don't find any
96 // methods there.
97 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
98 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
99 if (!Def->isUnconditionallyVisible() && !AllowHidden)
100 return nullptr;
101 }
102
103 // Since instance & class methods can have the same name, the loop below
104 // ensures we get the correct method.
105 //
106 // @interface Whatever
107 // - (int) class_method;
108 // + (float) class_method;
109 // @end
110 lookup_result R = lookup(Sel);
111 for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
112 Meth != MethEnd; ++Meth) {
113 auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
114 if (MD && MD->isInstanceMethod() == isInstance)
115 return MD;
116 }
117 return nullptr;
118}
119
120/// This routine returns 'true' if a user declared setter method was
121/// found in the class, its protocols, its super classes or categories.
122/// It also returns 'true' if one of its categories has declared a 'readwrite'
123/// property. This is because, user must provide a setter method for the
124/// category's 'readwrite' property.
126 const ObjCPropertyDecl *Property) const {
127 Selector Sel = Property->getSetterName();
128 lookup_result R = lookup(Sel);
129 for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
130 Meth != MethEnd; ++Meth) {
131 auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
132 if (MD && MD->isInstanceMethod() && !MD->isImplicit())
133 return true;
134 }
135
136 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
137 // Also look into categories, including class extensions, looking
138 // for a user declared instance method.
139 for (const auto *Cat : ID->visible_categories()) {
140 if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
141 if (!MD->isImplicit())
142 return true;
143 if (Cat->IsClassExtension())
144 continue;
145 // Also search through the categories looking for a 'readwrite'
146 // declaration of this property. If one found, presumably a setter will
147 // be provided (properties declared in categories will not get
148 // auto-synthesized).
149 for (const auto *P : Cat->properties())
150 if (P->getIdentifier() == Property->getIdentifier()) {
151 if (P->getPropertyAttributes() &
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) {
167 return true;
168 OSC = OSC->getSuperClass();
169 }
170 }
171 if (const auto *PD = dyn_cast<ObjCProtocolDecl>(this))
172 for (const auto *PI : PD->protocols())
173 if (PI->HasUserDeclaredSetterMethod(Property))
174 return true;
175 return false;
176}
177
180 const IdentifierInfo *propertyID,
181 ObjCPropertyQueryKind queryKind) {
182 // If this context is a hidden protocol definition, don't find any
183 // property.
184 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
185 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
186 if (!Def->isUnconditionallyVisible())
187 return nullptr;
188 }
189
190 // If context is class, then lookup property in its visible extensions.
191 // This comes before property is looked up in primary class.
192 if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
193 for (const auto *Ext : IDecl->visible_extensions())
195 propertyID,
196 queryKind))
197 return PD;
198 }
199
200 DeclContext::lookup_result R = DC->lookup(propertyID);
201 ObjCPropertyDecl *classProp = nullptr;
202 for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
203 ++I)
204 if (auto *PD = dyn_cast<ObjCPropertyDecl>(*I)) {
205 // If queryKind is unknown, we return the instance property if one
206 // exists; otherwise we return the class property.
208 !PD->isClassProperty()) ||
210 PD->isClassProperty()) ||
212 !PD->isClassProperty()))
213 return PD;
214
215 if (PD->isClassProperty())
216 classProp = PD;
217 }
218
220 // We can't find the instance property, return the class property.
221 return classProp;
222
223 return nullptr;
224}
225
228 SmallString<128> ivarName;
229 {
230 llvm::raw_svector_ostream os(ivarName);
231 os << '_' << getIdentifier()->getName();
232 }
233 return &Ctx.Idents.get(ivarName.str());
234}
235
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.
251 const IdentifierInfo *PropertyId,
252 ObjCPropertyQueryKind QueryKind) const {
253 // Don't find properties within hidden protocol definitions.
254 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
255 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
256 if (!Def->isUnconditionallyVisible())
257 return nullptr;
258 }
259
260 // Search the extensions of a class first; they override what's in
261 // the class itself.
262 if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) {
263 for (const auto *Ext : ClassDecl->visible_extensions()) {
264 if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind))
265 return P;
266 }
267 }
268
269 if (ObjCPropertyDecl *PD =
270 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
271 QueryKind))
272 return PD;
273
274 switch (getKind()) {
275 default:
276 break;
277 case Decl::ObjCProtocol: {
278 const auto *PID = cast<ObjCProtocolDecl>(this);
279 for (const auto *I : PID->protocols())
280 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
281 QueryKind))
282 return P;
283 break;
284 }
285 case Decl::ObjCInterface: {
286 const auto *OID = cast<ObjCInterfaceDecl>(this);
287 // Look through categories (but not extensions; they were handled above).
288 for (const auto *Cat : OID->visible_categories()) {
289 if (!Cat->IsClassExtension())
290 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(
291 PropertyId, QueryKind))
292 return P;
293 }
294
295 // Look through protocols.
296 for (const auto *I : OID->all_referenced_protocols())
297 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
298 QueryKind))
299 return P;
300
301 // Finally, check the super class.
302 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
303 return superClass->FindPropertyDeclaration(PropertyId, QueryKind);
304 break;
305 }
306 case Decl::ObjCCategory: {
307 const auto *OCD = cast<ObjCCategoryDecl>(this);
308 // Look through protocols.
309 if (!OCD->IsClassExtension())
310 for (const auto *I : OCD->protocols())
311 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
312 QueryKind))
313 return P;
314 break;
315 }
316 }
317 return nullptr;
318}
319
320void ObjCInterfaceDecl::anchor() {}
321
323 // If this particular declaration has a type parameter list, return it.
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.
335 decl = decl->getPreviousDecl()) {
336 if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten())
337 return written;
338 }
339
340 return nullptr;
341}
342
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
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
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.
383 const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const {
384 // FIXME: Should make sure no callers ever do this.
385 if (!hasDefinition())
386 return nullptr;
387
388 if (data().ExternallyCompleted)
389 LoadExternalDefinition();
390
391 if (ObjCPropertyDecl *PD =
392 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
393 QueryKind))
394 return PD;
395
396 // Look through protocols.
397 for (const auto *I : all_referenced_protocols())
398 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
399 QueryKind))
400 return P;
401
402 return nullptr;
403}
404
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())
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
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
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
443 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
444 ASTContext &C) {
445 if (data().ExternallyCompleted)
446 LoadExternalDefinition();
447
448 if (data().AllReferencedProtocols.empty() &&
449 data().ReferencedProtocols.empty()) {
450 data().AllReferencedProtocols.set(ExtList, ExtNum, C);
451 return;
452 }
453
454 // Check for duplicate protocol in class's protocol list.
455 // This is O(n*m). But it is extremely rare and number of protocols in
456 // class or its extension are very few.
458 for (unsigned i = 0; i < ExtNum; i++) {
459 bool protocolExists = false;
460 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
461 for (auto *Proto : all_referenced_protocols()) {
462 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
463 protocolExists = true;
464 break;
465 }
466 }
467 // Do we want to warn on a protocol in extension class which
468 // already exist in the class? Probably not.
469 if (!protocolExists)
470 ProtocolRefs.push_back(ProtoInExtension);
471 }
472
473 if (ProtocolRefs.empty())
474 return;
475
476 // Merge ProtocolRefs into class's protocol list;
477 ProtocolRefs.append(all_referenced_protocol_begin(),
479
480 data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),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
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(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
550 // Check for a complete definition and recover if not so.
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
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() &&
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
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
627 Data.setPointer(nullptr);
628 allocateDefinitionData();
629 // Don't propagate data to other redeclarations.
630}
631
634 Data = Definition->Data;
635}
636
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.
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
688 for (auto *P : all_referenced_protocols())
689 if (P->lookupProtocolNamed(Name))
690 return P;
691 ObjCInterfaceDecl *SuperClass = getSuperClass();
692 return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
693}
694
695/// lookupMethod - This method returns an instance/class method by looking in
696/// the class, its categories, and its super classes (using a linear search).
697/// When argument category "C" is specified, any implicit method found
698/// in this category is ignored.
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.
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;
768 Method = Instance ? ImpDecl->getInstanceMethod(Sel)
769 : ImpDecl->getClassMethod(Sel);
770
771 // Look through local category implementations associated with the class.
772 if (!Method)
773 Method = getCategoryMethod(Sel, Instance);
774
775 // Before we give up, check if the selector is an instance method.
776 // But only in the root. This matches gcc's behavior and what the
777 // runtime expects.
778 if (!Instance && !Method && !getSuperClass()) {
779 Method = lookupInstanceMethod(Sel);
780 // Look through local category implementations associated
781 // with the root class.
782 if (!Method)
783 Method = lookupPrivateMethod(Sel, true);
784 }
785
786 if (!Method && getSuperClass())
787 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
788 return Method;
789}
790
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;
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 =
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
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,
862 isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);
863}
864
866 GlobalDeclID ID) {
867 return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
868 Selector(), QualType(), nullptr, nullptr);
869}
870
872 return hasAttr<ObjCDirectAttr>() &&
873 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
874}
875
877 return getMethodFamily() == OMF_init &&
878 hasAttr<ObjCDesignatedInitializerAttr>();
879}
880
882 if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext()))
883 return PD->getIdentifier() == Ctx.getNSObjectName();
884 if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext()))
885 return ID->getIdentifier() == Ctx.getNSObjectName();
886 return false;
887}
888
890 const ObjCMethodDecl **InitMethod) const {
891 if (getMethodFamily() != OMF_init)
892 return false;
893 const DeclContext *DC = getDeclContext();
894 if (isa<ObjCProtocolDecl>(DC))
895 return false;
896 if (const ObjCInterfaceDecl *ID = getClassInterface())
897 return ID->isDesignatedInitializer(getSelector(), InitMethod);
898 return false;
899}
900
902 for (auto *param : parameters()) {
903 if (param->isDestroyedInCallee())
904 return true;
905 }
906 return false;
907}
908
910 return Body.get(getASTContext().getExternalSource());
911}
912
914 assert(PrevMethod);
915 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
916 setIsRedeclaration(true);
917 PrevMethod->setHasRedeclaration(true);
918}
919
920void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
922 ArrayRef<SourceLocation> SelLocs) {
923 ParamsAndSelLocs = nullptr;
924 NumParams = Params.size();
925 if (Params.empty() && SelLocs.empty())
926 return;
927
928 static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation),
929 "Alignment not sufficient for SourceLocation");
930
931 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
932 sizeof(SourceLocation) * SelLocs.size();
933 ParamsAndSelLocs = C.Allocate(Size);
934 std::uninitialized_copy(Params.begin(), Params.end(), getParams());
935 std::uninitialized_copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
936}
937
939 SmallVectorImpl<SourceLocation> &SelLocs) const {
940 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
941 SelLocs.push_back(getSelectorLoc(i));
942}
943
946 ArrayRef<SourceLocation> SelLocs) {
947 assert((!SelLocs.empty() || isImplicit()) &&
948 "No selector locs for non-implicit method");
949 if (isImplicit())
950 return setParamsAndSelLocs(C, Params, std::nullopt);
951
952 setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params,
953 DeclEndLoc));
954 if (getSelLocsKind() != SelLoc_NonStandard)
955 return setParamsAndSelLocs(C, Params, std::nullopt);
956
957 setParamsAndSelLocs(C, Params, SelLocs);
958}
959
960/// A definition will return its interface declaration.
961/// An interface declaration will return its definition.
962/// Otherwise it will return itself.
963ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
964 ASTContext &Ctx = getASTContext();
965 ObjCMethodDecl *Redecl = nullptr;
966 if (hasRedeclaration())
967 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
968 if (Redecl)
969 return Redecl;
970
971 auto *CtxD = cast<Decl>(getDeclContext());
972
973 if (!CtxD->isInvalidDecl()) {
974 if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
975 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
976 if (!ImplD->isInvalidDecl())
977 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
978
979 } else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
980 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
981 if (!ImplD->isInvalidDecl())
982 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
983
984 } else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
985 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
986 if (!IFD->isInvalidDecl())
987 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
988
989 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
990 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
991 if (!CatD->isInvalidDecl())
992 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
993 }
994 }
995
996 // Ensure that the discovered method redeclaration has a valid declaration
997 // context. Used to prevent infinite loops when iterating redeclarations in
998 // a partially invalid AST.
999 if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl())
1000 Redecl = nullptr;
1001
1002 if (!Redecl && isRedeclaration()) {
1003 // This is the last redeclaration, go back to the first method.
1004 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
1006 /*AllowHidden=*/true);
1007 }
1008
1009 return Redecl ? Redecl : this;
1010}
1011
1013 auto *CtxD = cast<Decl>(getDeclContext());
1014 const auto &Sel = getSelector();
1015
1016 if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
1017 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) {
1018 // When the container is the ObjCImplementationDecl (the primary
1019 // @implementation), then the canonical Decl is either in
1020 // the class Interface, or in any of its extension.
1021 //
1022 // So when we don't find it in the ObjCInterfaceDecl,
1023 // sift through extensions too.
1024 if (ObjCMethodDecl *MD = IFD->getMethod(Sel, isInstanceMethod()))
1025 return MD;
1026 for (auto *Ext : IFD->known_extensions())
1027 if (ObjCMethodDecl *MD = Ext->getMethod(Sel, isInstanceMethod()))
1028 return MD;
1029 }
1030 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
1031 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
1032 if (ObjCMethodDecl *MD = CatD->getMethod(Sel, isInstanceMethod()))
1033 return MD;
1034 }
1035
1036 if (isRedeclaration()) {
1037 // It is possible that we have not done deserializing the ObjCMethod yet.
1038 ObjCMethodDecl *MD =
1039 cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
1040 /*AllowHidden=*/true);
1041 return MD ? MD : this;
1042 }
1043
1044 return this;
1045}
1046
1048 if (Stmt *Body = getBody())
1049 return Body->getEndLoc();
1050 return DeclEndLoc;
1051}
1052
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
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 {
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
1146 const ObjCInterfaceDecl *OID,
1147 bool &selfIsPseudoStrong,
1148 bool &selfIsConsumed) const {
1149 QualType selfTy;
1150 selfIsPseudoStrong = false;
1151 selfIsConsumed = false;
1152 if (isInstanceMethod()) {
1153 // There may be no interface context due to error in declaration
1154 // of the interface (which has been reported). Recover gracefully.
1155 if (OID) {
1156 selfTy = Context.getObjCInterfaceType(OID);
1157 selfTy = Context.getObjCObjectPointerType(selfTy);
1158 } else {
1159 selfTy = Context.getObjCIdType();
1160 }
1161 } else // we have a factory method.
1162 selfTy = Context.getObjCClassType();
1163
1164 if (Context.getLangOpts().ObjCAutoRefCount) {
1165 if (isInstanceMethod()) {
1166 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
1167
1168 // 'self' is always __strong. It's actually pseudo-strong except
1169 // in init methods (or methods labeled ns_consumes_self), though.
1170 Qualifiers qs;
1172 selfTy = Context.getQualifiedType(selfTy, qs);
1173
1174 // In addition, 'self' is const unless this is an init method.
1175 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
1176 selfTy = selfTy.withConst();
1177 selfIsPseudoStrong = true;
1178 }
1179 }
1180 else {
1181 assert(isClassMethod());
1182 // 'self' is always const in class methods.
1183 selfTy = selfTy.withConst();
1184 selfIsPseudoStrong = true;
1185 }
1186 }
1187 return selfTy;
1188}
1189
1191 const ObjCInterfaceDecl *OID) {
1192 bool selfIsPseudoStrong, selfIsConsumed;
1193 QualType selfTy =
1194 getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
1195 auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),
1196 &Context.Idents.get("self"), selfTy,
1199
1200 if (selfIsConsumed)
1201 Self->addAttr(NSConsumedAttr::CreateImplicit(Context));
1202
1203 if (selfIsPseudoStrong)
1204 Self->setARCPseudoStrong(true);
1205
1207 Context, this, SourceLocation(), &Context.Idents.get("_cmd"),
1209}
1210
1212 if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
1213 return ID;
1214 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1215 return CD->getClassInterface();
1216 if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
1217 return IMD->getClassInterface();
1218 if (isa<ObjCProtocolDecl>(getDeclContext()))
1219 return nullptr;
1220 llvm_unreachable("unknown method context");
1221}
1222
1224 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1225 return CD;
1226 if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
1227 return IMD->getCategoryDecl();
1228 return nullptr;
1229}
1230
1232 const auto *TSI = getReturnTypeSourceInfo();
1233 if (TSI)
1234 return TSI->getTypeLoc().getSourceRange();
1235 return SourceRange();
1236}
1237
1239 ASTContext &Ctx = getASTContext();
1242}
1243
1245 // FIXME: Handle related result types here.
1246
1248 .substObjCMemberType(receiverType, getDeclContext(),
1250}
1251
1253 const ObjCMethodDecl *Method,
1255 bool MovedToSuper) {
1256 if (!Container)
1257 return;
1258
1259 // In categories look for overridden methods from protocols. A method from
1260 // category is not "overridden" since it is considered as the "same" method
1261 // (same USR) as the one from the interface.
1262 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1263 // Check whether we have a matching method at this category but only if we
1264 // are at the super class level.
1265 if (MovedToSuper)
1266 if (ObjCMethodDecl *
1267 Overridden = Container->getMethod(Method->getSelector(),
1268 Method->isInstanceMethod(),
1269 /*AllowHidden=*/true))
1270 if (Method != Overridden) {
1271 // We found an override at this category; there is no need to look
1272 // into its protocols.
1273 Methods.push_back(Overridden);
1274 return;
1275 }
1276
1277 for (const auto *P : Category->protocols())
1278 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1279 return;
1280 }
1281
1282 // Check whether we have a matching method at this level.
1283 if (const ObjCMethodDecl *
1284 Overridden = Container->getMethod(Method->getSelector(),
1285 Method->isInstanceMethod(),
1286 /*AllowHidden=*/true))
1287 if (Method != Overridden) {
1288 // We found an override at this level; there is no need to look
1289 // into other protocols or categories.
1290 Methods.push_back(Overridden);
1291 return;
1292 }
1293
1294 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
1295 for (const auto *P : Protocol->protocols())
1296 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1297 }
1298
1299 if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
1300 for (const auto *P : Interface->protocols())
1301 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1302
1303 for (const auto *Cat : Interface->known_categories())
1304 CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
1305
1306 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
1307 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
1308 /*MovedToSuper=*/true);
1309 }
1310}
1311
1312static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
1313 const ObjCMethodDecl *Method,
1315 CollectOverriddenMethodsRecurse(Container, Method, Methods,
1316 /*MovedToSuper=*/false);
1317}
1318
1321 assert(Method->isOverriding());
1322
1323 if (const auto *ProtD =
1324 dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1325 CollectOverriddenMethods(ProtD, Method, overridden);
1326
1327 } else if (const auto *IMD =
1328 dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1329 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1330 if (!ID)
1331 return;
1332 // Start searching for overridden methods using the method from the
1333 // interface as starting point.
1334 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1335 Method->isInstanceMethod(),
1336 /*AllowHidden=*/true))
1337 Method = IFaceMeth;
1338 CollectOverriddenMethods(ID, Method, overridden);
1339
1340 } else if (const auto *CatD =
1341 dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1342 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1343 if (!ID)
1344 return;
1345 // Start searching for overridden methods using the method from the
1346 // interface as starting point.
1347 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1348 Method->isInstanceMethod(),
1349 /*AllowHidden=*/true))
1350 Method = IFaceMeth;
1351 CollectOverriddenMethods(ID, Method, overridden);
1352
1353 } else {
1355 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1356 Method, overridden);
1357 }
1358}
1359
1361 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1362 const ObjCMethodDecl *Method = this;
1363
1364 if (Method->isRedeclaration()) {
1365 Method = cast<ObjCContainerDecl>(Method->getDeclContext())
1366 ->getMethod(Method->getSelector(), Method->isInstanceMethod(),
1367 /*AllowHidden=*/true);
1368 }
1369
1370 if (Method->isOverriding()) {
1371 collectOverriddenMethodsSlow(Method, Overridden);
1372 assert(!Overridden.empty() &&
1373 "ObjCMethodDecl's overriding bit is not as expected");
1374 }
1375}
1376
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>(getParent());
1386 // For accessor stubs, go back to the interface.
1387 if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container))
1389 Container = ImplDecl->getClassInterface();
1390
1391 bool IsGetter = (NumArgs == 0);
1392 bool IsInstance = isInstanceMethod();
1393
1394 /// Local function that attempts to find a matching property within the
1395 /// given Objective-C container.
1396 auto findMatchingProperty =
1397 [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
1398 if (IsInstance) {
1399 for (const auto *I : Container->instance_properties()) {
1400 Selector NextSel = IsGetter ? I->getGetterName()
1401 : I->getSetterName();
1402 if (NextSel == Sel)
1403 return I;
1404 }
1405 } else {
1406 for (const auto *I : Container->class_properties()) {
1407 Selector NextSel = IsGetter ? I->getGetterName()
1408 : I->getSetterName();
1409 if (NextSel == Sel)
1410 return I;
1411 }
1412 }
1413
1414 return nullptr;
1415 };
1416
1417 // Look in the container we were given.
1418 if (const auto *Found = findMatchingProperty(Container))
1419 return Found;
1420
1421 // If we're in a category or extension, look in the main class.
1422 const ObjCInterfaceDecl *ClassDecl = nullptr;
1423 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1424 ClassDecl = Category->getClassInterface();
1425 if (const auto *Found = findMatchingProperty(ClassDecl))
1426 return Found;
1427 } else {
1428 // Determine whether the container is a class.
1429 ClassDecl = cast<ObjCInterfaceDecl>(Container);
1430 }
1431 assert(ClassDecl && "Failed to find main class");
1432
1433 // If we have a class, check its visible extensions.
1434 for (const auto *Ext : ClassDecl->visible_extensions()) {
1435 if (Ext == Container)
1436 continue;
1437 if (const auto *Found = findMatchingProperty(Ext))
1438 return Found;
1439 }
1440
1441 assert(isSynthesizedAccessorStub() && "expected an accessor stub");
1442
1443 for (const auto *Cat : ClassDecl->known_categories()) {
1444 if (Cat == Container)
1445 continue;
1446 if (const auto *Found = findMatchingProperty(Cat))
1447 return Found;
1448 }
1449
1450 llvm_unreachable("Marked as a property accessor but no property found!");
1451 }
1452
1453 if (!CheckOverrides)
1454 return nullptr;
1455
1456 using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;
1457
1458 OverridesTy Overrides;
1459 getOverriddenMethods(Overrides);
1460 for (const auto *Override : Overrides)
1461 if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(false))
1462 return Prop;
1463
1464 return nullptr;
1465}
1466
1467//===----------------------------------------------------------------------===//
1468// ObjCTypeParamDecl
1469//===----------------------------------------------------------------------===//
1470
1471void ObjCTypeParamDecl::anchor() {}
1472
1474 ObjCTypeParamVariance variance,
1475 SourceLocation varianceLoc,
1476 unsigned index,
1477 SourceLocation nameLoc,
1478 IdentifierInfo *name,
1479 SourceLocation colonLoc,
1480 TypeSourceInfo *boundInfo) {
1481 auto *TPDecl =
1482 new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
1483 nameLoc, name, colonLoc, boundInfo);
1484 QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});
1485 TPDecl->setTypeForDecl(TPType.getTypePtr());
1486 return TPDecl;
1487}
1488
1490 GlobalDeclID ID) {
1491 return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,
1494 nullptr, SourceLocation(), nullptr);
1495}
1496
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,
1515 SourceLocation rAngleLoc)
1516 : Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) {
1517 std::copy(typeParams.begin(), typeParams.end(), begin());
1518}
1519
1521 ASTContext &ctx,
1522 SourceLocation lAngleLoc,
1524 SourceLocation rAngleLoc) {
1525 void *mem =
1526 ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),
1527 alignof(ObjCTypeParamList));
1528 return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
1529}
1530
1532 SmallVectorImpl<QualType> &typeArgs) const {
1533 typeArgs.reserve(size());
1534 for (auto *typeParam : *this)
1535 typeArgs.push_back(typeParam->getUnderlyingType());
1536}
1537
1538//===----------------------------------------------------------------------===//
1539// ObjCInterfaceDecl
1540//===----------------------------------------------------------------------===//
1541
1543 const ASTContext &C, DeclContext *DC, SourceLocation atLoc,
1544 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1545 ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal) {
1546 auto *Result = new (C, DC)
1547 ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
1548 isInternal);
1549 Result->Data.setInt(!C.getLangOpts().Modules);
1550 C.getObjCInterfaceType(Result, PrevDecl);
1551 return Result;
1552}
1553
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;
1584 const_cast<ObjCInterfaceDecl *>(this));
1585}
1586
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
1596 // Check for a complete definition and recover if not so.
1598 return;
1599 data().HasDesignatedInitializers = true;
1600}
1601
1603 // Check for a complete definition and recover if not so.
1605 return false;
1606 if (data().ExternallyCompleted)
1607 LoadExternalDefinition();
1608
1609 return data().HasDesignatedInitializers;
1610}
1611
1612StringRef
1614 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1615 return ObjCRTName->getMetadataName();
1616
1617 return getName();
1618}
1619
1620StringRef
1622 if (ObjCInterfaceDecl *ID =
1623 const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
1624 return ID->getObjCRuntimeNameAsString();
1625
1626 return getName();
1627}
1628
1630 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1631 if (data().ExternallyCompleted)
1632 LoadExternalDefinition();
1633
1635 const_cast<ObjCInterfaceDecl*>(Def));
1636 }
1637
1638 // FIXME: Should make sure no callers ever do this.
1639 return nullptr;
1640}
1641
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().
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()) {
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()) {
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()) {
1715 for (auto *IV : ImplDecl->ivars()) {
1716 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1717 layout.push_back(SynthesizeIvarChunk(
1718 IV->getASTContext().getTypeSize(IV->getType()), IV));
1719 continue;
1720 }
1721 if (!data().IvarList)
1722 data().IvarList = IV;
1723 else
1724 curIvar->setNextIvar(IV);
1725 curIvar = IV;
1726 }
1727
1728 if (!layout.empty()) {
1729 // Order synthesized ivars by their size.
1730 llvm::stable_sort(layout);
1731 unsigned Ix = 0, EIx = layout.size();
1732 if (!data().IvarList) {
1733 data().IvarList = layout[0].Ivar; Ix++;
1734 curIvar = data().IvarList;
1735 }
1736 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1737 curIvar->setNextIvar(layout[Ix].Ivar);
1738 }
1739 }
1740 }
1741 return data().IvarList;
1742}
1743
1744/// FindCategoryDeclaration - Finds category declaration in the list of
1745/// categories for this class and returns it. Name of the category is passed
1746/// in 'CategoryId'. If category not found, return 0;
1747///
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
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
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).
1789 bool lookupCategory,
1790 bool RHSIsQualifiedID) {
1791 if (!hasDefinition())
1792 return false;
1793
1794 ObjCInterfaceDecl *IDecl = this;
1795 // 1st, look up the class.
1796 for (auto *PI : IDecl->protocols()){
1797 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1798 return true;
1799 // This is dubious and is added to be compatible with gcc. In gcc, it is
1800 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1801 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1802 // object. This IMO, should be a bug.
1803 // FIXME: Treat this as an extension, and flag this as an error when GCC
1804 // extensions are not enabled.
1805 if (RHSIsQualifiedID &&
1806 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
1807 return true;
1808 }
1809
1810 // 2nd, look up the category.
1811 if (lookupCategory)
1812 for (const auto *Cat : visible_categories()) {
1813 for (auto *PI : Cat->protocols())
1814 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1815 return true;
1816 }
1817
1818 // 3rd, look up the super class(s)
1819 if (IDecl->getSuperClass())
1820 return
1821 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1822 RHSIsQualifiedID);
1823
1824 return false;
1825}
1826
1827//===----------------------------------------------------------------------===//
1828// ObjCIvarDecl
1829//===----------------------------------------------------------------------===//
1830
1831void ObjCIvarDecl::anchor() {}
1832
1834 SourceLocation StartLoc,
1835 SourceLocation IdLoc,
1836 const IdentifierInfo *Id, QualType T,
1837 TypeSourceInfo *TInfo, AccessControl ac,
1838 Expr *BW, bool synthesized) {
1839 if (DC) {
1840 // Ivar's can only appear in interfaces, implementations (via synthesized
1841 // properties), and class extensions (via direct declaration, or synthesized
1842 // properties).
1843 //
1844 // FIXME: This should really be asserting this:
1845 // (isa<ObjCCategoryDecl>(DC) &&
1846 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1847 // but unfortunately we sometimes place ivars into non-class extension
1848 // categories on error. This breaks an AST invariant, and should not be
1849 // fixed.
1850 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1851 isa<ObjCCategoryDecl>(DC)) &&
1852 "Invalid ivar decl context!");
1853 // Once a new ivar is created in any of class/class-extension/implementation
1854 // decl contexts, the previously built IvarList must be rebuilt.
1855 auto *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1856 if (!ID) {
1857 if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC))
1858 ID = IM->getClassInterface();
1859 else
1860 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1861 }
1862 ID->setIvarList(nullptr);
1863 }
1864
1865 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1866 synthesized);
1867}
1868
1870 return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1871 nullptr, QualType(), nullptr,
1872 ObjCIvarDecl::None, nullptr, false);
1873}
1874
1876 auto *DC = cast<ObjCContainerDecl>(getDeclContext());
1877
1878 switch (DC->getKind()) {
1879 default:
1880 case ObjCCategoryImpl:
1881 case ObjCProtocol:
1882 llvm_unreachable("invalid ivar container!");
1883
1884 // Ivars can only appear in class extension categories.
1885 case ObjCCategory: {
1886 auto *CD = cast<ObjCCategoryDecl>(DC);
1887 assert(CD->IsClassExtension() && "invalid container for ivar!");
1888 return CD->getClassInterface();
1889 }
1890
1891 case ObjCImplementation:
1892 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1893
1894 case ObjCInterface:
1895 return cast<ObjCInterfaceDecl>(DC);
1896 }
1897}
1898
1900 return getType().substObjCMemberType(objectType, getDeclContext(),
1902}
1903
1904//===----------------------------------------------------------------------===//
1905// ObjCAtDefsFieldDecl
1906//===----------------------------------------------------------------------===//
1907
1908void ObjCAtDefsFieldDecl::anchor() {}
1909
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
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,
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
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
1953 GlobalDeclID ID) {
1955 new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
1956 SourceLocation(), nullptr);
1957 Result->Data.setInt(!C.getLangOpts().Modules);
1958 return Result;
1959}
1960
1962 return hasAttr<ObjCNonRuntimeProtocolAttr>();
1963}
1964
1966 llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const {
1967 std::queue<const ObjCProtocolDecl *> WorkQueue;
1968 WorkQueue.push(this);
1969
1970 while (!WorkQueue.empty()) {
1971 const auto *PD = WorkQueue.front();
1972 WorkQueue.pop();
1973 for (const auto *Parent : PD->protocols()) {
1974 const auto *Can = Parent->getCanonicalDecl();
1975 auto Result = IPs.insert(Can);
1976 if (Result.second)
1977 WorkQueue.push(Parent);
1978 }
1979 }
1980}
1981
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.
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
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
2032 Data.setPointer(nullptr);
2033 allocateDefinitionData();
2034 // Don't propagate data to other redeclarations.
2035}
2036
2039 Data = Definition->Data;
2040}
2041
2043 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2044 for (auto *Prop : PDecl->properties()) {
2045 // Insert into PM if not there already.
2046 PM.insert(std::make_pair(
2047 std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
2048 Prop));
2049 }
2050 // Scan through protocol's protocols.
2051 for (const auto *PI : PDecl->protocols())
2052 PI->collectPropertiesToImplement(PM);
2053 }
2054}
2055
2058 PropertyDeclOrder &PO) const {
2059 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2060 if (!PS.insert(PDecl).second)
2061 return;
2062 for (auto *Prop : PDecl->properties()) {
2063 if (Prop == Property)
2064 continue;
2065 if (Prop->getIdentifier() == Property->getIdentifier()) {
2066 PO.push_back(Prop);
2067 return;
2068 }
2069 }
2070 // Scan through protocol's protocols which did not have a matching property.
2071 for (const auto *PI : PDecl->protocols())
2072 PI->collectInheritedProtocolProperties(Property, PS, PO);
2073 }
2074}
2075
2076StringRef
2078 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
2079 return ObjCRTName->getMetadataName();
2080
2081 return getName();
2082}
2083
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;
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
2130 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
2131 const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
2132 ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,
2133 SourceLocation IvarRBraceLoc) {
2134 auto *CatDecl =
2135 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
2136 IDecl, typeParamList, IvarLBraceLoc,
2137 IvarRBraceLoc);
2138 if (IDecl) {
2139 // Link this category into its class's category list.
2140 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
2141 if (IDecl->hasDefinition()) {
2142 IDecl->setCategoryListRaw(CatDecl);
2143 if (ASTMutationListener *L = C.getASTMutationListener())
2144 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
2145 }
2146 }
2147
2148 return CatDecl;
2149}
2150
2152 GlobalDeclID ID) {
2153 return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
2155 nullptr, nullptr, nullptr);
2156}
2157
2160 const_cast<ObjCCategoryDecl*>(this));
2161}
2162
2164 getASTContext().setObjCImplementation(this, ImplD);
2165}
2166
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
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
2194 return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
2196 SourceLocation());
2197}
2198
2200 // The class interface might be NULL if we are working with invalid code.
2201 if (const ObjCInterfaceDecl *ID = getClassInterface())
2202 return ID->FindCategoryDeclaration(getIdentifier());
2203 return nullptr;
2204}
2205
2206void ObjCImplDecl::anchor() {}
2207
2209 // FIXME: The context should be correct before we get here.
2210 property->setLexicalDeclContext(this);
2211 addDecl(property);
2212}
2213
2215 ASTContext &Ctx = getASTContext();
2216
2217 if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
2218 if (IFace)
2219 Ctx.setObjCImplementation(IFace, ImplD);
2220
2221 } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
2223 Ctx.setObjCImplementation(CD, ImplD);
2224 }
2225
2226 ClassInterface = IFace;
2227}
2228
2229/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
2230/// properties implemented in this \@implementation block and returns
2231/// the implemented property that uses it.
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.
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) {
2253 !PID->getPropertyDecl()->isClassProperty()) ||
2255 PID->getPropertyDecl()->isClassProperty()) ||
2257 !PID->getPropertyDecl()->isClassProperty()))
2258 return PID;
2259
2260 if (PID->getPropertyDecl()->isClassProperty())
2261 ClassPropImpl = PID;
2262 }
2263
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
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
2301 return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
2303}
2304
2306 CXXCtorInitializer ** initializers,
2307 unsigned numInitializers) {
2308 if (numInitializers > 0) {
2309 NumIvarInitializers = numInitializers;
2310 auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];
2311 memcpy(ivarInitializers, initializers,
2312 numInitializers * sizeof(CXXCtorInitializer*));
2313 IvarInitializers = ivarInitializers;
2314 }
2315}
2316
2319 return IvarInitializers.get(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
2338 ObjCInterfaceDecl* AliasedClass) {
2339 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
2340}
2341
2344 return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
2345 nullptr, nullptr);
2346}
2347
2348//===----------------------------------------------------------------------===//
2349// ObjCPropertyDecl
2350//===----------------------------------------------------------------------===//
2351
2352void ObjCPropertyDecl::anchor() {}
2353
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
2364 GlobalDeclID ID) {
2365 return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
2367 QualType(), nullptr, None);
2368}
2369
2371 return DeclType.substObjCMemberType(objectType, getDeclContext(),
2373}
2374
2376 return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
2377 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
2378}
2379
2380//===----------------------------------------------------------------------===//
2381// ObjCPropertyImplDecl
2382//===----------------------------------------------------------------------===//
2383
2385 DeclContext *DC,
2386 SourceLocation atLoc,
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
2398 return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
2399 SourceLocation(), nullptr, Dynamic,
2400 nullptr, SourceLocation());
2401}
2402
2404 SourceLocation EndLoc = getLocation();
2405 if (IvarLoc.isValid())
2406 EndLoc = IvarLoc;
2407
2408 return SourceRange(AtLoc, EndLoc);
2409}
Defines the clang::ASTContext interface.
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
const Decl * D
Expr * E
static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container, const ObjCMethodDecl *Method, SmallVectorImpl< const ObjCMethodDecl * > &Methods, bool MovedToSuper)
Definition: DeclObjC.cpp:1252
static bool isIntroducingInitializers(const ObjCInterfaceDecl *D)
Definition: DeclObjC.cpp:496
static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method, SmallVectorImpl< const ObjCMethodDecl * > &overridden)
Definition: DeclObjC.cpp:1319
static void CollectOverriddenMethods(const ObjCContainerDecl *Container, const ObjCMethodDecl *Method, SmallVectorImpl< const ObjCMethodDecl * > &Methods)
Definition: DeclObjC.cpp:1312
int Category
Definition: Format.cpp:3004
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
uint32_t Id
Definition: SemaARM.cpp:1144
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getObjCClassType() const
Represents the Objective-C Class type.
Definition: ASTContext.h:2139
void setObjCImplementation(ObjCInterfaceDecl *IFaceD, ObjCImplementationDecl *ImplD)
Set the implementation of ObjCInterfaceDecl.
IdentifierTable & Idents
Definition: ASTContext.h:660
const LangOptions & getLangOpts() const
Definition: ASTContext.h:797
IdentifierInfo * getNSObjectName() const
Retrieve the identifier 'NSObject'.
Definition: ASTContext.h:1956
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
Definition: ASTContext.h:2127
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2210
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
const ObjCMethodDecl * getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const
Get the duplicate declaration of a ObjCMethod in the same interface, or null if none exists.
QualType getObjCIdType() const
Represents the Objective-CC id type.
Definition: ASTContext.h:2117
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:734
QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl, ArrayRef< ObjCProtocolDecl * > protocols) const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1227
ObjCImplementationDecl * getObjCImplementation(ObjCInterfaceDecl *D)
Get the implementation of the ObjCInterfaceDecl D, or nullptr if none exists.
void setObjCMethodRedeclaration(const ObjCMethodDecl *MD, const ObjCMethodDecl *Redecl)
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2304
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1369
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2370
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
ObjCMethodDeclBitfields ObjCMethodDeclBits
Definition: DeclBase.h:2027
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1852
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1766
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:442
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:600
bool isUnconditionallyVisible() const
Determine whether this declaration is definitely visible to name lookup, independent of whether the o...
Definition: DeclBase.h:849
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:89
@ OBJC_TQ_None
Definition: DeclBase.h:199
SourceLocation getLocation() const
Definition: DeclBase.h:446
void setImplicit(bool I=true)
Definition: DeclBase.h:601
DeclContext * getDeclContext()
Definition: DeclBase.h:455
Kind getKind() const
Definition: DeclBase.h:449
This represents one expression.
Definition: Expr.h:110
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Definition: Decl.cpp:5378
Represents the results of name lookup.
Definition: Lookup.h:46
This represents a decl that may have a name.
Definition: Decl.h:249
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
void AddObjCProtocolDecl(const ObjCProtocolDecl *P)
Definition: ODRHash.cpp:782
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition: ODRHash.cpp:634
unsigned CalculateHash()
Definition: ODRHash.cpp:225
Represents a field declaration created by an @defs(...).
Definition: DeclObjC.h:2029
static ObjCAtDefsFieldDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:1917
static ObjCAtDefsFieldDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW)
Definition: DeclObjC.cpp:1911
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2328
static ObjCCategoryDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())
Definition: DeclObjC.cpp:2128
void setTypeParamList(ObjCTypeParamList *TPL)
Set the type parameters of this category.
Definition: DeclObjC.cpp:2167
static ObjCCategoryDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:2151
ObjCCategoryImplDecl * getImplementation() const
Definition: DeclObjC.cpp:2158
void setImplementation(ObjCCategoryImplDecl *ImplD)
Definition: DeclObjC.cpp:2163
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2544
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2199
static ObjCCategoryImplDecl * Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc)
Definition: DeclObjC.cpp:2182
static ObjCCategoryImplDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:2193
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition: DeclObjC.h:2774
static ObjCCompatibleAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl *aliasedClass)
Definition: DeclObjC.cpp:2335
static ObjCCompatibleAliasDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:2343
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:947
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:93
void setAtStartLoc(SourceLocation Loc)
Definition: DeclObjC.h:1097
llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
Definition: DeclObjC.h:1086
instmeth_range instance_methods() const
Definition: DeclObjC.h:1032
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
Definition: DeclObjC.h:1087
ObjCPropertyDecl * getProperty(const IdentifierInfo *Id, bool IsInstance) const
Definition: DeclObjC.cpp:236
ObjCIvarDecl * getIvarDecl(IdentifierInfo *Id) const
getIvarDecl - This method looks up an ivar in this ContextDecl.
Definition: DeclObjC.cpp:81
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
Definition: DeclObjC.cpp:250
virtual void collectPropertiesToImplement(PropertyMap &PM) const
This routine collects list of properties to be implemented in the class.
Definition: DeclObjC.h:1093
prop_range properties() const
Definition: DeclObjC.h:966
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Definition: DeclObjC.h:1065
ObjCContainerDecl(Kind DK, DeclContext *DC, const IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc)
Definition: DeclObjC.cpp:68
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const
This routine returns 'true' if a user declared setter method was found in the class,...
Definition: DeclObjC.cpp:125
void addPropertyImplementation(ObjCPropertyImplDecl *property)
Definition: DeclObjC.cpp:2208
propimpl_range property_impls() const
Definition: DeclObjC.h:2512
void setClassInterface(ObjCInterfaceDecl *IFace)
Definition: DeclObjC.cpp:2214
ObjCPropertyImplDecl * FindPropertyImplDecl(IdentifierInfo *propertyId, ObjCPropertyQueryKind queryKind) const
FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl added to the list of thos...
Definition: DeclObjC.cpp:2245
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2485
ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const
FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...
Definition: DeclObjC.cpp:2233
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2596
static ObjCImplementationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:2300
static ObjCImplementationDecl * Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *superDecl, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation superLoc=SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())
Definition: DeclObjC.cpp:2284
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Definition: DeclObjC.cpp:1621
CXXCtorInitializer *const * init_const_iterator
init_const_iterator - Iterates through the ivar initializer list.
Definition: DeclObjC.h:2656
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
Definition: DeclObjC.h:2720
init_iterator init_begin()
init_begin() - Retrieve an iterator to the first initializer.
Definition: DeclObjC.h:2668
void setIvarInitializers(ASTContext &C, CXXCtorInitializer **initializers, unsigned numInitializers)
Definition: DeclObjC.cpp:2305
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
void mergeClassExtensionProtocolList(ObjCProtocolDecl *const *List, unsigned Num, ASTContext &C)
mergeClassExtensionProtocolList - Merge class extension's protocol list into the protocol list for th...
Definition: DeclObjC.cpp:442
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameters of this class.
Definition: DeclObjC.cpp:322
all_protocol_iterator all_referenced_protocol_end() const
Definition: DeclObjC.h:1434
ObjCInterfaceDecl * lookupInheritedClass(const IdentifierInfo *ICName)
lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super class whose name is passe...
Definition: DeclObjC.cpp:668
ivar_iterator ivar_end() const
Definition: DeclObjC.h:1460
ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name 'PropertyId' in the p...
Definition: DeclObjC.cpp:382
ObjCMethodDecl * getCategoryMethod(Selector Sel, bool isInstance) const
Definition: DeclObjC.h:1350
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
Definition: DeclObjC.cpp:1542
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition: DeclObjC.cpp:637
void setCategoryListRaw(ObjCCategoryDecl *category)
Set the raw pointer to the start of the category/extension list.
Definition: DeclObjC.h:1797
bool hasDefinition() const
Determine whether this class has been defined.
Definition: DeclObjC.h:1527
all_protocol_range all_referenced_protocols() const
Definition: DeclObjC.h:1416
visible_extensions_range visible_extensions() const
Definition: DeclObjC.h:1722
ObjCTypeParamList * getTypeParamListAsWritten() const
Retrieve the type parameters written on this particular declaration of the class.
Definition: DeclObjC.h:1302
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
Definition: DeclObjC.cpp:1672
ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
Definition: DeclObjC.cpp:1748
ivar_iterator ivar_begin() const
Definition: DeclObjC.h:1452
protocol_range protocols() const
Definition: DeclObjC.h:1358
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Definition: DeclObjC.h:1846
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
Definition: DeclObjC.cpp:791
bool ivar_empty() const
Definition: DeclObjC.h:1472
void setImplementation(ObjCImplementationDecl *ImplD)
Definition: DeclObjC.cpp:1642
known_categories_range known_categories() const
Definition: DeclObjC.h:1686
const ObjCInterfaceDecl * isObjCRequiresPropertyDefs() const
isObjCRequiresPropertyDefs - Checks that a class or one of its super classes must not be auto-synthes...
Definition: DeclObjC.cpp:432
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition: DeclObjC.cpp:372
all_protocol_iterator all_referenced_protocol_begin() const
Definition: DeclObjC.h:1421
void setExternallyCompleted()
Indicate that this Objective-C class is complete, but that the external AST source will be responsibl...
Definition: DeclObjC.cpp:1587
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
Definition: DeclObjC.cpp:1775
ObjCCategoryDecl * getCategoryListRaw() const
Retrieve the raw pointer to the start of the category/extension list.
Definition: DeclObjC.h:1784
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition: DeclObjC.h:1522
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
Definition: DeclObjC.cpp:756
void setTypeParamList(ObjCTypeParamList *TPL)
Set the type parameters of this class.
Definition: DeclObjC.cpp:343
ObjCMethodDecl * getCategoryInstanceMethod(Selector Sel) const
Definition: DeclObjC.cpp:1765
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class,...
Definition: DeclObjC.cpp:699
ObjCProtocolDecl * lookupNestedProtocol(IdentifierInfo *Name)
Definition: DeclObjC.cpp:687
bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, bool lookupCategory, bool RHSIsQualifiedID=false)
ClassImplementsProtocol - Checks that 'lProto' protocol has been implemented in IDecl class,...
Definition: DeclObjC.cpp:1788
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Definition: DeclObjC.cpp:1613
const ObjCObjectType * getSuperClassType() const
Retrieve the superclass type.
Definition: DeclObjC.h:1564
ObjCImplementationDecl * getImplementation() const
Definition: DeclObjC.cpp:1629
static ObjCInterfaceDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:1554
bool hasDesignatedInitializers() const
Returns true if this interface decl contains at least one initializer marked with the 'objc_designate...
Definition: DeclObjC.cpp:1602
void getDesignatedInitializers(llvm::SmallVectorImpl< const ObjCMethodDecl * > &Methods) const
Returns the designated initializers for the interface.
Definition: DeclObjC.cpp:548
void startDefinition()
Starts the definition of this Objective-C class, taking it from a forward declaration (@class) to a d...
Definition: DeclObjC.cpp:616
void collectPropertiesToImplement(PropertyMap &PM) const override
This routine collects list of properties to be implemented in the class.
Definition: DeclObjC.cpp:405
bool isArcWeakrefUnavailable() const
isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...
Definition: DeclObjC.cpp:422
visible_categories_range visible_categories() const
Definition: DeclObjC.h:1652
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Definition: DeclObjC.h:1914
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:352
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
Definition: DeclObjC.h:1541
TypeSourceInfo * getSuperClassTInfo() const
Definition: DeclObjC.h:1572
bool isDesignatedInitializer(Selector Sel, const ObjCMethodDecl **InitMethod=nullptr) const
Returns true if the given selector is a designated initializer for the interface.
Definition: DeclObjC.cpp:570
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
Definition: DeclObjC.cpp:626
void setHasDesignatedInitializers()
Indicate that this interface decl contains at least one initializer marked with the 'objc_designated_...
Definition: DeclObjC.cpp:1595
void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition)
Definition: DeclObjC.cpp:632
known_extensions_range known_extensions() const
Definition: DeclObjC.h:1761
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1951
void setNextIvar(ObjCIvarDecl *ivar)
Definition: DeclObjC.h:1988
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
Definition: DeclObjC.cpp:1875
static ObjCIvarDecl * Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW=nullptr, bool synthesized=false)
Definition: DeclObjC.cpp:1833
static ObjCIvarDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:1869
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
Definition: DeclObjC.cpp:1899
void ** List
List is an array of pointers to objects that are not owned by this object.
Definition: DeclObjC.h:62
void set(void *const *InList, unsigned Elts, ASTContext &Ctx)
Definition: DeclObjC.cpp:45
unsigned NumElts
Definition: DeclObjC.h:63
ObjCList - This is a simple template class used to hold various lists of decls etc,...
Definition: DeclObjC.h:82
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
bool isDesignatedInitializerForTheInterface(const ObjCMethodDecl **InitMethod=nullptr) const
Returns true if the method selector resolves to a designated initializer in the class's interface.
Definition: DeclObjC.cpp:889
bool isOverriding() const
Whether this method overrides any other in the class hierarchy.
Definition: DeclObjC.h:462
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:373
unsigned param_size() const
Definition: DeclObjC.h:347
void setSelfDecl(ImplicitParamDecl *SD)
Definition: DeclObjC.h:419
bool isPropertyAccessor() const
Definition: DeclObjC.h:436
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
Definition: DeclObjC.cpp:1360
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
Definition: DeclObjC.cpp:852
void setHasRedeclaration(bool HRD) const
Definition: DeclObjC.h:272
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
Definition: DeclObjC.cpp:1378
QualType getSendResultType() const
Determine the type of an expression that sends a message to this function.
Definition: DeclObjC.cpp:1238
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Definition: DeclObjC.cpp:901
void setIsRedeclaration(bool RD)
Definition: DeclObjC.h:267
bool isVariadic() const
Definition: DeclObjC.h:431
void setCmdDecl(ImplicitParamDecl *CD)
Definition: DeclObjC.h:421
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:909
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclObjC.cpp:1012
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclObjC.cpp:1047
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:343
QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID, bool &selfIsPseudoStrong, bool &selfIsConsumed) const
Definition: DeclObjC.cpp:1145
bool hasRedeclaration() const
True if redeclared in the same interface.
Definition: DeclObjC.h:271
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod)
Definition: DeclObjC.cpp:913
param_type_iterator param_type_begin() const
Definition: DeclObjC.h:399
bool isSynthesizedAccessorStub() const
Definition: DeclObjC.h:444
SourceLocation getSelectorLoc(unsigned Index) const
Definition: DeclObjC.h:294
SourceRange getReturnTypeSourceRange() const
Definition: DeclObjC.cpp:1231
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs=std::nullopt)
Sets the method's parameters and selector source locations.
Definition: DeclObjC.cpp:944
bool isRedeclaration() const
True if this is a method redeclaration in the same interface.
Definition: DeclObjC.h:266
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition: DeclObjC.cpp:871
llvm::mapped_iterator< param_const_iterator, GetTypeFn > param_type_iterator
Definition: DeclObjC.h:397
Selector getSelector() const
Definition: DeclObjC.h:327
bool isInstanceMethod() const
Definition: DeclObjC.h:426
static ObjCMethodDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:865
bool isThisDeclarationADesignatedInitializer() const
Returns true if this specific method declaration is marked with the designated initializer attribute.
Definition: DeclObjC.cpp:876
ObjCCategoryDecl * getCategory()
If this method is declared or implemented in a category, return that category.
Definition: DeclObjC.cpp:1223
bool isDefined() const
Definition: DeclObjC.h:452
bool definedInNSObject(const ASTContext &) const
Is this method defined in the NSObject base class?
Definition: DeclObjC.cpp:881
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
Definition: DeclObjC.cpp:1053
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implicit parameters.
Definition: DeclObjC.cpp:1190
QualType getReturnType() const
Definition: DeclObjC.h:329
unsigned getNumSelectorLocs() const
Definition: DeclObjC.h:306
bool isClassMethod() const
Definition: DeclObjC.h:434
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1211
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition: DeclObjC.cpp:938
Represents a class type in Objective C.
Definition: Type.h:7150
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
QualType getUsageType(QualType objectType) const
Retrieve the type when this property is used with a specific base object type.
Definition: DeclObjC.cpp:2370
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
Definition: DeclObjC.cpp:179
static ObjCPropertyDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:2363
bool isDirectProperty() const
Definition: DeclObjC.cpp:2375
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.
Definition: DeclObjC.cpp:227
static ObjCPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, TypeSourceInfo *TSI, PropertyControl propControl=None)
Definition: DeclObjC.cpp:2355
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2804
static ObjCPropertyImplDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:2397
static ObjCPropertyImplDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc)
Definition: DeclObjC.cpp:2384
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclObjC.cpp:2403
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2083
void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition)
Definition: DeclObjC.cpp:2037
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
Definition: DeclObjC.cpp:2031
bool hasDefinition() const
Determine whether this protocol has a definition.
Definition: DeclObjC.h:2237
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance) const
Definition: DeclObjC.cpp:1997
static ObjCProtocolDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl)
Definition: DeclObjC.cpp:1941
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition: DeclObjC.h:2249
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
Definition: DeclObjC.cpp:2077
void getImpliedProtocols(llvm::DenseSet< const ObjCProtocolDecl * > &IPs) const
Get the set of all protocols implied by this protocols inheritance hierarchy.
Definition: DeclObjC.cpp:1965
void startDefinition()
Starts the definition of this Objective-C protocol.
Definition: DeclObjC.cpp:2023
static ObjCProtocolDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition: DeclObjC.cpp:1952
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
Definition: DeclObjC.cpp:1961
void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, ProtocolPropertySet &PS, PropertyDeclOrder &PO) const
Definition: DeclObjC.cpp:2056
ObjCProtocolDecl * lookupProtocolNamed(IdentifierInfo *PName)
Definition: DeclObjC.cpp:1982
protocol_range protocols() const
Definition: DeclObjC.h:2160
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
Definition: DeclObjC.cpp:2084
void collectPropertiesToImplement(PropertyMap &PM) const override
This routine collects list of properties to be implemented in the class.
Definition: DeclObjC.cpp:2042
void set(ObjCProtocolDecl *const *InList, unsigned Elts, const SourceLocation *Locs, ASTContext &Ctx)
Definition: DeclObjC.cpp:54
Represents the declaration of an Objective-C type parameter.
Definition: DeclObjC.h:578
static ObjCTypeParamDecl * Create(ASTContext &ctx, DeclContext *dc, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, SourceLocation nameLoc, IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo)
Definition: DeclObjC.cpp:1473
bool hasExplicitBound() const
Whether this type parameter has an explicitly-written type bound, e.g., "T : NSView".
Definition: DeclObjC.h:640
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclObjC.cpp:1497
static ObjCTypeParamDecl * CreateDeserialized(ASTContext &ctx, GlobalDeclID ID)
Definition: DeclObjC.cpp:1489
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition: DeclObjC.h:659
void gatherDefaultTypeArgs(SmallVectorImpl< QualType > &typeArgs) const
Gather the default set of type arguments to be substituted for these type parameters when dealing wit...
Definition: DeclObjC.cpp:1531
unsigned size() const
Determine the number of type parameters in this list.
Definition: DeclObjC.h:686
static ObjCTypeParamList * create(ASTContext &ctx, SourceLocation lAngleLoc, ArrayRef< ObjCTypeParamDecl * > typeParams, SourceLocation rAngleLoc)
Create a new Objective-C type parameter list.
Definition: DeclObjC.cpp:1520
Represents a parameter to a function.
Definition: Decl.h:1722
A (possibly-)qualified type.
Definition: Type.h:941
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition: Type.cpp:3476
QualType withConst() const
Definition: Type.h:1166
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7755
QualType substObjCMemberType(QualType objectType, const DeclContext *dc, ObjCSubstitutionContext context) const
Substitute type arguments from an object type for the Objective-C type parameters used in the subject...
Definition: Type.cpp:1613
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
Definition: Type.cpp:1606
The collection of all-type qualifiers we support.
Definition: Type.h:319
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:348
void setObjCLifetime(ObjCLifetime type)
Definition: Type.h:535
ObjCInterfaceDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:227
void setPreviousDecl(ObjCInterfaceDecl *PrevDecl)
Set the previous declaration.
Definition: Decl.h:4978
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:297
Smart pointer class that efficiently represents Objective-C method names.
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
unsigned getNumArgs() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition: Stmt.h:84
A container of type source information.
Definition: Type.h:7726
bool isObjCSelType() const
Definition: Type.h:8195
bool isObjCIdType() const
Definition: Type.h:8183
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3459
QualType getType() const
Definition: Decl.h:678
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ SelLoc_NonStandard
Non-standard.
@ SelLoc_StandardNoSpace
For nullary selectors, immediately before the end: "[foo release]" / "-(void)release;" Or immediately...
ObjCPropertyQueryKind
Definition: DeclObjC.h:718
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_initialize
@ OMF_autorelease
@ OMF_mutableCopy
@ OMF_performSelector
@ OMF_None
No particular method family.
@ OMF_retainCount
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef< SourceLocation > SelLocs, ArrayRef< Expr * > Args, SourceLocation EndLoc)
Returns true if all SelLocs are in a "standard" location.
@ Property
The type of a property.
@ Result
The result type of a method or function.
ObjCImplementationControl
Definition: DeclObjC.h:118
const FunctionProtoType * T
@ InvalidObjCMethodFamily
ObjCTypeParamVariance
Describes the variance of a given generic parameter.
Definition: DeclObjC.h:553
@ Invariant
The parameter is invariant: must match exactly.
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ ObjCSelf
Parameter for Objective-C 'self' argument.
@ ObjCCmd
Parameter for Objective-C '_cmd' argument.
T * get(ExternalASTSource *Source) const
Retrieve the pointer to the AST node that this lazy pointer points to.