clang 19.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
70 SourceLocation atStartLoc)
71 : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
72 setAtStartLoc(atStartLoc);
73}
74
75void ObjCContainerDecl::anchor() {}
76
77/// getIvarDecl - This method looks up an ivar in this ContextDecl.
78///
82 for (lookup_iterator Ivar = R.begin(), IvarEnd = R.end();
83 Ivar != IvarEnd; ++Ivar) {
84 if (auto *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
85 return ivar;
86 }
87 return nullptr;
88}
89
90// Get the local instance/class method declared in this interface.
93 bool AllowHidden) const {
94 // If this context is a hidden protocol definition, don't find any
95 // methods there.
96 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
97 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
98 if (!Def->isUnconditionallyVisible() && !AllowHidden)
99 return nullptr;
100 }
101
102 // Since instance & class methods can have the same name, the loop below
103 // ensures we get the correct method.
104 //
105 // @interface Whatever
106 // - (int) class_method;
107 // + (float) class_method;
108 // @end
109 lookup_result R = lookup(Sel);
110 for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
111 Meth != MethEnd; ++Meth) {
112 auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
113 if (MD && MD->isInstanceMethod() == isInstance)
114 return MD;
115 }
116 return nullptr;
117}
118
119/// This routine returns 'true' if a user declared setter method was
120/// found in the class, its protocols, its super classes or categories.
121/// It also returns 'true' if one of its categories has declared a 'readwrite'
122/// property. This is because, user must provide a setter method for the
123/// category's 'readwrite' property.
125 const ObjCPropertyDecl *Property) const {
126 Selector Sel = Property->getSetterName();
127 lookup_result R = lookup(Sel);
128 for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
129 Meth != MethEnd; ++Meth) {
130 auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
131 if (MD && MD->isInstanceMethod() && !MD->isImplicit())
132 return true;
133 }
134
135 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
136 // Also look into categories, including class extensions, looking
137 // for a user declared instance method.
138 for (const auto *Cat : ID->visible_categories()) {
139 if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
140 if (!MD->isImplicit())
141 return true;
142 if (Cat->IsClassExtension())
143 continue;
144 // Also search through the categories looking for a 'readwrite'
145 // declaration of this property. If one found, presumably a setter will
146 // be provided (properties declared in categories will not get
147 // auto-synthesized).
148 for (const auto *P : Cat->properties())
149 if (P->getIdentifier() == Property->getIdentifier()) {
150 if (P->getPropertyAttributes() &
152 return true;
153 break;
154 }
155 }
156
157 // Also look into protocols, for a user declared instance method.
158 for (const auto *Proto : ID->all_referenced_protocols())
159 if (Proto->HasUserDeclaredSetterMethod(Property))
160 return true;
161
162 // And in its super class.
163 ObjCInterfaceDecl *OSC = ID->getSuperClass();
164 while (OSC) {
166 return true;
167 OSC = OSC->getSuperClass();
168 }
169 }
170 if (const auto *PD = dyn_cast<ObjCProtocolDecl>(this))
171 for (const auto *PI : PD->protocols())
172 if (PI->HasUserDeclaredSetterMethod(Property))
173 return true;
174 return false;
175}
176
179 const IdentifierInfo *propertyID,
180 ObjCPropertyQueryKind queryKind) {
181 // If this context is a hidden protocol definition, don't find any
182 // property.
183 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
184 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
185 if (!Def->isUnconditionallyVisible())
186 return nullptr;
187 }
188
189 // If context is class, then lookup property in its visible extensions.
190 // This comes before property is looked up in primary class.
191 if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
192 for (const auto *Ext : IDecl->visible_extensions())
194 propertyID,
195 queryKind))
196 return PD;
197 }
198
199 DeclContext::lookup_result R = DC->lookup(propertyID);
200 ObjCPropertyDecl *classProp = nullptr;
201 for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
202 ++I)
203 if (auto *PD = dyn_cast<ObjCPropertyDecl>(*I)) {
204 // If queryKind is unknown, we return the instance property if one
205 // exists; otherwise we return the class property.
207 !PD->isClassProperty()) ||
209 PD->isClassProperty()) ||
211 !PD->isClassProperty()))
212 return PD;
213
214 if (PD->isClassProperty())
215 classProp = PD;
216 }
217
219 // We can't find the instance property, return the class property.
220 return classProp;
221
222 return nullptr;
223}
224
227 SmallString<128> ivarName;
228 {
229 llvm::raw_svector_ostream os(ivarName);
230 os << '_' << getIdentifier()->getName();
231 }
232 return &Ctx.Idents.get(ivarName.str());
233}
234
236 bool IsInstance) const {
237 for (auto *LookupResult : lookup(Id)) {
238 if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) {
239 if (Prop->isInstanceProperty() == IsInstance) {
240 return Prop;
241 }
242 }
243 }
244 return nullptr;
245}
246
247/// FindPropertyDeclaration - Finds declaration of the property given its name
248/// in 'PropertyId' and returns it. It returns 0, if not found.
250 const IdentifierInfo *PropertyId,
251 ObjCPropertyQueryKind QueryKind) const {
252 // Don't find properties within hidden protocol definitions.
253 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
254 if (const ObjCProtocolDecl *Def = Proto->getDefinition())
255 if (!Def->isUnconditionallyVisible())
256 return nullptr;
257 }
258
259 // Search the extensions of a class first; they override what's in
260 // the class itself.
261 if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) {
262 for (const auto *Ext : ClassDecl->visible_extensions()) {
263 if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind))
264 return P;
265 }
266 }
267
268 if (ObjCPropertyDecl *PD =
269 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
270 QueryKind))
271 return PD;
272
273 switch (getKind()) {
274 default:
275 break;
276 case Decl::ObjCProtocol: {
277 const auto *PID = cast<ObjCProtocolDecl>(this);
278 for (const auto *I : PID->protocols())
279 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
280 QueryKind))
281 return P;
282 break;
283 }
284 case Decl::ObjCInterface: {
285 const auto *OID = cast<ObjCInterfaceDecl>(this);
286 // Look through categories (but not extensions; they were handled above).
287 for (const auto *Cat : OID->visible_categories()) {
288 if (!Cat->IsClassExtension())
289 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(
290 PropertyId, QueryKind))
291 return P;
292 }
293
294 // Look through protocols.
295 for (const auto *I : OID->all_referenced_protocols())
296 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
297 QueryKind))
298 return P;
299
300 // Finally, check the super class.
301 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
302 return superClass->FindPropertyDeclaration(PropertyId, QueryKind);
303 break;
304 }
305 case Decl::ObjCCategory: {
306 const auto *OCD = cast<ObjCCategoryDecl>(this);
307 // Look through protocols.
308 if (!OCD->IsClassExtension())
309 for (const auto *I : OCD->protocols())
310 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
311 QueryKind))
312 return P;
313 break;
314 }
315 }
316 return nullptr;
317}
318
319void ObjCInterfaceDecl::anchor() {}
320
322 // If this particular declaration has a type parameter list, return it.
324 return written;
325
326 // If there is a definition, return its type parameter list.
327 if (const ObjCInterfaceDecl *def = getDefinition())
328 return def->getTypeParamListAsWritten();
329
330 // Otherwise, look at previous declarations to determine whether any
331 // of them has a type parameter list, skipping over those
332 // declarations that do not.
334 decl = decl->getPreviousDecl()) {
335 if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten())
336 return written;
337 }
338
339 return nullptr;
340}
341
343 TypeParamList = TPL;
344 if (!TPL)
345 return;
346 // Set the declaration context of each of the type parameters.
347 for (auto *typeParam : *TypeParamList)
348 typeParam->setDeclContext(this);
349}
350
352 // FIXME: Should make sure no callers ever do this.
353 if (!hasDefinition())
354 return nullptr;
355
356 if (data().ExternallyCompleted)
357 LoadExternalDefinition();
358
359 if (const ObjCObjectType *superType = getSuperClassType()) {
360 if (ObjCInterfaceDecl *superDecl = superType->getInterface()) {
361 if (ObjCInterfaceDecl *superDef = superDecl->getDefinition())
362 return superDef;
363
364 return superDecl;
365 }
366 }
367
368 return nullptr;
369}
370
372 if (TypeSourceInfo *superTInfo = getSuperClassTInfo())
373 return superTInfo->getTypeLoc().getBeginLoc();
374
375 return SourceLocation();
376}
377
378/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
379/// with name 'PropertyId' in the primary class; including those in protocols
380/// (direct or indirect) used by the primary class.
383 IdentifierInfo *PropertyId,
384 ObjCPropertyQueryKind QueryKind) const {
385 // FIXME: Should make sure no callers ever do this.
386 if (!hasDefinition())
387 return nullptr;
388
389 if (data().ExternallyCompleted)
390 LoadExternalDefinition();
391
392 if (ObjCPropertyDecl *PD =
393 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
394 QueryKind))
395 return PD;
396
397 // Look through protocols.
398 for (const auto *I : all_referenced_protocols())
399 if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
400 QueryKind))
401 return P;
402
403 return nullptr;
404}
405
407 for (auto *Prop : properties()) {
408 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
409 }
410 for (const auto *Ext : known_extensions()) {
411 const ObjCCategoryDecl *ClassExt = Ext;
412 for (auto *Prop : ClassExt->properties()) {
413 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
414 }
415 }
416 for (const auto *PI : all_referenced_protocols())
418 // Note, the properties declared only in class extensions are still copied
419 // into the main @interface's property list, and therefore we don't
420 // explicitly, have to search class extension properties.
421}
422
424 const ObjCInterfaceDecl *Class = this;
425 while (Class) {
426 if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
427 return true;
428 Class = Class->getSuperClass();
429 }
430 return false;
431}
432
434 const ObjCInterfaceDecl *Class = this;
435 while (Class) {
436 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
437 return Class;
438 Class = Class->getSuperClass();
439 }
440 return nullptr;
441}
442
444 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
445 ASTContext &C) {
446 if (data().ExternallyCompleted)
447 LoadExternalDefinition();
448
449 if (data().AllReferencedProtocols.empty() &&
450 data().ReferencedProtocols.empty()) {
451 data().AllReferencedProtocols.set(ExtList, ExtNum, C);
452 return;
453 }
454
455 // Check for duplicate protocol in class's protocol list.
456 // This is O(n*m). But it is extremely rare and number of protocols in
457 // class or its extension are very few.
459 for (unsigned i = 0; i < ExtNum; i++) {
460 bool protocolExists = false;
461 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
462 for (auto *Proto : all_referenced_protocols()) {
463 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
464 protocolExists = true;
465 break;
466 }
467 }
468 // Do we want to warn on a protocol in extension class which
469 // already exist in the class? Probably not.
470 if (!protocolExists)
471 ProtocolRefs.push_back(ProtoInExtension);
472 }
473
474 if (ProtocolRefs.empty())
475 return;
476
477 // Merge ProtocolRefs into class's protocol list;
478 ProtocolRefs.append(all_referenced_protocol_begin(),
480
481 data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
482}
483
484const ObjCInterfaceDecl *
485ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
486 const ObjCInterfaceDecl *IFace = this;
487 while (IFace) {
488 if (IFace->hasDesignatedInitializers())
489 return IFace;
490 if (!IFace->inheritsDesignatedInitializers())
491 break;
492 IFace = IFace->getSuperClass();
493 }
494 return nullptr;
495}
496
498 for (const auto *MD : D->instance_methods()) {
499 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
500 return true;
501 }
502 for (const auto *Ext : D->visible_extensions()) {
503 for (const auto *MD : Ext->instance_methods()) {
504 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
505 return true;
506 }
507 }
508 if (const auto *ImplD = D->getImplementation()) {
509 for (const auto *MD : ImplD->instance_methods()) {
510 if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
511 return true;
512 }
513 }
514 return false;
515}
516
517bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
518 switch (data().InheritedDesignatedInitializers) {
519 case DefinitionData::IDI_Inherited:
520 return true;
521 case DefinitionData::IDI_NotInherited:
522 return false;
523 case DefinitionData::IDI_Unknown:
524 // If the class introduced initializers we conservatively assume that we
525 // don't know if any of them is a designated initializer to avoid possible
526 // misleading warnings.
527 if (isIntroducingInitializers(this)) {
528 data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
529 } else {
530 if (auto SuperD = getSuperClass()) {
531 data().InheritedDesignatedInitializers =
532 SuperD->declaresOrInheritsDesignatedInitializers() ?
533 DefinitionData::IDI_Inherited :
534 DefinitionData::IDI_NotInherited;
535 } else {
536 data().InheritedDesignatedInitializers =
537 DefinitionData::IDI_NotInherited;
538 }
539 }
540 assert(data().InheritedDesignatedInitializers
541 != DefinitionData::IDI_Unknown);
542 return data().InheritedDesignatedInitializers ==
543 DefinitionData::IDI_Inherited;
544 }
545
546 llvm_unreachable("unexpected InheritedDesignatedInitializers value");
547}
548
551 // Check for a complete definition and recover if not so.
553 return;
554 if (data().ExternallyCompleted)
555 LoadExternalDefinition();
556
557 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
558 if (!IFace)
559 return;
560
561 for (const auto *MD : IFace->instance_methods())
562 if (MD->isThisDeclarationADesignatedInitializer())
563 Methods.push_back(MD);
564 for (const auto *Ext : IFace->visible_extensions()) {
565 for (const auto *MD : Ext->instance_methods())
566 if (MD->isThisDeclarationADesignatedInitializer())
567 Methods.push_back(MD);
568 }
569}
570
572 const ObjCMethodDecl **InitMethod) const {
573 bool HasCompleteDef = isThisDeclarationADefinition();
574 // During deserialization the data record for the ObjCInterfaceDecl could
575 // be made invariant by reusing the canonical decl. Take this into account
576 // when checking for the complete definition.
577 if (!HasCompleteDef && getCanonicalDecl()->hasDefinition() &&
579 HasCompleteDef = true;
580
581 // Check for a complete definition and recover if not so.
582 if (!HasCompleteDef)
583 return false;
584
585 if (data().ExternallyCompleted)
586 LoadExternalDefinition();
587
588 const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
589 if (!IFace)
590 return false;
591
592 if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
593 if (MD->isThisDeclarationADesignatedInitializer()) {
594 if (InitMethod)
595 *InitMethod = MD;
596 return true;
597 }
598 }
599 for (const auto *Ext : IFace->visible_extensions()) {
600 if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
601 if (MD->isThisDeclarationADesignatedInitializer()) {
602 if (InitMethod)
603 *InitMethod = MD;
604 return true;
605 }
606 }
607 }
608 return false;
609}
610
611void ObjCInterfaceDecl::allocateDefinitionData() {
612 assert(!hasDefinition() && "ObjC class already has a definition");
613 Data.setPointer(new (getASTContext()) DefinitionData());
614 Data.getPointer()->Definition = this;
615}
616
618 allocateDefinitionData();
619
620 // Update all of the declarations with a pointer to the definition.
621 for (auto *RD : redecls()) {
622 if (RD != this)
623 RD->Data = Data;
624 }
625}
626
628 Data.setPointer(nullptr);
629 allocateDefinitionData();
630 // Don't propagate data to other redeclarations.
631}
632
635 Data = Definition->Data;
636}
637
639 ObjCInterfaceDecl *&clsDeclared) {
640 // FIXME: Should make sure no callers ever do this.
641 if (!hasDefinition())
642 return nullptr;
643
644 if (data().ExternallyCompleted)
645 LoadExternalDefinition();
646
647 ObjCInterfaceDecl* ClassDecl = this;
648 while (ClassDecl != nullptr) {
649 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
650 clsDeclared = ClassDecl;
651 return I;
652 }
653
654 for (const auto *Ext : ClassDecl->visible_extensions()) {
655 if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
656 clsDeclared = ClassDecl;
657 return I;
658 }
659 }
660
661 ClassDecl = ClassDecl->getSuperClass();
662 }
663 return nullptr;
664}
665
666/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
667/// class whose name is passed as argument. If it is not one of the super classes
668/// the it returns NULL.
670 const IdentifierInfo*ICName) {
671 // FIXME: Should make sure no callers ever do this.
672 if (!hasDefinition())
673 return nullptr;
674
675 if (data().ExternallyCompleted)
676 LoadExternalDefinition();
677
678 ObjCInterfaceDecl* ClassDecl = this;
679 while (ClassDecl != nullptr) {
680 if (ClassDecl->getIdentifier() == ICName)
681 return ClassDecl;
682 ClassDecl = ClassDecl->getSuperClass();
683 }
684 return nullptr;
685}
686
689 for (auto *P : all_referenced_protocols())
690 if (P->lookupProtocolNamed(Name))
691 return P;
692 ObjCInterfaceDecl *SuperClass = getSuperClass();
693 return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
694}
695
696/// lookupMethod - This method returns an instance/class method by looking in
697/// the class, its categories, and its super classes (using a linear search).
698/// When argument category "C" is specified, any implicit method found
699/// in this category is ignored.
701 bool isInstance,
702 bool shallowCategoryLookup,
703 bool followSuper,
704 const ObjCCategoryDecl *C) const
705{
706 // FIXME: Should make sure no callers ever do this.
707 if (!hasDefinition())
708 return nullptr;
709
710 const ObjCInterfaceDecl* ClassDecl = this;
711 ObjCMethodDecl *MethodDecl = nullptr;
712
713 if (data().ExternallyCompleted)
714 LoadExternalDefinition();
715
716 while (ClassDecl) {
717 // 1. Look through primary class.
718 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
719 return MethodDecl;
720
721 // 2. Didn't find one yet - now look through categories.
722 for (const auto *Cat : ClassDecl->visible_categories())
723 if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
724 if (C != Cat || !MethodDecl->isImplicit())
725 return MethodDecl;
726
727 // 3. Didn't find one yet - look through primary class's protocols.
728 for (const auto *I : ClassDecl->protocols())
729 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
730 return MethodDecl;
731
732 // 4. Didn't find one yet - now look through categories' protocols
733 if (!shallowCategoryLookup)
734 for (const auto *Cat : ClassDecl->visible_categories()) {
735 // Didn't find one yet - look through protocols.
736 const ObjCList<ObjCProtocolDecl> &Protocols =
737 Cat->getReferencedProtocols();
738 for (auto *Protocol : Protocols)
739 if ((MethodDecl = Protocol->lookupMethod(Sel, isInstance)))
740 if (C != Cat || !MethodDecl->isImplicit())
741 return MethodDecl;
742 }
743
744
745 if (!followSuper)
746 return nullptr;
747
748 // 5. Get to the super class (if any).
749 ClassDecl = ClassDecl->getSuperClass();
750 }
751 return nullptr;
752}
753
754// Will search "local" class/category implementations for a method decl.
755// If failed, then we search in class's root for an instance method.
756// Returns 0 if no method is found.
758 const Selector &Sel,
759 bool Instance) const {
760 // FIXME: Should make sure no callers ever do this.
761 if (!hasDefinition())
762 return nullptr;
763
764 if (data().ExternallyCompleted)
765 LoadExternalDefinition();
766
767 ObjCMethodDecl *Method = nullptr;
769 Method = Instance ? ImpDecl->getInstanceMethod(Sel)
770 : ImpDecl->getClassMethod(Sel);
771
772 // Look through local category implementations associated with the class.
773 if (!Method)
774 Method = getCategoryMethod(Sel, Instance);
775
776 // Before we give up, check if the selector is an instance method.
777 // But only in the root. This matches gcc's behavior and what the
778 // runtime expects.
779 if (!Instance && !Method && !getSuperClass()) {
780 Method = lookupInstanceMethod(Sel);
781 // Look through local category implementations associated
782 // with the root class.
783 if (!Method)
784 Method = lookupPrivateMethod(Sel, true);
785 }
786
787 if (!Method && getSuperClass())
788 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
789 return Method;
790}
791
793 assert(hasDefinition() && "ODRHash only for records with definitions");
794
795 // Previously calculated hash is stored in DefinitionData.
796 if (hasODRHash())
797 return data().ODRHash;
798
799 // Only calculate hash on first call of getODRHash per record.
800 ODRHash Hasher;
802 data().ODRHash = Hasher.CalculateHash();
803 setHasODRHash(true);
804
805 return data().ODRHash;
806}
807
808bool ObjCInterfaceDecl::hasODRHash() const {
809 if (!hasDefinition())
810 return false;
811 return data().HasODRHash;
812}
813
814void ObjCInterfaceDecl::setHasODRHash(bool HasHash) {
815 assert(hasDefinition() && "Cannot set ODRHash without definition");
816 data().HasODRHash = HasHash;
817}
818
819//===----------------------------------------------------------------------===//
820// ObjCMethodDecl
821//===----------------------------------------------------------------------===//
822
823ObjCMethodDecl::ObjCMethodDecl(
824 SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo,
825 QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl,
826 bool isInstance, bool isVariadic, bool isPropertyAccessor,
827 bool isSynthesizedAccessorStub, bool isImplicitlyDeclared, bool isDefined,
828 ObjCImplementationControl impControl, bool HasRelatedResultType)
829 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
830 DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),
831 DeclEndLoc(endLoc) {
832
833 // Initialized the bits stored in DeclContext.
834 ObjCMethodDeclBits.Family =
836 setInstanceMethod(isInstance);
837 setVariadic(isVariadic);
838 setPropertyAccessor(isPropertyAccessor);
839 setSynthesizedAccessorStub(isSynthesizedAccessorStub);
840 setDefined(isDefined);
841 setIsRedeclaration(false);
842 setHasRedeclaration(false);
843 setDeclImplementation(impControl);
844 setObjCDeclQualifier(OBJC_TQ_None);
845 setRelatedResultType(HasRelatedResultType);
846 setSelLocsKind(SelLoc_StandardNoSpace);
847 setOverriding(false);
848 setHasSkippedBody(false);
849
850 setImplicit(isImplicitlyDeclared);
851}
852
854 ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
855 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
856 DeclContext *contextDecl, bool isInstance, bool isVariadic,
857 bool isPropertyAccessor, bool isSynthesizedAccessorStub,
858 bool isImplicitlyDeclared, bool isDefined,
859 ObjCImplementationControl impControl, bool HasRelatedResultType) {
860 return new (C, contextDecl) ObjCMethodDecl(
861 beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
863 isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);
864}
865
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 unsigned 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 DeclContext *DC,
1544 SourceLocation atLoc,
1546 ObjCTypeParamList *typeParamList,
1547 ObjCInterfaceDecl *PrevDecl,
1548 SourceLocation ClassLoc,
1549 bool isInternal){
1550 auto *Result = new (C, DC)
1551 ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
1552 isInternal);
1553 Result->Data.setInt(!C.getLangOpts().Modules);
1554 C.getObjCInterfaceType(Result, PrevDecl);
1555 return Result;
1556}
1557
1559 unsigned ID) {
1560 auto *Result = new (C, ID)
1561 ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,
1562 SourceLocation(), nullptr, false);
1563 Result->Data.setInt(!C.getLangOpts().Modules);
1564 return Result;
1565}
1566
1567ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
1569 ObjCTypeParamList *typeParamList,
1570 SourceLocation CLoc,
1571 ObjCInterfaceDecl *PrevDecl,
1572 bool IsInternal)
1573 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
1574 redeclarable_base(C) {
1575 setPreviousDecl(PrevDecl);
1576
1577 // Copy the 'data' pointer over.
1578 if (PrevDecl)
1579 Data = PrevDecl->Data;
1580
1581 setImplicit(IsInternal);
1582
1583 setTypeParamList(typeParamList);
1584}
1585
1586void ObjCInterfaceDecl::LoadExternalDefinition() const {
1587 assert(data().ExternallyCompleted && "Class is not externally completed");
1588 data().ExternallyCompleted = false;
1590 const_cast<ObjCInterfaceDecl *>(this));
1591}
1592
1594 assert(getASTContext().getExternalSource() &&
1595 "Class can't be externally completed without an external source");
1596 assert(hasDefinition() &&
1597 "Forward declarations can't be externally completed");
1598 data().ExternallyCompleted = true;
1599}
1600
1602 // Check for a complete definition and recover if not so.
1604 return;
1605 data().HasDesignatedInitializers = true;
1606}
1607
1609 // Check for a complete definition and recover if not so.
1611 return false;
1612 if (data().ExternallyCompleted)
1613 LoadExternalDefinition();
1614
1615 return data().HasDesignatedInitializers;
1616}
1617
1618StringRef
1620 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1621 return ObjCRTName->getMetadataName();
1622
1623 return getName();
1624}
1625
1626StringRef
1628 if (ObjCInterfaceDecl *ID =
1629 const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
1630 return ID->getObjCRuntimeNameAsString();
1631
1632 return getName();
1633}
1634
1636 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1637 if (data().ExternallyCompleted)
1638 LoadExternalDefinition();
1639
1641 const_cast<ObjCInterfaceDecl*>(Def));
1642 }
1643
1644 // FIXME: Should make sure no callers ever do this.
1645 return nullptr;
1646}
1647
1650}
1651
1652namespace {
1653
1654struct SynthesizeIvarChunk {
1655 uint64_t Size;
1656 ObjCIvarDecl *Ivar;
1657
1658 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1659 : Size(size), Ivar(ivar) {}
1660};
1661
1662bool operator<(const SynthesizeIvarChunk & LHS,
1663 const SynthesizeIvarChunk &RHS) {
1664 return LHS.Size < RHS.Size;
1665}
1666
1667} // namespace
1668
1669/// all_declared_ivar_begin - return first ivar declared in this class,
1670/// its extensions and its implementation. Lazily build the list on first
1671/// access.
1672///
1673/// Caveat: The list returned by this method reflects the current
1674/// state of the parser. The cache will be updated for every ivar
1675/// added by an extension or the implementation when they are
1676/// encountered.
1677/// See also ObjCIvarDecl::Create().
1679 // FIXME: Should make sure no callers ever do this.
1680 if (!hasDefinition())
1681 return nullptr;
1682
1683 ObjCIvarDecl *curIvar = nullptr;
1684 if (!data().IvarList) {
1685 // Force ivar deserialization upfront, before building IvarList.
1686 (void)ivar_empty();
1687 for (const auto *Ext : known_extensions()) {
1688 (void)Ext->ivar_empty();
1689 }
1690 if (!ivar_empty()) {
1692 data().IvarList = *I; ++I;
1693 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1694 curIvar->setNextIvar(*I);
1695 }
1696
1697 for (const auto *Ext : known_extensions()) {
1698 if (!Ext->ivar_empty()) {
1700 I = Ext->ivar_begin(),
1701 E = Ext->ivar_end();
1702 if (!data().IvarList) {
1703 data().IvarList = *I; ++I;
1704 curIvar = data().IvarList;
1705 }
1706 for ( ;I != E; curIvar = *I, ++I)
1707 curIvar->setNextIvar(*I);
1708 }
1709 }
1710 data().IvarListMissingImplementation = true;
1711 }
1712
1713 // cached and complete!
1714 if (!data().IvarListMissingImplementation)
1715 return data().IvarList;
1716
1717 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1718 data().IvarListMissingImplementation = false;
1719 if (!ImplDecl->ivar_empty()) {
1721 for (auto *IV : ImplDecl->ivars()) {
1722 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1723 layout.push_back(SynthesizeIvarChunk(
1724 IV->getASTContext().getTypeSize(IV->getType()), IV));
1725 continue;
1726 }
1727 if (!data().IvarList)
1728 data().IvarList = IV;
1729 else
1730 curIvar->setNextIvar(IV);
1731 curIvar = IV;
1732 }
1733
1734 if (!layout.empty()) {
1735 // Order synthesized ivars by their size.
1736 llvm::stable_sort(layout);
1737 unsigned Ix = 0, EIx = layout.size();
1738 if (!data().IvarList) {
1739 data().IvarList = layout[0].Ivar; Ix++;
1740 curIvar = data().IvarList;
1741 }
1742 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1743 curIvar->setNextIvar(layout[Ix].Ivar);
1744 }
1745 }
1746 }
1747 return data().IvarList;
1748}
1749
1750/// FindCategoryDeclaration - Finds category declaration in the list of
1751/// categories for this class and returns it. Name of the category is passed
1752/// in 'CategoryId'. If category not found, return 0;
1753///
1756 // FIXME: Should make sure no callers ever do this.
1757 if (!hasDefinition())
1758 return nullptr;
1759
1760 if (data().ExternallyCompleted)
1761 LoadExternalDefinition();
1762
1763 for (auto *Cat : visible_categories())
1764 if (Cat->getIdentifier() == CategoryId)
1765 return Cat;
1766
1767 return nullptr;
1768}
1769
1772 for (const auto *Cat : visible_categories()) {
1773 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1774 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1775 return MD;
1776 }
1777
1778 return nullptr;
1779}
1780
1782 for (const auto *Cat : visible_categories()) {
1783 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1784 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1785 return MD;
1786 }
1787
1788 return nullptr;
1789}
1790
1791/// ClassImplementsProtocol - Checks that 'lProto' protocol
1792/// has been implemented in IDecl class, its super class or categories (if
1793/// lookupCategory is true).
1795 bool lookupCategory,
1796 bool RHSIsQualifiedID) {
1797 if (!hasDefinition())
1798 return false;
1799
1800 ObjCInterfaceDecl *IDecl = this;
1801 // 1st, look up the class.
1802 for (auto *PI : IDecl->protocols()){
1803 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1804 return true;
1805 // This is dubious and is added to be compatible with gcc. In gcc, it is
1806 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1807 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1808 // object. This IMO, should be a bug.
1809 // FIXME: Treat this as an extension, and flag this as an error when GCC
1810 // extensions are not enabled.
1811 if (RHSIsQualifiedID &&
1812 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
1813 return true;
1814 }
1815
1816 // 2nd, look up the category.
1817 if (lookupCategory)
1818 for (const auto *Cat : visible_categories()) {
1819 for (auto *PI : Cat->protocols())
1820 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1821 return true;
1822 }
1823
1824 // 3rd, look up the super class(s)
1825 if (IDecl->getSuperClass())
1826 return
1827 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1828 RHSIsQualifiedID);
1829
1830 return false;
1831}
1832
1833//===----------------------------------------------------------------------===//
1834// ObjCIvarDecl
1835//===----------------------------------------------------------------------===//
1836
1837void ObjCIvarDecl::anchor() {}
1838
1840 SourceLocation StartLoc,
1842 QualType T, TypeSourceInfo *TInfo,
1843 AccessControl ac, Expr *BW,
1844 bool synthesized) {
1845 if (DC) {
1846 // Ivar's can only appear in interfaces, implementations (via synthesized
1847 // properties), and class extensions (via direct declaration, or synthesized
1848 // properties).
1849 //
1850 // FIXME: This should really be asserting this:
1851 // (isa<ObjCCategoryDecl>(DC) &&
1852 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1853 // but unfortunately we sometimes place ivars into non-class extension
1854 // categories on error. This breaks an AST invariant, and should not be
1855 // fixed.
1856 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1857 isa<ObjCCategoryDecl>(DC)) &&
1858 "Invalid ivar decl context!");
1859 // Once a new ivar is created in any of class/class-extension/implementation
1860 // decl contexts, the previously built IvarList must be rebuilt.
1861 auto *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1862 if (!ID) {
1863 if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC))
1864 ID = IM->getClassInterface();
1865 else
1866 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1867 }
1868 ID->setIvarList(nullptr);
1869 }
1870
1871 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1872 synthesized);
1873}
1874
1876 return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1877 nullptr, QualType(), nullptr,
1878 ObjCIvarDecl::None, nullptr, false);
1879}
1880
1882 auto *DC = cast<ObjCContainerDecl>(getDeclContext());
1883
1884 switch (DC->getKind()) {
1885 default:
1886 case ObjCCategoryImpl:
1887 case ObjCProtocol:
1888 llvm_unreachable("invalid ivar container!");
1889
1890 // Ivars can only appear in class extension categories.
1891 case ObjCCategory: {
1892 auto *CD = cast<ObjCCategoryDecl>(DC);
1893 assert(CD->IsClassExtension() && "invalid container for ivar!");
1894 return CD->getClassInterface();
1895 }
1896
1897 case ObjCImplementation:
1898 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1899
1900 case ObjCInterface:
1901 return cast<ObjCInterfaceDecl>(DC);
1902 }
1903}
1904
1906 return getType().substObjCMemberType(objectType, getDeclContext(),
1908}
1909
1910//===----------------------------------------------------------------------===//
1911// ObjCAtDefsFieldDecl
1912//===----------------------------------------------------------------------===//
1913
1914void ObjCAtDefsFieldDecl::anchor() {}
1915
1918 SourceLocation StartLoc, SourceLocation IdLoc,
1919 IdentifierInfo *Id, QualType T, Expr *BW) {
1920 return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1921}
1922
1924 unsigned ID) {
1925 return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
1926 SourceLocation(), nullptr, QualType(),
1927 nullptr);
1928}
1929
1930//===----------------------------------------------------------------------===//
1931// ObjCProtocolDecl
1932//===----------------------------------------------------------------------===//
1933
1934void ObjCProtocolDecl::anchor() {}
1935
1936ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
1938 SourceLocation atStartLoc,
1939 ObjCProtocolDecl *PrevDecl)
1940 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
1941 redeclarable_base(C) {
1942 setPreviousDecl(PrevDecl);
1943 if (PrevDecl)
1944 Data = PrevDecl->Data;
1945}
1946
1949 SourceLocation nameLoc,
1950 SourceLocation atStartLoc,
1951 ObjCProtocolDecl *PrevDecl) {
1952 auto *Result =
1953 new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
1954 Result->Data.setInt(!C.getLangOpts().Modules);
1955 return Result;
1956}
1957
1959 unsigned ID) {
1961 new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
1962 SourceLocation(), nullptr);
1963 Result->Data.setInt(!C.getLangOpts().Modules);
1964 return Result;
1965}
1966
1968 return hasAttr<ObjCNonRuntimeProtocolAttr>();
1969}
1970
1973 std::queue<const ObjCProtocolDecl *> WorkQueue;
1974 WorkQueue.push(this);
1975
1976 while (!WorkQueue.empty()) {
1977 const auto *PD = WorkQueue.front();
1978 WorkQueue.pop();
1979 for (const auto *Parent : PD->protocols()) {
1980 const auto *Can = Parent->getCanonicalDecl();
1981 auto Result = IPs.insert(Can);
1982 if (Result.second)
1983 WorkQueue.push(Parent);
1984 }
1985 }
1986}
1987
1989 ObjCProtocolDecl *PDecl = this;
1990
1991 if (Name == getIdentifier())
1992 return PDecl;
1993
1994 for (auto *I : protocols())
1995 if ((PDecl = I->lookupProtocolNamed(Name)))
1996 return PDecl;
1997
1998 return nullptr;
1999}
2000
2001// lookupMethod - Lookup a instance/class method in the protocol and protocols
2002// it inherited.
2004 bool isInstance) const {
2005 ObjCMethodDecl *MethodDecl = nullptr;
2006
2007 // If there is no definition or the definition is hidden, we don't find
2008 // anything.
2009 const ObjCProtocolDecl *Def = getDefinition();
2010 if (!Def || !Def->isUnconditionallyVisible())
2011 return nullptr;
2012
2013 if ((MethodDecl = getMethod(Sel, isInstance)))
2014 return MethodDecl;
2015
2016 for (const auto *I : protocols())
2017 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
2018 return MethodDecl;
2019 return nullptr;
2020}
2021
2022void ObjCProtocolDecl::allocateDefinitionData() {
2023 assert(!Data.getPointer() && "Protocol already has a definition!");
2024 Data.setPointer(new (getASTContext()) DefinitionData);
2025 Data.getPointer()->Definition = this;
2026 Data.getPointer()->HasODRHash = false;
2027}
2028
2030 allocateDefinitionData();
2031
2032 // Update all of the declarations with a pointer to the definition.
2033 for (auto *RD : redecls())
2034 RD->Data = this->Data;
2035}
2036
2038 Data.setPointer(nullptr);
2039 allocateDefinitionData();
2040 // Don't propagate data to other redeclarations.
2041}
2042
2045 Data = Definition->Data;
2046}
2047
2049 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2050 for (auto *Prop : PDecl->properties()) {
2051 // Insert into PM if not there already.
2052 PM.insert(std::make_pair(
2053 std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
2054 Prop));
2055 }
2056 // Scan through protocol's protocols.
2057 for (const auto *PI : PDecl->protocols())
2058 PI->collectPropertiesToImplement(PM);
2059 }
2060}
2061
2064 PropertyDeclOrder &PO) const {
2065 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2066 if (!PS.insert(PDecl).second)
2067 return;
2068 for (auto *Prop : PDecl->properties()) {
2069 if (Prop == Property)
2070 continue;
2071 if (Prop->getIdentifier() == Property->getIdentifier()) {
2072 PO.push_back(Prop);
2073 return;
2074 }
2075 }
2076 // Scan through protocol's protocols which did not have a matching property.
2077 for (const auto *PI : PDecl->protocols())
2078 PI->collectInheritedProtocolProperties(Property, PS, PO);
2079 }
2080}
2081
2082StringRef
2084 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
2085 return ObjCRTName->getMetadataName();
2086
2087 return getName();
2088}
2089
2091 assert(hasDefinition() && "ODRHash only for records with definitions");
2092
2093 // Previously calculated hash is stored in DefinitionData.
2094 if (hasODRHash())
2095 return data().ODRHash;
2096
2097 // Only calculate hash on first call of getODRHash per record.
2098 ODRHash Hasher;
2100 data().ODRHash = Hasher.CalculateHash();
2101 setHasODRHash(true);
2102
2103 return data().ODRHash;
2104}
2105
2106bool ObjCProtocolDecl::hasODRHash() const {
2107 if (!hasDefinition())
2108 return false;
2109 return data().HasODRHash;
2110}
2111
2112void ObjCProtocolDecl::setHasODRHash(bool HasHash) {
2113 assert(hasDefinition() && "Cannot set ODRHash without definition");
2114 data().HasODRHash = HasHash;
2115}
2116
2117//===----------------------------------------------------------------------===//
2118// ObjCCategoryDecl
2119//===----------------------------------------------------------------------===//
2120
2121void ObjCCategoryDecl::anchor() {}
2122
2123ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
2124 SourceLocation ClassNameLoc,
2125 SourceLocation CategoryNameLoc,
2127 ObjCTypeParamList *typeParamList,
2128 SourceLocation IvarLBraceLoc,
2129 SourceLocation IvarRBraceLoc)
2130 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
2131 ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
2132 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
2133 setTypeParamList(typeParamList);
2134}
2135
2137 SourceLocation AtLoc,
2138 SourceLocation ClassNameLoc,
2139 SourceLocation CategoryNameLoc,
2141 ObjCInterfaceDecl *IDecl,
2142 ObjCTypeParamList *typeParamList,
2143 SourceLocation IvarLBraceLoc,
2144 SourceLocation IvarRBraceLoc) {
2145 auto *CatDecl =
2146 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
2147 IDecl, typeParamList, IvarLBraceLoc,
2148 IvarRBraceLoc);
2149 if (IDecl) {
2150 // Link this category into its class's category list.
2151 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
2152 if (IDecl->hasDefinition()) {
2153 IDecl->setCategoryListRaw(CatDecl);
2154 if (ASTMutationListener *L = C.getASTMutationListener())
2155 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
2156 }
2157 }
2158
2159 return CatDecl;
2160}
2161
2163 unsigned ID) {
2164 return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
2166 nullptr, nullptr, nullptr);
2167}
2168
2171 const_cast<ObjCCategoryDecl*>(this));
2172}
2173
2175 getASTContext().setObjCImplementation(this, ImplD);
2176}
2177
2179 TypeParamList = TPL;
2180 if (!TPL)
2181 return;
2182 // Set the declaration context of each of the type parameters.
2183 for (auto *typeParam : *TypeParamList)
2184 typeParam->setDeclContext(this);
2185}
2186
2187//===----------------------------------------------------------------------===//
2188// ObjCCategoryImplDecl
2189//===----------------------------------------------------------------------===//
2190
2191void ObjCCategoryImplDecl::anchor() {}
2192
2196 ObjCInterfaceDecl *ClassInterface,
2197 SourceLocation nameLoc,
2198 SourceLocation atStartLoc,
2199 SourceLocation CategoryNameLoc) {
2200 if (ClassInterface && ClassInterface->hasDefinition())
2201 ClassInterface = ClassInterface->getDefinition();
2202 return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
2203 atStartLoc, CategoryNameLoc);
2204}
2205
2207 unsigned ID) {
2208 return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
2210 SourceLocation());
2211}
2212
2214 // The class interface might be NULL if we are working with invalid code.
2215 if (const ObjCInterfaceDecl *ID = getClassInterface())
2216 return ID->FindCategoryDeclaration(getIdentifier());
2217 return nullptr;
2218}
2219
2220void ObjCImplDecl::anchor() {}
2221
2223 // FIXME: The context should be correct before we get here.
2224 property->setLexicalDeclContext(this);
2225 addDecl(property);
2226}
2227
2229 ASTContext &Ctx = getASTContext();
2230
2231 if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
2232 if (IFace)
2233 Ctx.setObjCImplementation(IFace, ImplD);
2234
2235 } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
2237 Ctx.setObjCImplementation(CD, ImplD);
2238 }
2239
2240 ClassInterface = IFace;
2241}
2242
2243/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
2244/// properties implemented in this \@implementation block and returns
2245/// the implemented property that uses it.
2248 for (auto *PID : property_impls())
2249 if (PID->getPropertyIvarDecl() &&
2250 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
2251 return PID;
2252 return nullptr;
2253}
2254
2255/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
2256/// added to the list of those properties \@synthesized/\@dynamic in this
2257/// category \@implementation block.
2260 ObjCPropertyQueryKind QueryKind) const {
2261 ObjCPropertyImplDecl *ClassPropImpl = nullptr;
2262 for (auto *PID : property_impls())
2263 // If queryKind is unknown, we return the instance property if one
2264 // exists; otherwise we return the class property.
2265 if (PID->getPropertyDecl()->getIdentifier() == Id) {
2267 !PID->getPropertyDecl()->isClassProperty()) ||
2269 PID->getPropertyDecl()->isClassProperty()) ||
2271 !PID->getPropertyDecl()->isClassProperty()))
2272 return PID;
2273
2274 if (PID->getPropertyDecl()->isClassProperty())
2275 ClassPropImpl = PID;
2276 }
2277
2279 // We can't find the instance property, return the class property.
2280 return ClassPropImpl;
2281
2282 return nullptr;
2283}
2284
2285raw_ostream &clang::operator<<(raw_ostream &OS,
2286 const ObjCCategoryImplDecl &CID) {
2287 OS << CID.getName();
2288 return OS;
2289}
2290
2291//===----------------------------------------------------------------------===//
2292// ObjCImplementationDecl
2293//===----------------------------------------------------------------------===//
2294
2295void ObjCImplementationDecl::anchor() {}
2296
2299 ObjCInterfaceDecl *ClassInterface,
2300 ObjCInterfaceDecl *SuperDecl,
2301 SourceLocation nameLoc,
2302 SourceLocation atStartLoc,
2303 SourceLocation superLoc,
2304 SourceLocation IvarLBraceLoc,
2305 SourceLocation IvarRBraceLoc) {
2306 if (ClassInterface && ClassInterface->hasDefinition())
2307 ClassInterface = ClassInterface->getDefinition();
2308 return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
2309 nameLoc, atStartLoc, superLoc,
2310 IvarLBraceLoc, IvarRBraceLoc);
2311}
2312
2315 return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
2317}
2318
2320 CXXCtorInitializer ** initializers,
2321 unsigned numInitializers) {
2322 if (numInitializers > 0) {
2323 NumIvarInitializers = numInitializers;
2324 auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];
2325 memcpy(ivarInitializers, initializers,
2326 numInitializers * sizeof(CXXCtorInitializer*));
2327 IvarInitializers = ivarInitializers;
2328 }
2329}
2330
2333 return IvarInitializers.get(getASTContext().getExternalSource());
2334}
2335
2336raw_ostream &clang::operator<<(raw_ostream &OS,
2337 const ObjCImplementationDecl &ID) {
2338 OS << ID.getName();
2339 return OS;
2340}
2341
2342//===----------------------------------------------------------------------===//
2343// ObjCCompatibleAliasDecl
2344//===----------------------------------------------------------------------===//
2345
2346void ObjCCompatibleAliasDecl::anchor() {}
2347
2352 ObjCInterfaceDecl* AliasedClass) {
2353 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
2354}
2355
2358 return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
2359 nullptr, nullptr);
2360}
2361
2362//===----------------------------------------------------------------------===//
2363// ObjCPropertyDecl
2364//===----------------------------------------------------------------------===//
2365
2366void ObjCPropertyDecl::anchor() {}
2367
2371 SourceLocation AtLoc,
2372 SourceLocation LParenLoc,
2373 QualType T,
2374 TypeSourceInfo *TSI,
2375 PropertyControl propControl) {
2376 return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
2377 propControl);
2378}
2379
2381 unsigned ID) {
2382 return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
2384 QualType(), nullptr, None);
2385}
2386
2388 return DeclType.substObjCMemberType(objectType, getDeclContext(),
2390}
2391
2393 return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
2394 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
2395}
2396
2397//===----------------------------------------------------------------------===//
2398// ObjCPropertyImplDecl
2399//===----------------------------------------------------------------------===//
2400
2402 DeclContext *DC,
2403 SourceLocation atLoc,
2405 ObjCPropertyDecl *property,
2406 Kind PK,
2407 ObjCIvarDecl *ivar,
2408 SourceLocation ivarLoc) {
2409 return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
2410 ivarLoc);
2411}
2412
2414 unsigned ID) {
2415 return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
2416 SourceLocation(), nullptr, Dynamic,
2417 nullptr, SourceLocation());
2418}
2419
2421 SourceLocation EndLoc = getLocation();
2422 if (IvarLoc.isValid())
2423 EndLoc = IvarLoc;
2424
2425 return SourceRange(AtLoc, EndLoc);
2426}
Defines the clang::ASTContext interface.
NodeId Parent
Definition: ASTDiff.cpp:191
int Id
Definition: ASTDiff.cpp:190
StringRef P
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:497
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:2955
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,...
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:182
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:2070
void setObjCImplementation(ObjCInterfaceDecl *IFaceD, ObjCImplementationDecl *ImplD)
Set the implementation of ObjCInterfaceDecl.
IdentifierTable & Idents
Definition: ASTContext.h:639
const LangOptions & getLangOpts() const
Definition: ASTContext.h:770
IdentifierInfo * getNSObjectName() const
Retrieve the identifier 'NSObject'.
Definition: ASTContext.h:1887
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
Definition: ASTContext.h:2058
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2141
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:2048
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:713
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:1182
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:2293
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1379
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2352
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1446
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2076
ObjCMethodDeclBitfields ObjCMethodDeclBits
Definition: DeclBase.h:2015
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1785
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1699
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:440
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:598
bool isUnconditionallyVisible() const
Determine whether this declaration is definitely visible to name lookup, independent of whether the o...
Definition: DeclBase.h:859
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:88
@ OBJC_TQ_None
Definition: DeclBase.h:198
SourceLocation getLocation() const
Definition: DeclBase.h:444
void setImplicit(bool I=true)
Definition: DeclBase.h:599
DeclContext * getDeclContext()
Definition: DeclBase.h:453
Kind getKind() const
Definition: DeclBase.h:447
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:5338
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:768
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition: ODRHash.cpp:626
unsigned CalculateHash()
Definition: ODRHash.cpp:218
Represents a field declaration created by an @defs(...).
Definition: DeclObjC.h:2026
static ObjCAtDefsFieldDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:1923
static ObjCAtDefsFieldDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW)
Definition: DeclObjC.cpp:1917
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2323
static ObjCCategoryDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:2162
void setTypeParamList(ObjCTypeParamList *TPL)
Set the type parameters of this category.
Definition: DeclObjC.cpp:2178
static ObjCCategoryDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())
Definition: DeclObjC.cpp:2136
ObjCCategoryImplDecl * getImplementation() const
Definition: DeclObjC.cpp:2169
void setImplementation(ObjCCategoryImplDecl *ImplD)
Definition: DeclObjC.cpp:2174
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2542
static ObjCCategoryImplDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:2206
static ObjCCategoryImplDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc)
Definition: DeclObjC.cpp:2194
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2213
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition: DeclObjC.h:2772
static ObjCCompatibleAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl *aliasedClass)
Definition: DeclObjC.cpp:2349
static ObjCCompatibleAliasDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:2357
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:944
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:92
void setAtStartLoc(SourceLocation Loc)
Definition: DeclObjC.h:1094
llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
Definition: DeclObjC.h:1083
instmeth_range instance_methods() const
Definition: DeclObjC.h:1029
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
Definition: DeclObjC.h:1084
ObjCPropertyDecl * getProperty(const IdentifierInfo *Id, bool IsInstance) const
Definition: DeclObjC.cpp:235
ObjCIvarDecl * getIvarDecl(IdentifierInfo *Id) const
getIvarDecl - This method looks up an ivar in this ContextDecl.
Definition: DeclObjC.cpp:80
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
Definition: DeclObjC.cpp:249
virtual void collectPropertiesToImplement(PropertyMap &PM) const
This routine collects list of properties to be implemented in the class.
Definition: DeclObjC.h:1090
prop_range properties() const
Definition: DeclObjC.h:963
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Definition: DeclObjC.h:1062
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const
This routine returns 'true' if a user declared setter method was found in the class,...
Definition: DeclObjC.cpp:124
ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc)
Definition: DeclObjC.cpp:68
void addPropertyImplementation(ObjCPropertyImplDecl *property)
Definition: DeclObjC.cpp:2222
propimpl_range property_impls() const
Definition: DeclObjC.h:2510
void setClassInterface(ObjCInterfaceDecl *IFace)
Definition: DeclObjC.cpp:2228
ObjCPropertyImplDecl * FindPropertyImplDecl(IdentifierInfo *propertyId, ObjCPropertyQueryKind queryKind) const
FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl added to the list of thos...
Definition: DeclObjC.cpp:2259
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2483
ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const
FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...
Definition: DeclObjC.cpp:2247
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2595
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:2298
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Definition: DeclObjC.cpp:1627
CXXCtorInitializer *const * init_const_iterator
init_const_iterator - Iterates through the ivar initializer list.
Definition: DeclObjC.h:2654
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
Definition: DeclObjC.h:2718
init_iterator init_begin()
init_begin() - Retrieve an iterator to the first initializer.
Definition: DeclObjC.h:2666
void setIvarInitializers(ASTContext &C, CXXCtorInitializer **initializers, unsigned numInitializers)
Definition: DeclObjC.cpp:2319
static ObjCImplementationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:2314
Represents an ObjC class declaration.
Definition: DeclObjC.h:1150
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:443
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameters of this class.
Definition: DeclObjC.cpp:321
all_protocol_iterator all_referenced_protocol_end() const
Definition: DeclObjC.h:1431
ObjCInterfaceDecl * lookupInheritedClass(const IdentifierInfo *ICName)
lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super class whose name is passe...
Definition: DeclObjC.cpp:669
ivar_iterator ivar_end() const
Definition: DeclObjC.h:1457
ObjCMethodDecl * getCategoryMethod(Selector Sel, bool isInstance) const
Definition: DeclObjC.h:1347
ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name 'PropertyId' in the p...
Definition: DeclObjC.cpp:382
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
Definition: DeclObjC.cpp:1542
static ObjCInterfaceDecl * CreateDeserialized(const ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:1558
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition: DeclObjC.cpp:638
void setCategoryListRaw(ObjCCategoryDecl *category)
Set the raw pointer to the start of the category/extension list.
Definition: DeclObjC.h:1793
bool hasDefinition() const
Determine whether this class has been defined.
Definition: DeclObjC.h:1524
all_protocol_range all_referenced_protocols() const
Definition: DeclObjC.h:1413
visible_extensions_range visible_extensions() const
Definition: DeclObjC.h:1719
ObjCTypeParamList * getTypeParamListAsWritten() const
Retrieve the type parameters written on this particular declaration of the class.
Definition: DeclObjC.h:1300
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
Definition: DeclObjC.cpp:1678
ivar_iterator ivar_begin() const
Definition: DeclObjC.h:1449
protocol_range protocols() const
Definition: DeclObjC.h:1355
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Definition: DeclObjC.h:1842
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
Definition: DeclObjC.cpp:792
bool ivar_empty() const
Definition: DeclObjC.h:1469
void setImplementation(ObjCImplementationDecl *ImplD)
Definition: DeclObjC.cpp:1648
known_categories_range known_categories() const
Definition: DeclObjC.h:1683
const ObjCInterfaceDecl * isObjCRequiresPropertyDefs() const
isObjCRequiresPropertyDefs - Checks that a class or one of its super classes must not be auto-synthes...
Definition: DeclObjC.cpp:433
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition: DeclObjC.cpp:371
all_protocol_iterator all_referenced_protocol_begin() const
Definition: DeclObjC.h:1418
void setExternallyCompleted()
Indicate that this Objective-C class is complete, but that the external AST source will be responsibl...
Definition: DeclObjC.cpp:1593
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
Definition: DeclObjC.cpp:1781
ObjCCategoryDecl * getCategoryListRaw() const
Retrieve the raw pointer to the start of the category/extension list.
Definition: DeclObjC.h:1780
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition: DeclObjC.h:1519
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
Definition: DeclObjC.cpp:1755
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
Definition: DeclObjC.cpp:757
void setTypeParamList(ObjCTypeParamList *TPL)
Set the type parameters of this class.
Definition: DeclObjC.cpp:342
ObjCMethodDecl * getCategoryInstanceMethod(Selector Sel) const
Definition: DeclObjC.cpp:1771
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:700
ObjCProtocolDecl * lookupNestedProtocol(IdentifierInfo *Name)
Definition: DeclObjC.cpp:688
bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, bool lookupCategory, bool RHSIsQualifiedID=false)
ClassImplementsProtocol - Checks that 'lProto' protocol has been implemented in IDecl class,...
Definition: DeclObjC.cpp:1794
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Definition: DeclObjC.cpp:1619
const ObjCObjectType * getSuperClassType() const
Retrieve the superclass type.
Definition: DeclObjC.h:1561
ObjCImplementationDecl * getImplementation() const
Definition: DeclObjC.cpp:1635
bool hasDesignatedInitializers() const
Returns true if this interface decl contains at least one initializer marked with the 'objc_designate...
Definition: DeclObjC.cpp:1608
void getDesignatedInitializers(llvm::SmallVectorImpl< const ObjCMethodDecl * > &Methods) const
Returns the designated initializers for the interface.
Definition: DeclObjC.cpp:549
void startDefinition()
Starts the definition of this Objective-C class, taking it from a forward declaration (@class) to a d...
Definition: DeclObjC.cpp:617
void collectPropertiesToImplement(PropertyMap &PM) const override
This routine collects list of properties to be implemented in the class.
Definition: DeclObjC.cpp:406
bool isArcWeakrefUnavailable() const
isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...
Definition: DeclObjC.cpp:423
visible_categories_range visible_categories() const
Definition: DeclObjC.h:1649
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Definition: DeclObjC.h:1910
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:351
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
Definition: DeclObjC.h:1538
TypeSourceInfo * getSuperClassTInfo() const
Definition: DeclObjC.h:1569
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:571
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
Definition: DeclObjC.cpp:627
void setHasDesignatedInitializers()
Indicate that this interface decl contains at least one initializer marked with the 'objc_designated_...
Definition: DeclObjC.cpp:1601
void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition)
Definition: DeclObjC.cpp:633
known_extensions_range known_extensions() const
Definition: DeclObjC.h:1757
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1947
void setNextIvar(ObjCIvarDecl *ivar)
Definition: DeclObjC.h:1985
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
Definition: DeclObjC.cpp:1881
static ObjCIvarDecl * Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW=nullptr, bool synthesized=false)
Definition: DeclObjC.cpp:1839
static ObjCIvarDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:1875
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:1905
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:853
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
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
static ObjCMethodDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:866
Represents a class type in Objective C.
Definition: Type.h:6297
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:729
QualType getUsageType(QualType objectType) const
Retrieve the type when this property is used with a specific base object type.
Definition: DeclObjC.cpp:2387
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
Definition: DeclObjC.cpp:178
bool isDirectProperty() const
Definition: DeclObjC.cpp:2392
static ObjCPropertyDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:2380
static ObjCPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, TypeSourceInfo *TSI, PropertyControl propControl=None)
Definition: DeclObjC.cpp:2368
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.
Definition: DeclObjC.cpp:226
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2802
static ObjCPropertyImplDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:2413
static ObjCPropertyImplDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc)
Definition: DeclObjC.cpp:2401
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclObjC.cpp:2420
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2079
void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition)
Definition: DeclObjC.cpp:2043
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
Definition: DeclObjC.cpp:2037
bool hasDefinition() const
Determine whether this protocol has a definition.
Definition: DeclObjC.h:2232
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance) const
Definition: DeclObjC.cpp:2003
static ObjCProtocolDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl)
Definition: DeclObjC.cpp:1947
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition: DeclObjC.h:2244
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
Definition: DeclObjC.cpp:2083
void getImpliedProtocols(llvm::DenseSet< const ObjCProtocolDecl * > &IPs) const
Get the set of all protocols implied by this protocols inheritance hierarchy.
Definition: DeclObjC.cpp:1971
void startDefinition()
Starts the definition of this Objective-C protocol.
Definition: DeclObjC.cpp:2029
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
Definition: DeclObjC.cpp:1967
void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, ProtocolPropertySet &PS, PropertyDeclOrder &PO) const
Definition: DeclObjC.cpp:2062
ObjCProtocolDecl * lookupProtocolNamed(IdentifierInfo *PName)
Definition: DeclObjC.cpp:1988
static ObjCProtocolDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Definition: DeclObjC.cpp:1958
protocol_range protocols() const
Definition: DeclObjC.h:2155
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
Definition: DeclObjC.cpp:2090
void collectPropertiesToImplement(PropertyMap &PM) const override
This routine collects list of properties to be implemented in the class.
Definition: DeclObjC.cpp:2048
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:639
static ObjCTypeParamDecl * CreateDeserialized(ASTContext &ctx, unsigned ID)
Definition: DeclObjC.cpp:1489
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclObjC.cpp:1497
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition: DeclObjC.h:658
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:685
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:1749
A (possibly-)qualified type.
Definition: Type.h:737
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition: Type.cpp:3403
QualType withConst() const
Definition: Type.h:951
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6902
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:1551
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:1544
The collection of all-type qualifiers we support.
Definition: Type.h:147
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:175
void setObjCLifetime(ObjCLifetime type)
Definition: Type.h:355
ObjCInterfaceDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
void setPreviousDecl(ObjCInterfaceDecl *PrevDecl)
Set the previous declaration.
Definition: Decl.h:4959
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:296
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:6873
bool isObjCSelType() const
Definition: Type.h:7327
bool isObjCIdType() const
Definition: Type.h:7315
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3449
QualType getType() const
Definition: Decl.h:717
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:717
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
@ 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.