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