clang 24.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///
79 lookup_result R = lookup(Id);
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())
191 if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,
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 =
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.
331 for (const ObjCInterfaceDecl *decl = getMostRecentDecl(); decl;
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
349ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const {
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 =
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())
413 PI->collectPropertiesToImplement(PM);
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
429const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
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
630 const ObjCInterfaceDecl *Definition) {
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,
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 const PrintingPolicy &Policy,
870 bool Qualified) const {
871 if (!Qualified) {
872 printName(OS, Policy);
873 return;
874 }
875
876 OS << (isInstanceMethod() ? '-' : '+');
877 OS << '[';
878 if (const auto *ID = getClassInterface()) {
879 OS << ID->getName();
880 } else if (const auto *PD = dyn_cast<ObjCProtocolDecl>(getDeclContext())) {
881 OS << PD->getName();
882 } else {
883 assert(false && "Context should be set for ObjCMethodDecl");
884 OS << "<Unknown>";
885 }
886 OS << ' ' << getSelector() << ']';
887}
888
890 return hasAttr<ObjCDirectAttr>() &&
891 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
892}
893
898
900 if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext()))
901 return PD->getIdentifier() == Ctx.getNSObjectName();
902 if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext()))
903 return ID->getIdentifier() == Ctx.getNSObjectName();
904 return false;
905}
906
908 const ObjCMethodDecl **InitMethod) const {
909 if (getMethodFamily() != OMF_init)
910 return false;
911 const DeclContext *DC = getDeclContext();
912 if (isa<ObjCProtocolDecl>(DC))
913 return false;
914 if (const ObjCInterfaceDecl *ID = getClassInterface())
915 return ID->isDesignatedInitializer(getSelector(), InitMethod);
916 return false;
917}
918
920 for (auto *param : parameters()) {
921 if (param->isDestroyedInCallee())
922 return true;
923 }
924 return false;
925}
926
928 return Body.get(getASTContext().getExternalSource());
929}
930
931void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
932 assert(PrevMethod);
933 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
934 setIsRedeclaration(true);
935 PrevMethod->setHasRedeclaration(true);
936}
937
938void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
940 ArrayRef<SourceLocation> SelLocs) {
941 ParamsAndSelLocs = nullptr;
942 NumParams = Params.size();
943 if (Params.empty() && SelLocs.empty())
944 return;
945
946 static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation),
947 "Alignment not sufficient for SourceLocation");
948
949 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
950 sizeof(SourceLocation) * SelLocs.size();
951 ParamsAndSelLocs = C.Allocate(Size);
952 llvm::uninitialized_copy(Params, getParams());
953 llvm::uninitialized_copy(SelLocs, getStoredSelLocs());
954}
955
957 SmallVectorImpl<SourceLocation> &SelLocs) const {
958 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
959 SelLocs.push_back(getSelectorLoc(i));
960}
961
964 ArrayRef<SourceLocation> SelLocs) {
965 assert((!SelLocs.empty() || isImplicit()) &&
966 "No selector locs for non-implicit method");
967 if (isImplicit())
968 return setParamsAndSelLocs(C, Params, {});
969
970 setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params,
971 DeclEndLoc));
972 if (getSelLocsKind() != SelLoc_NonStandard)
973 return setParamsAndSelLocs(C, Params, {});
974
975 setParamsAndSelLocs(C, Params, SelLocs);
976}
977
978/// A definition will return its interface declaration.
979/// An interface declaration will return its definition.
980/// Otherwise it will return itself.
982 ASTContext &Ctx = getASTContext();
983 ObjCMethodDecl *Redecl = nullptr;
984 if (hasRedeclaration())
985 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
986 if (Redecl)
987 return Redecl;
988
989 auto *CtxD = cast<Decl>(getDeclContext());
990
991 if (!CtxD->isInvalidDecl()) {
992 if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
993 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
994 if (!ImplD->isInvalidDecl())
995 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
996
997 } else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
998 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
999 if (!ImplD->isInvalidDecl())
1000 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
1001
1002 } else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
1003 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
1004 if (!IFD->isInvalidDecl())
1005 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
1006
1007 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
1008 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
1009 if (!CatD->isInvalidDecl())
1010 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
1011 }
1012 }
1013
1014 // Ensure that the discovered method redeclaration has a valid declaration
1015 // context. Used to prevent infinite loops when iterating redeclarations in
1016 // a partially invalid AST.
1017 if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl())
1018 Redecl = nullptr;
1019
1020 if (!Redecl && isRedeclaration()) {
1021 // This is the last redeclaration, go back to the first method.
1022 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
1024 /*AllowHidden=*/true);
1025 }
1026
1027 return Redecl ? Redecl : this;
1028}
1029
1031 auto *CtxD = cast<Decl>(getDeclContext());
1032 const auto &Sel = getSelector();
1033
1034 if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
1035 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) {
1036 // When the container is the ObjCImplementationDecl (the primary
1037 // @implementation), then the canonical Decl is either in
1038 // the class Interface, or in any of its extension.
1039 //
1040 // So when we don't find it in the ObjCInterfaceDecl,
1041 // sift through extensions too.
1042 if (ObjCMethodDecl *MD = IFD->getMethod(Sel, isInstanceMethod()))
1043 return MD;
1044 for (auto *Ext : IFD->known_extensions())
1045 if (ObjCMethodDecl *MD = Ext->getMethod(Sel, isInstanceMethod()))
1046 return MD;
1047 }
1048 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
1049 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
1050 if (ObjCMethodDecl *MD = CatD->getMethod(Sel, isInstanceMethod()))
1051 return MD;
1052 }
1053
1054 if (isRedeclaration()) {
1055 // It is possible that we have not done deserializing the ObjCMethod yet.
1056 ObjCMethodDecl *MD =
1057 cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
1058 /*AllowHidden=*/true);
1059 return MD ? MD : this;
1060 }
1061
1062 return this;
1063}
1064
1066 if (Stmt *Body = getBody())
1067 return Body->getEndLoc();
1068 return DeclEndLoc;
1069}
1070
1072 auto family = static_cast<ObjCMethodFamily>(ObjCMethodDeclBits.Family);
1073 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
1074 return family;
1075
1076 // Check for an explicit attribute.
1077 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
1078 // The unfortunate necessity of mapping between enums here is due
1079 // to the attributes framework.
1080 switch (attr->getFamily()) {
1081 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
1082 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
1083 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
1084 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
1085 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
1086 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
1087 }
1088 ObjCMethodDeclBits.Family = family;
1089 return family;
1090 }
1091
1092 family = getSelector().getMethodFamily();
1093 switch (family) {
1094 case OMF_None: break;
1095
1096 // init only has a conventional meaning for an instance method, and
1097 // it has to return an object.
1098 case OMF_init:
1099 if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
1100 family = OMF_None;
1101 break;
1102
1103 // alloc/copy/new have a conventional meaning for both class and
1104 // instance methods, but they require an object return.
1105 case OMF_alloc:
1106 case OMF_copy:
1107 case OMF_mutableCopy:
1108 case OMF_new:
1109 if (!getReturnType()->isObjCObjectPointerType())
1110 family = OMF_None;
1111 break;
1112
1113 // These selectors have a conventional meaning only for instance methods.
1114 case OMF_dealloc:
1115 case OMF_finalize:
1116 case OMF_retain:
1117 case OMF_release:
1118 case OMF_autorelease:
1119 case OMF_retainCount:
1120 case OMF_self:
1121 if (!isInstanceMethod())
1122 family = OMF_None;
1123 break;
1124
1125 case OMF_initialize:
1126 if (isInstanceMethod() || !getReturnType()->isVoidType())
1127 family = OMF_None;
1128 break;
1129
1131 if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
1132 family = OMF_None;
1133 else {
1134 unsigned noParams = param_size();
1135 if (noParams < 1 || noParams > 3)
1136 family = OMF_None;
1137 else {
1139 QualType ArgT = (*it);
1140 if (!ArgT->isObjCSelType()) {
1141 family = OMF_None;
1142 break;
1143 }
1144 while (--noParams) {
1145 it++;
1146 ArgT = (*it);
1147 if (!ArgT->isObjCIdType()) {
1148 family = OMF_None;
1149 break;
1150 }
1151 }
1152 }
1153 }
1154 break;
1155
1156 }
1157
1158 // Cache the result.
1159 ObjCMethodDeclBits.Family = family;
1160 return family;
1161}
1162
1164 const ObjCInterfaceDecl *OID,
1165 bool &selfIsPseudoStrong,
1166 bool &selfIsConsumed) const {
1167 QualType selfTy;
1168 selfIsPseudoStrong = false;
1169 selfIsConsumed = false;
1170 if (isInstanceMethod()) {
1171 // There may be no interface context due to error in declaration
1172 // of the interface (which has been reported). Recover gracefully.
1173 if (OID) {
1174 selfTy = Context.getObjCInterfaceType(OID);
1175 selfTy = Context.getObjCObjectPointerType(selfTy);
1176 } else {
1177 selfTy = Context.getObjCIdType();
1178 }
1179 } else // we have a factory method.
1180 selfTy = Context.getObjCClassType();
1181
1182 if (Context.getLangOpts().ObjCAutoRefCount) {
1183 if (isInstanceMethod()) {
1184 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
1185
1186 // 'self' is always __strong. It's actually pseudo-strong except
1187 // in init methods (or methods labeled ns_consumes_self), though.
1188 Qualifiers qs;
1190 selfTy = Context.getQualifiedType(selfTy, qs);
1191
1192 // In addition, 'self' is const unless this is an init method.
1193 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
1194 selfTy = selfTy.withConst();
1195 selfIsPseudoStrong = true;
1196 }
1197 }
1198 else {
1199 assert(isClassMethod());
1200 // 'self' is always const in class methods.
1201 selfTy = selfTy.withConst();
1202 selfIsPseudoStrong = true;
1203 }
1204 }
1205 return selfTy;
1206}
1207
1209 const ObjCInterfaceDecl *OID) {
1210 bool selfIsPseudoStrong, selfIsConsumed;
1211 QualType selfTy =
1212 getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
1213 auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),
1214 &Context.Idents.get("self"), selfTy,
1217
1218 if (selfIsConsumed)
1219 Self->addAttr(NSConsumedAttr::CreateImplicit(Context));
1220
1221 if (selfIsPseudoStrong)
1222 Self->setARCPseudoStrong(true);
1223
1224 auto *CmdDecl = ImplicitParamDecl::Create(
1225 Context, this, SourceLocation(), &Context.Idents.get("_cmd"),
1226 Context.getObjCSelType(), ImplicitParamKind::ObjCCmd);
1227 setCmdDecl(CmdDecl);
1228}
1229
1231 if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
1232 return ID;
1233 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1234 return CD->getClassInterface();
1235 if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
1236 return IMD->getClassInterface();
1238 return nullptr;
1239 llvm_unreachable("unknown method context");
1240}
1241
1243 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1244 return CD;
1245 if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
1246 return IMD->getCategoryDecl();
1247 return nullptr;
1248}
1249
1251 const auto *TSI = getReturnTypeSourceInfo();
1252 if (TSI)
1253 return TSI->getTypeLoc().getSourceRange();
1254 return SourceRange();
1255}
1256
1262
1264 // FIXME: Handle related result types here.
1265
1267 .substObjCMemberType(receiverType, getDeclContext(),
1269}
1270
1272 const ObjCMethodDecl *Method,
1274 bool MovedToSuper) {
1275 if (!Container)
1276 return;
1277
1278 // In categories look for overridden methods from protocols. A method from
1279 // category is not "overridden" since it is considered as the "same" method
1280 // (same USR) as the one from the interface.
1281 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1282 // Check whether we have a matching method at this category but only if we
1283 // are at the super class level.
1284 if (MovedToSuper)
1285 if (ObjCMethodDecl *
1286 Overridden = Container->getMethod(Method->getSelector(),
1287 Method->isInstanceMethod(),
1288 /*AllowHidden=*/true))
1289 if (Method != Overridden) {
1290 // We found an override at this category; there is no need to look
1291 // into its protocols.
1292 Methods.push_back(Overridden);
1293 return;
1294 }
1295
1296 for (const auto *P : Category->protocols())
1297 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1298 return;
1299 }
1300
1301 // Check whether we have a matching method at this level.
1302 if (const ObjCMethodDecl *
1303 Overridden = Container->getMethod(Method->getSelector(),
1304 Method->isInstanceMethod(),
1305 /*AllowHidden=*/true))
1306 if (Method != Overridden) {
1307 // We found an override at this level; there is no need to look
1308 // into other protocols or categories.
1309 Methods.push_back(Overridden);
1310 return;
1311 }
1312
1313 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
1314 for (const auto *P : Protocol->protocols())
1315 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1316 }
1317
1318 if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
1319 for (const auto *P : Interface->protocols())
1320 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1321
1322 for (const auto *Cat : Interface->known_categories())
1323 CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
1324
1325 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
1326 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
1327 /*MovedToSuper=*/true);
1328 }
1329}
1330
1331static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
1332 const ObjCMethodDecl *Method,
1334 CollectOverriddenMethodsRecurse(Container, Method, Methods,
1335 /*MovedToSuper=*/false);
1336}
1337
1340 assert(Method->isOverriding());
1341
1342 if (const auto *ProtD =
1343 dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1344 CollectOverriddenMethods(ProtD, Method, overridden);
1345
1346 } else if (const auto *IMD =
1347 dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1348 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1349 if (!ID)
1350 return;
1351 // Start searching for overridden methods using the method from the
1352 // interface as starting point.
1353 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1354 Method->isInstanceMethod(),
1355 /*AllowHidden=*/true))
1356 Method = IFaceMeth;
1357 CollectOverriddenMethods(ID, Method, overridden);
1358
1359 } else if (const auto *CatD =
1360 dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1361 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1362 if (!ID)
1363 return;
1364 // Start searching for overridden methods using the method from the
1365 // interface as starting point.
1366 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1367 Method->isInstanceMethod(),
1368 /*AllowHidden=*/true))
1369 Method = IFaceMeth;
1370 CollectOverriddenMethods(ID, Method, overridden);
1371
1372 } else {
1374 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1375 Method, overridden);
1376 }
1377}
1378
1380 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1381 const ObjCMethodDecl *Method = this;
1382
1383 if (Method->isRedeclaration()) {
1384 Method = cast<ObjCContainerDecl>(Method->getDeclContext())
1385 ->getMethod(Method->getSelector(), Method->isInstanceMethod(),
1386 /*AllowHidden=*/true);
1387 }
1388
1389 if (Method->isOverriding()) {
1391 assert(!Overridden.empty() &&
1392 "ObjCMethodDecl's overriding bit is not as expected");
1393 }
1394}
1395
1396const ObjCPropertyDecl *
1397ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
1398 Selector Sel = getSelector();
1399 unsigned NumArgs = Sel.getNumArgs();
1400 if (NumArgs > 1)
1401 return nullptr;
1402
1403 if (isPropertyAccessor()) {
1404 const auto *Container = cast<ObjCContainerDecl>(getParent());
1405 // For accessor stubs, go back to the interface.
1406 if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container))
1408 Container = ImplDecl->getClassInterface();
1409
1410 bool IsGetter = (NumArgs == 0);
1411 bool IsInstance = isInstanceMethod();
1412
1413 /// Local function that attempts to find a matching property within the
1414 /// given Objective-C container.
1415 auto findMatchingProperty =
1416 [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
1417 if (IsInstance) {
1418 for (const auto *I : Container->instance_properties()) {
1419 Selector NextSel = IsGetter ? I->getGetterName()
1420 : I->getSetterName();
1421 if (NextSel == Sel)
1422 return I;
1423 }
1424 } else {
1425 for (const auto *I : Container->class_properties()) {
1426 Selector NextSel = IsGetter ? I->getGetterName()
1427 : I->getSetterName();
1428 if (NextSel == Sel)
1429 return I;
1430 }
1431 }
1432
1433 return nullptr;
1434 };
1435
1436 // Look in the container we were given.
1437 if (const auto *Found = findMatchingProperty(Container))
1438 return Found;
1439
1440 // If we're in a category or extension, look in the main class.
1441 const ObjCInterfaceDecl *ClassDecl = nullptr;
1442 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1443 ClassDecl = Category->getClassInterface();
1444 if (const auto *Found = findMatchingProperty(ClassDecl))
1445 return Found;
1446 } else {
1447 // Determine whether the container is a class.
1448 ClassDecl = cast<ObjCInterfaceDecl>(Container);
1449 }
1450 assert(ClassDecl && "Failed to find main class");
1451
1452 // If we have a class, check its visible extensions.
1453 for (const auto *Ext : ClassDecl->visible_extensions()) {
1454 if (Ext == Container)
1455 continue;
1456 if (const auto *Found = findMatchingProperty(Ext))
1457 return Found;
1458 }
1459
1460 assert(isSynthesizedAccessorStub() && "expected an accessor stub");
1461
1462 for (const auto *Cat : ClassDecl->known_categories()) {
1463 if (Cat == Container)
1464 continue;
1465 if (const auto *Found = findMatchingProperty(Cat))
1466 return Found;
1467 }
1468
1469 llvm_unreachable("Marked as a property accessor but no property found!");
1470 }
1471
1472 if (!CheckOverrides)
1473 return nullptr;
1474
1475 using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;
1476
1477 OverridesTy Overrides;
1478 getOverriddenMethods(Overrides);
1479 for (const auto *Override : Overrides)
1480 if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(false))
1481 return Prop;
1482
1483 return nullptr;
1484}
1485
1486//===----------------------------------------------------------------------===//
1487// ObjCTypeParamDecl
1488//===----------------------------------------------------------------------===//
1489
1490void ObjCTypeParamDecl::anchor() {}
1491
1493 ObjCTypeParamVariance variance,
1494 SourceLocation varianceLoc,
1495 unsigned index,
1496 SourceLocation nameLoc,
1497 IdentifierInfo *name,
1498 SourceLocation colonLoc,
1499 TypeSourceInfo *boundInfo) {
1500 auto *TPDecl =
1501 new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
1502 nameLoc, name, colonLoc, boundInfo);
1503 QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});
1504 TPDecl->setTypeForDecl(TPType.getTypePtr());
1505 return TPDecl;
1506}
1507
1509 GlobalDeclID ID) {
1510 return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,
1513 nullptr, SourceLocation(), nullptr);
1514}
1515
1517 SourceLocation startLoc = VarianceLoc;
1518 if (startLoc.isInvalid())
1519 startLoc = getLocation();
1520
1521 if (hasExplicitBound()) {
1522 return SourceRange(startLoc,
1523 getTypeSourceInfo()->getTypeLoc().getEndLoc());
1524 }
1525
1526 return SourceRange(startLoc);
1527}
1528
1529//===----------------------------------------------------------------------===//
1530// ObjCTypeParamList
1531//===----------------------------------------------------------------------===//
1532ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,
1534 SourceLocation rAngleLoc)
1535 : Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) {
1536 llvm::copy(typeParams, begin());
1537}
1538
1539ObjCTypeParamList *ObjCTypeParamList::create(
1540 ASTContext &ctx,
1541 SourceLocation lAngleLoc,
1543 SourceLocation rAngleLoc) {
1544 void *mem =
1545 ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),
1546 alignof(ObjCTypeParamList));
1547 return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
1548}
1549
1551 SmallVectorImpl<QualType> &typeArgs) const {
1552 typeArgs.reserve(size());
1553 for (auto *typeParam : *this)
1554 typeArgs.push_back(typeParam->getUnderlyingType());
1555}
1556
1557//===----------------------------------------------------------------------===//
1558// ObjCInterfaceDecl
1559//===----------------------------------------------------------------------===//
1560
1561ObjCInterfaceDecl *ObjCInterfaceDecl::Create(
1562 const ASTContext &C, DeclContext *DC, SourceLocation atLoc,
1563 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1564 ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal) {
1565 auto *Result = new (C, DC)
1566 ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
1567 isInternal);
1568 Result->Data.setInt(!C.getLangOpts().Modules);
1569 C.getObjCInterfaceType(Result, PrevDecl);
1570 return Result;
1571}
1572
1574 GlobalDeclID ID) {
1575 auto *Result = new (C, ID)
1576 ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,
1577 SourceLocation(), nullptr, false);
1578 Result->Data.setInt(!C.getLangOpts().Modules);
1579 return Result;
1580}
1581
1582ObjCInterfaceDecl::ObjCInterfaceDecl(
1583 const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
1584 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1585 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal)
1586 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
1587 redeclarable_base(C) {
1588 setPreviousDecl(PrevDecl);
1589
1590 // Copy the 'data' pointer over.
1591 if (PrevDecl)
1592 Data = PrevDecl->Data;
1593
1594 setImplicit(IsInternal);
1595
1596 setTypeParamList(typeParamList);
1597}
1598
1599void ObjCInterfaceDecl::LoadExternalDefinition() const {
1600 assert(data().ExternallyCompleted && "Class is not externally completed");
1601 data().ExternallyCompleted = false;
1603 const_cast<ObjCInterfaceDecl *>(this));
1604}
1605
1607 assert(getASTContext().getExternalSource() &&
1608 "Class can't be externally completed without an external source");
1609 assert(hasDefinition() &&
1610 "Forward declarations can't be externally completed");
1611 data().ExternallyCompleted = true;
1612}
1613
1615 // Check for a complete definition and recover if not so.
1617 return;
1618 data().HasDesignatedInitializers = true;
1619}
1620
1622 // Check for a complete definition and recover if not so.
1624 return false;
1625 if (data().ExternallyCompleted)
1626 LoadExternalDefinition();
1627
1628 return data().HasDesignatedInitializers;
1629}
1630
1631StringRef
1633 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1634 return ObjCRTName->getMetadataName();
1635
1636 return getName();
1637}
1638
1639StringRef
1641 if (ObjCInterfaceDecl *ID =
1642 const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
1643 return ID->getObjCRuntimeNameAsString();
1644
1645 return getName();
1646}
1647
1649 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1650 if (data().ExternallyCompleted)
1651 LoadExternalDefinition();
1652
1654 const_cast<ObjCInterfaceDecl*>(Def));
1655 }
1656
1657 // FIXME: Should make sure no callers ever do this.
1658 return nullptr;
1659}
1660
1664
1665namespace {
1666
1667struct SynthesizeIvarChunk {
1668 uint64_t Size;
1669 ObjCIvarDecl *Ivar;
1670
1671 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1672 : Size(size), Ivar(ivar) {}
1673};
1674
1675bool operator<(const SynthesizeIvarChunk & LHS,
1676 const SynthesizeIvarChunk &RHS) {
1677 return LHS.Size < RHS.Size;
1678}
1679
1680} // namespace
1681
1682/// all_declared_ivar_begin - return first ivar declared in this class,
1683/// its extensions and its implementation. Lazily build the list on first
1684/// access.
1685///
1686/// Caveat: The list returned by this method reflects the current
1687/// state of the parser. The cache will be updated for every ivar
1688/// added by an extension or the implementation when they are
1689/// encountered.
1690/// See also ObjCIvarDecl::Create().
1692 // FIXME: Should make sure no callers ever do this.
1693 if (!hasDefinition())
1694 return nullptr;
1695
1696 ObjCIvarDecl *curIvar = nullptr;
1697 if (!data().IvarList) {
1698 // Force ivar deserialization upfront, before building IvarList.
1699 (void)ivar_empty();
1700 for (const auto *Ext : known_extensions()) {
1701 (void)Ext->ivar_empty();
1702 }
1703 if (!ivar_empty()) {
1705 data().IvarList = *I; ++I;
1706 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1707 curIvar->setNextIvar(*I);
1708 }
1709
1710 for (const auto *Ext : known_extensions()) {
1711 if (!Ext->ivar_empty()) {
1713 I = Ext->ivar_begin(),
1714 E = Ext->ivar_end();
1715 if (!data().IvarList) {
1716 data().IvarList = *I; ++I;
1717 curIvar = data().IvarList;
1718 }
1719 for ( ;I != E; curIvar = *I, ++I)
1720 curIvar->setNextIvar(*I);
1721 }
1722 }
1723 data().IvarListMissingImplementation = true;
1724 }
1725
1726 // cached and complete!
1727 if (!data().IvarListMissingImplementation)
1728 return data().IvarList;
1729
1730 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1731 data().IvarListMissingImplementation = false;
1732 if (!ImplDecl->ivar_empty()) {
1734 for (auto *IV : ImplDecl->ivars()) {
1735 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1736 layout.push_back(SynthesizeIvarChunk(
1737 IV->getASTContext().getTypeSize(IV->getType()), IV));
1738 continue;
1739 }
1740 if (!data().IvarList)
1741 data().IvarList = IV;
1742 else
1743 curIvar->setNextIvar(IV);
1744 curIvar = IV;
1745 }
1746
1747 if (!layout.empty()) {
1748 // Order synthesized ivars by their size.
1749 llvm::stable_sort(layout);
1750 unsigned Ix = 0, EIx = layout.size();
1751 if (!data().IvarList) {
1752 data().IvarList = layout[0].Ivar; Ix++;
1753 curIvar = data().IvarList;
1754 }
1755 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1756 curIvar->setNextIvar(layout[Ix].Ivar);
1757 }
1758 }
1759 }
1760 return data().IvarList;
1761}
1762
1763/// FindCategoryDeclaration - Finds category declaration in the list of
1764/// categories for this class and returns it. Name of the category is passed
1765/// in 'CategoryId'. If category not found, return 0;
1766///
1768 const IdentifierInfo *CategoryId) const {
1769 // FIXME: Should make sure no callers ever do this.
1770 if (!hasDefinition())
1771 return nullptr;
1772
1773 if (data().ExternallyCompleted)
1774 LoadExternalDefinition();
1775
1776 for (auto *Cat : visible_categories())
1777 if (Cat->getIdentifier() == CategoryId)
1778 return Cat;
1779
1780 return nullptr;
1781}
1782
1785 for (const auto *Cat : visible_categories()) {
1786 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1787 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1788 return MD;
1789 }
1790
1791 return nullptr;
1792}
1793
1795 for (const auto *Cat : visible_categories()) {
1796 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1797 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1798 return MD;
1799 }
1800
1801 return nullptr;
1802}
1803
1804/// ClassImplementsProtocol - Checks that 'lProto' protocol
1805/// has been implemented in IDecl class, its super class or categories (if
1806/// lookupCategory is true).
1808 bool lookupCategory,
1809 bool RHSIsQualifiedID) {
1810 if (!hasDefinition())
1811 return false;
1812
1813 ObjCInterfaceDecl *IDecl = this;
1814 // 1st, look up the class.
1815 for (auto *PI : IDecl->protocols()){
1816 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1817 return true;
1818 // This is dubious and is added to be compatible with gcc. In gcc, it is
1819 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1820 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1821 // object. This IMO, should be a bug.
1822 // FIXME: Treat this as an extension, and flag this as an error when GCC
1823 // extensions are not enabled.
1824 if (RHSIsQualifiedID &&
1825 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
1826 return true;
1827 }
1828
1829 // 2nd, look up the category.
1830 if (lookupCategory)
1831 for (const auto *Cat : visible_categories()) {
1832 for (auto *PI : Cat->protocols())
1833 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1834 return true;
1835 }
1836
1837 // 3rd, look up the super class(s)
1838 if (IDecl->getSuperClass())
1839 return
1840 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1841 RHSIsQualifiedID);
1842
1843 return false;
1844}
1845
1846//===----------------------------------------------------------------------===//
1847// ObjCIvarDecl
1848//===----------------------------------------------------------------------===//
1849
1850void ObjCIvarDecl::anchor() {}
1851
1853 SourceLocation StartLoc,
1854 SourceLocation IdLoc,
1855 const IdentifierInfo *Id, QualType T,
1856 TypeSourceInfo *TInfo, AccessControl ac,
1857 Expr *BW, bool synthesized) {
1858 if (DC) {
1859 // Ivar's can only appear in interfaces, implementations (via synthesized
1860 // properties), and class extensions (via direct declaration, or synthesized
1861 // properties).
1862 //
1863 // FIXME: This should really be asserting this:
1864 // (isa<ObjCCategoryDecl>(DC) &&
1865 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1866 // but unfortunately we sometimes place ivars into non-class extension
1867 // categories on error. This breaks an AST invariant, and should not be
1868 // fixed.
1870 isa<ObjCCategoryDecl>(DC)) &&
1871 "Invalid ivar decl context!");
1872 // Once a new ivar is created in any of class/class-extension/implementation
1873 // decl contexts, the previously built IvarList must be rebuilt.
1874 auto *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1875 if (!ID) {
1876 if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC))
1877 ID = IM->getClassInterface();
1878 else
1879 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1880 }
1881 ID->setIvarList(nullptr);
1882 }
1883
1884 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1885 synthesized);
1886}
1887
1889 return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1890 nullptr, QualType(), nullptr,
1891 ObjCIvarDecl::None, nullptr, false);
1892}
1893
1896
1897 switch (DC->getKind()) {
1898 default:
1899 case ObjCCategoryImpl:
1900 case ObjCProtocol:
1901 llvm_unreachable("invalid ivar container!");
1902
1903 // Ivars can only appear in class extension categories.
1904 case ObjCCategory: {
1905 auto *CD = cast<ObjCCategoryDecl>(DC);
1906 assert(CD->IsClassExtension() && "invalid container for ivar!");
1907 return CD->getClassInterface();
1908 }
1909
1910 case ObjCImplementation:
1911 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1912
1913 case ObjCInterface:
1914 return cast<ObjCInterfaceDecl>(DC);
1915 }
1916}
1917
1922
1923//===----------------------------------------------------------------------===//
1924// ObjCAtDefsFieldDecl
1925//===----------------------------------------------------------------------===//
1926
1927void ObjCAtDefsFieldDecl::anchor() {}
1928
1931 SourceLocation StartLoc, SourceLocation IdLoc,
1932 IdentifierInfo *Id, QualType T, Expr *BW) {
1933 return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1934}
1935
1937 GlobalDeclID ID) {
1938 return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
1939 SourceLocation(), nullptr, QualType(),
1940 nullptr);
1941}
1942
1943//===----------------------------------------------------------------------===//
1944// ObjCProtocolDecl
1945//===----------------------------------------------------------------------===//
1946
1947void ObjCProtocolDecl::anchor() {}
1948
1949ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
1950 IdentifierInfo *Id, SourceLocation nameLoc,
1951 SourceLocation atStartLoc,
1952 ObjCProtocolDecl *PrevDecl)
1953 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
1954 redeclarable_base(C) {
1955 setPreviousDecl(PrevDecl);
1956 if (PrevDecl)
1957 Data = PrevDecl->Data;
1958}
1959
1961 IdentifierInfo *Id,
1962 SourceLocation nameLoc,
1963 SourceLocation atStartLoc,
1964 ObjCProtocolDecl *PrevDecl) {
1965 auto *Result =
1966 new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
1967 Result->Data.setInt(!C.getLangOpts().Modules);
1968 return Result;
1969}
1970
1972 GlobalDeclID ID) {
1973 ObjCProtocolDecl *Result =
1974 new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
1975 SourceLocation(), nullptr);
1976 Result->Data.setInt(!C.getLangOpts().Modules);
1977 return Result;
1978}
1979
1983
1985 llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const {
1986 std::queue<const ObjCProtocolDecl *> WorkQueue;
1987 WorkQueue.push(this);
1988
1989 while (!WorkQueue.empty()) {
1990 const auto *PD = WorkQueue.front();
1991 WorkQueue.pop();
1992 for (const auto *Parent : PD->protocols()) {
1993 const auto *Can = Parent->getCanonicalDecl();
1994 auto Result = IPs.insert(Can);
1995 if (Result.second)
1996 WorkQueue.push(Parent);
1997 }
1998 }
1999}
2000
2002 ObjCProtocolDecl *PDecl = this;
2003
2004 if (Name == getIdentifier())
2005 return PDecl;
2006
2007 for (auto *I : protocols())
2008 if ((PDecl = I->lookupProtocolNamed(Name)))
2009 return PDecl;
2010
2011 return nullptr;
2012}
2013
2014// lookupMethod - Lookup a instance/class method in the protocol and protocols
2015// it inherited.
2017 bool isInstance) const {
2018 ObjCMethodDecl *MethodDecl = nullptr;
2019
2020 // If there is no definition or the definition is hidden, we don't find
2021 // anything.
2022 const ObjCProtocolDecl *Def = getDefinition();
2023 if (!Def || !Def->isUnconditionallyVisible())
2024 return nullptr;
2025
2026 if ((MethodDecl = getMethod(Sel, isInstance)))
2027 return MethodDecl;
2028
2029 for (const auto *I : protocols())
2030 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
2031 return MethodDecl;
2032 return nullptr;
2033}
2034
2035void ObjCProtocolDecl::allocateDefinitionData() {
2036 assert(!Data.getPointer() && "Protocol already has a definition!");
2037 Data.setPointer(new (getASTContext()) DefinitionData);
2038 Data.getPointer()->Definition = this;
2039 Data.getPointer()->HasODRHash = false;
2040}
2041
2043 allocateDefinitionData();
2044
2045 // Update all of the declarations with a pointer to the definition.
2046 for (auto *RD : redecls())
2047 RD->Data = this->Data;
2048}
2049
2051 Data.setPointer(nullptr);
2052 allocateDefinitionData();
2053 // Don't propagate data to other redeclarations.
2054}
2055
2057 const ObjCProtocolDecl *Definition) {
2058 Data = Definition->Data;
2059}
2060
2062 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2063 for (auto *Prop : PDecl->properties()) {
2064 // Insert into PM if not there already.
2065 PM.insert(std::make_pair(
2066 std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
2067 Prop));
2068 }
2069 // Scan through protocol's protocols.
2070 for (const auto *PI : PDecl->protocols())
2071 PI->collectPropertiesToImplement(PM);
2072 }
2073}
2074
2077 PropertyDeclOrder &PO) const {
2078 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2079 if (!PS.insert(PDecl).second)
2080 return;
2081 for (auto *Prop : PDecl->properties()) {
2082 if (Prop == Property)
2083 continue;
2084 if (Prop->getIdentifier() == Property->getIdentifier()) {
2085 PO.push_back(Prop);
2086 return;
2087 }
2088 }
2089 // Scan through protocol's protocols which did not have a matching property.
2090 for (const auto *PI : PDecl->protocols())
2091 PI->collectInheritedProtocolProperties(Property, PS, PO);
2092 }
2093}
2094
2095StringRef
2097 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
2098 return ObjCRTName->getMetadataName();
2099
2100 return getName();
2101}
2102
2104 assert(hasDefinition() && "ODRHash only for records with definitions");
2105
2106 // Previously calculated hash is stored in DefinitionData.
2107 if (hasODRHash())
2108 return data().ODRHash;
2109
2110 // Only calculate hash on first call of getODRHash per record.
2111 ODRHash Hasher;
2113 data().ODRHash = Hasher.CalculateHash();
2114 setHasODRHash(true);
2115
2116 return data().ODRHash;
2117}
2118
2119bool ObjCProtocolDecl::hasODRHash() const {
2120 if (!hasDefinition())
2121 return false;
2122 return data().HasODRHash;
2123}
2124
2125void ObjCProtocolDecl::setHasODRHash(bool HasHash) {
2126 assert(hasDefinition() && "Cannot set ODRHash without definition");
2127 data().HasODRHash = HasHash;
2128}
2129
2130//===----------------------------------------------------------------------===//
2131// ObjCCategoryDecl
2132//===----------------------------------------------------------------------===//
2133
2134void ObjCCategoryDecl::anchor() {}
2135
2136ObjCCategoryDecl::ObjCCategoryDecl(
2137 DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc,
2138 SourceLocation CategoryNameLoc, const IdentifierInfo *Id,
2139 ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList,
2140 SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc)
2141 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
2142 ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
2143 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
2144 setTypeParamList(typeParamList);
2145}
2146
2149 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
2150 const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
2151 ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,
2152 SourceLocation IvarRBraceLoc) {
2153 auto *CatDecl =
2154 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
2155 IDecl, typeParamList, IvarLBraceLoc,
2156 IvarRBraceLoc);
2157 if (IDecl) {
2158 // Link this category into its class's category list.
2159 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
2160 if (IDecl->hasDefinition()) {
2161 IDecl->setCategoryListRaw(CatDecl);
2162 if (ASTMutationListener *L = C.getASTMutationListener())
2163 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
2164 }
2165 }
2166
2167 return CatDecl;
2168}
2169
2171 GlobalDeclID ID) {
2172 return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
2174 nullptr, nullptr, nullptr);
2175}
2176
2179 const_cast<ObjCCategoryDecl*>(this));
2180}
2181
2185
2187 TypeParamList = TPL;
2188 if (!TPL)
2189 return;
2190 // Set the declaration context of each of the type parameters.
2191 for (auto *typeParam : *TypeParamList)
2192 typeParam->setDeclContext(this);
2193}
2194
2195//===----------------------------------------------------------------------===//
2196// ObjCCategoryImplDecl
2197//===----------------------------------------------------------------------===//
2198
2199void ObjCCategoryImplDecl::anchor() {}
2200
2201ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create(
2202 ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,
2203 ObjCInterfaceDecl *ClassInterface, SourceLocation nameLoc,
2204 SourceLocation atStartLoc, SourceLocation CategoryNameLoc) {
2205 if (ClassInterface && ClassInterface->hasDefinition())
2206 ClassInterface = ClassInterface->getDefinition();
2207 return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
2208 atStartLoc, CategoryNameLoc);
2209}
2210
2213 return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
2215 SourceLocation());
2216}
2217
2219 // The class interface might be NULL if we are working with invalid code.
2220 if (const ObjCInterfaceDecl *ID = getClassInterface())
2221 return ID->FindCategoryDeclaration(getIdentifier());
2222 return nullptr;
2223}
2224
2225void ObjCImplDecl::anchor() {}
2226
2228 // FIXME: The context should be correct before we get here.
2229 property->setLexicalDeclContext(this);
2230 addDecl(property);
2231}
2232
2234 ASTContext &Ctx = getASTContext();
2235
2236 if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
2237 if (IFace)
2238 Ctx.setObjCImplementation(IFace, ImplD);
2239
2240 } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
2242 Ctx.setObjCImplementation(CD, ImplD);
2243 }
2244
2245 ClassInterface = IFace;
2246}
2247
2248/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
2249/// properties implemented in this \@implementation block and returns
2250/// the implemented property that uses it.
2253 for (auto *PID : property_impls())
2254 if (PID->getPropertyIvarDecl() &&
2255 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
2256 return PID;
2257 return nullptr;
2258}
2259
2260/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
2261/// added to the list of those properties \@synthesized/\@dynamic in this
2262/// category \@implementation block.
2265 ObjCPropertyQueryKind QueryKind) const {
2266 ObjCPropertyImplDecl *ClassPropImpl = nullptr;
2267 for (auto *PID : property_impls())
2268 // If queryKind is unknown, we return the instance property if one
2269 // exists; otherwise we return the class property.
2270 if (PID->getPropertyDecl()->getIdentifier() == Id) {
2272 !PID->getPropertyDecl()->isClassProperty()) ||
2274 PID->getPropertyDecl()->isClassProperty()) ||
2276 !PID->getPropertyDecl()->isClassProperty()))
2277 return PID;
2278
2279 if (PID->getPropertyDecl()->isClassProperty())
2280 ClassPropImpl = PID;
2281 }
2282
2284 // We can't find the instance property, return the class property.
2285 return ClassPropImpl;
2286
2287 return nullptr;
2288}
2289
2290raw_ostream &clang::operator<<(raw_ostream &OS,
2291 const ObjCCategoryImplDecl &CID) {
2292 OS << CID.getName();
2293 return OS;
2294}
2295
2296//===----------------------------------------------------------------------===//
2297// ObjCImplementationDecl
2298//===----------------------------------------------------------------------===//
2299
2300void ObjCImplementationDecl::anchor() {}
2301
2304 ObjCInterfaceDecl *ClassInterface,
2305 ObjCInterfaceDecl *SuperDecl,
2306 SourceLocation nameLoc,
2307 SourceLocation atStartLoc,
2308 SourceLocation superLoc,
2309 SourceLocation IvarLBraceLoc,
2310 SourceLocation IvarRBraceLoc) {
2311 if (ClassInterface && ClassInterface->hasDefinition())
2312 ClassInterface = ClassInterface->getDefinition();
2313 return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
2314 nameLoc, atStartLoc, superLoc,
2315 IvarLBraceLoc, IvarRBraceLoc);
2316}
2317
2320 return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
2322}
2323
2325 CXXCtorInitializer ** initializers,
2326 unsigned numInitializers) {
2327 if (numInitializers > 0) {
2328 NumIvarInitializers = numInitializers;
2329 auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];
2330 memcpy(ivarInitializers, initializers,
2331 numInitializers * sizeof(CXXCtorInitializer*));
2332 IvarInitializers = ivarInitializers;
2333 }
2334}
2335
2338 return IvarInitializers.get(getASTContext().getExternalSource());
2339}
2340
2341raw_ostream &clang::operator<<(raw_ostream &OS,
2342 const ObjCImplementationDecl &ID) {
2343 OS << ID.getName();
2344 return OS;
2345}
2346
2347//===----------------------------------------------------------------------===//
2348// ObjCCompatibleAliasDecl
2349//===----------------------------------------------------------------------===//
2350
2351void ObjCCompatibleAliasDecl::anchor() {}
2352
2356 IdentifierInfo *Id,
2357 ObjCInterfaceDecl* AliasedClass) {
2358 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
2359}
2360
2363 return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
2364 nullptr, nullptr);
2365}
2366
2367//===----------------------------------------------------------------------===//
2368// ObjCPropertyDecl
2369//===----------------------------------------------------------------------===//
2370
2371void ObjCPropertyDecl::anchor() {}
2372
2375 const IdentifierInfo *Id, SourceLocation AtLoc,
2376 SourceLocation LParenLoc, QualType T,
2377 TypeSourceInfo *TSI, PropertyControl propControl) {
2378 return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
2379 propControl);
2380}
2381
2383 GlobalDeclID ID) {
2384 return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
2386 QualType(), nullptr, None);
2387}
2388
2390 const PrintingPolicy &Policy,
2391 bool Qualified) const {
2392 if (!Qualified) {
2393 printName(OS, Policy);
2394 return;
2395 }
2396
2397 OS << (isInstanceProperty() ? '-' : '+');
2398 OS << '[';
2399 const ObjCContainerDecl *Parent = nullptr;
2400 if (const auto *MD = getGetterMethodDecl()) {
2401 Parent = MD->getClassInterface();
2402 if (!Parent)
2403 Parent = dyn_cast<ObjCProtocolDecl>(MD->getDeclContext());
2404 }
2405 if (!Parent) {
2406 Parent = dyn_cast<ObjCContainerDecl>(getDeclContext());
2407 }
2408
2409 if (Parent) {
2410 OS << Parent->getName();
2411 } else {
2412 assert(false && "Parent should not be null");
2413 OS << "<Unknown>";
2414 }
2415
2416 OS << ' ' << getName() << ']';
2417}
2418
2423
2425 return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
2426 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
2427}
2428
2429//===----------------------------------------------------------------------===//
2430// ObjCPropertyImplDecl
2431//===----------------------------------------------------------------------===//
2432
2434 DeclContext *DC,
2435 SourceLocation atLoc,
2437 ObjCPropertyDecl *property,
2438 Kind PK,
2439 ObjCIvarDecl *ivar,
2440 SourceLocation ivarLoc) {
2441 return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
2442 ivarLoc);
2443}
2444
2447 return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
2448 SourceLocation(), nullptr, Dynamic,
2449 nullptr, SourceLocation());
2450}
2451
2453 SourceLocation EndLoc = getLocation();
2454 if (IvarLoc.isValid())
2455 EndLoc = IvarLoc;
2456
2457 return SourceRange(AtLoc, EndLoc);
2458}
Defines the clang::ASTContext interface.
static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container, const ObjCMethodDecl *Method, SmallVectorImpl< const ObjCMethodDecl * > &Methods, bool MovedToSuper)
static bool isIntroducingInitializers(const ObjCInterfaceDecl *D)
Definition DeclObjC.cpp:493
static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method, SmallVectorImpl< const ObjCMethodDecl * > &overridden)
static void CollectOverriddenMethods(const ObjCContainerDecl *Container, const ObjCMethodDecl *Method, SmallVectorImpl< const ObjCMethodDecl * > &Methods)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
void setObjCImplementation(ObjCInterfaceDecl *IFaceD, ObjCImplementationDecl *ImplD)
Set the implementation of ObjCInterfaceDecl.
IdentifierTable & Idents
Definition ASTContext.h:823
const LangOptions & getLangOpts() const
Definition ASTContext.h:980
IdentifierInfo * getNSObjectName() const
Retrieve the identifier 'NSObject'.
const ObjCMethodDecl * getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const
Get the duplicate declaration of a ObjCMethod in the same interface, or null if none exists.
void * Allocate(size_t Size, unsigned Align=8) const
Definition ASTContext.h:897
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.
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:2402
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
lookup_result::iterator lookup_iterator
Definition DeclBase.h:2608
DeclContextLookupResult lookup_result
Definition DeclBase.h:2607
ObjCMethodDeclBitfields ObjCMethodDeclBits
Definition DeclBase.h:2063
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
DeclContext(Decl::Kind K)
void addDecl(Decl *D)
Add the declaration D into this context.
SourceLocation getEndLoc() const LLVM_READONLY
Definition DeclBase.h:443
T * getAttr() const
Definition DeclBase.h:581
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
bool isUnconditionallyVisible() const
Determine whether this declaration is definitely visible to name lookup, independent of whether the o...
Definition DeclBase.h:871
Kind
Lists the kind of concrete classes of Decl.
Definition DeclBase.h:89
virtual Decl * getNextRedeclarationImpl()
Returns the next redeclaration or itself if this is the only decl.
Definition DeclBase.h:1008
SourceLocation getLocation() const
Definition DeclBase.h:447
void setImplicit(bool I=true)
Definition DeclBase.h:602
DeclContext * getDeclContext()
Definition DeclBase.h:456
bool hasAttr() const
Definition DeclBase.h:585
friend class DeclContext
Definition DeclBase.h:260
void setLexicalDeclContext(DeclContext *DC)
Definition DeclBase.cpp:389
Kind getKind() const
Definition DeclBase.h:450
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, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Definition Decl.cpp:5665
Represents the results of name lookup.
Definition Lookup.h:147
This represents a decl that may have a name.
Definition Decl.h:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:286
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const
Pretty-print the unqualified name of this declaration.
Definition Decl.cpp:1675
void AddObjCProtocolDecl(const ObjCProtocolDecl *P)
Definition ODRHash.cpp:819
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition ODRHash.cpp:671
unsigned CalculateHash()
Definition ODRHash.cpp:238
Represents a field declaration created by an @defs(...).
Definition DeclObjC.h:2036
static ObjCAtDefsFieldDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ObjCAtDefsFieldDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW)
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2335
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())
void setTypeParamList(ObjCTypeParamList *TPL)
Set the type parameters of this category.
static ObjCCategoryDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
ObjCCategoryImplDecl * getImplementation() const
specific_decl_iterator< ObjCIvarDecl > ivar_iterator
Definition DeclObjC.h:2445
void setImplementation(ObjCCategoryImplDecl *ImplD)
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2551
ObjCCategoryDecl * getCategoryDecl() const
static ObjCCategoryImplDecl * Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc)
static ObjCCategoryImplDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition DeclObjC.h:2781
static ObjCCompatibleAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl *aliasedClass)
static ObjCCompatibleAliasDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
ObjCContainerDecl - Represents a container for method declarations.
Definition DeclObjC.h:954
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition DeclObjC.cpp:90
void setAtStartLoc(SourceLocation Loc)
Definition DeclObjC.h:1104
instmeth_range instance_methods() const
Definition DeclObjC.h:1039
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
Definition DeclObjC.h:1094
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
llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
Definition DeclObjC.h:1091
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
llvm::SmallVector< ObjCPropertyDecl *, 8 > PropertyDeclOrder
Definition DeclObjC.h:1095
prop_range properties() const
Definition DeclObjC.h:973
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Definition DeclObjC.h:1072
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)
propimpl_range property_impls() const
Definition DeclObjC.h:2519
void setClassInterface(ObjCInterfaceDecl *IFace)
ObjCPropertyImplDecl * FindPropertyImplDecl(IdentifierInfo *propertyId, ObjCPropertyQueryKind queryKind) const
FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl added to the list of thos...
const ObjCInterfaceDecl * getClassInterface() const
Definition DeclObjC.h:2492
ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const
FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2603
static ObjCImplementationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ObjCImplementationDecl * Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *superDecl, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation superLoc=SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
CXXCtorInitializer *const * init_const_iterator
init_const_iterator - Iterates through the ivar initializer list.
Definition DeclObjC.h:2663
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
Definition DeclObjC.h:2727
init_iterator init_begin()
init_begin() - Retrieve an iterator to the first initializer.
Definition DeclObjC.h:2675
void setIvarInitializers(ASTContext &C, CXXCtorInitializer **initializers, unsigned numInitializers)
Represents an ObjC class declaration.
Definition DeclObjC.h:1160
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:1441
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:1467
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:1357
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
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:1804
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
bool hasDefinition() const
Determine whether this class has been defined.
Definition DeclObjC.h:1534
all_protocol_range all_referenced_protocols() const
Definition DeclObjC.h:1423
visible_extensions_range visible_extensions() const
Definition DeclObjC.h:1729
ObjCTypeParamList * getTypeParamListAsWritten() const
Retrieve the type parameters written on this particular declaration of the class.
Definition DeclObjC.h:1309
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
ivar_iterator ivar_begin() const
Definition DeclObjC.h:1459
protocol_range protocols() const
Definition DeclObjC.h:1365
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Definition DeclObjC.h:1853
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
Definition DeclObjC.cpp:788
bool ivar_empty() const
Definition DeclObjC.h:1479
void setImplementation(ObjCImplementationDecl *ImplD)
known_categories_range known_categories() const
Definition DeclObjC.h:1693
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:1428
void setExternallyCompleted()
Indicate that this Objective-C class is complete, but that the external AST source will be responsibl...
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
ObjCCategoryDecl * getCategoryListRaw() const
Retrieve the raw pointer to the start of the category/extension list.
Definition DeclObjC.h:1791
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition DeclObjC.h:1529
friend class ASTContext
Definition DeclObjC.h:1161
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
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,...
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
const ObjCObjectType * getSuperClassType() const
Retrieve the superclass type.
Definition DeclObjC.h:1571
ObjCImplementationDecl * getImplementation() const
static ObjCInterfaceDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
bool hasDesignatedInitializers() const
Returns true if this interface decl contains at least one initializer marked with the 'objc_designate...
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
ObjCInterfaceDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
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:1659
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Definition DeclObjC.h:1921
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:1548
TypeSourceInfo * getSuperClassTInfo() const
Definition DeclObjC.h:1579
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_...
specific_decl_iterator< ObjCIvarDecl > ivar_iterator
Definition DeclObjC.h:1454
void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition)
Definition DeclObjC.cpp:629
known_extensions_range known_extensions() const
Definition DeclObjC.h:1768
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1958
void setNextIvar(ObjCIvarDecl *ivar)
Definition DeclObjC.h:1995
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
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)
static ObjCIvarDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
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
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:907
ArrayRef< ParmVarDecl * > parameters() const
Definition DeclObjC.h:376
unsigned param_size() const
Definition DeclObjC.h:350
void setSelfDecl(ImplicitParamDecl *SD)
Definition DeclObjC.h:422
bool isPropertyAccessor() const
Definition DeclObjC.h:439
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
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:275
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
QualType getSendResultType() const
Determine the type of an expression that sends a message to this function.
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Definition DeclObjC.cpp:919
void setIsRedeclaration(bool RD)
Definition DeclObjC.h:270
bool isVariadic() const
Definition DeclObjC.h:434
void setCmdDecl(ImplicitParamDecl *CD)
Definition DeclObjC.h:424
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition DeclObjC.cpp:927
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
SourceLocation getEndLoc() const LLVM_READONLY
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition DeclObjC.h:346
QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID, bool &selfIsPseudoStrong, bool &selfIsConsumed) const
bool hasRedeclaration() const
True if redeclared in the same interface.
Definition DeclObjC.h:274
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
Definition DeclObjC.cpp:962
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod)
Definition DeclObjC.cpp:931
param_type_iterator param_type_begin() const
Definition DeclObjC.h:402
bool isSynthesizedAccessorStub() const
Definition DeclObjC.h:447
SourceLocation getSelectorLoc(unsigned Index) const
Definition DeclObjC.h:297
SourceRange getReturnTypeSourceRange() const
bool isRedeclaration() const
True if this is a method redeclaration in the same interface.
Definition DeclObjC.h:269
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition DeclObjC.cpp:889
Selector getSelector() const
Definition DeclObjC.h:330
bool isInstanceMethod() const
Definition DeclObjC.h:429
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:894
llvm::mapped_iterator< param_const_iterator, GetTypeFn > param_type_iterator
Definition DeclObjC.h:399
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
Definition DeclObjC.cpp:868
ObjCCategoryDecl * getCategory()
If this method is declared or implemented in a category, return that category.
bool isDefined() const
Definition DeclObjC.h:455
bool definedInNSObject(const ASTContext &) const
Is this method defined in the NSObject base class?
Definition DeclObjC.cpp:899
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implicit parameters.
QualType getReturnType() const
Definition DeclObjC.h:332
unsigned getNumSelectorLocs() const
Definition DeclObjC.h:309
bool isClassMethod() const
Definition DeclObjC.h:437
ObjCInterfaceDecl * getClassInterface()
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition DeclObjC.cpp:956
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:734
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
QualType getUsageType(QualType objectType) const
Retrieve the type when this property is used with a specific base object type.
ObjCMethodDecl * getGetterMethodDecl() const
Definition DeclObjC.h:907
bool isInstanceProperty() const
Definition DeclObjC.h:860
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)
bool isDirectProperty() const
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)
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition DeclObjC.h:2811
static ObjCPropertyImplDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ObjCPropertyImplDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2090
void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition)
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
bool hasDefinition() const
Determine whether this protocol has a definition.
Definition DeclObjC.h:2244
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance) const
static ObjCProtocolDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl)
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition DeclObjC.h:2256
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
void getImpliedProtocols(llvm::DenseSet< const ObjCProtocolDecl * > &IPs) const
Get the set of all protocols implied by this protocols inheritance hierarchy.
void startDefinition()
Starts the definition of this Objective-C protocol.
static ObjCProtocolDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, ProtocolPropertySet &PS, PropertyDeclOrder &PO) const
ObjCProtocolDecl * lookupProtocolNamed(IdentifierInfo *PName)
protocol_range protocols() const
Definition DeclObjC.h:2167
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
void collectPropertiesToImplement(PropertyMap &PM) const override
This routine collects list of properties to be implemented in the class.
void set(ObjCProtocolDecl *const *InList, unsigned Elts, const SourceLocation *Locs, ASTContext &Ctx)
Definition DeclObjC.cpp:51
static ObjCTypeParamDecl * Create(ASTContext &ctx, DeclContext *dc, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, SourceLocation nameLoc, IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo)
bool hasExplicitBound() const
Whether this type parameter has an explicitly-written type bound, e.g., "T : NSView".
Definition DeclObjC.h:643
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ObjCTypeParamDecl * CreateDeserialized(ASTContext &ctx, GlobalDeclID ID)
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition DeclObjC.h:665
void gatherDefaultTypeArgs(SmallVectorImpl< QualType > &typeArgs) const
Gather the default set of type arguments to be substituted for these type parameters when dealing wit...
unsigned size() const
Determine the number of type parameters in this list.
Definition DeclObjC.h:692
static ObjCTypeParamList * create(ASTContext &ctx, SourceLocation lAngleLoc, ArrayRef< ObjCTypeParamDecl * > typeParams, SourceLocation rAngleLoc)
Create a new Objective-C type parameter list.
Represents a parameter to a function.
Definition Decl.h:1819
A (possibly-)qualified type.
Definition TypeBase.h:938
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition Type.cpp:3716
QualType withConst() const
Definition TypeBase.h:1175
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8504
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:1721
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:1714
The collection of all-type qualifiers we support.
Definition TypeBase.h:332
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:362
void setObjCLifetime(ObjCLifetime type)
Definition TypeBase.h:549
void setPreviousDecl(ObjCInterfaceDecl *PrevDecl)
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.
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:8475
bool isObjCSelType() const
Definition TypeBase.h:8965
bool isObjCIdType() const
Definition TypeBase.h:8953
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:3746
QualType getType() const
Definition Decl.h:723
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ SelLoc_NonStandard
Non-standard.
@ SelLoc_StandardNoSpace
For nullary selectors, immediately before the end: "[foo release]" / "-(void)release;" Or immediately...
ObjCPropertyQueryKind
Definition DeclObjC.h:722
@ InvalidObjCMethodFamily
@ Override
Merge availability attributes for an override, which requires an exact match or a weakening of constr...
Definition Sema.h:631
@ 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_performSelector
@ OMF_None
No particular method family.
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.
Definition TypeBase.h:912
@ Result
The result type of a method or function.
Definition TypeBase.h:906
const FunctionProtoType * T
ObjCImplementationControl
Definition DeclObjC.h:118
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
ObjCTypeParamVariance
Describes the variance of a given generic parameter.
Definition DeclObjC.h:556
@ Invariant
The parameter is invariant: must match exactly.
Definition DeclObjC.h:558
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6025
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6031
@ ObjCSelf
Parameter for Objective-C 'self' argument.
Definition Decl.h:1756
@ ObjCCmd
Parameter for Objective-C '_cmd' argument.
Definition Decl.h:1759
Describes how types, statements, expressions, and declarations should be printed.