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