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