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