xref: /freebsd/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
10b57cec5SDimitry Andric //===- DeclObjC.cpp - ObjC Declaration AST Node Implementation ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the Objective-C related Decl classes.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTMutationListener.h"
160b57cec5SDimitry Andric #include "clang/AST/Attr.h"
170b57cec5SDimitry Andric #include "clang/AST/Decl.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
190b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
200b57cec5SDimitry Andric #include "clang/AST/Type.h"
210b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
220b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
230b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
240b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
250b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
260b57cec5SDimitry Andric #include "llvm/ADT/None.h"
270b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
280b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
290b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
300b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
310b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
320b57cec5SDimitry Andric #include <algorithm>
330b57cec5SDimitry Andric #include <cassert>
340b57cec5SDimitry Andric #include <cstdint>
350b57cec5SDimitry Andric #include <cstring>
36e8d8bef9SDimitry Andric #include <queue>
370b57cec5SDimitry Andric #include <utility>
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric using namespace clang;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
420b57cec5SDimitry Andric // ObjCListBase
430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
460b57cec5SDimitry Andric   List = nullptr;
470b57cec5SDimitry Andric   if (Elts == 0) return;  // Setting to an empty list is a noop.
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   List = new (Ctx) void*[Elts];
500b57cec5SDimitry Andric   NumElts = Elts;
510b57cec5SDimitry Andric   memcpy(List, InList, sizeof(void*)*Elts);
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
550b57cec5SDimitry Andric                            const SourceLocation *Locs, ASTContext &Ctx) {
560b57cec5SDimitry Andric   if (Elts == 0)
570b57cec5SDimitry Andric     return;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   Locations = new (Ctx) SourceLocation[Elts];
600b57cec5SDimitry Andric   memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
610b57cec5SDimitry Andric   set(InList, Elts, Ctx);
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
650b57cec5SDimitry Andric // ObjCInterfaceDecl
660b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,
690b57cec5SDimitry Andric                                      IdentifierInfo *Id, SourceLocation nameLoc,
700b57cec5SDimitry Andric                                      SourceLocation atStartLoc)
710b57cec5SDimitry Andric     : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
720b57cec5SDimitry Andric   setAtStartLoc(atStartLoc);
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric void ObjCContainerDecl::anchor() {}
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric /// getIvarDecl - This method looks up an ivar in this ContextDecl.
780b57cec5SDimitry Andric ///
790b57cec5SDimitry Andric ObjCIvarDecl *
800b57cec5SDimitry Andric ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
810b57cec5SDimitry Andric   lookup_result R = lookup(Id);
820b57cec5SDimitry Andric   for (lookup_iterator Ivar = R.begin(), IvarEnd = R.end();
830b57cec5SDimitry Andric        Ivar != IvarEnd; ++Ivar) {
840b57cec5SDimitry Andric     if (auto *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
850b57cec5SDimitry Andric       return ivar;
860b57cec5SDimitry Andric   }
870b57cec5SDimitry Andric   return nullptr;
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric // Get the local instance/class method declared in this interface.
910b57cec5SDimitry Andric ObjCMethodDecl *
920b57cec5SDimitry Andric ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
930b57cec5SDimitry Andric                              bool AllowHidden) const {
940b57cec5SDimitry Andric   // If this context is a hidden protocol definition, don't find any
950b57cec5SDimitry Andric   // methods there.
960b57cec5SDimitry Andric   if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
970b57cec5SDimitry Andric     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
985ffd83dbSDimitry Andric       if (!Def->isUnconditionallyVisible() && !AllowHidden)
990b57cec5SDimitry Andric         return nullptr;
1000b57cec5SDimitry Andric   }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   // Since instance & class methods can have the same name, the loop below
1030b57cec5SDimitry Andric   // ensures we get the correct method.
1040b57cec5SDimitry Andric   //
1050b57cec5SDimitry Andric   // @interface Whatever
1060b57cec5SDimitry Andric   // - (int) class_method;
1070b57cec5SDimitry Andric   // + (float) class_method;
1080b57cec5SDimitry Andric   // @end
1090b57cec5SDimitry Andric   lookup_result R = lookup(Sel);
1100b57cec5SDimitry Andric   for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
1110b57cec5SDimitry Andric        Meth != MethEnd; ++Meth) {
1120b57cec5SDimitry Andric     auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
1130b57cec5SDimitry Andric     if (MD && MD->isInstanceMethod() == isInstance)
1140b57cec5SDimitry Andric       return MD;
1150b57cec5SDimitry Andric   }
1160b57cec5SDimitry Andric   return nullptr;
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric /// This routine returns 'true' if a user declared setter method was
1200b57cec5SDimitry Andric /// found in the class, its protocols, its super classes or categories.
1210b57cec5SDimitry Andric /// It also returns 'true' if one of its categories has declared a 'readwrite'
1220b57cec5SDimitry Andric /// property.  This is because, user must provide a setter method for the
1230b57cec5SDimitry Andric /// category's 'readwrite' property.
1240b57cec5SDimitry Andric bool ObjCContainerDecl::HasUserDeclaredSetterMethod(
1250b57cec5SDimitry Andric     const ObjCPropertyDecl *Property) const {
1260b57cec5SDimitry Andric   Selector Sel = Property->getSetterName();
1270b57cec5SDimitry Andric   lookup_result R = lookup(Sel);
1280b57cec5SDimitry Andric   for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
1290b57cec5SDimitry Andric        Meth != MethEnd; ++Meth) {
1300b57cec5SDimitry Andric     auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);
1310b57cec5SDimitry Andric     if (MD && MD->isInstanceMethod() && !MD->isImplicit())
1320b57cec5SDimitry Andric       return true;
1330b57cec5SDimitry Andric   }
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
1360b57cec5SDimitry Andric     // Also look into categories, including class extensions, looking
1370b57cec5SDimitry Andric     // for a user declared instance method.
1380b57cec5SDimitry Andric     for (const auto *Cat : ID->visible_categories()) {
1390b57cec5SDimitry Andric       if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
1400b57cec5SDimitry Andric         if (!MD->isImplicit())
1410b57cec5SDimitry Andric           return true;
1420b57cec5SDimitry Andric       if (Cat->IsClassExtension())
1430b57cec5SDimitry Andric         continue;
1440b57cec5SDimitry Andric       // Also search through the categories looking for a 'readwrite'
1450b57cec5SDimitry Andric       // declaration of this property. If one found, presumably a setter will
1460b57cec5SDimitry Andric       // be provided (properties declared in categories will not get
1470b57cec5SDimitry Andric       // auto-synthesized).
1480b57cec5SDimitry Andric       for (const auto *P : Cat->properties())
1490b57cec5SDimitry Andric         if (P->getIdentifier() == Property->getIdentifier()) {
1505ffd83dbSDimitry Andric           if (P->getPropertyAttributes() &
1515ffd83dbSDimitry Andric               ObjCPropertyAttribute::kind_readwrite)
1520b57cec5SDimitry Andric             return true;
1530b57cec5SDimitry Andric           break;
1540b57cec5SDimitry Andric         }
1550b57cec5SDimitry Andric     }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric     // Also look into protocols, for a user declared instance method.
1580b57cec5SDimitry Andric     for (const auto *Proto : ID->all_referenced_protocols())
1590b57cec5SDimitry Andric       if (Proto->HasUserDeclaredSetterMethod(Property))
1600b57cec5SDimitry Andric         return true;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric     // And in its super class.
1630b57cec5SDimitry Andric     ObjCInterfaceDecl *OSC = ID->getSuperClass();
1640b57cec5SDimitry Andric     while (OSC) {
1650b57cec5SDimitry Andric       if (OSC->HasUserDeclaredSetterMethod(Property))
1660b57cec5SDimitry Andric         return true;
1670b57cec5SDimitry Andric       OSC = OSC->getSuperClass();
1680b57cec5SDimitry Andric     }
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric   if (const auto *PD = dyn_cast<ObjCProtocolDecl>(this))
1710b57cec5SDimitry Andric     for (const auto *PI : PD->protocols())
1720b57cec5SDimitry Andric       if (PI->HasUserDeclaredSetterMethod(Property))
1730b57cec5SDimitry Andric         return true;
1740b57cec5SDimitry Andric   return false;
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric ObjCPropertyDecl *
1780b57cec5SDimitry Andric ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
1790b57cec5SDimitry Andric                                    const IdentifierInfo *propertyID,
1800b57cec5SDimitry Andric                                    ObjCPropertyQueryKind queryKind) {
1810b57cec5SDimitry Andric   // If this context is a hidden protocol definition, don't find any
1820b57cec5SDimitry Andric   // property.
1830b57cec5SDimitry Andric   if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
1840b57cec5SDimitry Andric     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
1855ffd83dbSDimitry Andric       if (!Def->isUnconditionallyVisible())
1860b57cec5SDimitry Andric         return nullptr;
1870b57cec5SDimitry Andric   }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   // If context is class, then lookup property in its visible extensions.
1900b57cec5SDimitry Andric   // This comes before property is looked up in primary class.
1910b57cec5SDimitry Andric   if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
1920b57cec5SDimitry Andric     for (const auto *Ext : IDecl->visible_extensions())
1930b57cec5SDimitry Andric       if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,
1940b57cec5SDimitry Andric                                                        propertyID,
1950b57cec5SDimitry Andric                                                        queryKind))
1960b57cec5SDimitry Andric         return PD;
1970b57cec5SDimitry Andric   }
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   DeclContext::lookup_result R = DC->lookup(propertyID);
2000b57cec5SDimitry Andric   ObjCPropertyDecl *classProp = nullptr;
2010b57cec5SDimitry Andric   for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
2020b57cec5SDimitry Andric        ++I)
2030b57cec5SDimitry Andric     if (auto *PD = dyn_cast<ObjCPropertyDecl>(*I)) {
2040b57cec5SDimitry Andric       // If queryKind is unknown, we return the instance property if one
2050b57cec5SDimitry Andric       // exists; otherwise we return the class property.
2060b57cec5SDimitry Andric       if ((queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown &&
2070b57cec5SDimitry Andric            !PD->isClassProperty()) ||
2080b57cec5SDimitry Andric           (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_class &&
2090b57cec5SDimitry Andric            PD->isClassProperty()) ||
2100b57cec5SDimitry Andric           (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance &&
2110b57cec5SDimitry Andric            !PD->isClassProperty()))
2120b57cec5SDimitry Andric         return PD;
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric       if (PD->isClassProperty())
2150b57cec5SDimitry Andric         classProp = PD;
2160b57cec5SDimitry Andric     }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric   if (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown)
2190b57cec5SDimitry Andric     // We can't find the instance property, return the class property.
2200b57cec5SDimitry Andric     return classProp;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   return nullptr;
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric IdentifierInfo *
2260b57cec5SDimitry Andric ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
2270b57cec5SDimitry Andric   SmallString<128> ivarName;
2280b57cec5SDimitry Andric   {
2290b57cec5SDimitry Andric     llvm::raw_svector_ostream os(ivarName);
2300b57cec5SDimitry Andric     os << '_' << getIdentifier()->getName();
2310b57cec5SDimitry Andric   }
2320b57cec5SDimitry Andric   return &Ctx.Idents.get(ivarName.str());
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
235*04eeddc0SDimitry Andric ObjCPropertyDecl *ObjCContainerDecl::getProperty(const IdentifierInfo *Id,
236*04eeddc0SDimitry Andric                                                  bool IsInstance) const {
237*04eeddc0SDimitry Andric   for (auto *LookupResult : lookup(Id)) {
238*04eeddc0SDimitry Andric     if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) {
239*04eeddc0SDimitry Andric       if (Prop->isInstanceProperty() == IsInstance) {
240*04eeddc0SDimitry Andric         return Prop;
241*04eeddc0SDimitry Andric       }
242*04eeddc0SDimitry Andric     }
243*04eeddc0SDimitry Andric   }
244*04eeddc0SDimitry Andric   return nullptr;
245*04eeddc0SDimitry Andric }
246*04eeddc0SDimitry Andric 
2470b57cec5SDimitry Andric /// FindPropertyDeclaration - Finds declaration of the property given its name
2480b57cec5SDimitry Andric /// in 'PropertyId' and returns it. It returns 0, if not found.
2490b57cec5SDimitry Andric ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
2500b57cec5SDimitry Andric     const IdentifierInfo *PropertyId,
2510b57cec5SDimitry Andric     ObjCPropertyQueryKind QueryKind) const {
2520b57cec5SDimitry Andric   // Don't find properties within hidden protocol definitions.
2530b57cec5SDimitry Andric   if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
2540b57cec5SDimitry Andric     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
2555ffd83dbSDimitry Andric       if (!Def->isUnconditionallyVisible())
2560b57cec5SDimitry Andric         return nullptr;
2570b57cec5SDimitry Andric   }
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   // Search the extensions of a class first; they override what's in
2600b57cec5SDimitry Andric   // the class itself.
2610b57cec5SDimitry Andric   if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) {
2620b57cec5SDimitry Andric     for (const auto *Ext : ClassDecl->visible_extensions()) {
2630b57cec5SDimitry Andric       if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind))
2640b57cec5SDimitry Andric         return P;
2650b57cec5SDimitry Andric     }
2660b57cec5SDimitry Andric   }
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   if (ObjCPropertyDecl *PD =
2690b57cec5SDimitry Andric         ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
2700b57cec5SDimitry Andric                                            QueryKind))
2710b57cec5SDimitry Andric     return PD;
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   switch (getKind()) {
2740b57cec5SDimitry Andric     default:
2750b57cec5SDimitry Andric       break;
2760b57cec5SDimitry Andric     case Decl::ObjCProtocol: {
2770b57cec5SDimitry Andric       const auto *PID = cast<ObjCProtocolDecl>(this);
2780b57cec5SDimitry Andric       for (const auto *I : PID->protocols())
2790b57cec5SDimitry Andric         if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
2800b57cec5SDimitry Andric                                                              QueryKind))
2810b57cec5SDimitry Andric           return P;
2820b57cec5SDimitry Andric       break;
2830b57cec5SDimitry Andric     }
2840b57cec5SDimitry Andric     case Decl::ObjCInterface: {
2850b57cec5SDimitry Andric       const auto *OID = cast<ObjCInterfaceDecl>(this);
2860b57cec5SDimitry Andric       // Look through categories (but not extensions; they were handled above).
2870b57cec5SDimitry Andric       for (const auto *Cat : OID->visible_categories()) {
2880b57cec5SDimitry Andric         if (!Cat->IsClassExtension())
2890b57cec5SDimitry Andric           if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(
2900b57cec5SDimitry Andric                                              PropertyId, QueryKind))
2910b57cec5SDimitry Andric             return P;
2920b57cec5SDimitry Andric       }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric       // Look through protocols.
2950b57cec5SDimitry Andric       for (const auto *I : OID->all_referenced_protocols())
2960b57cec5SDimitry Andric         if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
2970b57cec5SDimitry Andric                                                              QueryKind))
2980b57cec5SDimitry Andric           return P;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric       // Finally, check the super class.
3010b57cec5SDimitry Andric       if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
3020b57cec5SDimitry Andric         return superClass->FindPropertyDeclaration(PropertyId, QueryKind);
3030b57cec5SDimitry Andric       break;
3040b57cec5SDimitry Andric     }
3050b57cec5SDimitry Andric     case Decl::ObjCCategory: {
3060b57cec5SDimitry Andric       const auto *OCD = cast<ObjCCategoryDecl>(this);
3070b57cec5SDimitry Andric       // Look through protocols.
3080b57cec5SDimitry Andric       if (!OCD->IsClassExtension())
3090b57cec5SDimitry Andric         for (const auto *I : OCD->protocols())
3100b57cec5SDimitry Andric           if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
3110b57cec5SDimitry Andric                                                                QueryKind))
3120b57cec5SDimitry Andric             return P;
3130b57cec5SDimitry Andric       break;
3140b57cec5SDimitry Andric     }
3150b57cec5SDimitry Andric   }
3160b57cec5SDimitry Andric   return nullptr;
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric void ObjCInterfaceDecl::anchor() {}
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const {
3220b57cec5SDimitry Andric   // If this particular declaration has a type parameter list, return it.
3230b57cec5SDimitry Andric   if (ObjCTypeParamList *written = getTypeParamListAsWritten())
3240b57cec5SDimitry Andric     return written;
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   // If there is a definition, return its type parameter list.
3270b57cec5SDimitry Andric   if (const ObjCInterfaceDecl *def = getDefinition())
3280b57cec5SDimitry Andric     return def->getTypeParamListAsWritten();
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   // Otherwise, look at previous declarations to determine whether any
3310b57cec5SDimitry Andric   // of them has a type parameter list, skipping over those
3320b57cec5SDimitry Andric   // declarations that do not.
3330b57cec5SDimitry Andric   for (const ObjCInterfaceDecl *decl = getMostRecentDecl(); decl;
3340b57cec5SDimitry Andric        decl = decl->getPreviousDecl()) {
3350b57cec5SDimitry Andric     if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten())
3360b57cec5SDimitry Andric       return written;
3370b57cec5SDimitry Andric   }
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   return nullptr;
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric void ObjCInterfaceDecl::setTypeParamList(ObjCTypeParamList *TPL) {
3430b57cec5SDimitry Andric   TypeParamList = TPL;
3440b57cec5SDimitry Andric   if (!TPL)
3450b57cec5SDimitry Andric     return;
3460b57cec5SDimitry Andric   // Set the declaration context of each of the type parameters.
3470b57cec5SDimitry Andric   for (auto *typeParam : *TypeParamList)
3480b57cec5SDimitry Andric     typeParam->setDeclContext(this);
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const {
3520b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
3530b57cec5SDimitry Andric   if (!hasDefinition())
3540b57cec5SDimitry Andric     return nullptr;
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric   if (data().ExternallyCompleted)
3570b57cec5SDimitry Andric     LoadExternalDefinition();
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   if (const ObjCObjectType *superType = getSuperClassType()) {
3600b57cec5SDimitry Andric     if (ObjCInterfaceDecl *superDecl = superType->getInterface()) {
3610b57cec5SDimitry Andric       if (ObjCInterfaceDecl *superDef = superDecl->getDefinition())
3620b57cec5SDimitry Andric         return superDef;
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric       return superDecl;
3650b57cec5SDimitry Andric     }
3660b57cec5SDimitry Andric   }
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric   return nullptr;
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const {
3720b57cec5SDimitry Andric   if (TypeSourceInfo *superTInfo = getSuperClassTInfo())
3730b57cec5SDimitry Andric     return superTInfo->getTypeLoc().getBeginLoc();
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   return SourceLocation();
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
3790b57cec5SDimitry Andric /// with name 'PropertyId' in the primary class; including those in protocols
3800b57cec5SDimitry Andric /// (direct or indirect) used by the primary class.
3810b57cec5SDimitry Andric ObjCPropertyDecl *
3820b57cec5SDimitry Andric ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
3830b57cec5SDimitry Andric                        IdentifierInfo *PropertyId,
3840b57cec5SDimitry Andric                        ObjCPropertyQueryKind QueryKind) const {
3850b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
3860b57cec5SDimitry Andric   if (!hasDefinition())
3870b57cec5SDimitry Andric     return nullptr;
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   if (data().ExternallyCompleted)
3900b57cec5SDimitry Andric     LoadExternalDefinition();
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric   if (ObjCPropertyDecl *PD =
3930b57cec5SDimitry Andric       ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,
3940b57cec5SDimitry Andric                                          QueryKind))
3950b57cec5SDimitry Andric     return PD;
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   // Look through protocols.
3980b57cec5SDimitry Andric   for (const auto *I : all_referenced_protocols())
3990b57cec5SDimitry Andric     if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,
4000b57cec5SDimitry Andric                                                          QueryKind))
4010b57cec5SDimitry Andric       return P;
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   return nullptr;
4040b57cec5SDimitry Andric }
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
4070b57cec5SDimitry Andric                                                      PropertyDeclOrder &PO) const {
4080b57cec5SDimitry Andric   for (auto *Prop : properties()) {
4090b57cec5SDimitry Andric     PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
4100b57cec5SDimitry Andric     PO.push_back(Prop);
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric   for (const auto *Ext : known_extensions()) {
4130b57cec5SDimitry Andric     const ObjCCategoryDecl *ClassExt = Ext;
4140b57cec5SDimitry Andric     for (auto *Prop : ClassExt->properties()) {
4150b57cec5SDimitry Andric       PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
4160b57cec5SDimitry Andric       PO.push_back(Prop);
4170b57cec5SDimitry Andric     }
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric   for (const auto *PI : all_referenced_protocols())
4200b57cec5SDimitry Andric     PI->collectPropertiesToImplement(PM, PO);
4210b57cec5SDimitry Andric   // Note, the properties declared only in class extensions are still copied
4220b57cec5SDimitry Andric   // into the main @interface's property list, and therefore we don't
4230b57cec5SDimitry Andric   // explicitly, have to search class extension properties.
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {
4270b57cec5SDimitry Andric   const ObjCInterfaceDecl *Class = this;
4280b57cec5SDimitry Andric   while (Class) {
4290b57cec5SDimitry Andric     if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
4300b57cec5SDimitry Andric       return true;
4310b57cec5SDimitry Andric     Class = Class->getSuperClass();
4320b57cec5SDimitry Andric   }
4330b57cec5SDimitry Andric   return false;
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
4370b57cec5SDimitry Andric   const ObjCInterfaceDecl *Class = this;
4380b57cec5SDimitry Andric   while (Class) {
4390b57cec5SDimitry Andric     if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
4400b57cec5SDimitry Andric       return Class;
4410b57cec5SDimitry Andric     Class = Class->getSuperClass();
4420b57cec5SDimitry Andric   }
4430b57cec5SDimitry Andric   return nullptr;
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
4470b57cec5SDimitry Andric                               ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
4480b57cec5SDimitry Andric                               ASTContext &C) {
4490b57cec5SDimitry Andric   if (data().ExternallyCompleted)
4500b57cec5SDimitry Andric     LoadExternalDefinition();
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   if (data().AllReferencedProtocols.empty() &&
4530b57cec5SDimitry Andric       data().ReferencedProtocols.empty()) {
4540b57cec5SDimitry Andric     data().AllReferencedProtocols.set(ExtList, ExtNum, C);
4550b57cec5SDimitry Andric     return;
4560b57cec5SDimitry Andric   }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric   // Check for duplicate protocol in class's protocol list.
4590b57cec5SDimitry Andric   // This is O(n*m). But it is extremely rare and number of protocols in
4600b57cec5SDimitry Andric   // class or its extension are very few.
4610b57cec5SDimitry Andric   SmallVector<ObjCProtocolDecl *, 8> ProtocolRefs;
4620b57cec5SDimitry Andric   for (unsigned i = 0; i < ExtNum; i++) {
4630b57cec5SDimitry Andric     bool protocolExists = false;
4640b57cec5SDimitry Andric     ObjCProtocolDecl *ProtoInExtension = ExtList[i];
4650b57cec5SDimitry Andric     for (auto *Proto : all_referenced_protocols()) {
4660b57cec5SDimitry Andric       if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
4670b57cec5SDimitry Andric         protocolExists = true;
4680b57cec5SDimitry Andric         break;
4690b57cec5SDimitry Andric       }
4700b57cec5SDimitry Andric     }
4710b57cec5SDimitry Andric     // Do we want to warn on a protocol in extension class which
4720b57cec5SDimitry Andric     // already exist in the class? Probably not.
4730b57cec5SDimitry Andric     if (!protocolExists)
4740b57cec5SDimitry Andric       ProtocolRefs.push_back(ProtoInExtension);
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   if (ProtocolRefs.empty())
4780b57cec5SDimitry Andric     return;
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   // Merge ProtocolRefs into class's protocol list;
4810b57cec5SDimitry Andric   ProtocolRefs.append(all_referenced_protocol_begin(),
4820b57cec5SDimitry Andric                       all_referenced_protocol_end());
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
4850b57cec5SDimitry Andric }
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric const ObjCInterfaceDecl *
4880b57cec5SDimitry Andric ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
4890b57cec5SDimitry Andric   const ObjCInterfaceDecl *IFace = this;
4900b57cec5SDimitry Andric   while (IFace) {
4910b57cec5SDimitry Andric     if (IFace->hasDesignatedInitializers())
4920b57cec5SDimitry Andric       return IFace;
4930b57cec5SDimitry Andric     if (!IFace->inheritsDesignatedInitializers())
4940b57cec5SDimitry Andric       break;
4950b57cec5SDimitry Andric     IFace = IFace->getSuperClass();
4960b57cec5SDimitry Andric   }
4970b57cec5SDimitry Andric   return nullptr;
4980b57cec5SDimitry Andric }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {
5010b57cec5SDimitry Andric   for (const auto *MD : D->instance_methods()) {
5020b57cec5SDimitry Andric     if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
5030b57cec5SDimitry Andric       return true;
5040b57cec5SDimitry Andric   }
5050b57cec5SDimitry Andric   for (const auto *Ext : D->visible_extensions()) {
5060b57cec5SDimitry Andric     for (const auto *MD : Ext->instance_methods()) {
5070b57cec5SDimitry Andric       if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
5080b57cec5SDimitry Andric         return true;
5090b57cec5SDimitry Andric     }
5100b57cec5SDimitry Andric   }
5110b57cec5SDimitry Andric   if (const auto *ImplD = D->getImplementation()) {
5120b57cec5SDimitry Andric     for (const auto *MD : ImplD->instance_methods()) {
5130b57cec5SDimitry Andric       if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
5140b57cec5SDimitry Andric         return true;
5150b57cec5SDimitry Andric     }
5160b57cec5SDimitry Andric   }
5170b57cec5SDimitry Andric   return false;
5180b57cec5SDimitry Andric }
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
5210b57cec5SDimitry Andric   switch (data().InheritedDesignatedInitializers) {
5220b57cec5SDimitry Andric   case DefinitionData::IDI_Inherited:
5230b57cec5SDimitry Andric     return true;
5240b57cec5SDimitry Andric   case DefinitionData::IDI_NotInherited:
5250b57cec5SDimitry Andric     return false;
5260b57cec5SDimitry Andric   case DefinitionData::IDI_Unknown:
5270b57cec5SDimitry Andric     // If the class introduced initializers we conservatively assume that we
5280b57cec5SDimitry Andric     // don't know if any of them is a designated initializer to avoid possible
5290b57cec5SDimitry Andric     // misleading warnings.
5300b57cec5SDimitry Andric     if (isIntroducingInitializers(this)) {
5310b57cec5SDimitry Andric       data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
5320b57cec5SDimitry Andric     } else {
5330b57cec5SDimitry Andric       if (auto SuperD = getSuperClass()) {
5340b57cec5SDimitry Andric         data().InheritedDesignatedInitializers =
5350b57cec5SDimitry Andric           SuperD->declaresOrInheritsDesignatedInitializers() ?
5360b57cec5SDimitry Andric             DefinitionData::IDI_Inherited :
5370b57cec5SDimitry Andric             DefinitionData::IDI_NotInherited;
5380b57cec5SDimitry Andric       } else {
5390b57cec5SDimitry Andric         data().InheritedDesignatedInitializers =
5400b57cec5SDimitry Andric           DefinitionData::IDI_NotInherited;
5410b57cec5SDimitry Andric       }
5420b57cec5SDimitry Andric     }
5430b57cec5SDimitry Andric     assert(data().InheritedDesignatedInitializers
5440b57cec5SDimitry Andric              != DefinitionData::IDI_Unknown);
5450b57cec5SDimitry Andric     return data().InheritedDesignatedInitializers ==
5460b57cec5SDimitry Andric         DefinitionData::IDI_Inherited;
5470b57cec5SDimitry Andric   }
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   llvm_unreachable("unexpected InheritedDesignatedInitializers value");
5500b57cec5SDimitry Andric }
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric void ObjCInterfaceDecl::getDesignatedInitializers(
5530b57cec5SDimitry Andric     llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
5540b57cec5SDimitry Andric   // Check for a complete definition and recover if not so.
5550b57cec5SDimitry Andric   if (!isThisDeclarationADefinition())
5560b57cec5SDimitry Andric     return;
5570b57cec5SDimitry Andric   if (data().ExternallyCompleted)
5580b57cec5SDimitry Andric     LoadExternalDefinition();
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric   const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
5610b57cec5SDimitry Andric   if (!IFace)
5620b57cec5SDimitry Andric     return;
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric   for (const auto *MD : IFace->instance_methods())
5650b57cec5SDimitry Andric     if (MD->isThisDeclarationADesignatedInitializer())
5660b57cec5SDimitry Andric       Methods.push_back(MD);
5670b57cec5SDimitry Andric   for (const auto *Ext : IFace->visible_extensions()) {
5680b57cec5SDimitry Andric     for (const auto *MD : Ext->instance_methods())
5690b57cec5SDimitry Andric       if (MD->isThisDeclarationADesignatedInitializer())
5700b57cec5SDimitry Andric         Methods.push_back(MD);
5710b57cec5SDimitry Andric   }
5720b57cec5SDimitry Andric }
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
5750b57cec5SDimitry Andric                                       const ObjCMethodDecl **InitMethod) const {
5760b57cec5SDimitry Andric   bool HasCompleteDef = isThisDeclarationADefinition();
5770b57cec5SDimitry Andric   // During deserialization the data record for the ObjCInterfaceDecl could
5780b57cec5SDimitry Andric   // be made invariant by reusing the canonical decl. Take this into account
5790b57cec5SDimitry Andric   // when checking for the complete definition.
5800b57cec5SDimitry Andric   if (!HasCompleteDef && getCanonicalDecl()->hasDefinition() &&
5810b57cec5SDimitry Andric       getCanonicalDecl()->getDefinition() == getDefinition())
5820b57cec5SDimitry Andric     HasCompleteDef = true;
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric   // Check for a complete definition and recover if not so.
5850b57cec5SDimitry Andric   if (!HasCompleteDef)
5860b57cec5SDimitry Andric     return false;
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   if (data().ExternallyCompleted)
5890b57cec5SDimitry Andric     LoadExternalDefinition();
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric   const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
5920b57cec5SDimitry Andric   if (!IFace)
5930b57cec5SDimitry Andric     return false;
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
5960b57cec5SDimitry Andric     if (MD->isThisDeclarationADesignatedInitializer()) {
5970b57cec5SDimitry Andric       if (InitMethod)
5980b57cec5SDimitry Andric         *InitMethod = MD;
5990b57cec5SDimitry Andric       return true;
6000b57cec5SDimitry Andric     }
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric   for (const auto *Ext : IFace->visible_extensions()) {
6030b57cec5SDimitry Andric     if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
6040b57cec5SDimitry Andric       if (MD->isThisDeclarationADesignatedInitializer()) {
6050b57cec5SDimitry Andric         if (InitMethod)
6060b57cec5SDimitry Andric           *InitMethod = MD;
6070b57cec5SDimitry Andric         return true;
6080b57cec5SDimitry Andric       }
6090b57cec5SDimitry Andric     }
6100b57cec5SDimitry Andric   }
6110b57cec5SDimitry Andric   return false;
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric void ObjCInterfaceDecl::allocateDefinitionData() {
6150b57cec5SDimitry Andric   assert(!hasDefinition() && "ObjC class already has a definition");
6160b57cec5SDimitry Andric   Data.setPointer(new (getASTContext()) DefinitionData());
6170b57cec5SDimitry Andric   Data.getPointer()->Definition = this;
6180b57cec5SDimitry Andric }
6190b57cec5SDimitry Andric 
6200b57cec5SDimitry Andric void ObjCInterfaceDecl::startDefinition() {
6210b57cec5SDimitry Andric   allocateDefinitionData();
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   // Update all of the declarations with a pointer to the definition.
6240b57cec5SDimitry Andric   for (auto *RD : redecls()) {
6250b57cec5SDimitry Andric     if (RD != this)
6260b57cec5SDimitry Andric       RD->Data = Data;
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric }
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
6310b57cec5SDimitry Andric                                               ObjCInterfaceDecl *&clsDeclared) {
6320b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
6330b57cec5SDimitry Andric   if (!hasDefinition())
6340b57cec5SDimitry Andric     return nullptr;
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric   if (data().ExternallyCompleted)
6370b57cec5SDimitry Andric     LoadExternalDefinition();
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   ObjCInterfaceDecl* ClassDecl = this;
6400b57cec5SDimitry Andric   while (ClassDecl != nullptr) {
6410b57cec5SDimitry Andric     if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
6420b57cec5SDimitry Andric       clsDeclared = ClassDecl;
6430b57cec5SDimitry Andric       return I;
6440b57cec5SDimitry Andric     }
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric     for (const auto *Ext : ClassDecl->visible_extensions()) {
6470b57cec5SDimitry Andric       if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
6480b57cec5SDimitry Andric         clsDeclared = ClassDecl;
6490b57cec5SDimitry Andric         return I;
6500b57cec5SDimitry Andric       }
6510b57cec5SDimitry Andric     }
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric     ClassDecl = ClassDecl->getSuperClass();
6540b57cec5SDimitry Andric   }
6550b57cec5SDimitry Andric   return nullptr;
6560b57cec5SDimitry Andric }
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
6590b57cec5SDimitry Andric /// class whose name is passed as argument. If it is not one of the super classes
6600b57cec5SDimitry Andric /// the it returns NULL.
6610b57cec5SDimitry Andric ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
6620b57cec5SDimitry Andric                                         const IdentifierInfo*ICName) {
6630b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
6640b57cec5SDimitry Andric   if (!hasDefinition())
6650b57cec5SDimitry Andric     return nullptr;
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   if (data().ExternallyCompleted)
6680b57cec5SDimitry Andric     LoadExternalDefinition();
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric   ObjCInterfaceDecl* ClassDecl = this;
6710b57cec5SDimitry Andric   while (ClassDecl != nullptr) {
6720b57cec5SDimitry Andric     if (ClassDecl->getIdentifier() == ICName)
6730b57cec5SDimitry Andric       return ClassDecl;
6740b57cec5SDimitry Andric     ClassDecl = ClassDecl->getSuperClass();
6750b57cec5SDimitry Andric   }
6760b57cec5SDimitry Andric   return nullptr;
6770b57cec5SDimitry Andric }
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric ObjCProtocolDecl *
6800b57cec5SDimitry Andric ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
6810b57cec5SDimitry Andric   for (auto *P : all_referenced_protocols())
6820b57cec5SDimitry Andric     if (P->lookupProtocolNamed(Name))
6830b57cec5SDimitry Andric       return P;
6840b57cec5SDimitry Andric   ObjCInterfaceDecl *SuperClass = getSuperClass();
6850b57cec5SDimitry Andric   return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
6860b57cec5SDimitry Andric }
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric /// lookupMethod - This method returns an instance/class method by looking in
6890b57cec5SDimitry Andric /// the class, its categories, and its super classes (using a linear search).
6900b57cec5SDimitry Andric /// When argument category "C" is specified, any implicit method found
6910b57cec5SDimitry Andric /// in this category is ignored.
6920b57cec5SDimitry Andric ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
6930b57cec5SDimitry Andric                                                 bool isInstance,
6940b57cec5SDimitry Andric                                                 bool shallowCategoryLookup,
6950b57cec5SDimitry Andric                                                 bool followSuper,
6960b57cec5SDimitry Andric                                                 const ObjCCategoryDecl *C) const
6970b57cec5SDimitry Andric {
6980b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
6990b57cec5SDimitry Andric   if (!hasDefinition())
7000b57cec5SDimitry Andric     return nullptr;
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric   const ObjCInterfaceDecl* ClassDecl = this;
7030b57cec5SDimitry Andric   ObjCMethodDecl *MethodDecl = nullptr;
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric   if (data().ExternallyCompleted)
7060b57cec5SDimitry Andric     LoadExternalDefinition();
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric   while (ClassDecl) {
7090b57cec5SDimitry Andric     // 1. Look through primary class.
7100b57cec5SDimitry Andric     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
7110b57cec5SDimitry Andric       return MethodDecl;
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric     // 2. Didn't find one yet - now look through categories.
7140b57cec5SDimitry Andric     for (const auto *Cat : ClassDecl->visible_categories())
7150b57cec5SDimitry Andric       if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
7160b57cec5SDimitry Andric         if (C != Cat || !MethodDecl->isImplicit())
7170b57cec5SDimitry Andric           return MethodDecl;
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric     // 3. Didn't find one yet - look through primary class's protocols.
7200b57cec5SDimitry Andric     for (const auto *I : ClassDecl->protocols())
7210b57cec5SDimitry Andric       if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
7220b57cec5SDimitry Andric         return MethodDecl;
7230b57cec5SDimitry Andric 
7240b57cec5SDimitry Andric     // 4. Didn't find one yet - now look through categories' protocols
7250b57cec5SDimitry Andric     if (!shallowCategoryLookup)
7260b57cec5SDimitry Andric       for (const auto *Cat : ClassDecl->visible_categories()) {
7270b57cec5SDimitry Andric         // Didn't find one yet - look through protocols.
7280b57cec5SDimitry Andric         const ObjCList<ObjCProtocolDecl> &Protocols =
7290b57cec5SDimitry Andric           Cat->getReferencedProtocols();
7300b57cec5SDimitry Andric         for (auto *Protocol : Protocols)
7310b57cec5SDimitry Andric           if ((MethodDecl = Protocol->lookupMethod(Sel, isInstance)))
7320b57cec5SDimitry Andric             if (C != Cat || !MethodDecl->isImplicit())
7330b57cec5SDimitry Andric               return MethodDecl;
7340b57cec5SDimitry Andric       }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric     if (!followSuper)
7380b57cec5SDimitry Andric       return nullptr;
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric     // 5. Get to the super class (if any).
7410b57cec5SDimitry Andric     ClassDecl = ClassDecl->getSuperClass();
7420b57cec5SDimitry Andric   }
7430b57cec5SDimitry Andric   return nullptr;
7440b57cec5SDimitry Andric }
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric // Will search "local" class/category implementations for a method decl.
7470b57cec5SDimitry Andric // If failed, then we search in class's root for an instance method.
7480b57cec5SDimitry Andric // Returns 0 if no method is found.
7490b57cec5SDimitry Andric ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
7500b57cec5SDimitry Andric                                    const Selector &Sel,
7510b57cec5SDimitry Andric                                    bool Instance) const {
7520b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
7530b57cec5SDimitry Andric   if (!hasDefinition())
7540b57cec5SDimitry Andric     return nullptr;
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   if (data().ExternallyCompleted)
7570b57cec5SDimitry Andric     LoadExternalDefinition();
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   ObjCMethodDecl *Method = nullptr;
7600b57cec5SDimitry Andric   if (ObjCImplementationDecl *ImpDecl = getImplementation())
7610b57cec5SDimitry Andric     Method = Instance ? ImpDecl->getInstanceMethod(Sel)
7620b57cec5SDimitry Andric                       : ImpDecl->getClassMethod(Sel);
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric   // Look through local category implementations associated with the class.
7650b57cec5SDimitry Andric   if (!Method)
7660b57cec5SDimitry Andric     Method = getCategoryMethod(Sel, Instance);
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric   // Before we give up, check if the selector is an instance method.
7690b57cec5SDimitry Andric   // But only in the root. This matches gcc's behavior and what the
7700b57cec5SDimitry Andric   // runtime expects.
7710b57cec5SDimitry Andric   if (!Instance && !Method && !getSuperClass()) {
7720b57cec5SDimitry Andric     Method = lookupInstanceMethod(Sel);
7730b57cec5SDimitry Andric     // Look through local category implementations associated
7740b57cec5SDimitry Andric     // with the root class.
7750b57cec5SDimitry Andric     if (!Method)
7760b57cec5SDimitry Andric       Method = lookupPrivateMethod(Sel, true);
7770b57cec5SDimitry Andric   }
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric   if (!Method && getSuperClass())
7800b57cec5SDimitry Andric     return getSuperClass()->lookupPrivateMethod(Sel, Instance);
7810b57cec5SDimitry Andric   return Method;
7820b57cec5SDimitry Andric }
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7850b57cec5SDimitry Andric // ObjCMethodDecl
7860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7870b57cec5SDimitry Andric 
788480093f4SDimitry Andric ObjCMethodDecl::ObjCMethodDecl(
789480093f4SDimitry Andric     SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo,
790480093f4SDimitry Andric     QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl,
791480093f4SDimitry Andric     bool isInstance, bool isVariadic, bool isPropertyAccessor,
792480093f4SDimitry Andric     bool isSynthesizedAccessorStub, bool isImplicitlyDeclared, bool isDefined,
793480093f4SDimitry Andric     ImplementationControl impControl, bool HasRelatedResultType)
7940b57cec5SDimitry Andric     : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
7950b57cec5SDimitry Andric       DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),
7960b57cec5SDimitry Andric       DeclEndLoc(endLoc) {
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric   // Initialized the bits stored in DeclContext.
7990b57cec5SDimitry Andric   ObjCMethodDeclBits.Family =
8000b57cec5SDimitry Andric       static_cast<ObjCMethodFamily>(InvalidObjCMethodFamily);
8010b57cec5SDimitry Andric   setInstanceMethod(isInstance);
8020b57cec5SDimitry Andric   setVariadic(isVariadic);
8030b57cec5SDimitry Andric   setPropertyAccessor(isPropertyAccessor);
804480093f4SDimitry Andric   setSynthesizedAccessorStub(isSynthesizedAccessorStub);
8050b57cec5SDimitry Andric   setDefined(isDefined);
8060b57cec5SDimitry Andric   setIsRedeclaration(false);
8070b57cec5SDimitry Andric   setHasRedeclaration(false);
8080b57cec5SDimitry Andric   setDeclImplementation(impControl);
8090b57cec5SDimitry Andric   setObjCDeclQualifier(OBJC_TQ_None);
8100b57cec5SDimitry Andric   setRelatedResultType(HasRelatedResultType);
8110b57cec5SDimitry Andric   setSelLocsKind(SelLoc_StandardNoSpace);
8120b57cec5SDimitry Andric   setOverriding(false);
8130b57cec5SDimitry Andric   setHasSkippedBody(false);
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric   setImplicit(isImplicitlyDeclared);
8160b57cec5SDimitry Andric }
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric ObjCMethodDecl *ObjCMethodDecl::Create(
8190b57cec5SDimitry Andric     ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
8200b57cec5SDimitry Andric     Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
8210b57cec5SDimitry Andric     DeclContext *contextDecl, bool isInstance, bool isVariadic,
822480093f4SDimitry Andric     bool isPropertyAccessor, bool isSynthesizedAccessorStub,
823480093f4SDimitry Andric     bool isImplicitlyDeclared, bool isDefined, ImplementationControl impControl,
824480093f4SDimitry Andric     bool HasRelatedResultType) {
8250b57cec5SDimitry Andric   return new (C, contextDecl) ObjCMethodDecl(
8260b57cec5SDimitry Andric       beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
827480093f4SDimitry Andric       isVariadic, isPropertyAccessor, isSynthesizedAccessorStub,
828480093f4SDimitry Andric       isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);
8290b57cec5SDimitry Andric }
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
8320b57cec5SDimitry Andric   return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
8330b57cec5SDimitry Andric                                     Selector(), QualType(), nullptr, nullptr);
8340b57cec5SDimitry Andric }
8350b57cec5SDimitry Andric 
836480093f4SDimitry Andric bool ObjCMethodDecl::isDirectMethod() const {
837fe6060f1SDimitry Andric   return hasAttr<ObjCDirectAttr>() &&
838fe6060f1SDimitry Andric          !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
839480093f4SDimitry Andric }
840480093f4SDimitry Andric 
8410b57cec5SDimitry Andric bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
8420b57cec5SDimitry Andric   return getMethodFamily() == OMF_init &&
8430b57cec5SDimitry Andric       hasAttr<ObjCDesignatedInitializerAttr>();
8440b57cec5SDimitry Andric }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric bool ObjCMethodDecl::definedInNSObject(const ASTContext &Ctx) const {
8470b57cec5SDimitry Andric   if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext()))
8480b57cec5SDimitry Andric     return PD->getIdentifier() == Ctx.getNSObjectName();
8490b57cec5SDimitry Andric   if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext()))
8500b57cec5SDimitry Andric     return ID->getIdentifier() == Ctx.getNSObjectName();
8510b57cec5SDimitry Andric   return false;
8520b57cec5SDimitry Andric }
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
8550b57cec5SDimitry Andric     const ObjCMethodDecl **InitMethod) const {
8560b57cec5SDimitry Andric   if (getMethodFamily() != OMF_init)
8570b57cec5SDimitry Andric     return false;
8580b57cec5SDimitry Andric   const DeclContext *DC = getDeclContext();
8590b57cec5SDimitry Andric   if (isa<ObjCProtocolDecl>(DC))
8600b57cec5SDimitry Andric     return false;
8610b57cec5SDimitry Andric   if (const ObjCInterfaceDecl *ID = getClassInterface())
8620b57cec5SDimitry Andric     return ID->isDesignatedInitializer(getSelector(), InitMethod);
8630b57cec5SDimitry Andric   return false;
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric 
866349cc55cSDimitry Andric bool ObjCMethodDecl::hasParamDestroyedInCallee() const {
867349cc55cSDimitry Andric   for (auto param : parameters()) {
868349cc55cSDimitry Andric     if (param->isDestroyedInCallee())
869349cc55cSDimitry Andric       return true;
870349cc55cSDimitry Andric   }
871349cc55cSDimitry Andric   return false;
872349cc55cSDimitry Andric }
873349cc55cSDimitry Andric 
8740b57cec5SDimitry Andric Stmt *ObjCMethodDecl::getBody() const {
8750b57cec5SDimitry Andric   return Body.get(getASTContext().getExternalSource());
8760b57cec5SDimitry Andric }
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
8790b57cec5SDimitry Andric   assert(PrevMethod);
8800b57cec5SDimitry Andric   getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
8810b57cec5SDimitry Andric   setIsRedeclaration(true);
8820b57cec5SDimitry Andric   PrevMethod->setHasRedeclaration(true);
8830b57cec5SDimitry Andric }
8840b57cec5SDimitry Andric 
8850b57cec5SDimitry Andric void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
8860b57cec5SDimitry Andric                                          ArrayRef<ParmVarDecl*> Params,
8870b57cec5SDimitry Andric                                          ArrayRef<SourceLocation> SelLocs) {
8880b57cec5SDimitry Andric   ParamsAndSelLocs = nullptr;
8890b57cec5SDimitry Andric   NumParams = Params.size();
8900b57cec5SDimitry Andric   if (Params.empty() && SelLocs.empty())
8910b57cec5SDimitry Andric     return;
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation),
8940b57cec5SDimitry Andric                 "Alignment not sufficient for SourceLocation");
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric   unsigned Size = sizeof(ParmVarDecl *) * NumParams +
8970b57cec5SDimitry Andric                   sizeof(SourceLocation) * SelLocs.size();
8980b57cec5SDimitry Andric   ParamsAndSelLocs = C.Allocate(Size);
8990b57cec5SDimitry Andric   std::copy(Params.begin(), Params.end(), getParams());
9000b57cec5SDimitry Andric   std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
9010b57cec5SDimitry Andric }
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric void ObjCMethodDecl::getSelectorLocs(
9040b57cec5SDimitry Andric                                SmallVectorImpl<SourceLocation> &SelLocs) const {
9050b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
9060b57cec5SDimitry Andric     SelLocs.push_back(getSelectorLoc(i));
9070b57cec5SDimitry Andric }
9080b57cec5SDimitry Andric 
9090b57cec5SDimitry Andric void ObjCMethodDecl::setMethodParams(ASTContext &C,
9100b57cec5SDimitry Andric                                      ArrayRef<ParmVarDecl*> Params,
9110b57cec5SDimitry Andric                                      ArrayRef<SourceLocation> SelLocs) {
9120b57cec5SDimitry Andric   assert((!SelLocs.empty() || isImplicit()) &&
9130b57cec5SDimitry Andric          "No selector locs for non-implicit method");
9140b57cec5SDimitry Andric   if (isImplicit())
9150b57cec5SDimitry Andric     return setParamsAndSelLocs(C, Params, llvm::None);
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric   setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params,
9180b57cec5SDimitry Andric                                         DeclEndLoc));
9190b57cec5SDimitry Andric   if (getSelLocsKind() != SelLoc_NonStandard)
9200b57cec5SDimitry Andric     return setParamsAndSelLocs(C, Params, llvm::None);
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric   setParamsAndSelLocs(C, Params, SelLocs);
9230b57cec5SDimitry Andric }
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric /// A definition will return its interface declaration.
9260b57cec5SDimitry Andric /// An interface declaration will return its definition.
9270b57cec5SDimitry Andric /// Otherwise it will return itself.
9280b57cec5SDimitry Andric ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
9290b57cec5SDimitry Andric   ASTContext &Ctx = getASTContext();
9300b57cec5SDimitry Andric   ObjCMethodDecl *Redecl = nullptr;
9310b57cec5SDimitry Andric   if (hasRedeclaration())
9320b57cec5SDimitry Andric     Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
9330b57cec5SDimitry Andric   if (Redecl)
9340b57cec5SDimitry Andric     return Redecl;
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric   auto *CtxD = cast<Decl>(getDeclContext());
9370b57cec5SDimitry Andric 
9380b57cec5SDimitry Andric   if (!CtxD->isInvalidDecl()) {
9390b57cec5SDimitry Andric     if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
9400b57cec5SDimitry Andric       if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
9410b57cec5SDimitry Andric         if (!ImplD->isInvalidDecl())
9420b57cec5SDimitry Andric           Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric     } else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
9450b57cec5SDimitry Andric       if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
9460b57cec5SDimitry Andric         if (!ImplD->isInvalidDecl())
9470b57cec5SDimitry Andric           Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric     } else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
9500b57cec5SDimitry Andric       if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
9510b57cec5SDimitry Andric         if (!IFD->isInvalidDecl())
9520b57cec5SDimitry Andric           Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric     } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
9550b57cec5SDimitry Andric       if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
9560b57cec5SDimitry Andric         if (!CatD->isInvalidDecl())
9570b57cec5SDimitry Andric           Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
9580b57cec5SDimitry Andric     }
9590b57cec5SDimitry Andric   }
9600b57cec5SDimitry Andric 
9610b57cec5SDimitry Andric   // Ensure that the discovered method redeclaration has a valid declaration
9620b57cec5SDimitry Andric   // context. Used to prevent infinite loops when iterating redeclarations in
9630b57cec5SDimitry Andric   // a partially invalid AST.
9640b57cec5SDimitry Andric   if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl())
9650b57cec5SDimitry Andric     Redecl = nullptr;
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric   if (!Redecl && isRedeclaration()) {
9680b57cec5SDimitry Andric     // This is the last redeclaration, go back to the first method.
9690b57cec5SDimitry Andric     return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
970e8d8bef9SDimitry Andric                                                     isInstanceMethod(),
971e8d8bef9SDimitry Andric                                                     /*AllowHidden=*/true);
9720b57cec5SDimitry Andric   }
9730b57cec5SDimitry Andric 
9740b57cec5SDimitry Andric   return Redecl ? Redecl : this;
9750b57cec5SDimitry Andric }
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
9780b57cec5SDimitry Andric   auto *CtxD = cast<Decl>(getDeclContext());
979480093f4SDimitry Andric   const auto &Sel = getSelector();
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric   if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
982480093f4SDimitry Andric     if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) {
983480093f4SDimitry Andric       // When the container is the ObjCImplementationDecl (the primary
984480093f4SDimitry Andric       // @implementation), then the canonical Decl is either in
985480093f4SDimitry Andric       // the class Interface, or in any of its extension.
986480093f4SDimitry Andric       //
987480093f4SDimitry Andric       // So when we don't find it in the ObjCInterfaceDecl,
988480093f4SDimitry Andric       // sift through extensions too.
989480093f4SDimitry Andric       if (ObjCMethodDecl *MD = IFD->getMethod(Sel, isInstanceMethod()))
9900b57cec5SDimitry Andric         return MD;
991480093f4SDimitry Andric       for (auto *Ext : IFD->known_extensions())
992480093f4SDimitry Andric         if (ObjCMethodDecl *MD = Ext->getMethod(Sel, isInstanceMethod()))
993480093f4SDimitry Andric           return MD;
994480093f4SDimitry Andric     }
9950b57cec5SDimitry Andric   } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
9960b57cec5SDimitry Andric     if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
997480093f4SDimitry Andric       if (ObjCMethodDecl *MD = CatD->getMethod(Sel, isInstanceMethod()))
9980b57cec5SDimitry Andric         return MD;
9990b57cec5SDimitry Andric   }
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric   if (isRedeclaration()) {
10020b57cec5SDimitry Andric     // It is possible that we have not done deserializing the ObjCMethod yet.
10030b57cec5SDimitry Andric     ObjCMethodDecl *MD =
1004e8d8bef9SDimitry Andric         cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
1005e8d8bef9SDimitry Andric                                                  /*AllowHidden=*/true);
10060b57cec5SDimitry Andric     return MD ? MD : this;
10070b57cec5SDimitry Andric   }
10080b57cec5SDimitry Andric 
10090b57cec5SDimitry Andric   return this;
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric SourceLocation ObjCMethodDecl::getEndLoc() const {
10130b57cec5SDimitry Andric   if (Stmt *Body = getBody())
10140b57cec5SDimitry Andric     return Body->getEndLoc();
10150b57cec5SDimitry Andric   return DeclEndLoc;
10160b57cec5SDimitry Andric }
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
10190b57cec5SDimitry Andric   auto family = static_cast<ObjCMethodFamily>(ObjCMethodDeclBits.Family);
10200b57cec5SDimitry Andric   if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
10210b57cec5SDimitry Andric     return family;
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric   // Check for an explicit attribute.
10240b57cec5SDimitry Andric   if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
10250b57cec5SDimitry Andric     // The unfortunate necessity of mapping between enums here is due
10260b57cec5SDimitry Andric     // to the attributes framework.
10270b57cec5SDimitry Andric     switch (attr->getFamily()) {
10280b57cec5SDimitry Andric     case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
10290b57cec5SDimitry Andric     case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
10300b57cec5SDimitry Andric     case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
10310b57cec5SDimitry Andric     case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
10320b57cec5SDimitry Andric     case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
10330b57cec5SDimitry Andric     case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
10340b57cec5SDimitry Andric     }
10350b57cec5SDimitry Andric     ObjCMethodDeclBits.Family = family;
10360b57cec5SDimitry Andric     return family;
10370b57cec5SDimitry Andric   }
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric   family = getSelector().getMethodFamily();
10400b57cec5SDimitry Andric   switch (family) {
10410b57cec5SDimitry Andric   case OMF_None: break;
10420b57cec5SDimitry Andric 
10430b57cec5SDimitry Andric   // init only has a conventional meaning for an instance method, and
10440b57cec5SDimitry Andric   // it has to return an object.
10450b57cec5SDimitry Andric   case OMF_init:
10460b57cec5SDimitry Andric     if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
10470b57cec5SDimitry Andric       family = OMF_None;
10480b57cec5SDimitry Andric     break;
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   // alloc/copy/new have a conventional meaning for both class and
10510b57cec5SDimitry Andric   // instance methods, but they require an object return.
10520b57cec5SDimitry Andric   case OMF_alloc:
10530b57cec5SDimitry Andric   case OMF_copy:
10540b57cec5SDimitry Andric   case OMF_mutableCopy:
10550b57cec5SDimitry Andric   case OMF_new:
10560b57cec5SDimitry Andric     if (!getReturnType()->isObjCObjectPointerType())
10570b57cec5SDimitry Andric       family = OMF_None;
10580b57cec5SDimitry Andric     break;
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric   // These selectors have a conventional meaning only for instance methods.
10610b57cec5SDimitry Andric   case OMF_dealloc:
10620b57cec5SDimitry Andric   case OMF_finalize:
10630b57cec5SDimitry Andric   case OMF_retain:
10640b57cec5SDimitry Andric   case OMF_release:
10650b57cec5SDimitry Andric   case OMF_autorelease:
10660b57cec5SDimitry Andric   case OMF_retainCount:
10670b57cec5SDimitry Andric   case OMF_self:
10680b57cec5SDimitry Andric     if (!isInstanceMethod())
10690b57cec5SDimitry Andric       family = OMF_None;
10700b57cec5SDimitry Andric     break;
10710b57cec5SDimitry Andric 
10720b57cec5SDimitry Andric   case OMF_initialize:
10730b57cec5SDimitry Andric     if (isInstanceMethod() || !getReturnType()->isVoidType())
10740b57cec5SDimitry Andric       family = OMF_None;
10750b57cec5SDimitry Andric     break;
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric   case OMF_performSelector:
10780b57cec5SDimitry Andric     if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
10790b57cec5SDimitry Andric       family = OMF_None;
10800b57cec5SDimitry Andric     else {
10810b57cec5SDimitry Andric       unsigned noParams = param_size();
10820b57cec5SDimitry Andric       if (noParams < 1 || noParams > 3)
10830b57cec5SDimitry Andric         family = OMF_None;
10840b57cec5SDimitry Andric       else {
10850b57cec5SDimitry Andric         ObjCMethodDecl::param_type_iterator it = param_type_begin();
10860b57cec5SDimitry Andric         QualType ArgT = (*it);
10870b57cec5SDimitry Andric         if (!ArgT->isObjCSelType()) {
10880b57cec5SDimitry Andric           family = OMF_None;
10890b57cec5SDimitry Andric           break;
10900b57cec5SDimitry Andric         }
10910b57cec5SDimitry Andric         while (--noParams) {
10920b57cec5SDimitry Andric           it++;
10930b57cec5SDimitry Andric           ArgT = (*it);
10940b57cec5SDimitry Andric           if (!ArgT->isObjCIdType()) {
10950b57cec5SDimitry Andric             family = OMF_None;
10960b57cec5SDimitry Andric             break;
10970b57cec5SDimitry Andric           }
10980b57cec5SDimitry Andric         }
10990b57cec5SDimitry Andric       }
11000b57cec5SDimitry Andric     }
11010b57cec5SDimitry Andric     break;
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric   }
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   // Cache the result.
11060b57cec5SDimitry Andric   ObjCMethodDeclBits.Family = family;
11070b57cec5SDimitry Andric   return family;
11080b57cec5SDimitry Andric }
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric QualType ObjCMethodDecl::getSelfType(ASTContext &Context,
11110b57cec5SDimitry Andric                                      const ObjCInterfaceDecl *OID,
11120b57cec5SDimitry Andric                                      bool &selfIsPseudoStrong,
1113480093f4SDimitry Andric                                      bool &selfIsConsumed) const {
11140b57cec5SDimitry Andric   QualType selfTy;
11150b57cec5SDimitry Andric   selfIsPseudoStrong = false;
11160b57cec5SDimitry Andric   selfIsConsumed = false;
11170b57cec5SDimitry Andric   if (isInstanceMethod()) {
11180b57cec5SDimitry Andric     // There may be no interface context due to error in declaration
11190b57cec5SDimitry Andric     // of the interface (which has been reported). Recover gracefully.
11200b57cec5SDimitry Andric     if (OID) {
11210b57cec5SDimitry Andric       selfTy = Context.getObjCInterfaceType(OID);
11220b57cec5SDimitry Andric       selfTy = Context.getObjCObjectPointerType(selfTy);
11230b57cec5SDimitry Andric     } else {
11240b57cec5SDimitry Andric       selfTy = Context.getObjCIdType();
11250b57cec5SDimitry Andric     }
11260b57cec5SDimitry Andric   } else // we have a factory method.
11270b57cec5SDimitry Andric     selfTy = Context.getObjCClassType();
11280b57cec5SDimitry Andric 
11290b57cec5SDimitry Andric   if (Context.getLangOpts().ObjCAutoRefCount) {
11300b57cec5SDimitry Andric     if (isInstanceMethod()) {
11310b57cec5SDimitry Andric       selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
11320b57cec5SDimitry Andric 
11330b57cec5SDimitry Andric       // 'self' is always __strong.  It's actually pseudo-strong except
11340b57cec5SDimitry Andric       // in init methods (or methods labeled ns_consumes_self), though.
11350b57cec5SDimitry Andric       Qualifiers qs;
11360b57cec5SDimitry Andric       qs.setObjCLifetime(Qualifiers::OCL_Strong);
11370b57cec5SDimitry Andric       selfTy = Context.getQualifiedType(selfTy, qs);
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric       // In addition, 'self' is const unless this is an init method.
11400b57cec5SDimitry Andric       if (getMethodFamily() != OMF_init && !selfIsConsumed) {
11410b57cec5SDimitry Andric         selfTy = selfTy.withConst();
11420b57cec5SDimitry Andric         selfIsPseudoStrong = true;
11430b57cec5SDimitry Andric       }
11440b57cec5SDimitry Andric     }
11450b57cec5SDimitry Andric     else {
11460b57cec5SDimitry Andric       assert(isClassMethod());
11470b57cec5SDimitry Andric       // 'self' is always const in class methods.
11480b57cec5SDimitry Andric       selfTy = selfTy.withConst();
11490b57cec5SDimitry Andric       selfIsPseudoStrong = true;
11500b57cec5SDimitry Andric     }
11510b57cec5SDimitry Andric   }
11520b57cec5SDimitry Andric   return selfTy;
11530b57cec5SDimitry Andric }
11540b57cec5SDimitry Andric 
11550b57cec5SDimitry Andric void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
11560b57cec5SDimitry Andric                                           const ObjCInterfaceDecl *OID) {
11570b57cec5SDimitry Andric   bool selfIsPseudoStrong, selfIsConsumed;
11580b57cec5SDimitry Andric   QualType selfTy =
11590b57cec5SDimitry Andric     getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);
11600b57cec5SDimitry Andric   auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),
11610b57cec5SDimitry Andric                                          &Context.Idents.get("self"), selfTy,
11620b57cec5SDimitry Andric                                          ImplicitParamDecl::ObjCSelf);
11630b57cec5SDimitry Andric   setSelfDecl(Self);
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   if (selfIsConsumed)
11660b57cec5SDimitry Andric     Self->addAttr(NSConsumedAttr::CreateImplicit(Context));
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric   if (selfIsPseudoStrong)
11690b57cec5SDimitry Andric     Self->setARCPseudoStrong(true);
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric   setCmdDecl(ImplicitParamDecl::Create(
11720b57cec5SDimitry Andric       Context, this, SourceLocation(), &Context.Idents.get("_cmd"),
11730b57cec5SDimitry Andric       Context.getObjCSelType(), ImplicitParamDecl::ObjCCmd));
11740b57cec5SDimitry Andric }
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
11770b57cec5SDimitry Andric   if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
11780b57cec5SDimitry Andric     return ID;
11790b57cec5SDimitry Andric   if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
11800b57cec5SDimitry Andric     return CD->getClassInterface();
11810b57cec5SDimitry Andric   if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
11820b57cec5SDimitry Andric     return IMD->getClassInterface();
11830b57cec5SDimitry Andric   if (isa<ObjCProtocolDecl>(getDeclContext()))
11840b57cec5SDimitry Andric     return nullptr;
11850b57cec5SDimitry Andric   llvm_unreachable("unknown method context");
11860b57cec5SDimitry Andric }
11870b57cec5SDimitry Andric 
1188e8d8bef9SDimitry Andric ObjCCategoryDecl *ObjCMethodDecl::getCategory() {
1189e8d8bef9SDimitry Andric   if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
1190e8d8bef9SDimitry Andric     return CD;
1191e8d8bef9SDimitry Andric   if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
1192e8d8bef9SDimitry Andric     return IMD->getCategoryDecl();
1193e8d8bef9SDimitry Andric   return nullptr;
1194e8d8bef9SDimitry Andric }
1195e8d8bef9SDimitry Andric 
11960b57cec5SDimitry Andric SourceRange ObjCMethodDecl::getReturnTypeSourceRange() const {
11970b57cec5SDimitry Andric   const auto *TSI = getReturnTypeSourceInfo();
11980b57cec5SDimitry Andric   if (TSI)
11990b57cec5SDimitry Andric     return TSI->getTypeLoc().getSourceRange();
12000b57cec5SDimitry Andric   return SourceRange();
12010b57cec5SDimitry Andric }
12020b57cec5SDimitry Andric 
12030b57cec5SDimitry Andric QualType ObjCMethodDecl::getSendResultType() const {
12040b57cec5SDimitry Andric   ASTContext &Ctx = getASTContext();
12050b57cec5SDimitry Andric   return getReturnType().getNonLValueExprType(Ctx)
12060b57cec5SDimitry Andric            .substObjCTypeArgs(Ctx, {}, ObjCSubstitutionContext::Result);
12070b57cec5SDimitry Andric }
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric QualType ObjCMethodDecl::getSendResultType(QualType receiverType) const {
12100b57cec5SDimitry Andric   // FIXME: Handle related result types here.
12110b57cec5SDimitry Andric 
12120b57cec5SDimitry Andric   return getReturnType().getNonLValueExprType(getASTContext())
12130b57cec5SDimitry Andric            .substObjCMemberType(receiverType, getDeclContext(),
12140b57cec5SDimitry Andric                                 ObjCSubstitutionContext::Result);
12150b57cec5SDimitry Andric }
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
12180b57cec5SDimitry Andric                                             const ObjCMethodDecl *Method,
12190b57cec5SDimitry Andric                                SmallVectorImpl<const ObjCMethodDecl *> &Methods,
12200b57cec5SDimitry Andric                                             bool MovedToSuper) {
12210b57cec5SDimitry Andric   if (!Container)
12220b57cec5SDimitry Andric     return;
12230b57cec5SDimitry Andric 
12240b57cec5SDimitry Andric   // In categories look for overridden methods from protocols. A method from
12250b57cec5SDimitry Andric   // category is not "overridden" since it is considered as the "same" method
12260b57cec5SDimitry Andric   // (same USR) as the one from the interface.
12270b57cec5SDimitry Andric   if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
12280b57cec5SDimitry Andric     // Check whether we have a matching method at this category but only if we
12290b57cec5SDimitry Andric     // are at the super class level.
12300b57cec5SDimitry Andric     if (MovedToSuper)
12310b57cec5SDimitry Andric       if (ObjCMethodDecl *
12320b57cec5SDimitry Andric             Overridden = Container->getMethod(Method->getSelector(),
12330b57cec5SDimitry Andric                                               Method->isInstanceMethod(),
12340b57cec5SDimitry Andric                                               /*AllowHidden=*/true))
12350b57cec5SDimitry Andric         if (Method != Overridden) {
12360b57cec5SDimitry Andric           // We found an override at this category; there is no need to look
12370b57cec5SDimitry Andric           // into its protocols.
12380b57cec5SDimitry Andric           Methods.push_back(Overridden);
12390b57cec5SDimitry Andric           return;
12400b57cec5SDimitry Andric         }
12410b57cec5SDimitry Andric 
12420b57cec5SDimitry Andric     for (const auto *P : Category->protocols())
12430b57cec5SDimitry Andric       CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
12440b57cec5SDimitry Andric     return;
12450b57cec5SDimitry Andric   }
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric   // Check whether we have a matching method at this level.
12480b57cec5SDimitry Andric   if (const ObjCMethodDecl *
12490b57cec5SDimitry Andric         Overridden = Container->getMethod(Method->getSelector(),
12500b57cec5SDimitry Andric                                           Method->isInstanceMethod(),
12510b57cec5SDimitry Andric                                           /*AllowHidden=*/true))
12520b57cec5SDimitry Andric     if (Method != Overridden) {
12530b57cec5SDimitry Andric       // We found an override at this level; there is no need to look
12540b57cec5SDimitry Andric       // into other protocols or categories.
12550b57cec5SDimitry Andric       Methods.push_back(Overridden);
12560b57cec5SDimitry Andric       return;
12570b57cec5SDimitry Andric     }
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric   if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
12600b57cec5SDimitry Andric     for (const auto *P : Protocol->protocols())
12610b57cec5SDimitry Andric       CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
12620b57cec5SDimitry Andric   }
12630b57cec5SDimitry Andric 
12640b57cec5SDimitry Andric   if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
12650b57cec5SDimitry Andric     for (const auto *P : Interface->protocols())
12660b57cec5SDimitry Andric       CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
12670b57cec5SDimitry Andric 
12680b57cec5SDimitry Andric     for (const auto *Cat : Interface->known_categories())
12690b57cec5SDimitry Andric       CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric     if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
12720b57cec5SDimitry Andric       return CollectOverriddenMethodsRecurse(Super, Method, Methods,
12730b57cec5SDimitry Andric                                              /*MovedToSuper=*/true);
12740b57cec5SDimitry Andric   }
12750b57cec5SDimitry Andric }
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
12780b57cec5SDimitry Andric                                             const ObjCMethodDecl *Method,
12790b57cec5SDimitry Andric                              SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
12800b57cec5SDimitry Andric   CollectOverriddenMethodsRecurse(Container, Method, Methods,
12810b57cec5SDimitry Andric                                   /*MovedToSuper=*/false);
12820b57cec5SDimitry Andric }
12830b57cec5SDimitry Andric 
12840b57cec5SDimitry Andric static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
12850b57cec5SDimitry Andric                           SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
12860b57cec5SDimitry Andric   assert(Method->isOverriding());
12870b57cec5SDimitry Andric 
12880b57cec5SDimitry Andric   if (const auto *ProtD =
12890b57cec5SDimitry Andric           dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
12900b57cec5SDimitry Andric     CollectOverriddenMethods(ProtD, Method, overridden);
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric   } else if (const auto *IMD =
12930b57cec5SDimitry Andric                  dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
12940b57cec5SDimitry Andric     const ObjCInterfaceDecl *ID = IMD->getClassInterface();
12950b57cec5SDimitry Andric     if (!ID)
12960b57cec5SDimitry Andric       return;
12970b57cec5SDimitry Andric     // Start searching for overridden methods using the method from the
12980b57cec5SDimitry Andric     // interface as starting point.
12990b57cec5SDimitry Andric     if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
13000b57cec5SDimitry Andric                                                     Method->isInstanceMethod(),
13010b57cec5SDimitry Andric                                                     /*AllowHidden=*/true))
13020b57cec5SDimitry Andric       Method = IFaceMeth;
13030b57cec5SDimitry Andric     CollectOverriddenMethods(ID, Method, overridden);
13040b57cec5SDimitry Andric 
13050b57cec5SDimitry Andric   } else if (const auto *CatD =
13060b57cec5SDimitry Andric                  dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
13070b57cec5SDimitry Andric     const ObjCInterfaceDecl *ID = CatD->getClassInterface();
13080b57cec5SDimitry Andric     if (!ID)
13090b57cec5SDimitry Andric       return;
13100b57cec5SDimitry Andric     // Start searching for overridden methods using the method from the
13110b57cec5SDimitry Andric     // interface as starting point.
13120b57cec5SDimitry Andric     if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
13130b57cec5SDimitry Andric                                                      Method->isInstanceMethod(),
13140b57cec5SDimitry Andric                                                      /*AllowHidden=*/true))
13150b57cec5SDimitry Andric       Method = IFaceMeth;
13160b57cec5SDimitry Andric     CollectOverriddenMethods(ID, Method, overridden);
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric   } else {
13190b57cec5SDimitry Andric     CollectOverriddenMethods(
13200b57cec5SDimitry Andric                   dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
13210b57cec5SDimitry Andric                   Method, overridden);
13220b57cec5SDimitry Andric   }
13230b57cec5SDimitry Andric }
13240b57cec5SDimitry Andric 
13250b57cec5SDimitry Andric void ObjCMethodDecl::getOverriddenMethods(
13260b57cec5SDimitry Andric                     SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
13270b57cec5SDimitry Andric   const ObjCMethodDecl *Method = this;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   if (Method->isRedeclaration()) {
1330e8d8bef9SDimitry Andric     Method = cast<ObjCContainerDecl>(Method->getDeclContext())
1331e8d8bef9SDimitry Andric                  ->getMethod(Method->getSelector(), Method->isInstanceMethod(),
1332e8d8bef9SDimitry Andric                              /*AllowHidden=*/true);
13330b57cec5SDimitry Andric   }
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric   if (Method->isOverriding()) {
13360b57cec5SDimitry Andric     collectOverriddenMethodsSlow(Method, Overridden);
13370b57cec5SDimitry Andric     assert(!Overridden.empty() &&
13380b57cec5SDimitry Andric            "ObjCMethodDecl's overriding bit is not as expected");
13390b57cec5SDimitry Andric   }
13400b57cec5SDimitry Andric }
13410b57cec5SDimitry Andric 
13420b57cec5SDimitry Andric const ObjCPropertyDecl *
13430b57cec5SDimitry Andric ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
13440b57cec5SDimitry Andric   Selector Sel = getSelector();
13450b57cec5SDimitry Andric   unsigned NumArgs = Sel.getNumArgs();
13460b57cec5SDimitry Andric   if (NumArgs > 1)
13470b57cec5SDimitry Andric     return nullptr;
13480b57cec5SDimitry Andric 
13490b57cec5SDimitry Andric   if (isPropertyAccessor()) {
13500b57cec5SDimitry Andric     const auto *Container = cast<ObjCContainerDecl>(getParent());
1351480093f4SDimitry Andric     // For accessor stubs, go back to the interface.
1352480093f4SDimitry Andric     if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container))
1353480093f4SDimitry Andric       if (isSynthesizedAccessorStub())
1354480093f4SDimitry Andric         Container = ImplDecl->getClassInterface();
1355480093f4SDimitry Andric 
13560b57cec5SDimitry Andric     bool IsGetter = (NumArgs == 0);
13570b57cec5SDimitry Andric     bool IsInstance = isInstanceMethod();
13580b57cec5SDimitry Andric 
13590b57cec5SDimitry Andric     /// Local function that attempts to find a matching property within the
13600b57cec5SDimitry Andric     /// given Objective-C container.
13610b57cec5SDimitry Andric     auto findMatchingProperty =
13620b57cec5SDimitry Andric       [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
13630b57cec5SDimitry Andric       if (IsInstance) {
13640b57cec5SDimitry Andric         for (const auto *I : Container->instance_properties()) {
13650b57cec5SDimitry Andric           Selector NextSel = IsGetter ? I->getGetterName()
13660b57cec5SDimitry Andric                                       : I->getSetterName();
13670b57cec5SDimitry Andric           if (NextSel == Sel)
13680b57cec5SDimitry Andric             return I;
13690b57cec5SDimitry Andric         }
13700b57cec5SDimitry Andric       } else {
13710b57cec5SDimitry Andric         for (const auto *I : Container->class_properties()) {
13720b57cec5SDimitry Andric           Selector NextSel = IsGetter ? I->getGetterName()
13730b57cec5SDimitry Andric                                       : I->getSetterName();
13740b57cec5SDimitry Andric           if (NextSel == Sel)
13750b57cec5SDimitry Andric             return I;
13760b57cec5SDimitry Andric         }
13770b57cec5SDimitry Andric       }
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric       return nullptr;
13800b57cec5SDimitry Andric     };
13810b57cec5SDimitry Andric 
13820b57cec5SDimitry Andric     // Look in the container we were given.
13830b57cec5SDimitry Andric     if (const auto *Found = findMatchingProperty(Container))
13840b57cec5SDimitry Andric       return Found;
13850b57cec5SDimitry Andric 
13860b57cec5SDimitry Andric     // If we're in a category or extension, look in the main class.
13870b57cec5SDimitry Andric     const ObjCInterfaceDecl *ClassDecl = nullptr;
13880b57cec5SDimitry Andric     if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
13890b57cec5SDimitry Andric       ClassDecl = Category->getClassInterface();
13900b57cec5SDimitry Andric       if (const auto *Found = findMatchingProperty(ClassDecl))
13910b57cec5SDimitry Andric         return Found;
13920b57cec5SDimitry Andric     } else {
13930b57cec5SDimitry Andric       // Determine whether the container is a class.
13945ffd83dbSDimitry Andric       ClassDecl = cast<ObjCInterfaceDecl>(Container);
13950b57cec5SDimitry Andric     }
13965ffd83dbSDimitry Andric     assert(ClassDecl && "Failed to find main class");
13970b57cec5SDimitry Andric 
13980b57cec5SDimitry Andric     // If we have a class, check its visible extensions.
13990b57cec5SDimitry Andric     for (const auto *Ext : ClassDecl->visible_extensions()) {
14000b57cec5SDimitry Andric       if (Ext == Container)
14010b57cec5SDimitry Andric         continue;
14020b57cec5SDimitry Andric       if (const auto *Found = findMatchingProperty(Ext))
14030b57cec5SDimitry Andric         return Found;
14040b57cec5SDimitry Andric     }
14050b57cec5SDimitry Andric 
1406480093f4SDimitry Andric     assert(isSynthesizedAccessorStub() && "expected an accessor stub");
14075ffd83dbSDimitry Andric 
1408480093f4SDimitry Andric     for (const auto *Cat : ClassDecl->known_categories()) {
1409480093f4SDimitry Andric       if (Cat == Container)
1410480093f4SDimitry Andric         continue;
1411480093f4SDimitry Andric       if (const auto *Found = findMatchingProperty(Cat))
1412480093f4SDimitry Andric         return Found;
1413480093f4SDimitry Andric     }
1414480093f4SDimitry Andric 
14150b57cec5SDimitry Andric     llvm_unreachable("Marked as a property accessor but no property found!");
14160b57cec5SDimitry Andric   }
14170b57cec5SDimitry Andric 
14180b57cec5SDimitry Andric   if (!CheckOverrides)
14190b57cec5SDimitry Andric     return nullptr;
14200b57cec5SDimitry Andric 
14210b57cec5SDimitry Andric   using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;
14220b57cec5SDimitry Andric 
14230b57cec5SDimitry Andric   OverridesTy Overrides;
14240b57cec5SDimitry Andric   getOverriddenMethods(Overrides);
14250b57cec5SDimitry Andric   for (const auto *Override : Overrides)
14260b57cec5SDimitry Andric     if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(false))
14270b57cec5SDimitry Andric       return Prop;
14280b57cec5SDimitry Andric 
14290b57cec5SDimitry Andric   return nullptr;
14300b57cec5SDimitry Andric }
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14330b57cec5SDimitry Andric // ObjCTypeParamDecl
14340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric void ObjCTypeParamDecl::anchor() {}
14370b57cec5SDimitry Andric 
14380b57cec5SDimitry Andric ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc,
14390b57cec5SDimitry Andric                                              ObjCTypeParamVariance variance,
14400b57cec5SDimitry Andric                                              SourceLocation varianceLoc,
14410b57cec5SDimitry Andric                                              unsigned index,
14420b57cec5SDimitry Andric                                              SourceLocation nameLoc,
14430b57cec5SDimitry Andric                                              IdentifierInfo *name,
14440b57cec5SDimitry Andric                                              SourceLocation colonLoc,
14450b57cec5SDimitry Andric                                              TypeSourceInfo *boundInfo) {
14460b57cec5SDimitry Andric   auto *TPDecl =
14470b57cec5SDimitry Andric     new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
14480b57cec5SDimitry Andric                                     nameLoc, name, colonLoc, boundInfo);
14490b57cec5SDimitry Andric   QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});
14500b57cec5SDimitry Andric   TPDecl->setTypeForDecl(TPType.getTypePtr());
14510b57cec5SDimitry Andric   return TPDecl;
14520b57cec5SDimitry Andric }
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx,
14550b57cec5SDimitry Andric                                                          unsigned ID) {
14560b57cec5SDimitry Andric   return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,
14570b57cec5SDimitry Andric                                          ObjCTypeParamVariance::Invariant,
14580b57cec5SDimitry Andric                                          SourceLocation(), 0, SourceLocation(),
14590b57cec5SDimitry Andric                                          nullptr, SourceLocation(), nullptr);
14600b57cec5SDimitry Andric }
14610b57cec5SDimitry Andric 
14620b57cec5SDimitry Andric SourceRange ObjCTypeParamDecl::getSourceRange() const {
14630b57cec5SDimitry Andric   SourceLocation startLoc = VarianceLoc;
14640b57cec5SDimitry Andric   if (startLoc.isInvalid())
14650b57cec5SDimitry Andric     startLoc = getLocation();
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric   if (hasExplicitBound()) {
14680b57cec5SDimitry Andric     return SourceRange(startLoc,
14690b57cec5SDimitry Andric                        getTypeSourceInfo()->getTypeLoc().getEndLoc());
14700b57cec5SDimitry Andric   }
14710b57cec5SDimitry Andric 
14720b57cec5SDimitry Andric   return SourceRange(startLoc);
14730b57cec5SDimitry Andric }
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14760b57cec5SDimitry Andric // ObjCTypeParamList
14770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14780b57cec5SDimitry Andric ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,
14790b57cec5SDimitry Andric                                      ArrayRef<ObjCTypeParamDecl *> typeParams,
14800b57cec5SDimitry Andric                                      SourceLocation rAngleLoc)
1481e8d8bef9SDimitry Andric     : Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) {
14820b57cec5SDimitry Andric   std::copy(typeParams.begin(), typeParams.end(), begin());
14830b57cec5SDimitry Andric }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric ObjCTypeParamList *ObjCTypeParamList::create(
14860b57cec5SDimitry Andric                      ASTContext &ctx,
14870b57cec5SDimitry Andric                      SourceLocation lAngleLoc,
14880b57cec5SDimitry Andric                      ArrayRef<ObjCTypeParamDecl *> typeParams,
14890b57cec5SDimitry Andric                      SourceLocation rAngleLoc) {
14900b57cec5SDimitry Andric   void *mem =
14910b57cec5SDimitry Andric       ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),
14920b57cec5SDimitry Andric                    alignof(ObjCTypeParamList));
14930b57cec5SDimitry Andric   return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);
14940b57cec5SDimitry Andric }
14950b57cec5SDimitry Andric 
14960b57cec5SDimitry Andric void ObjCTypeParamList::gatherDefaultTypeArgs(
14970b57cec5SDimitry Andric        SmallVectorImpl<QualType> &typeArgs) const {
14980b57cec5SDimitry Andric   typeArgs.reserve(size());
14990b57cec5SDimitry Andric   for (auto typeParam : *this)
15000b57cec5SDimitry Andric     typeArgs.push_back(typeParam->getUnderlyingType());
15010b57cec5SDimitry Andric }
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15040b57cec5SDimitry Andric // ObjCInterfaceDecl
15050b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
15080b57cec5SDimitry Andric                                              DeclContext *DC,
15090b57cec5SDimitry Andric                                              SourceLocation atLoc,
15100b57cec5SDimitry Andric                                              IdentifierInfo *Id,
15110b57cec5SDimitry Andric                                              ObjCTypeParamList *typeParamList,
15120b57cec5SDimitry Andric                                              ObjCInterfaceDecl *PrevDecl,
15130b57cec5SDimitry Andric                                              SourceLocation ClassLoc,
15140b57cec5SDimitry Andric                                              bool isInternal){
15150b57cec5SDimitry Andric   auto *Result = new (C, DC)
15160b57cec5SDimitry Andric       ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,
15170b57cec5SDimitry Andric                         isInternal);
15180b57cec5SDimitry Andric   Result->Data.setInt(!C.getLangOpts().Modules);
15190b57cec5SDimitry Andric   C.getObjCInterfaceType(Result, PrevDecl);
15200b57cec5SDimitry Andric   return Result;
15210b57cec5SDimitry Andric }
15220b57cec5SDimitry Andric 
15230b57cec5SDimitry Andric ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
15240b57cec5SDimitry Andric                                                          unsigned ID) {
15250b57cec5SDimitry Andric   auto *Result = new (C, ID)
15260b57cec5SDimitry Andric       ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,
15270b57cec5SDimitry Andric                         SourceLocation(), nullptr, false);
15280b57cec5SDimitry Andric   Result->Data.setInt(!C.getLangOpts().Modules);
15290b57cec5SDimitry Andric   return Result;
15300b57cec5SDimitry Andric }
15310b57cec5SDimitry Andric 
15320b57cec5SDimitry Andric ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
15330b57cec5SDimitry Andric                                      SourceLocation AtLoc, IdentifierInfo *Id,
15340b57cec5SDimitry Andric                                      ObjCTypeParamList *typeParamList,
15350b57cec5SDimitry Andric                                      SourceLocation CLoc,
15360b57cec5SDimitry Andric                                      ObjCInterfaceDecl *PrevDecl,
15370b57cec5SDimitry Andric                                      bool IsInternal)
15380b57cec5SDimitry Andric     : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
15390b57cec5SDimitry Andric       redeclarable_base(C) {
15400b57cec5SDimitry Andric   setPreviousDecl(PrevDecl);
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric   // Copy the 'data' pointer over.
15430b57cec5SDimitry Andric   if (PrevDecl)
15440b57cec5SDimitry Andric     Data = PrevDecl->Data;
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric   setImplicit(IsInternal);
15470b57cec5SDimitry Andric 
15480b57cec5SDimitry Andric   setTypeParamList(typeParamList);
15490b57cec5SDimitry Andric }
15500b57cec5SDimitry Andric 
15510b57cec5SDimitry Andric void ObjCInterfaceDecl::LoadExternalDefinition() const {
15520b57cec5SDimitry Andric   assert(data().ExternallyCompleted && "Class is not externally completed");
15530b57cec5SDimitry Andric   data().ExternallyCompleted = false;
15540b57cec5SDimitry Andric   getASTContext().getExternalSource()->CompleteType(
15550b57cec5SDimitry Andric                                         const_cast<ObjCInterfaceDecl *>(this));
15560b57cec5SDimitry Andric }
15570b57cec5SDimitry Andric 
15580b57cec5SDimitry Andric void ObjCInterfaceDecl::setExternallyCompleted() {
15590b57cec5SDimitry Andric   assert(getASTContext().getExternalSource() &&
15600b57cec5SDimitry Andric          "Class can't be externally completed without an external source");
15610b57cec5SDimitry Andric   assert(hasDefinition() &&
15620b57cec5SDimitry Andric          "Forward declarations can't be externally completed");
15630b57cec5SDimitry Andric   data().ExternallyCompleted = true;
15640b57cec5SDimitry Andric }
15650b57cec5SDimitry Andric 
15660b57cec5SDimitry Andric void ObjCInterfaceDecl::setHasDesignatedInitializers() {
15670b57cec5SDimitry Andric   // Check for a complete definition and recover if not so.
15680b57cec5SDimitry Andric   if (!isThisDeclarationADefinition())
15690b57cec5SDimitry Andric     return;
15700b57cec5SDimitry Andric   data().HasDesignatedInitializers = true;
15710b57cec5SDimitry Andric }
15720b57cec5SDimitry Andric 
15730b57cec5SDimitry Andric bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
15740b57cec5SDimitry Andric   // Check for a complete definition and recover if not so.
15750b57cec5SDimitry Andric   if (!isThisDeclarationADefinition())
15760b57cec5SDimitry Andric     return false;
15770b57cec5SDimitry Andric   if (data().ExternallyCompleted)
15780b57cec5SDimitry Andric     LoadExternalDefinition();
15790b57cec5SDimitry Andric 
15800b57cec5SDimitry Andric   return data().HasDesignatedInitializers;
15810b57cec5SDimitry Andric }
15820b57cec5SDimitry Andric 
15830b57cec5SDimitry Andric StringRef
15840b57cec5SDimitry Andric ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
15850b57cec5SDimitry Andric   if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
15860b57cec5SDimitry Andric     return ObjCRTName->getMetadataName();
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric   return getName();
15890b57cec5SDimitry Andric }
15900b57cec5SDimitry Andric 
15910b57cec5SDimitry Andric StringRef
15920b57cec5SDimitry Andric ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
15930b57cec5SDimitry Andric   if (ObjCInterfaceDecl *ID =
15940b57cec5SDimitry Andric       const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
15950b57cec5SDimitry Andric     return ID->getObjCRuntimeNameAsString();
15960b57cec5SDimitry Andric 
15970b57cec5SDimitry Andric   return getName();
15980b57cec5SDimitry Andric }
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
16010b57cec5SDimitry Andric   if (const ObjCInterfaceDecl *Def = getDefinition()) {
16020b57cec5SDimitry Andric     if (data().ExternallyCompleted)
16030b57cec5SDimitry Andric       LoadExternalDefinition();
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric     return getASTContext().getObjCImplementation(
16060b57cec5SDimitry Andric              const_cast<ObjCInterfaceDecl*>(Def));
16070b57cec5SDimitry Andric   }
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
16100b57cec5SDimitry Andric   return nullptr;
16110b57cec5SDimitry Andric }
16120b57cec5SDimitry Andric 
16130b57cec5SDimitry Andric void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
16140b57cec5SDimitry Andric   getASTContext().setObjCImplementation(getDefinition(), ImplD);
16150b57cec5SDimitry Andric }
16160b57cec5SDimitry Andric 
16170b57cec5SDimitry Andric namespace {
16180b57cec5SDimitry Andric 
16190b57cec5SDimitry Andric struct SynthesizeIvarChunk {
16200b57cec5SDimitry Andric   uint64_t Size;
16210b57cec5SDimitry Andric   ObjCIvarDecl *Ivar;
16220b57cec5SDimitry Andric 
16230b57cec5SDimitry Andric   SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
16240b57cec5SDimitry Andric       : Size(size), Ivar(ivar) {}
16250b57cec5SDimitry Andric };
16260b57cec5SDimitry Andric 
16270b57cec5SDimitry Andric bool operator<(const SynthesizeIvarChunk & LHS,
16280b57cec5SDimitry Andric                const SynthesizeIvarChunk &RHS) {
16290b57cec5SDimitry Andric     return LHS.Size < RHS.Size;
16300b57cec5SDimitry Andric }
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric } // namespace
16330b57cec5SDimitry Andric 
16340b57cec5SDimitry Andric /// all_declared_ivar_begin - return first ivar declared in this class,
16350b57cec5SDimitry Andric /// its extensions and its implementation. Lazily build the list on first
16360b57cec5SDimitry Andric /// access.
16370b57cec5SDimitry Andric ///
16380b57cec5SDimitry Andric /// Caveat: The list returned by this method reflects the current
16390b57cec5SDimitry Andric /// state of the parser. The cache will be updated for every ivar
16400b57cec5SDimitry Andric /// added by an extension or the implementation when they are
16410b57cec5SDimitry Andric /// encountered.
16420b57cec5SDimitry Andric /// See also ObjCIvarDecl::Create().
16430b57cec5SDimitry Andric ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
16440b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
16450b57cec5SDimitry Andric   if (!hasDefinition())
16460b57cec5SDimitry Andric     return nullptr;
16470b57cec5SDimitry Andric 
16480b57cec5SDimitry Andric   ObjCIvarDecl *curIvar = nullptr;
16490b57cec5SDimitry Andric   if (!data().IvarList) {
16500b57cec5SDimitry Andric     if (!ivar_empty()) {
16510b57cec5SDimitry Andric       ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
16520b57cec5SDimitry Andric       data().IvarList = *I; ++I;
16530b57cec5SDimitry Andric       for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
16540b57cec5SDimitry Andric         curIvar->setNextIvar(*I);
16550b57cec5SDimitry Andric     }
16560b57cec5SDimitry Andric 
16570b57cec5SDimitry Andric     for (const auto *Ext : known_extensions()) {
16580b57cec5SDimitry Andric       if (!Ext->ivar_empty()) {
16590b57cec5SDimitry Andric         ObjCCategoryDecl::ivar_iterator
16600b57cec5SDimitry Andric           I = Ext->ivar_begin(),
16610b57cec5SDimitry Andric           E = Ext->ivar_end();
16620b57cec5SDimitry Andric         if (!data().IvarList) {
16630b57cec5SDimitry Andric           data().IvarList = *I; ++I;
16640b57cec5SDimitry Andric           curIvar = data().IvarList;
16650b57cec5SDimitry Andric         }
16660b57cec5SDimitry Andric         for ( ;I != E; curIvar = *I, ++I)
16670b57cec5SDimitry Andric           curIvar->setNextIvar(*I);
16680b57cec5SDimitry Andric       }
16690b57cec5SDimitry Andric     }
16700b57cec5SDimitry Andric     data().IvarListMissingImplementation = true;
16710b57cec5SDimitry Andric   }
16720b57cec5SDimitry Andric 
16730b57cec5SDimitry Andric   // cached and complete!
16740b57cec5SDimitry Andric   if (!data().IvarListMissingImplementation)
16750b57cec5SDimitry Andric       return data().IvarList;
16760b57cec5SDimitry Andric 
16770b57cec5SDimitry Andric   if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
16780b57cec5SDimitry Andric     data().IvarListMissingImplementation = false;
16790b57cec5SDimitry Andric     if (!ImplDecl->ivar_empty()) {
16800b57cec5SDimitry Andric       SmallVector<SynthesizeIvarChunk, 16> layout;
16810b57cec5SDimitry Andric       for (auto *IV : ImplDecl->ivars()) {
16820b57cec5SDimitry Andric         if (IV->getSynthesize() && !IV->isInvalidDecl()) {
16830b57cec5SDimitry Andric           layout.push_back(SynthesizeIvarChunk(
16840b57cec5SDimitry Andric                              IV->getASTContext().getTypeSize(IV->getType()), IV));
16850b57cec5SDimitry Andric           continue;
16860b57cec5SDimitry Andric         }
16870b57cec5SDimitry Andric         if (!data().IvarList)
16880b57cec5SDimitry Andric           data().IvarList = IV;
16890b57cec5SDimitry Andric         else
16900b57cec5SDimitry Andric           curIvar->setNextIvar(IV);
16910b57cec5SDimitry Andric         curIvar = IV;
16920b57cec5SDimitry Andric       }
16930b57cec5SDimitry Andric 
16940b57cec5SDimitry Andric       if (!layout.empty()) {
16950b57cec5SDimitry Andric         // Order synthesized ivars by their size.
16960b57cec5SDimitry Andric         llvm::stable_sort(layout);
16970b57cec5SDimitry Andric         unsigned Ix = 0, EIx = layout.size();
16980b57cec5SDimitry Andric         if (!data().IvarList) {
16990b57cec5SDimitry Andric           data().IvarList = layout[0].Ivar; Ix++;
17000b57cec5SDimitry Andric           curIvar = data().IvarList;
17010b57cec5SDimitry Andric         }
17020b57cec5SDimitry Andric         for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
17030b57cec5SDimitry Andric           curIvar->setNextIvar(layout[Ix].Ivar);
17040b57cec5SDimitry Andric       }
17050b57cec5SDimitry Andric     }
17060b57cec5SDimitry Andric   }
17070b57cec5SDimitry Andric   return data().IvarList;
17080b57cec5SDimitry Andric }
17090b57cec5SDimitry Andric 
17100b57cec5SDimitry Andric /// FindCategoryDeclaration - Finds category declaration in the list of
17110b57cec5SDimitry Andric /// categories for this class and returns it. Name of the category is passed
17120b57cec5SDimitry Andric /// in 'CategoryId'. If category not found, return 0;
17130b57cec5SDimitry Andric ///
17140b57cec5SDimitry Andric ObjCCategoryDecl *
17150b57cec5SDimitry Andric ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
17160b57cec5SDimitry Andric   // FIXME: Should make sure no callers ever do this.
17170b57cec5SDimitry Andric   if (!hasDefinition())
17180b57cec5SDimitry Andric     return nullptr;
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric   if (data().ExternallyCompleted)
17210b57cec5SDimitry Andric     LoadExternalDefinition();
17220b57cec5SDimitry Andric 
17230b57cec5SDimitry Andric   for (auto *Cat : visible_categories())
17240b57cec5SDimitry Andric     if (Cat->getIdentifier() == CategoryId)
17250b57cec5SDimitry Andric       return Cat;
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric   return nullptr;
17280b57cec5SDimitry Andric }
17290b57cec5SDimitry Andric 
17300b57cec5SDimitry Andric ObjCMethodDecl *
17310b57cec5SDimitry Andric ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
17320b57cec5SDimitry Andric   for (const auto *Cat : visible_categories()) {
17330b57cec5SDimitry Andric     if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
17340b57cec5SDimitry Andric       if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
17350b57cec5SDimitry Andric         return MD;
17360b57cec5SDimitry Andric   }
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric   return nullptr;
17390b57cec5SDimitry Andric }
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
17420b57cec5SDimitry Andric   for (const auto *Cat : visible_categories()) {
17430b57cec5SDimitry Andric     if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
17440b57cec5SDimitry Andric       if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
17450b57cec5SDimitry Andric         return MD;
17460b57cec5SDimitry Andric   }
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric   return nullptr;
17490b57cec5SDimitry Andric }
17500b57cec5SDimitry Andric 
17510b57cec5SDimitry Andric /// ClassImplementsProtocol - Checks that 'lProto' protocol
17520b57cec5SDimitry Andric /// has been implemented in IDecl class, its super class or categories (if
17530b57cec5SDimitry Andric /// lookupCategory is true).
17540b57cec5SDimitry Andric bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
17550b57cec5SDimitry Andric                                     bool lookupCategory,
17560b57cec5SDimitry Andric                                     bool RHSIsQualifiedID) {
17570b57cec5SDimitry Andric   if (!hasDefinition())
17580b57cec5SDimitry Andric     return false;
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric   ObjCInterfaceDecl *IDecl = this;
17610b57cec5SDimitry Andric   // 1st, look up the class.
17620b57cec5SDimitry Andric   for (auto *PI : IDecl->protocols()){
17630b57cec5SDimitry Andric     if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
17640b57cec5SDimitry Andric       return true;
17650b57cec5SDimitry Andric     // This is dubious and is added to be compatible with gcc.  In gcc, it is
17660b57cec5SDimitry Andric     // also allowed assigning a protocol-qualified 'id' type to a LHS object
17670b57cec5SDimitry Andric     // when protocol in qualified LHS is in list of protocols in the rhs 'id'
17680b57cec5SDimitry Andric     // object. This IMO, should be a bug.
17690b57cec5SDimitry Andric     // FIXME: Treat this as an extension, and flag this as an error when GCC
17700b57cec5SDimitry Andric     // extensions are not enabled.
17710b57cec5SDimitry Andric     if (RHSIsQualifiedID &&
17720b57cec5SDimitry Andric         getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
17730b57cec5SDimitry Andric       return true;
17740b57cec5SDimitry Andric   }
17750b57cec5SDimitry Andric 
17760b57cec5SDimitry Andric   // 2nd, look up the category.
17770b57cec5SDimitry Andric   if (lookupCategory)
17780b57cec5SDimitry Andric     for (const auto *Cat : visible_categories()) {
17790b57cec5SDimitry Andric       for (auto *PI : Cat->protocols())
17800b57cec5SDimitry Andric         if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
17810b57cec5SDimitry Andric           return true;
17820b57cec5SDimitry Andric     }
17830b57cec5SDimitry Andric 
17840b57cec5SDimitry Andric   // 3rd, look up the super class(s)
17850b57cec5SDimitry Andric   if (IDecl->getSuperClass())
17860b57cec5SDimitry Andric     return
17870b57cec5SDimitry Andric   IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
17880b57cec5SDimitry Andric                                                   RHSIsQualifiedID);
17890b57cec5SDimitry Andric 
17900b57cec5SDimitry Andric   return false;
17910b57cec5SDimitry Andric }
17920b57cec5SDimitry Andric 
17930b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17940b57cec5SDimitry Andric // ObjCIvarDecl
17950b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17960b57cec5SDimitry Andric 
17970b57cec5SDimitry Andric void ObjCIvarDecl::anchor() {}
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
18000b57cec5SDimitry Andric                                    SourceLocation StartLoc,
18010b57cec5SDimitry Andric                                    SourceLocation IdLoc, IdentifierInfo *Id,
18020b57cec5SDimitry Andric                                    QualType T, TypeSourceInfo *TInfo,
18030b57cec5SDimitry Andric                                    AccessControl ac, Expr *BW,
18040b57cec5SDimitry Andric                                    bool synthesized) {
18050b57cec5SDimitry Andric   if (DC) {
18060b57cec5SDimitry Andric     // Ivar's can only appear in interfaces, implementations (via synthesized
18070b57cec5SDimitry Andric     // properties), and class extensions (via direct declaration, or synthesized
18080b57cec5SDimitry Andric     // properties).
18090b57cec5SDimitry Andric     //
18100b57cec5SDimitry Andric     // FIXME: This should really be asserting this:
18110b57cec5SDimitry Andric     //   (isa<ObjCCategoryDecl>(DC) &&
18120b57cec5SDimitry Andric     //    cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
18130b57cec5SDimitry Andric     // but unfortunately we sometimes place ivars into non-class extension
18140b57cec5SDimitry Andric     // categories on error. This breaks an AST invariant, and should not be
18150b57cec5SDimitry Andric     // fixed.
18160b57cec5SDimitry Andric     assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
18170b57cec5SDimitry Andric             isa<ObjCCategoryDecl>(DC)) &&
18180b57cec5SDimitry Andric            "Invalid ivar decl context!");
18190b57cec5SDimitry Andric     // Once a new ivar is created in any of class/class-extension/implementation
18200b57cec5SDimitry Andric     // decl contexts, the previously built IvarList must be rebuilt.
18210b57cec5SDimitry Andric     auto *ID = dyn_cast<ObjCInterfaceDecl>(DC);
18220b57cec5SDimitry Andric     if (!ID) {
18230b57cec5SDimitry Andric       if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC))
18240b57cec5SDimitry Andric         ID = IM->getClassInterface();
18250b57cec5SDimitry Andric       else
18260b57cec5SDimitry Andric         ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
18270b57cec5SDimitry Andric     }
18280b57cec5SDimitry Andric     ID->setIvarList(nullptr);
18290b57cec5SDimitry Andric   }
18300b57cec5SDimitry Andric 
18310b57cec5SDimitry Andric   return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
18320b57cec5SDimitry Andric                                   synthesized);
18330b57cec5SDimitry Andric }
18340b57cec5SDimitry Andric 
18350b57cec5SDimitry Andric ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
18360b57cec5SDimitry Andric   return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
18370b57cec5SDimitry Andric                                   nullptr, QualType(), nullptr,
18380b57cec5SDimitry Andric                                   ObjCIvarDecl::None, nullptr, false);
18390b57cec5SDimitry Andric }
18400b57cec5SDimitry Andric 
18410b57cec5SDimitry Andric const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
18420b57cec5SDimitry Andric   const auto *DC = cast<ObjCContainerDecl>(getDeclContext());
18430b57cec5SDimitry Andric 
18440b57cec5SDimitry Andric   switch (DC->getKind()) {
18450b57cec5SDimitry Andric   default:
18460b57cec5SDimitry Andric   case ObjCCategoryImpl:
18470b57cec5SDimitry Andric   case ObjCProtocol:
18480b57cec5SDimitry Andric     llvm_unreachable("invalid ivar container!");
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric     // Ivars can only appear in class extension categories.
18510b57cec5SDimitry Andric   case ObjCCategory: {
18520b57cec5SDimitry Andric     const auto *CD = cast<ObjCCategoryDecl>(DC);
18530b57cec5SDimitry Andric     assert(CD->IsClassExtension() && "invalid container for ivar!");
18540b57cec5SDimitry Andric     return CD->getClassInterface();
18550b57cec5SDimitry Andric   }
18560b57cec5SDimitry Andric 
18570b57cec5SDimitry Andric   case ObjCImplementation:
18580b57cec5SDimitry Andric     return cast<ObjCImplementationDecl>(DC)->getClassInterface();
18590b57cec5SDimitry Andric 
18600b57cec5SDimitry Andric   case ObjCInterface:
18610b57cec5SDimitry Andric     return cast<ObjCInterfaceDecl>(DC);
18620b57cec5SDimitry Andric   }
18630b57cec5SDimitry Andric }
18640b57cec5SDimitry Andric 
18650b57cec5SDimitry Andric QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
18660b57cec5SDimitry Andric   return getType().substObjCMemberType(objectType, getDeclContext(),
18670b57cec5SDimitry Andric                                        ObjCSubstitutionContext::Property);
18680b57cec5SDimitry Andric }
18690b57cec5SDimitry Andric 
18700b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18710b57cec5SDimitry Andric // ObjCAtDefsFieldDecl
18720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18730b57cec5SDimitry Andric 
18740b57cec5SDimitry Andric void ObjCAtDefsFieldDecl::anchor() {}
18750b57cec5SDimitry Andric 
18760b57cec5SDimitry Andric ObjCAtDefsFieldDecl
18770b57cec5SDimitry Andric *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
18780b57cec5SDimitry Andric                              SourceLocation StartLoc,  SourceLocation IdLoc,
18790b57cec5SDimitry Andric                              IdentifierInfo *Id, QualType T, Expr *BW) {
18800b57cec5SDimitry Andric   return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
18810b57cec5SDimitry Andric }
18820b57cec5SDimitry Andric 
18830b57cec5SDimitry Andric ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
18840b57cec5SDimitry Andric                                                              unsigned ID) {
18850b57cec5SDimitry Andric   return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
18860b57cec5SDimitry Andric                                          SourceLocation(), nullptr, QualType(),
18870b57cec5SDimitry Andric                                          nullptr);
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18910b57cec5SDimitry Andric // ObjCProtocolDecl
18920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric void ObjCProtocolDecl::anchor() {}
18950b57cec5SDimitry Andric 
18960b57cec5SDimitry Andric ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
18970b57cec5SDimitry Andric                                    IdentifierInfo *Id, SourceLocation nameLoc,
18980b57cec5SDimitry Andric                                    SourceLocation atStartLoc,
18990b57cec5SDimitry Andric                                    ObjCProtocolDecl *PrevDecl)
19000b57cec5SDimitry Andric     : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
19010b57cec5SDimitry Andric       redeclarable_base(C) {
19020b57cec5SDimitry Andric   setPreviousDecl(PrevDecl);
19030b57cec5SDimitry Andric   if (PrevDecl)
19040b57cec5SDimitry Andric     Data = PrevDecl->Data;
19050b57cec5SDimitry Andric }
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
19080b57cec5SDimitry Andric                                            IdentifierInfo *Id,
19090b57cec5SDimitry Andric                                            SourceLocation nameLoc,
19100b57cec5SDimitry Andric                                            SourceLocation atStartLoc,
19110b57cec5SDimitry Andric                                            ObjCProtocolDecl *PrevDecl) {
19120b57cec5SDimitry Andric   auto *Result =
19130b57cec5SDimitry Andric       new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
19140b57cec5SDimitry Andric   Result->Data.setInt(!C.getLangOpts().Modules);
19150b57cec5SDimitry Andric   return Result;
19160b57cec5SDimitry Andric }
19170b57cec5SDimitry Andric 
19180b57cec5SDimitry Andric ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
19190b57cec5SDimitry Andric                                                        unsigned ID) {
19200b57cec5SDimitry Andric   ObjCProtocolDecl *Result =
19210b57cec5SDimitry Andric       new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
19220b57cec5SDimitry Andric                                    SourceLocation(), nullptr);
19230b57cec5SDimitry Andric   Result->Data.setInt(!C.getLangOpts().Modules);
19240b57cec5SDimitry Andric   return Result;
19250b57cec5SDimitry Andric }
19260b57cec5SDimitry Andric 
1927e8d8bef9SDimitry Andric bool ObjCProtocolDecl::isNonRuntimeProtocol() const {
1928e8d8bef9SDimitry Andric   return hasAttr<ObjCNonRuntimeProtocolAttr>();
1929e8d8bef9SDimitry Andric }
1930e8d8bef9SDimitry Andric 
1931e8d8bef9SDimitry Andric void ObjCProtocolDecl::getImpliedProtocols(
1932e8d8bef9SDimitry Andric     llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const {
1933e8d8bef9SDimitry Andric   std::queue<const ObjCProtocolDecl *> WorkQueue;
1934e8d8bef9SDimitry Andric   WorkQueue.push(this);
1935e8d8bef9SDimitry Andric 
1936e8d8bef9SDimitry Andric   while (!WorkQueue.empty()) {
1937e8d8bef9SDimitry Andric     const auto *PD = WorkQueue.front();
1938e8d8bef9SDimitry Andric     WorkQueue.pop();
1939e8d8bef9SDimitry Andric     for (const auto *Parent : PD->protocols()) {
1940e8d8bef9SDimitry Andric       const auto *Can = Parent->getCanonicalDecl();
1941e8d8bef9SDimitry Andric       auto Result = IPs.insert(Can);
1942e8d8bef9SDimitry Andric       if (Result.second)
1943e8d8bef9SDimitry Andric         WorkQueue.push(Parent);
1944e8d8bef9SDimitry Andric     }
1945e8d8bef9SDimitry Andric   }
1946e8d8bef9SDimitry Andric }
1947e8d8bef9SDimitry Andric 
19480b57cec5SDimitry Andric ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
19490b57cec5SDimitry Andric   ObjCProtocolDecl *PDecl = this;
19500b57cec5SDimitry Andric 
19510b57cec5SDimitry Andric   if (Name == getIdentifier())
19520b57cec5SDimitry Andric     return PDecl;
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric   for (auto *I : protocols())
19550b57cec5SDimitry Andric     if ((PDecl = I->lookupProtocolNamed(Name)))
19560b57cec5SDimitry Andric       return PDecl;
19570b57cec5SDimitry Andric 
19580b57cec5SDimitry Andric   return nullptr;
19590b57cec5SDimitry Andric }
19600b57cec5SDimitry Andric 
19610b57cec5SDimitry Andric // lookupMethod - Lookup a instance/class method in the protocol and protocols
19620b57cec5SDimitry Andric // it inherited.
19630b57cec5SDimitry Andric ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
19640b57cec5SDimitry Andric                                                bool isInstance) const {
19650b57cec5SDimitry Andric   ObjCMethodDecl *MethodDecl = nullptr;
19660b57cec5SDimitry Andric 
19670b57cec5SDimitry Andric   // If there is no definition or the definition is hidden, we don't find
19680b57cec5SDimitry Andric   // anything.
19690b57cec5SDimitry Andric   const ObjCProtocolDecl *Def = getDefinition();
19705ffd83dbSDimitry Andric   if (!Def || !Def->isUnconditionallyVisible())
19710b57cec5SDimitry Andric     return nullptr;
19720b57cec5SDimitry Andric 
19730b57cec5SDimitry Andric   if ((MethodDecl = getMethod(Sel, isInstance)))
19740b57cec5SDimitry Andric     return MethodDecl;
19750b57cec5SDimitry Andric 
19760b57cec5SDimitry Andric   for (const auto *I : protocols())
19770b57cec5SDimitry Andric     if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
19780b57cec5SDimitry Andric       return MethodDecl;
19790b57cec5SDimitry Andric   return nullptr;
19800b57cec5SDimitry Andric }
19810b57cec5SDimitry Andric 
19820b57cec5SDimitry Andric void ObjCProtocolDecl::allocateDefinitionData() {
19830b57cec5SDimitry Andric   assert(!Data.getPointer() && "Protocol already has a definition!");
19840b57cec5SDimitry Andric   Data.setPointer(new (getASTContext()) DefinitionData);
19850b57cec5SDimitry Andric   Data.getPointer()->Definition = this;
19860b57cec5SDimitry Andric }
19870b57cec5SDimitry Andric 
19880b57cec5SDimitry Andric void ObjCProtocolDecl::startDefinition() {
19890b57cec5SDimitry Andric   allocateDefinitionData();
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric   // Update all of the declarations with a pointer to the definition.
19920b57cec5SDimitry Andric   for (auto *RD : redecls())
19930b57cec5SDimitry Andric     RD->Data = this->Data;
19940b57cec5SDimitry Andric }
19950b57cec5SDimitry Andric 
19960b57cec5SDimitry Andric void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
19970b57cec5SDimitry Andric                                                     PropertyDeclOrder &PO) const {
19980b57cec5SDimitry Andric   if (const ObjCProtocolDecl *PDecl = getDefinition()) {
19990b57cec5SDimitry Andric     for (auto *Prop : PDecl->properties()) {
20000b57cec5SDimitry Andric       // Insert into PM if not there already.
20010b57cec5SDimitry Andric       PM.insert(std::make_pair(
20020b57cec5SDimitry Andric           std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),
20030b57cec5SDimitry Andric           Prop));
20040b57cec5SDimitry Andric       PO.push_back(Prop);
20050b57cec5SDimitry Andric     }
20060b57cec5SDimitry Andric     // Scan through protocol's protocols.
20070b57cec5SDimitry Andric     for (const auto *PI : PDecl->protocols())
20080b57cec5SDimitry Andric       PI->collectPropertiesToImplement(PM, PO);
20090b57cec5SDimitry Andric   }
20100b57cec5SDimitry Andric }
20110b57cec5SDimitry Andric 
20120b57cec5SDimitry Andric void ObjCProtocolDecl::collectInheritedProtocolProperties(
20130b57cec5SDimitry Andric     const ObjCPropertyDecl *Property, ProtocolPropertySet &PS,
20140b57cec5SDimitry Andric     PropertyDeclOrder &PO) const {
20150b57cec5SDimitry Andric   if (const ObjCProtocolDecl *PDecl = getDefinition()) {
20160b57cec5SDimitry Andric     if (!PS.insert(PDecl).second)
20170b57cec5SDimitry Andric       return;
20180b57cec5SDimitry Andric     for (auto *Prop : PDecl->properties()) {
20190b57cec5SDimitry Andric       if (Prop == Property)
20200b57cec5SDimitry Andric         continue;
20210b57cec5SDimitry Andric       if (Prop->getIdentifier() == Property->getIdentifier()) {
20220b57cec5SDimitry Andric         PO.push_back(Prop);
20230b57cec5SDimitry Andric         return;
20240b57cec5SDimitry Andric       }
20250b57cec5SDimitry Andric     }
20260b57cec5SDimitry Andric     // Scan through protocol's protocols which did not have a matching property.
20270b57cec5SDimitry Andric     for (const auto *PI : PDecl->protocols())
20280b57cec5SDimitry Andric       PI->collectInheritedProtocolProperties(Property, PS, PO);
20290b57cec5SDimitry Andric   }
20300b57cec5SDimitry Andric }
20310b57cec5SDimitry Andric 
20320b57cec5SDimitry Andric StringRef
20330b57cec5SDimitry Andric ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
20340b57cec5SDimitry Andric   if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
20350b57cec5SDimitry Andric     return ObjCRTName->getMetadataName();
20360b57cec5SDimitry Andric 
20370b57cec5SDimitry Andric   return getName();
20380b57cec5SDimitry Andric }
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
20410b57cec5SDimitry Andric // ObjCCategoryDecl
20420b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
20430b57cec5SDimitry Andric 
20440b57cec5SDimitry Andric void ObjCCategoryDecl::anchor() {}
20450b57cec5SDimitry Andric 
20460b57cec5SDimitry Andric ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
20470b57cec5SDimitry Andric                                    SourceLocation ClassNameLoc,
20480b57cec5SDimitry Andric                                    SourceLocation CategoryNameLoc,
20490b57cec5SDimitry Andric                                    IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
20500b57cec5SDimitry Andric                                    ObjCTypeParamList *typeParamList,
20510b57cec5SDimitry Andric                                    SourceLocation IvarLBraceLoc,
20520b57cec5SDimitry Andric                                    SourceLocation IvarRBraceLoc)
20530b57cec5SDimitry Andric     : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
20540b57cec5SDimitry Andric       ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
20550b57cec5SDimitry Andric       IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
20560b57cec5SDimitry Andric   setTypeParamList(typeParamList);
20570b57cec5SDimitry Andric }
20580b57cec5SDimitry Andric 
20590b57cec5SDimitry Andric ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
20600b57cec5SDimitry Andric                                            SourceLocation AtLoc,
20610b57cec5SDimitry Andric                                            SourceLocation ClassNameLoc,
20620b57cec5SDimitry Andric                                            SourceLocation CategoryNameLoc,
20630b57cec5SDimitry Andric                                            IdentifierInfo *Id,
20640b57cec5SDimitry Andric                                            ObjCInterfaceDecl *IDecl,
20650b57cec5SDimitry Andric                                            ObjCTypeParamList *typeParamList,
20660b57cec5SDimitry Andric                                            SourceLocation IvarLBraceLoc,
20670b57cec5SDimitry Andric                                            SourceLocation IvarRBraceLoc) {
20680b57cec5SDimitry Andric   auto *CatDecl =
20690b57cec5SDimitry Andric       new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
20700b57cec5SDimitry Andric                                    IDecl, typeParamList, IvarLBraceLoc,
20710b57cec5SDimitry Andric                                    IvarRBraceLoc);
20720b57cec5SDimitry Andric   if (IDecl) {
20730b57cec5SDimitry Andric     // Link this category into its class's category list.
20740b57cec5SDimitry Andric     CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
20750b57cec5SDimitry Andric     if (IDecl->hasDefinition()) {
20760b57cec5SDimitry Andric       IDecl->setCategoryListRaw(CatDecl);
20770b57cec5SDimitry Andric       if (ASTMutationListener *L = C.getASTMutationListener())
20780b57cec5SDimitry Andric         L->AddedObjCCategoryToInterface(CatDecl, IDecl);
20790b57cec5SDimitry Andric     }
20800b57cec5SDimitry Andric   }
20810b57cec5SDimitry Andric 
20820b57cec5SDimitry Andric   return CatDecl;
20830b57cec5SDimitry Andric }
20840b57cec5SDimitry Andric 
20850b57cec5SDimitry Andric ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
20860b57cec5SDimitry Andric                                                        unsigned ID) {
20870b57cec5SDimitry Andric   return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
20880b57cec5SDimitry Andric                                       SourceLocation(), SourceLocation(),
20890b57cec5SDimitry Andric                                       nullptr, nullptr, nullptr);
20900b57cec5SDimitry Andric }
20910b57cec5SDimitry Andric 
20920b57cec5SDimitry Andric ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
20930b57cec5SDimitry Andric   return getASTContext().getObjCImplementation(
20940b57cec5SDimitry Andric                                            const_cast<ObjCCategoryDecl*>(this));
20950b57cec5SDimitry Andric }
20960b57cec5SDimitry Andric 
20970b57cec5SDimitry Andric void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
20980b57cec5SDimitry Andric   getASTContext().setObjCImplementation(this, ImplD);
20990b57cec5SDimitry Andric }
21000b57cec5SDimitry Andric 
21010b57cec5SDimitry Andric void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) {
21020b57cec5SDimitry Andric   TypeParamList = TPL;
21030b57cec5SDimitry Andric   if (!TPL)
21040b57cec5SDimitry Andric     return;
21050b57cec5SDimitry Andric   // Set the declaration context of each of the type parameters.
21060b57cec5SDimitry Andric   for (auto *typeParam : *TypeParamList)
21070b57cec5SDimitry Andric     typeParam->setDeclContext(this);
21080b57cec5SDimitry Andric }
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21110b57cec5SDimitry Andric // ObjCCategoryImplDecl
21120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21130b57cec5SDimitry Andric 
21140b57cec5SDimitry Andric void ObjCCategoryImplDecl::anchor() {}
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric ObjCCategoryImplDecl *
21170b57cec5SDimitry Andric ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
21180b57cec5SDimitry Andric                              IdentifierInfo *Id,
21190b57cec5SDimitry Andric                              ObjCInterfaceDecl *ClassInterface,
21200b57cec5SDimitry Andric                              SourceLocation nameLoc,
21210b57cec5SDimitry Andric                              SourceLocation atStartLoc,
21220b57cec5SDimitry Andric                              SourceLocation CategoryNameLoc) {
21230b57cec5SDimitry Andric   if (ClassInterface && ClassInterface->hasDefinition())
21240b57cec5SDimitry Andric     ClassInterface = ClassInterface->getDefinition();
21250b57cec5SDimitry Andric   return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
21260b57cec5SDimitry Andric                                           atStartLoc, CategoryNameLoc);
21270b57cec5SDimitry Andric }
21280b57cec5SDimitry Andric 
21290b57cec5SDimitry Andric ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
21300b57cec5SDimitry Andric                                                                unsigned ID) {
21310b57cec5SDimitry Andric   return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
21320b57cec5SDimitry Andric                                           SourceLocation(), SourceLocation(),
21330b57cec5SDimitry Andric                                           SourceLocation());
21340b57cec5SDimitry Andric }
21350b57cec5SDimitry Andric 
21360b57cec5SDimitry Andric ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
21370b57cec5SDimitry Andric   // The class interface might be NULL if we are working with invalid code.
21380b57cec5SDimitry Andric   if (const ObjCInterfaceDecl *ID = getClassInterface())
21390b57cec5SDimitry Andric     return ID->FindCategoryDeclaration(getIdentifier());
21400b57cec5SDimitry Andric   return nullptr;
21410b57cec5SDimitry Andric }
21420b57cec5SDimitry Andric 
21430b57cec5SDimitry Andric void ObjCImplDecl::anchor() {}
21440b57cec5SDimitry Andric 
21450b57cec5SDimitry Andric void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
21460b57cec5SDimitry Andric   // FIXME: The context should be correct before we get here.
21470b57cec5SDimitry Andric   property->setLexicalDeclContext(this);
21480b57cec5SDimitry Andric   addDecl(property);
21490b57cec5SDimitry Andric }
21500b57cec5SDimitry Andric 
21510b57cec5SDimitry Andric void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
21520b57cec5SDimitry Andric   ASTContext &Ctx = getASTContext();
21530b57cec5SDimitry Andric 
21540b57cec5SDimitry Andric   if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
21550b57cec5SDimitry Andric     if (IFace)
21560b57cec5SDimitry Andric       Ctx.setObjCImplementation(IFace, ImplD);
21570b57cec5SDimitry Andric 
21580b57cec5SDimitry Andric   } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
21590b57cec5SDimitry Andric     if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
21600b57cec5SDimitry Andric       Ctx.setObjCImplementation(CD, ImplD);
21610b57cec5SDimitry Andric   }
21620b57cec5SDimitry Andric 
21630b57cec5SDimitry Andric   ClassInterface = IFace;
21640b57cec5SDimitry Andric }
21650b57cec5SDimitry Andric 
21660b57cec5SDimitry Andric /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
21670b57cec5SDimitry Andric /// properties implemented in this \@implementation block and returns
21680b57cec5SDimitry Andric /// the implemented property that uses it.
21690b57cec5SDimitry Andric ObjCPropertyImplDecl *ObjCImplDecl::
21700b57cec5SDimitry Andric FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
21710b57cec5SDimitry Andric   for (auto *PID : property_impls())
21720b57cec5SDimitry Andric     if (PID->getPropertyIvarDecl() &&
21730b57cec5SDimitry Andric         PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
21740b57cec5SDimitry Andric       return PID;
21750b57cec5SDimitry Andric   return nullptr;
21760b57cec5SDimitry Andric }
21770b57cec5SDimitry Andric 
21780b57cec5SDimitry Andric /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
21790b57cec5SDimitry Andric /// added to the list of those properties \@synthesized/\@dynamic in this
21800b57cec5SDimitry Andric /// category \@implementation block.
21810b57cec5SDimitry Andric ObjCPropertyImplDecl *ObjCImplDecl::
21820b57cec5SDimitry Andric FindPropertyImplDecl(IdentifierInfo *Id,
21830b57cec5SDimitry Andric                      ObjCPropertyQueryKind QueryKind) const {
21840b57cec5SDimitry Andric   ObjCPropertyImplDecl *ClassPropImpl = nullptr;
21850b57cec5SDimitry Andric   for (auto *PID : property_impls())
21860b57cec5SDimitry Andric     // If queryKind is unknown, we return the instance property if one
21870b57cec5SDimitry Andric     // exists; otherwise we return the class property.
21880b57cec5SDimitry Andric     if (PID->getPropertyDecl()->getIdentifier() == Id) {
21890b57cec5SDimitry Andric       if ((QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown &&
21900b57cec5SDimitry Andric            !PID->getPropertyDecl()->isClassProperty()) ||
21910b57cec5SDimitry Andric           (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_class &&
21920b57cec5SDimitry Andric            PID->getPropertyDecl()->isClassProperty()) ||
21930b57cec5SDimitry Andric           (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance &&
21940b57cec5SDimitry Andric            !PID->getPropertyDecl()->isClassProperty()))
21950b57cec5SDimitry Andric         return PID;
21960b57cec5SDimitry Andric 
21970b57cec5SDimitry Andric       if (PID->getPropertyDecl()->isClassProperty())
21980b57cec5SDimitry Andric         ClassPropImpl = PID;
21990b57cec5SDimitry Andric     }
22000b57cec5SDimitry Andric 
22010b57cec5SDimitry Andric   if (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown)
22020b57cec5SDimitry Andric     // We can't find the instance property, return the class property.
22030b57cec5SDimitry Andric     return ClassPropImpl;
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric   return nullptr;
22060b57cec5SDimitry Andric }
22070b57cec5SDimitry Andric 
22080b57cec5SDimitry Andric raw_ostream &clang::operator<<(raw_ostream &OS,
22090b57cec5SDimitry Andric                                const ObjCCategoryImplDecl &CID) {
22100b57cec5SDimitry Andric   OS << CID.getName();
22110b57cec5SDimitry Andric   return OS;
22120b57cec5SDimitry Andric }
22130b57cec5SDimitry Andric 
22140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22150b57cec5SDimitry Andric // ObjCImplementationDecl
22160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22170b57cec5SDimitry Andric 
22180b57cec5SDimitry Andric void ObjCImplementationDecl::anchor() {}
22190b57cec5SDimitry Andric 
22200b57cec5SDimitry Andric ObjCImplementationDecl *
22210b57cec5SDimitry Andric ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
22220b57cec5SDimitry Andric                                ObjCInterfaceDecl *ClassInterface,
22230b57cec5SDimitry Andric                                ObjCInterfaceDecl *SuperDecl,
22240b57cec5SDimitry Andric                                SourceLocation nameLoc,
22250b57cec5SDimitry Andric                                SourceLocation atStartLoc,
22260b57cec5SDimitry Andric                                SourceLocation superLoc,
22270b57cec5SDimitry Andric                                SourceLocation IvarLBraceLoc,
22280b57cec5SDimitry Andric                                SourceLocation IvarRBraceLoc) {
22290b57cec5SDimitry Andric   if (ClassInterface && ClassInterface->hasDefinition())
22300b57cec5SDimitry Andric     ClassInterface = ClassInterface->getDefinition();
22310b57cec5SDimitry Andric   return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
22320b57cec5SDimitry Andric                                             nameLoc, atStartLoc, superLoc,
22330b57cec5SDimitry Andric                                             IvarLBraceLoc, IvarRBraceLoc);
22340b57cec5SDimitry Andric }
22350b57cec5SDimitry Andric 
22360b57cec5SDimitry Andric ObjCImplementationDecl *
22370b57cec5SDimitry Andric ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
22380b57cec5SDimitry Andric   return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
22390b57cec5SDimitry Andric                                             SourceLocation(), SourceLocation());
22400b57cec5SDimitry Andric }
22410b57cec5SDimitry Andric 
22420b57cec5SDimitry Andric void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
22430b57cec5SDimitry Andric                                              CXXCtorInitializer ** initializers,
22440b57cec5SDimitry Andric                                                  unsigned numInitializers) {
22450b57cec5SDimitry Andric   if (numInitializers > 0) {
22460b57cec5SDimitry Andric     NumIvarInitializers = numInitializers;
22470b57cec5SDimitry Andric     auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];
22480b57cec5SDimitry Andric     memcpy(ivarInitializers, initializers,
22490b57cec5SDimitry Andric            numInitializers * sizeof(CXXCtorInitializer*));
22500b57cec5SDimitry Andric     IvarInitializers = ivarInitializers;
22510b57cec5SDimitry Andric   }
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric 
22540b57cec5SDimitry Andric ObjCImplementationDecl::init_const_iterator
22550b57cec5SDimitry Andric ObjCImplementationDecl::init_begin() const {
22560b57cec5SDimitry Andric   return IvarInitializers.get(getASTContext().getExternalSource());
22570b57cec5SDimitry Andric }
22580b57cec5SDimitry Andric 
22590b57cec5SDimitry Andric raw_ostream &clang::operator<<(raw_ostream &OS,
22600b57cec5SDimitry Andric                                const ObjCImplementationDecl &ID) {
22610b57cec5SDimitry Andric   OS << ID.getName();
22620b57cec5SDimitry Andric   return OS;
22630b57cec5SDimitry Andric }
22640b57cec5SDimitry Andric 
22650b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22660b57cec5SDimitry Andric // ObjCCompatibleAliasDecl
22670b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22680b57cec5SDimitry Andric 
22690b57cec5SDimitry Andric void ObjCCompatibleAliasDecl::anchor() {}
22700b57cec5SDimitry Andric 
22710b57cec5SDimitry Andric ObjCCompatibleAliasDecl *
22720b57cec5SDimitry Andric ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
22730b57cec5SDimitry Andric                                 SourceLocation L,
22740b57cec5SDimitry Andric                                 IdentifierInfo *Id,
22750b57cec5SDimitry Andric                                 ObjCInterfaceDecl* AliasedClass) {
22760b57cec5SDimitry Andric   return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
22770b57cec5SDimitry Andric }
22780b57cec5SDimitry Andric 
22790b57cec5SDimitry Andric ObjCCompatibleAliasDecl *
22800b57cec5SDimitry Andric ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
22810b57cec5SDimitry Andric   return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
22820b57cec5SDimitry Andric                                              nullptr, nullptr);
22830b57cec5SDimitry Andric }
22840b57cec5SDimitry Andric 
22850b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22860b57cec5SDimitry Andric // ObjCPropertyDecl
22870b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22880b57cec5SDimitry Andric 
22890b57cec5SDimitry Andric void ObjCPropertyDecl::anchor() {}
22900b57cec5SDimitry Andric 
22910b57cec5SDimitry Andric ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
22920b57cec5SDimitry Andric                                            SourceLocation L,
22930b57cec5SDimitry Andric                                            IdentifierInfo *Id,
22940b57cec5SDimitry Andric                                            SourceLocation AtLoc,
22950b57cec5SDimitry Andric                                            SourceLocation LParenLoc,
22960b57cec5SDimitry Andric                                            QualType T,
22970b57cec5SDimitry Andric                                            TypeSourceInfo *TSI,
22980b57cec5SDimitry Andric                                            PropertyControl propControl) {
22990b57cec5SDimitry Andric   return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,
23000b57cec5SDimitry Andric                                       propControl);
23010b57cec5SDimitry Andric }
23020b57cec5SDimitry Andric 
23030b57cec5SDimitry Andric ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
23040b57cec5SDimitry Andric                                                        unsigned ID) {
23050b57cec5SDimitry Andric   return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
23060b57cec5SDimitry Andric                                       SourceLocation(), SourceLocation(),
23070b57cec5SDimitry Andric                                       QualType(), nullptr, None);
23080b57cec5SDimitry Andric }
23090b57cec5SDimitry Andric 
23100b57cec5SDimitry Andric QualType ObjCPropertyDecl::getUsageType(QualType objectType) const {
23110b57cec5SDimitry Andric   return DeclType.substObjCMemberType(objectType, getDeclContext(),
23120b57cec5SDimitry Andric                                       ObjCSubstitutionContext::Property);
23130b57cec5SDimitry Andric }
23140b57cec5SDimitry Andric 
2315fe6060f1SDimitry Andric bool ObjCPropertyDecl::isDirectProperty() const {
2316fe6060f1SDimitry Andric   return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&
2317fe6060f1SDimitry Andric          !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
2318fe6060f1SDimitry Andric }
2319fe6060f1SDimitry Andric 
23200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23210b57cec5SDimitry Andric // ObjCPropertyImplDecl
23220b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
23250b57cec5SDimitry Andric                                                    DeclContext *DC,
23260b57cec5SDimitry Andric                                                    SourceLocation atLoc,
23270b57cec5SDimitry Andric                                                    SourceLocation L,
23280b57cec5SDimitry Andric                                                    ObjCPropertyDecl *property,
23290b57cec5SDimitry Andric                                                    Kind PK,
23300b57cec5SDimitry Andric                                                    ObjCIvarDecl *ivar,
23310b57cec5SDimitry Andric                                                    SourceLocation ivarLoc) {
23320b57cec5SDimitry Andric   return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
23330b57cec5SDimitry Andric                                           ivarLoc);
23340b57cec5SDimitry Andric }
23350b57cec5SDimitry Andric 
23360b57cec5SDimitry Andric ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
23370b57cec5SDimitry Andric                                                                unsigned ID) {
23380b57cec5SDimitry Andric   return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
23390b57cec5SDimitry Andric                                           SourceLocation(), nullptr, Dynamic,
23400b57cec5SDimitry Andric                                           nullptr, SourceLocation());
23410b57cec5SDimitry Andric }
23420b57cec5SDimitry Andric 
23430b57cec5SDimitry Andric SourceRange ObjCPropertyImplDecl::getSourceRange() const {
23440b57cec5SDimitry Andric   SourceLocation EndLoc = getLocation();
23450b57cec5SDimitry Andric   if (IvarLoc.isValid())
23460b57cec5SDimitry Andric     EndLoc = IvarLoc;
23470b57cec5SDimitry Andric 
23480b57cec5SDimitry Andric   return SourceRange(AtLoc, EndLoc);
23490b57cec5SDimitry Andric }
2350