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