clang 23.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 return hasAttr<ObjCDirectAttr>() &&
870 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
871}
872
877
879 if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext()))
880 return PD->getIdentifier() == Ctx.getNSObjectName();
881 if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext()))
882 return ID->getIdentifier() == Ctx.getNSObjectName();
883 return false;
884}
885
887 const ObjCMethodDecl **InitMethod) const {
888 if (getMethodFamily() != OMF_init)
889 return false;
890 const DeclContext *DC = getDeclContext();
891 if (isa<ObjCProtocolDecl>(DC))
892 return false;
893 if (const ObjCInterfaceDecl *ID = getClassInterface())
894 return ID->isDesignatedInitializer(getSelector(), InitMethod);
895 return false;
896}
897
899 for (auto *param : parameters()) {
900 if (param->isDestroyedInCallee())
901 return true;
902 }
903 return false;
904}
905
907 return Body.get(getASTContext().getExternalSource());
908}
909
910void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
911 assert(PrevMethod);
912 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
913 setIsRedeclaration(true);
914 PrevMethod->setHasRedeclaration(true);
915}
916
917void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
919 ArrayRef<SourceLocation> SelLocs) {
920 ParamsAndSelLocs = nullptr;
921 NumParams = Params.size();
922 if (Params.empty() && SelLocs.empty())
923 return;
924
925 static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation),
926 "Alignment not sufficient for SourceLocation");
927
928 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
929 sizeof(SourceLocation) * SelLocs.size();
930 ParamsAndSelLocs = C.Allocate(Size);
931 llvm::uninitialized_copy(Params, getParams());
932 llvm::uninitialized_copy(SelLocs, getStoredSelLocs());
933}
934
936 SmallVectorImpl<SourceLocation> &SelLocs) const {
937 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
938 SelLocs.push_back(getSelectorLoc(i));
939}
940
943 ArrayRef<SourceLocation> SelLocs) {
944 assert((!SelLocs.empty() || isImplicit()) &&
945 "No selector locs for non-implicit method");
946 if (isImplicit())
947 return setParamsAndSelLocs(C, Params, {});
948
949 setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params,
950 DeclEndLoc));
951 if (getSelLocsKind() != SelLoc_NonStandard)
952 return setParamsAndSelLocs(C, Params, {});
953
954 setParamsAndSelLocs(C, Params, SelLocs);
955}
956
957/// A definition will return its interface declaration.
958/// An interface declaration will return its definition.
959/// Otherwise it will return itself.
961 ASTContext &Ctx = getASTContext();
962 ObjCMethodDecl *Redecl = nullptr;
963 if (hasRedeclaration())
964 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
965 if (Redecl)
966 return Redecl;
967
968 auto *CtxD = cast<Decl>(getDeclContext());
969
970 if (!CtxD->isInvalidDecl()) {
971 if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
972 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
973 if (!ImplD->isInvalidDecl())
974 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
975
976 } else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
977 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
978 if (!ImplD->isInvalidDecl())
979 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
980
981 } else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
982 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
983 if (!IFD->isInvalidDecl())
984 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
985
986 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
987 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
988 if (!CatD->isInvalidDecl())
989 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
990 }
991 }
992
993 // Ensure that the discovered method redeclaration has a valid declaration
994 // context. Used to prevent infinite loops when iterating redeclarations in
995 // a partially invalid AST.
996 if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl())
997 Redecl = nullptr;
998
999 if (!Redecl && isRedeclaration()) {
1000 // This is the last redeclaration, go back to the first method.
1001 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
1003 /*AllowHidden=*/true);
1004 }
1005
1006 return Redecl ? Redecl : this;
1007}
1008
1010 auto *CtxD = cast<Decl>(getDeclContext());
1011 const auto &Sel = getSelector();
1012
1013 if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
1014 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) {
1015 // When the container is the ObjCImplementationDecl (the primary
1016 // @implementation), then the canonical Decl is either in
1017 // the class Interface, or in any of its extension.
1018 //
1019 // So when we don't find it in the ObjCInterfaceDecl,
1020 // sift through extensions too.
1021 if (ObjCMethodDecl *MD = IFD->getMethod(Sel, isInstanceMethod()))
1022 return MD;
1023 for (auto *Ext : IFD->known_extensions())
1024 if (ObjCMethodDecl *MD = Ext->getMethod(Sel, isInstanceMethod()))
1025 return MD;
1026 }
1027 } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
1028 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
1029 if (ObjCMethodDecl *MD = CatD->getMethod(Sel, isInstanceMethod()))
1030 return MD;
1031 }
1032
1033 if (isRedeclaration()) {
1034 // It is possible that we have not done deserializing the ObjCMethod yet.
1035 ObjCMethodDecl *MD =
1036 cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
1037 /*AllowHidden=*/true);
1038 return MD ? MD : this;
1039 }
1040
1041 return this;
1042}
1043
1045 if (Stmt *Body = getBody())
1046 return Body->getEndLoc();
1047 return DeclEndLoc;
1048}
1049
1051 auto family = static_cast<ObjCMethodFamily>(ObjCMethodDeclBits.Family);
1052 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
1053 return family;
1054
1055 // Check for an explicit attribute.
1056 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
1057 // The unfortunate necessity of mapping between enums here is due
1058 // to the attributes framework.
1059 switch (attr->getFamily()) {
1060 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
1061 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
1062 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
1063 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
1064 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
1065 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
1066 }
1067 ObjCMethodDeclBits.Family = family;
1068 return family;
1069 }
1070
1071 family = getSelector().getMethodFamily();
1072 switch (family) {
1073 case OMF_None: break;
1074
1075 // init only has a conventional meaning for an instance method, and
1076 // it has to return an object.
1077 case OMF_init:
1078 if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
1079 family = OMF_None;
1080 break;
1081
1082 // alloc/copy/new have a conventional meaning for both class and
1083 // instance methods, but they require an object return.
1084 case OMF_alloc:
1085 case OMF_copy:
1086 case OMF_mutableCopy:
1087 case OMF_new:
1088 if (!getReturnType()->isObjCObjectPointerType())
1089 family = OMF_None;
1090 break;
1091
1092 // These selectors have a conventional meaning only for instance methods.
1093 case OMF_dealloc:
1094 case OMF_finalize:
1095 case OMF_retain:
1096 case OMF_release:
1097 case OMF_autorelease:
1098 case OMF_retainCount:
1099 case OMF_self:
1100 if (!isInstanceMethod())
1101 family = OMF_None;
1102 break;
1103
1104 case OMF_initialize:
1105 if (isInstanceMethod() || !getReturnType()->isVoidType())
1106 family = OMF_None;
1107 break;
1108
1110 if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
1111 family = OMF_None;
1112 else {
1113 unsigned noParams = param_size();
1114 if (noParams < 1 || noParams > 3)
1115 family = OMF_None;
1116 else {
1118 QualType ArgT = (*it);
1119 if (!ArgT->isObjCSelType()) {
1120 family = OMF_None;
1121 break;
1122 }
1123 while (--noParams) {
1124 it++;
1125 ArgT = (*it);
1126 if (!ArgT->isObjCIdType()) {
1127 family = OMF_None;
1128 break;
1129 }
1130 }
1131 }
1132 }
1133 break;
1134
1135 }
1136
1137 // Cache the result.
1138 ObjCMethodDeclBits.Family = family;
1139 return family;
1140}
1141
1143 const ObjCInterfaceDecl *OID,
1144 bool &selfIsPseudoStrong,
1145 bool &selfIsConsumed) const {
1146 QualType selfTy;
1147 selfIsPseudoStrong = false;
1148 selfIsConsumed = false;
1149 if (isInstanceMethod()) {
1150 // There may be no interface context due to error in declaration
1151 // of the interface (which has been reported). Recover gracefully.
1152 if (OID) {
1153 selfTy = Context.getObjCInterfaceType(OID);
1154 selfTy = Context.getObjCObjectPointerType(selfTy);
1155 } else {
1156 selfTy = Context.getObjCIdType();
1157 }
1158 } else // we have a factory method.
1159 selfTy = Context.getObjCClassType();
1160
1161 if (Context.getLangOpts().ObjCAutoRefCount) {
1162 if (isInstanceMethod()) {
1163 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
1164
1165 // 'self' is always __strong. It's actually pseudo-strong except
1166 // in init methods (or methods labeled ns_consumes_self), though.
1167 Qualifiers qs;
1169 selfTy = Context.getQualifiedType(selfTy, qs);
1170
1171 // In addition, 'self' is const unless this is an init method.
1172 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
1173 selfTy = selfTy.withConst();
1174 selfIsPseudoStrong = true;
1175 }
1176 }
1177 else {
1178 assert(isClassMethod());
1179 // 'self' is always const in class methods.
1180 selfTy = selfTy.withConst();
1181 selfIsPseudoStrong = true;
1182 }
1183 }
1184 return selfTy;
1185}
1186
1188 const ObjCInterfaceDecl *OID) {
1189 bool selfIsPseudoStrong, selfIsConsumed;
1190 QualType selfTy =
1191 getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
1192 auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),
1193 &Context.Idents.get("self"), selfTy,
1196
1197 if (selfIsConsumed)
1198 Self->addAttr(NSConsumedAttr::CreateImplicit(Context));
1199
1200 if (selfIsPseudoStrong)
1201 Self->setARCPseudoStrong(true);
1202
1203 auto *CmdDecl = ImplicitParamDecl::Create(
1204 Context, this, SourceLocation(), &Context.Idents.get("_cmd"),
1205 Context.getObjCSelType(), ImplicitParamKind::ObjCCmd);
1206 setCmdDecl(CmdDecl);
1207}
1208
1210 if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
1211 return ID;
1212 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1213 return CD->getClassInterface();
1214 if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
1215 return IMD->getClassInterface();
1217 return nullptr;
1218 llvm_unreachable("unknown method context");
1219}
1220
1222 if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1223 return CD;
1224 if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
1225 return IMD->getCategoryDecl();
1226 return nullptr;
1227}
1228
1230 const auto *TSI = getReturnTypeSourceInfo();
1231 if (TSI)
1232 return TSI->getTypeLoc().getSourceRange();
1233 return SourceRange();
1234}
1235
1241
1243 // FIXME: Handle related result types here.
1244
1246 .substObjCMemberType(receiverType, getDeclContext(),
1248}
1249
1251 const ObjCMethodDecl *Method,
1253 bool MovedToSuper) {
1254 if (!Container)
1255 return;
1256
1257 // In categories look for overridden methods from protocols. A method from
1258 // category is not "overridden" since it is considered as the "same" method
1259 // (same USR) as the one from the interface.
1260 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1261 // Check whether we have a matching method at this category but only if we
1262 // are at the super class level.
1263 if (MovedToSuper)
1264 if (ObjCMethodDecl *
1265 Overridden = Container->getMethod(Method->getSelector(),
1266 Method->isInstanceMethod(),
1267 /*AllowHidden=*/true))
1268 if (Method != Overridden) {
1269 // We found an override at this category; there is no need to look
1270 // into its protocols.
1271 Methods.push_back(Overridden);
1272 return;
1273 }
1274
1275 for (const auto *P : Category->protocols())
1276 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1277 return;
1278 }
1279
1280 // Check whether we have a matching method at this level.
1281 if (const ObjCMethodDecl *
1282 Overridden = Container->getMethod(Method->getSelector(),
1283 Method->isInstanceMethod(),
1284 /*AllowHidden=*/true))
1285 if (Method != Overridden) {
1286 // We found an override at this level; there is no need to look
1287 // into other protocols or categories.
1288 Methods.push_back(Overridden);
1289 return;
1290 }
1291
1292 if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
1293 for (const auto *P : Protocol->protocols())
1294 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1295 }
1296
1297 if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
1298 for (const auto *P : Interface->protocols())
1299 CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1300
1301 for (const auto *Cat : Interface->known_categories())
1302 CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
1303
1304 if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
1305 return CollectOverriddenMethodsRecurse(Super, Method, Methods,
1306 /*MovedToSuper=*/true);
1307 }
1308}
1309
1310static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
1311 const ObjCMethodDecl *Method,
1313 CollectOverriddenMethodsRecurse(Container, Method, Methods,
1314 /*MovedToSuper=*/false);
1315}
1316
1319 assert(Method->isOverriding());
1320
1321 if (const auto *ProtD =
1322 dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1323 CollectOverriddenMethods(ProtD, Method, overridden);
1324
1325 } else if (const auto *IMD =
1326 dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1327 const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1328 if (!ID)
1329 return;
1330 // Start searching for overridden methods using the method from the
1331 // interface as starting point.
1332 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1333 Method->isInstanceMethod(),
1334 /*AllowHidden=*/true))
1335 Method = IFaceMeth;
1336 CollectOverriddenMethods(ID, Method, overridden);
1337
1338 } else if (const auto *CatD =
1339 dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1340 const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1341 if (!ID)
1342 return;
1343 // Start searching for overridden methods using the method from the
1344 // interface as starting point.
1345 if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
1346 Method->isInstanceMethod(),
1347 /*AllowHidden=*/true))
1348 Method = IFaceMeth;
1349 CollectOverriddenMethods(ID, Method, overridden);
1350
1351 } else {
1353 dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1354 Method, overridden);
1355 }
1356}
1357
1359 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1360 const ObjCMethodDecl *Method = this;
1361
1362 if (Method->isRedeclaration()) {
1363 Method = cast<ObjCContainerDecl>(Method->getDeclContext())
1364 ->getMethod(Method->getSelector(), Method->isInstanceMethod(),
1365 /*AllowHidden=*/true);
1366 }
1367
1368 if (Method->isOverriding()) {
1370 assert(!Overridden.empty() &&
1371 "ObjCMethodDecl's overriding bit is not as expected");
1372 }
1373}
1374
1375const ObjCPropertyDecl *
1376ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
1377 Selector Sel = getSelector();
1378 unsigned NumArgs = Sel.getNumArgs();
1379 if (NumArgs > 1)
1380 return nullptr;
1381
1382 if (isPropertyAccessor()) {
1383 const auto *Container = cast<ObjCContainerDecl>(getParent());
1384 // For accessor stubs, go back to the interface.
1385 if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container))
1387 Container = ImplDecl->getClassInterface();
1388
1389 bool IsGetter = (NumArgs == 0);
1390 bool IsInstance = isInstanceMethod();
1391
1392 /// Local function that attempts to find a matching property within the
1393 /// given Objective-C container.
1394 auto findMatchingProperty =
1395 [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
1396 if (IsInstance) {
1397 for (const auto *I : Container->instance_properties()) {
1398 Selector NextSel = IsGetter ? I->getGetterName()
1399 : I->getSetterName();
1400 if (NextSel == Sel)
1401 return I;
1402 }
1403 } else {
1404 for (const auto *I : Container->class_properties()) {
1405 Selector NextSel = IsGetter ? I->getGetterName()
1406 : I->getSetterName();
1407 if (NextSel == Sel)
1408 return I;
1409 }
1410 }
1411
1412 return nullptr;
1413 };
1414
1415 // Look in the container we were given.
1416 if (const auto *Found = findMatchingProperty(Container))
1417 return Found;
1418
1419 // If we're in a category or extension, look in the main class.
1420 const ObjCInterfaceDecl *ClassDecl = nullptr;
1421 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
1422 ClassDecl = Category->getClassInterface();
1423 if (const auto *Found = findMatchingProperty(ClassDecl))
1424 return Found;
1425 } else {
1426 // Determine whether the container is a class.
1427 ClassDecl = cast<ObjCInterfaceDecl>(Container);
1428 }
1429 assert(ClassDecl && "Failed to find main class");
1430
1431 // If we have a class, check its visible extensions.
1432 for (const auto *Ext : ClassDecl->visible_extensions()) {
1433 if (Ext == Container)
1434 continue;
1435 if (const auto *Found = findMatchingProperty(Ext))
1436 return Found;
1437 }
1438
1439 assert(isSynthesizedAccessorStub() && "expected an accessor stub");
1440
1441 for (const auto *Cat : ClassDecl->known_categories()) {
1442 if (Cat == Container)
1443 continue;
1444 if (const auto *Found = findMatchingProperty(Cat))
1445 return Found;
1446 }
1447
1448 llvm_unreachable("Marked as a property accessor but no property found!");
1449 }
1450
1451 if (!CheckOverrides)
1452 return nullptr;
1453
1454 using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;
1455
1456 OverridesTy Overrides;
1457 getOverriddenMethods(Overrides);
1458 for (const auto *Override : Overrides)
1459 if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(false))
1460 return Prop;
1461
1462 return nullptr;
1463}
1464
1465//===----------------------------------------------------------------------===//
1466// ObjCTypeParamDecl
1467//===----------------------------------------------------------------------===//
1468
1469void ObjCTypeParamDecl::anchor() {}
1470
1472 ObjCTypeParamVariance variance,
1473 SourceLocation varianceLoc,
1474 unsigned index,
1475 SourceLocation nameLoc,
1476 IdentifierInfo *name,
1477 SourceLocation colonLoc,
1478 TypeSourceInfo *boundInfo) {
1479 auto *TPDecl =
1480 new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
1481 nameLoc, name, colonLoc, boundInfo);
1482 QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});
1483 TPDecl->setTypeForDecl(TPType.getTypePtr());
1484 return TPDecl;
1485}
1486
1488 GlobalDeclID ID) {
1489 return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,
1492 nullptr, SourceLocation(), nullptr);
1493}
1494
1496 SourceLocation startLoc = VarianceLoc;
1497 if (startLoc.isInvalid())
1498 startLoc = getLocation();
1499
1500 if (hasExplicitBound()) {
1501 return SourceRange(startLoc,
1502 getTypeSourceInfo()->getTypeLoc().getEndLoc());
1503 }
1504
1505 return SourceRange(startLoc);
1506}
1507
1508//===----------------------------------------------------------------------===//
1509// ObjCTypeParamList
1510//===----------------------------------------------------------------------===//
1511ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,
1513 SourceLocation rAngleLoc)
1514 : Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) {
1515 llvm::copy(typeParams, begin());
1516}
1517
1518ObjCTypeParamList *ObjCTypeParamList::create(
1519 ASTContext &ctx,
1520 SourceLocation lAngleLoc,
1522 SourceLocation rAngleLoc) {
1523 void *mem =
1524 ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),
1525 alignof(ObjCTypeParamList));
1526 return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
1527}
1528
1530 SmallVectorImpl<QualType> &typeArgs) const {
1531 typeArgs.reserve(size());
1532 for (auto *typeParam : *this)
1533 typeArgs.push_back(typeParam->getUnderlyingType());
1534}
1535
1536//===----------------------------------------------------------------------===//
1537// ObjCInterfaceDecl
1538//===----------------------------------------------------------------------===//
1539
1540ObjCInterfaceDecl *ObjCInterfaceDecl::Create(
1541 const ASTContext &C, DeclContext *DC, SourceLocation atLoc,
1542 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1543 ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal) {
1544 auto *Result = new (C, DC)
1545 ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
1546 isInternal);
1547 Result->Data.setInt(!C.getLangOpts().Modules);
1548 C.getObjCInterfaceType(Result, PrevDecl);
1549 return Result;
1550}
1551
1553 GlobalDeclID ID) {
1554 auto *Result = new (C, ID)
1555 ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,
1556 SourceLocation(), nullptr, false);
1557 Result->Data.setInt(!C.getLangOpts().Modules);
1558 return Result;
1559}
1560
1561ObjCInterfaceDecl::ObjCInterfaceDecl(
1562 const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
1563 const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1564 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal)
1565 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
1566 redeclarable_base(C) {
1567 setPreviousDecl(PrevDecl);
1568
1569 // Copy the 'data' pointer over.
1570 if (PrevDecl)
1571 Data = PrevDecl->Data;
1572
1573 setImplicit(IsInternal);
1574
1575 setTypeParamList(typeParamList);
1576}
1577
1578void ObjCInterfaceDecl::LoadExternalDefinition() const {
1579 assert(data().ExternallyCompleted && "Class is not externally completed");
1580 data().ExternallyCompleted = false;
1582 const_cast<ObjCInterfaceDecl *>(this));
1583}
1584
1586 assert(getASTContext().getExternalSource() &&
1587 "Class can't be externally completed without an external source");
1588 assert(hasDefinition() &&
1589 "Forward declarations can't be externally completed");
1590 data().ExternallyCompleted = true;
1591}
1592
1594 // Check for a complete definition and recover if not so.
1596 return;
1597 data().HasDesignatedInitializers = true;
1598}
1599
1601 // Check for a complete definition and recover if not so.
1603 return false;
1604 if (data().ExternallyCompleted)
1605 LoadExternalDefinition();
1606
1607 return data().HasDesignatedInitializers;
1608}
1609
1610StringRef
1612 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
1613 return ObjCRTName->getMetadataName();
1614
1615 return getName();
1616}
1617
1618StringRef
1620 if (ObjCInterfaceDecl *ID =
1621 const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
1622 return ID->getObjCRuntimeNameAsString();
1623
1624 return getName();
1625}
1626
1628 if (const ObjCInterfaceDecl *Def = getDefinition()) {
1629 if (data().ExternallyCompleted)
1630 LoadExternalDefinition();
1631
1633 const_cast<ObjCInterfaceDecl*>(Def));
1634 }
1635
1636 // FIXME: Should make sure no callers ever do this.
1637 return nullptr;
1638}
1639
1643
1644namespace {
1645
1646struct SynthesizeIvarChunk {
1647 uint64_t Size;
1648 ObjCIvarDecl *Ivar;
1649
1650 SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1651 : Size(size), Ivar(ivar) {}
1652};
1653
1654bool operator<(const SynthesizeIvarChunk & LHS,
1655 const SynthesizeIvarChunk &RHS) {
1656 return LHS.Size < RHS.Size;
1657}
1658
1659} // namespace
1660
1661/// all_declared_ivar_begin - return first ivar declared in this class,
1662/// its extensions and its implementation. Lazily build the list on first
1663/// access.
1664///
1665/// Caveat: The list returned by this method reflects the current
1666/// state of the parser. The cache will be updated for every ivar
1667/// added by an extension or the implementation when they are
1668/// encountered.
1669/// See also ObjCIvarDecl::Create().
1671 // FIXME: Should make sure no callers ever do this.
1672 if (!hasDefinition())
1673 return nullptr;
1674
1675 ObjCIvarDecl *curIvar = nullptr;
1676 if (!data().IvarList) {
1677 // Force ivar deserialization upfront, before building IvarList.
1678 (void)ivar_empty();
1679 for (const auto *Ext : known_extensions()) {
1680 (void)Ext->ivar_empty();
1681 }
1682 if (!ivar_empty()) {
1684 data().IvarList = *I; ++I;
1685 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1686 curIvar->setNextIvar(*I);
1687 }
1688
1689 for (const auto *Ext : known_extensions()) {
1690 if (!Ext->ivar_empty()) {
1692 I = Ext->ivar_begin(),
1693 E = Ext->ivar_end();
1694 if (!data().IvarList) {
1695 data().IvarList = *I; ++I;
1696 curIvar = data().IvarList;
1697 }
1698 for ( ;I != E; curIvar = *I, ++I)
1699 curIvar->setNextIvar(*I);
1700 }
1701 }
1702 data().IvarListMissingImplementation = true;
1703 }
1704
1705 // cached and complete!
1706 if (!data().IvarListMissingImplementation)
1707 return data().IvarList;
1708
1709 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1710 data().IvarListMissingImplementation = false;
1711 if (!ImplDecl->ivar_empty()) {
1713 for (auto *IV : ImplDecl->ivars()) {
1714 if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1715 layout.push_back(SynthesizeIvarChunk(
1716 IV->getASTContext().getTypeSize(IV->getType()), IV));
1717 continue;
1718 }
1719 if (!data().IvarList)
1720 data().IvarList = IV;
1721 else
1722 curIvar->setNextIvar(IV);
1723 curIvar = IV;
1724 }
1725
1726 if (!layout.empty()) {
1727 // Order synthesized ivars by their size.
1728 llvm::stable_sort(layout);
1729 unsigned Ix = 0, EIx = layout.size();
1730 if (!data().IvarList) {
1731 data().IvarList = layout[0].Ivar; Ix++;
1732 curIvar = data().IvarList;
1733 }
1734 for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1735 curIvar->setNextIvar(layout[Ix].Ivar);
1736 }
1737 }
1738 }
1739 return data().IvarList;
1740}
1741
1742/// FindCategoryDeclaration - Finds category declaration in the list of
1743/// categories for this class and returns it. Name of the category is passed
1744/// in 'CategoryId'. If category not found, return 0;
1745///
1747 const IdentifierInfo *CategoryId) const {
1748 // FIXME: Should make sure no callers ever do this.
1749 if (!hasDefinition())
1750 return nullptr;
1751
1752 if (data().ExternallyCompleted)
1753 LoadExternalDefinition();
1754
1755 for (auto *Cat : visible_categories())
1756 if (Cat->getIdentifier() == CategoryId)
1757 return Cat;
1758
1759 return nullptr;
1760}
1761
1764 for (const auto *Cat : visible_categories()) {
1765 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1766 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1767 return MD;
1768 }
1769
1770 return nullptr;
1771}
1772
1774 for (const auto *Cat : visible_categories()) {
1775 if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1776 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1777 return MD;
1778 }
1779
1780 return nullptr;
1781}
1782
1783/// ClassImplementsProtocol - Checks that 'lProto' protocol
1784/// has been implemented in IDecl class, its super class or categories (if
1785/// lookupCategory is true).
1787 bool lookupCategory,
1788 bool RHSIsQualifiedID) {
1789 if (!hasDefinition())
1790 return false;
1791
1792 ObjCInterfaceDecl *IDecl = this;
1793 // 1st, look up the class.
1794 for (auto *PI : IDecl->protocols()){
1795 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1796 return true;
1797 // This is dubious and is added to be compatible with gcc. In gcc, it is
1798 // also allowed assigning a protocol-qualified 'id' type to a LHS object
1799 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1800 // object. This IMO, should be a bug.
1801 // FIXME: Treat this as an extension, and flag this as an error when GCC
1802 // extensions are not enabled.
1803 if (RHSIsQualifiedID &&
1804 getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
1805 return true;
1806 }
1807
1808 // 2nd, look up the category.
1809 if (lookupCategory)
1810 for (const auto *Cat : visible_categories()) {
1811 for (auto *PI : Cat->protocols())
1812 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
1813 return true;
1814 }
1815
1816 // 3rd, look up the super class(s)
1817 if (IDecl->getSuperClass())
1818 return
1819 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1820 RHSIsQualifiedID);
1821
1822 return false;
1823}
1824
1825//===----------------------------------------------------------------------===//
1826// ObjCIvarDecl
1827//===----------------------------------------------------------------------===//
1828
1829void ObjCIvarDecl::anchor() {}
1830
1832 SourceLocation StartLoc,
1833 SourceLocation IdLoc,
1834 const IdentifierInfo *Id, QualType T,
1835 TypeSourceInfo *TInfo, AccessControl ac,
1836 Expr *BW, bool synthesized) {
1837 if (DC) {
1838 // Ivar's can only appear in interfaces, implementations (via synthesized
1839 // properties), and class extensions (via direct declaration, or synthesized
1840 // properties).
1841 //
1842 // FIXME: This should really be asserting this:
1843 // (isa<ObjCCategoryDecl>(DC) &&
1844 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1845 // but unfortunately we sometimes place ivars into non-class extension
1846 // categories on error. This breaks an AST invariant, and should not be
1847 // fixed.
1849 isa<ObjCCategoryDecl>(DC)) &&
1850 "Invalid ivar decl context!");
1851 // Once a new ivar is created in any of class/class-extension/implementation
1852 // decl contexts, the previously built IvarList must be rebuilt.
1853 auto *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1854 if (!ID) {
1855 if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC))
1856 ID = IM->getClassInterface();
1857 else
1858 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1859 }
1860 ID->setIvarList(nullptr);
1861 }
1862
1863 return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1864 synthesized);
1865}
1866
1868 return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1869 nullptr, QualType(), nullptr,
1870 ObjCIvarDecl::None, nullptr, false);
1871}
1872
1875
1876 switch (DC->getKind()) {
1877 default:
1878 case ObjCCategoryImpl:
1879 case ObjCProtocol:
1880 llvm_unreachable("invalid ivar container!");
1881
1882 // Ivars can only appear in class extension categories.
1883 case ObjCCategory: {
1884 auto *CD = cast<ObjCCategoryDecl>(DC);
1885 assert(CD->IsClassExtension() && "invalid container for ivar!");
1886 return CD->getClassInterface();
1887 }
1888
1889 case ObjCImplementation:
1890 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1891
1892 case ObjCInterface:
1893 return cast<ObjCInterfaceDecl>(DC);
1894 }
1895}
1896
1901
1902//===----------------------------------------------------------------------===//
1903// ObjCAtDefsFieldDecl
1904//===----------------------------------------------------------------------===//
1905
1906void ObjCAtDefsFieldDecl::anchor() {}
1907
1910 SourceLocation StartLoc, SourceLocation IdLoc,
1911 IdentifierInfo *Id, QualType T, Expr *BW) {
1912 return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1913}
1914
1916 GlobalDeclID ID) {
1917 return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
1918 SourceLocation(), nullptr, QualType(),
1919 nullptr);
1920}
1921
1922//===----------------------------------------------------------------------===//
1923// ObjCProtocolDecl
1924//===----------------------------------------------------------------------===//
1925
1926void ObjCProtocolDecl::anchor() {}
1927
1928ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
1929 IdentifierInfo *Id, SourceLocation nameLoc,
1930 SourceLocation atStartLoc,
1931 ObjCProtocolDecl *PrevDecl)
1932 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
1933 redeclarable_base(C) {
1934 setPreviousDecl(PrevDecl);
1935 if (PrevDecl)
1936 Data = PrevDecl->Data;
1937}
1938
1940 IdentifierInfo *Id,
1941 SourceLocation nameLoc,
1942 SourceLocation atStartLoc,
1943 ObjCProtocolDecl *PrevDecl) {
1944 auto *Result =
1945 new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
1946 Result->Data.setInt(!C.getLangOpts().Modules);
1947 return Result;
1948}
1949
1951 GlobalDeclID ID) {
1952 ObjCProtocolDecl *Result =
1953 new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
1954 SourceLocation(), nullptr);
1955 Result->Data.setInt(!C.getLangOpts().Modules);
1956 return Result;
1957}
1958
1962
1964 llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const {
1965 std::queue<const ObjCProtocolDecl *> WorkQueue;
1966 WorkQueue.push(this);
1967
1968 while (!WorkQueue.empty()) {
1969 const auto *PD = WorkQueue.front();
1970 WorkQueue.pop();
1971 for (const auto *Parent : PD->protocols()) {
1972 const auto *Can = Parent->getCanonicalDecl();
1973 auto Result = IPs.insert(Can);
1974 if (Result.second)
1975 WorkQueue.push(Parent);
1976 }
1977 }
1978}
1979
1981 ObjCProtocolDecl *PDecl = this;
1982
1983 if (Name == getIdentifier())
1984 return PDecl;
1985
1986 for (auto *I : protocols())
1987 if ((PDecl = I->lookupProtocolNamed(Name)))
1988 return PDecl;
1989
1990 return nullptr;
1991}
1992
1993// lookupMethod - Lookup a instance/class method in the protocol and protocols
1994// it inherited.
1996 bool isInstance) const {
1997 ObjCMethodDecl *MethodDecl = nullptr;
1998
1999 // If there is no definition or the definition is hidden, we don't find
2000 // anything.
2001 const ObjCProtocolDecl *Def = getDefinition();
2002 if (!Def || !Def->isUnconditionallyVisible())
2003 return nullptr;
2004
2005 if ((MethodDecl = getMethod(Sel, isInstance)))
2006 return MethodDecl;
2007
2008 for (const auto *I : protocols())
2009 if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
2010 return MethodDecl;
2011 return nullptr;
2012}
2013
2014void ObjCProtocolDecl::allocateDefinitionData() {
2015 assert(!Data.getPointer() && "Protocol already has a definition!");
2016 Data.setPointer(new (getASTContext()) DefinitionData);
2017 Data.getPointer()->Definition = this;
2018 Data.getPointer()->HasODRHash = false;
2019}
2020
2022 allocateDefinitionData();
2023
2024 // Update all of the declarations with a pointer to the definition.
2025 for (auto *RD : redecls())
2026 RD->Data = this->Data;
2027}
2028
2030 Data.setPointer(nullptr);
2031 allocateDefinitionData();
2032 // Don't propagate data to other redeclarations.
2033}
2034
2036 const ObjCProtocolDecl *Definition) {
2037 Data = Definition->Data;
2038}
2039
2041 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2042 for (auto *Prop : PDecl->properties()) {
2043 // Insert into PM if not there already.
2044 PM.insert(std::make_pair(
2045 std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
2046 Prop));
2047 }
2048 // Scan through protocol's protocols.
2049 for (const auto *PI : PDecl->protocols())
2050 PI->collectPropertiesToImplement(PM);
2051 }
2052}
2053
2056 PropertyDeclOrder &PO) const {
2057 if (const ObjCProtocolDecl *PDecl = getDefinition()) {
2058 if (!PS.insert(PDecl).second)
2059 return;
2060 for (auto *Prop : PDecl->properties()) {
2061 if (Prop == Property)
2062 continue;
2063 if (Prop->getIdentifier() == Property->getIdentifier()) {
2064 PO.push_back(Prop);
2065 return;
2066 }
2067 }
2068 // Scan through protocol's protocols which did not have a matching property.
2069 for (const auto *PI : PDecl->protocols())
2070 PI->collectInheritedProtocolProperties(Property, PS, PO);
2071 }
2072}
2073
2074StringRef
2076 if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
2077 return ObjCRTName->getMetadataName();
2078
2079 return getName();
2080}
2081
2083 assert(hasDefinition() && "ODRHash only for records with definitions");
2084
2085 // Previously calculated hash is stored in DefinitionData.
2086 if (hasODRHash())
2087 return data().ODRHash;
2088
2089 // Only calculate hash on first call of getODRHash per record.
2090 ODRHash Hasher;
2092 data().ODRHash = Hasher.CalculateHash();
2093 setHasODRHash(true);
2094
2095 return data().ODRHash;
2096}
2097
2098bool ObjCProtocolDecl::hasODRHash() const {
2099 if (!hasDefinition())
2100 return false;
2101 return data().HasODRHash;
2102}
2103
2104void ObjCProtocolDecl::setHasODRHash(bool HasHash) {
2105 assert(hasDefinition() && "Cannot set ODRHash without definition");
2106 data().HasODRHash = HasHash;
2107}
2108
2109//===----------------------------------------------------------------------===//
2110// ObjCCategoryDecl
2111//===----------------------------------------------------------------------===//
2112
2113void ObjCCategoryDecl::anchor() {}
2114
2115ObjCCategoryDecl::ObjCCategoryDecl(
2116 DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc,
2117 SourceLocation CategoryNameLoc, const IdentifierInfo *Id,
2118 ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList,
2119 SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc)
2120 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
2121 ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
2122 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
2123 setTypeParamList(typeParamList);
2124}
2125
2128 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
2129 const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
2130 ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,
2131 SourceLocation IvarRBraceLoc) {
2132 auto *CatDecl =
2133 new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
2134 IDecl, typeParamList, IvarLBraceLoc,
2135 IvarRBraceLoc);
2136 if (IDecl) {
2137 // Link this category into its class's category list.
2138 CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
2139 if (IDecl->hasDefinition()) {
2140 IDecl->setCategoryListRaw(CatDecl);
2141 if (ASTMutationListener *L = C.getASTMutationListener())
2142 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
2143 }
2144 }
2145
2146 return CatDecl;
2147}
2148
2150 GlobalDeclID ID) {
2151 return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
2153 nullptr, nullptr, nullptr);
2154}
2155
2158 const_cast<ObjCCategoryDecl*>(this));
2159}
2160
2164
2166 TypeParamList = TPL;
2167 if (!TPL)
2168 return;
2169 // Set the declaration context of each of the type parameters.
2170 for (auto *typeParam : *TypeParamList)
2171 typeParam->setDeclContext(this);
2172}
2173
2174//===----------------------------------------------------------------------===//
2175// ObjCCategoryImplDecl
2176//===----------------------------------------------------------------------===//
2177
2178void ObjCCategoryImplDecl::anchor() {}
2179
2180ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create(
2181 ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,
2182 ObjCInterfaceDecl *ClassInterface, SourceLocation nameLoc,
2183 SourceLocation atStartLoc, SourceLocation CategoryNameLoc) {
2184 if (ClassInterface && ClassInterface->hasDefinition())
2185 ClassInterface = ClassInterface->getDefinition();
2186 return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
2187 atStartLoc, CategoryNameLoc);
2188}
2189
2192 return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
2194 SourceLocation());
2195}
2196
2198 // The class interface might be NULL if we are working with invalid code.
2199 if (const ObjCInterfaceDecl *ID = getClassInterface())
2200 return ID->FindCategoryDeclaration(getIdentifier());
2201 return nullptr;
2202}
2203
2204void ObjCImplDecl::anchor() {}
2205
2207 // FIXME: The context should be correct before we get here.
2208 property->setLexicalDeclContext(this);
2209 addDecl(property);
2210}
2211
2213 ASTContext &Ctx = getASTContext();
2214
2215 if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
2216 if (IFace)
2217 Ctx.setObjCImplementation(IFace, ImplD);
2218
2219 } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
2221 Ctx.setObjCImplementation(CD, ImplD);
2222 }
2223
2224 ClassInterface = IFace;
2225}
2226
2227/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
2228/// properties implemented in this \@implementation block and returns
2229/// the implemented property that uses it.
2232 for (auto *PID : property_impls())
2233 if (PID->getPropertyIvarDecl() &&
2234 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
2235 return PID;
2236 return nullptr;
2237}
2238
2239/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
2240/// added to the list of those properties \@synthesized/\@dynamic in this
2241/// category \@implementation block.
2244 ObjCPropertyQueryKind QueryKind) const {
2245 ObjCPropertyImplDecl *ClassPropImpl = nullptr;
2246 for (auto *PID : property_impls())
2247 // If queryKind is unknown, we return the instance property if one
2248 // exists; otherwise we return the class property.
2249 if (PID->getPropertyDecl()->getIdentifier() == Id) {
2251 !PID->getPropertyDecl()->isClassProperty()) ||
2253 PID->getPropertyDecl()->isClassProperty()) ||
2255 !PID->getPropertyDecl()->isClassProperty()))
2256 return PID;
2257
2258 if (PID->getPropertyDecl()->isClassProperty())
2259 ClassPropImpl = PID;
2260 }
2261
2263 // We can't find the instance property, return the class property.
2264 return ClassPropImpl;
2265
2266 return nullptr;
2267}
2268
2269raw_ostream &clang::operator<<(raw_ostream &OS,
2270 const ObjCCategoryImplDecl &CID) {
2271 OS << CID.getName();
2272 return OS;
2273}
2274
2275//===----------------------------------------------------------------------===//
2276// ObjCImplementationDecl
2277//===----------------------------------------------------------------------===//
2278
2279void ObjCImplementationDecl::anchor() {}
2280
2283 ObjCInterfaceDecl *ClassInterface,
2284 ObjCInterfaceDecl *SuperDecl,
2285 SourceLocation nameLoc,
2286 SourceLocation atStartLoc,
2287 SourceLocation superLoc,
2288 SourceLocation IvarLBraceLoc,
2289 SourceLocation IvarRBraceLoc) {
2290 if (ClassInterface && ClassInterface->hasDefinition())
2291 ClassInterface = ClassInterface->getDefinition();
2292 return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
2293 nameLoc, atStartLoc, superLoc,
2294 IvarLBraceLoc, IvarRBraceLoc);
2295}
2296
2299 return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
2301}
2302
2304 CXXCtorInitializer ** initializers,
2305 unsigned numInitializers) {
2306 if (numInitializers > 0) {
2307 NumIvarInitializers = numInitializers;
2308 auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];
2309 memcpy(ivarInitializers, initializers,
2310 numInitializers * sizeof(CXXCtorInitializer*));
2311 IvarInitializers = ivarInitializers;
2312 }
2313}
2314
2317 return IvarInitializers.get(getASTContext().getExternalSource());
2318}
2319
2320raw_ostream &clang::operator<<(raw_ostream &OS,
2321 const ObjCImplementationDecl &ID) {
2322 OS << ID.getName();
2323 return OS;
2324}
2325
2326//===----------------------------------------------------------------------===//
2327// ObjCCompatibleAliasDecl
2328//===----------------------------------------------------------------------===//
2329
2330void ObjCCompatibleAliasDecl::anchor() {}
2331
2335 IdentifierInfo *Id,
2336 ObjCInterfaceDecl* AliasedClass) {
2337 return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
2338}
2339
2342 return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
2343 nullptr, nullptr);
2344}
2345
2346//===----------------------------------------------------------------------===//
2347// ObjCPropertyDecl
2348//===----------------------------------------------------------------------===//
2349
2350void ObjCPropertyDecl::anchor() {}
2351
2354 const IdentifierInfo *Id, SourceLocation AtLoc,
2355 SourceLocation LParenLoc, QualType T,
2356 TypeSourceInfo *TSI, PropertyControl propControl) {
2357 return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
2358 propControl);
2359}
2360
2362 GlobalDeclID ID) {
2363 return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
2365 QualType(), nullptr, None);
2366}
2367
2372
2374 return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
2375 !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
2376}
2377
2378//===----------------------------------------------------------------------===//
2379// ObjCPropertyImplDecl
2380//===----------------------------------------------------------------------===//
2381
2383 DeclContext *DC,
2384 SourceLocation atLoc,
2386 ObjCPropertyDecl *property,
2387 Kind PK,
2388 ObjCIvarDecl *ivar,
2389 SourceLocation ivarLoc) {
2390 return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
2391 ivarLoc);
2392}
2393
2396 return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
2397 SourceLocation(), nullptr, Dynamic,
2398 nullptr, SourceLocation());
2399}
2400
2402 SourceLocation EndLoc = getLocation();
2403 if (IvarLoc.isValid())
2404 EndLoc = IvarLoc;
2405
2406 return SourceRange(AtLoc, EndLoc);
2407}
Defines the clang::ASTContext interface.
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:227
void setObjCImplementation(ObjCInterfaceDecl *IFaceD, ObjCImplementationDecl *ImplD)
Set the implementation of ObjCInterfaceDecl.
IdentifierTable & Idents
Definition ASTContext.h:805
const LangOptions & getLangOpts() const
Definition ASTContext.h:959
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:879
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:2385
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
lookup_result::iterator lookup_iterator
Definition DeclBase.h:2591
DeclContextLookupResult lookup_result
Definition DeclBase.h:2590
ObjCMethodDeclBitfields ObjCMethodDeclBits
Definition DeclBase.h:2059
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:547
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:867
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:1004
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:386
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:5597
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
void AddObjCProtocolDecl(const ObjCProtocolDecl *P)
Definition ODRHash.cpp:791
void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record)
Definition ODRHash.cpp:643
unsigned CalculateHash()
Definition ODRHash.cpp:231
Represents a field declaration created by an @defs(...).
Definition DeclObjC.h:2030
static ObjCAtDefsFieldDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
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:2329
static ObjCCategoryDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())
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:2439
void setImplementation(ObjCCategoryImplDecl *ImplD)
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2545
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:2775
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:948
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition DeclObjC.cpp:90
void setAtStartLoc(SourceLocation Loc)
Definition DeclObjC.h:1098
instmeth_range instance_methods() const
Definition DeclObjC.h:1033
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
Definition DeclObjC.h:1088
ObjCPropertyDecl * getProperty(const IdentifierInfo *Id, bool IsInstance) const
Definition DeclObjC.cpp:233
ObjCIvarDecl * getIvarDecl(IdentifierInfo *Id) const
getIvarDecl - This method looks up an ivar in this ContextDecl.
Definition DeclObjC.cpp:78
llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
Definition DeclObjC.h:1085
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:1089
prop_range properties() const
Definition DeclObjC.h:967
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Definition DeclObjC.h:1066
ObjCContainerDecl(Kind DK, DeclContext *DC, const IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc)
Definition DeclObjC.cpp:65
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const
This routine returns 'true' if a user declared setter method was found in the class,...
Definition DeclObjC.cpp:122
void addPropertyImplementation(ObjCPropertyImplDecl *property)
propimpl_range property_impls() const
Definition DeclObjC.h:2513
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:2486
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:2597
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:2657
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
Definition DeclObjC.h:2721
init_iterator init_begin()
init_begin() - Retrieve an iterator to the first initializer.
Definition DeclObjC.h:2669
void setIvarInitializers(ASTContext &C, CXXCtorInitializer **initializers, unsigned numInitializers)
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
void mergeClassExtensionProtocolList(ObjCProtocolDecl *const *List, unsigned Num, ASTContext &C)
mergeClassExtensionProtocolList - Merge class extension's protocol list into the protocol list for th...
Definition DeclObjC.cpp:439
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameters of this class.
Definition DeclObjC.cpp:319
all_protocol_iterator all_referenced_protocol_end() const
Definition DeclObjC.h:1435
ObjCInterfaceDecl * lookupInheritedClass(const IdentifierInfo *ICName)
lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super class whose name is passe...
Definition DeclObjC.cpp:665
ivar_iterator ivar_end() const
Definition DeclObjC.h:1461
ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name 'PropertyId' in the p...
Definition DeclObjC.cpp:379
ObjCMethodDecl * getCategoryMethod(Selector Sel, bool isInstance) const
Definition DeclObjC.h:1351
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition DeclObjC.cpp:634
void setCategoryListRaw(ObjCCategoryDecl *category)
Set the raw pointer to the start of the category/extension list.
Definition DeclObjC.h:1798
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:1528
all_protocol_range all_referenced_protocols() const
Definition DeclObjC.h:1417
visible_extensions_range visible_extensions() const
Definition DeclObjC.h:1723
ObjCTypeParamList * getTypeParamListAsWritten() const
Retrieve the type parameters written on this particular declaration of the class.
Definition DeclObjC.h:1303
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
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:1453
protocol_range protocols() const
Definition DeclObjC.h:1359
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Definition DeclObjC.h:1847
unsigned getODRHash()
Get precomputed ODRHash or add a new one.
Definition DeclObjC.cpp:788
bool ivar_empty() const
Definition DeclObjC.h:1473
void setImplementation(ObjCImplementationDecl *ImplD)
known_categories_range known_categories() const
Definition DeclObjC.h:1687
const ObjCInterfaceDecl * isObjCRequiresPropertyDefs() const
isObjCRequiresPropertyDefs - Checks that a class or one of its super classes must not be auto-synthes...
Definition DeclObjC.cpp:429
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition DeclObjC.cpp:369
all_protocol_iterator all_referenced_protocol_begin() const
Definition DeclObjC.h:1422
void setExternallyCompleted()
Indicate that this Objective-C class is complete, but that the external AST source will be responsibl...
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
ObjCCategoryDecl * getCategoryListRaw() const
Retrieve the raw pointer to the start of the category/extension list.
Definition DeclObjC.h:1785
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition DeclObjC.h:1523
friend class ASTContext
Definition DeclObjC.h:1155
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:1565
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:1653
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Definition DeclObjC.h:1915
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
Definition DeclObjC.h:1542
TypeSourceInfo * getSuperClassTInfo() const
Definition DeclObjC.h:1573
bool isDesignatedInitializer(Selector Sel, const ObjCMethodDecl **InitMethod=nullptr) const
Returns true if the given selector is a designated initializer for the interface.
Definition DeclObjC.cpp:567
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
Definition DeclObjC.cpp:623
void setHasDesignatedInitializers()
Indicate that this interface decl contains at least one initializer marked with the 'objc_designated_...
specific_decl_iterator< ObjCIvarDecl > ivar_iterator
Definition DeclObjC.h:1448
void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition)
Definition DeclObjC.cpp:629
known_extensions_range known_extensions() const
Definition DeclObjC.h:1762
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
void setNextIvar(ObjCIvarDecl *ivar)
Definition DeclObjC.h:1989
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
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:886
ArrayRef< ParmVarDecl * > parameters() const
Definition DeclObjC.h:373
unsigned param_size() const
Definition DeclObjC.h:347
void setSelfDecl(ImplicitParamDecl *SD)
Definition DeclObjC.h:419
bool isPropertyAccessor() const
Definition DeclObjC.h:436
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
Definition DeclObjC.cpp:849
void setHasRedeclaration(bool HRD) const
Definition DeclObjC.h:272
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
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:898
void setIsRedeclaration(bool RD)
Definition DeclObjC.h:267
bool isVariadic() const
Definition DeclObjC.h:431
void setCmdDecl(ImplicitParamDecl *CD)
Definition DeclObjC.h:421
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition DeclObjC.cpp:906
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
SourceLocation getEndLoc() const LLVM_READONLY
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition DeclObjC.h:343
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:271
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
Definition DeclObjC.cpp:941
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod)
Definition DeclObjC.cpp:910
param_type_iterator param_type_begin() const
Definition DeclObjC.h:399
bool isSynthesizedAccessorStub() const
Definition DeclObjC.h:444
SourceLocation getSelectorLoc(unsigned Index) const
Definition DeclObjC.h:294
SourceRange getReturnTypeSourceRange() const
bool isRedeclaration() const
True if this is a method redeclaration in the same interface.
Definition DeclObjC.h:266
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition DeclObjC.cpp:868
Selector getSelector() const
Definition DeclObjC.h:327
bool isInstanceMethod() const
Definition DeclObjC.h:426
static ObjCMethodDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Definition DeclObjC.cpp:862
bool isThisDeclarationADesignatedInitializer() const
Returns true if this specific method declaration is marked with the designated initializer attribute.
Definition DeclObjC.cpp:873
llvm::mapped_iterator< param_const_iterator, GetTypeFn > param_type_iterator
Definition DeclObjC.h:396
ObjCCategoryDecl * getCategory()
If this method is declared or implemented in a category, return that category.
bool isDefined() const
Definition DeclObjC.h:452
bool definedInNSObject(const ASTContext &) const
Is this method defined in the NSObject base class?
Definition DeclObjC.cpp:878
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implicit parameters.
QualType getReturnType() const
Definition DeclObjC.h:329
unsigned getNumSelectorLocs() const
Definition DeclObjC.h:306
bool isClassMethod() const
Definition DeclObjC.h:434
ObjCInterfaceDecl * getClassInterface()
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition DeclObjC.cpp:935
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
QualType getUsageType(QualType objectType) const
Retrieve the type when this property is used with a specific base object type.
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:2805
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:2084
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:2238
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:2250
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:2161
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:640
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:662
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:689
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:1808
A (possibly-)qualified type.
Definition TypeBase.h:937
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition Type.cpp:3677
QualType withConst() const
Definition TypeBase.h:1170
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8436
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:1703
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:1696
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:361
void setObjCLifetime(ObjCLifetime type)
Definition TypeBase.h:548
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:86
A container of type source information.
Definition TypeBase.h:8407
bool isObjCSelType() const
Definition TypeBase.h:8897
bool isObjCIdType() const
Definition TypeBase.h:8885
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:3630
QualType getType() const
Definition Decl.h:723
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
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:719
@ InvalidObjCMethodFamily
@ Override
Merge availability attributes for an override, which requires an exact match or a weakening of constr...
Definition Sema.h:636
@ 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:911
@ Result
The result type of a method or function.
Definition TypeBase.h:905
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:553
@ Invariant
The parameter is invariant: must match exactly.
Definition DeclObjC.h:555
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5966
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5972
@ ObjCSelf
Parameter for Objective-C 'self' argument.
Definition Decl.h:1745
@ ObjCCmd
Parameter for Objective-C '_cmd' argument.
Definition Decl.h:1748