Path: blob/main/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp
35259 views
//===- DeclObjC.cpp - ObjC Declaration AST Node Implementation ------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the Objective-C related Decl classes.9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/DeclObjC.h"13#include "clang/AST/ASTContext.h"14#include "clang/AST/ASTMutationListener.h"15#include "clang/AST/Attr.h"16#include "clang/AST/Decl.h"17#include "clang/AST/DeclBase.h"18#include "clang/AST/ODRHash.h"19#include "clang/AST/Stmt.h"20#include "clang/AST/Type.h"21#include "clang/AST/TypeLoc.h"22#include "clang/Basic/IdentifierTable.h"23#include "clang/Basic/LLVM.h"24#include "clang/Basic/LangOptions.h"25#include "clang/Basic/SourceLocation.h"26#include "llvm/ADT/SmallString.h"27#include "llvm/ADT/SmallVector.h"28#include "llvm/Support/Casting.h"29#include "llvm/Support/ErrorHandling.h"30#include "llvm/Support/raw_ostream.h"31#include <algorithm>32#include <cassert>33#include <cstdint>34#include <cstring>35#include <queue>36#include <utility>3738using namespace clang;3940//===----------------------------------------------------------------------===//41// ObjCListBase42//===----------------------------------------------------------------------===//4344void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {45List = nullptr;46if (Elts == 0) return; // Setting to an empty list is a noop.4748List = new (Ctx) void*[Elts];49NumElts = Elts;50memcpy(List, InList, sizeof(void*)*Elts);51}5253void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,54const SourceLocation *Locs, ASTContext &Ctx) {55if (Elts == 0)56return;5758Locations = new (Ctx) SourceLocation[Elts];59memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);60set(InList, Elts, Ctx);61}6263//===----------------------------------------------------------------------===//64// ObjCInterfaceDecl65//===----------------------------------------------------------------------===//6667ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,68const IdentifierInfo *Id,69SourceLocation nameLoc,70SourceLocation atStartLoc)71: NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {72setAtStartLoc(atStartLoc);73}7475void ObjCContainerDecl::anchor() {}7677/// getIvarDecl - This method looks up an ivar in this ContextDecl.78///79ObjCIvarDecl *80ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {81lookup_result R = lookup(Id);82for (lookup_iterator Ivar = R.begin(), IvarEnd = R.end();83Ivar != IvarEnd; ++Ivar) {84if (auto *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))85return ivar;86}87return nullptr;88}8990// Get the local instance/class method declared in this interface.91ObjCMethodDecl *92ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,93bool AllowHidden) const {94// If this context is a hidden protocol definition, don't find any95// methods there.96if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {97if (const ObjCProtocolDecl *Def = Proto->getDefinition())98if (!Def->isUnconditionallyVisible() && !AllowHidden)99return nullptr;100}101102// Since instance & class methods can have the same name, the loop below103// ensures we get the correct method.104//105// @interface Whatever106// - (int) class_method;107// + (float) class_method;108// @end109lookup_result R = lookup(Sel);110for (lookup_iterator Meth = R.begin(), MethEnd = R.end();111Meth != MethEnd; ++Meth) {112auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);113if (MD && MD->isInstanceMethod() == isInstance)114return MD;115}116return nullptr;117}118119/// This routine returns 'true' if a user declared setter method was120/// found in the class, its protocols, its super classes or categories.121/// It also returns 'true' if one of its categories has declared a 'readwrite'122/// property. This is because, user must provide a setter method for the123/// category's 'readwrite' property.124bool ObjCContainerDecl::HasUserDeclaredSetterMethod(125const ObjCPropertyDecl *Property) const {126Selector Sel = Property->getSetterName();127lookup_result R = lookup(Sel);128for (lookup_iterator Meth = R.begin(), MethEnd = R.end();129Meth != MethEnd; ++Meth) {130auto *MD = dyn_cast<ObjCMethodDecl>(*Meth);131if (MD && MD->isInstanceMethod() && !MD->isImplicit())132return true;133}134135if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {136// Also look into categories, including class extensions, looking137// for a user declared instance method.138for (const auto *Cat : ID->visible_categories()) {139if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))140if (!MD->isImplicit())141return true;142if (Cat->IsClassExtension())143continue;144// Also search through the categories looking for a 'readwrite'145// declaration of this property. If one found, presumably a setter will146// be provided (properties declared in categories will not get147// auto-synthesized).148for (const auto *P : Cat->properties())149if (P->getIdentifier() == Property->getIdentifier()) {150if (P->getPropertyAttributes() &151ObjCPropertyAttribute::kind_readwrite)152return true;153break;154}155}156157// Also look into protocols, for a user declared instance method.158for (const auto *Proto : ID->all_referenced_protocols())159if (Proto->HasUserDeclaredSetterMethod(Property))160return true;161162// And in its super class.163ObjCInterfaceDecl *OSC = ID->getSuperClass();164while (OSC) {165if (OSC->HasUserDeclaredSetterMethod(Property))166return true;167OSC = OSC->getSuperClass();168}169}170if (const auto *PD = dyn_cast<ObjCProtocolDecl>(this))171for (const auto *PI : PD->protocols())172if (PI->HasUserDeclaredSetterMethod(Property))173return true;174return false;175}176177ObjCPropertyDecl *178ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,179const IdentifierInfo *propertyID,180ObjCPropertyQueryKind queryKind) {181// If this context is a hidden protocol definition, don't find any182// property.183if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {184if (const ObjCProtocolDecl *Def = Proto->getDefinition())185if (!Def->isUnconditionallyVisible())186return nullptr;187}188189// If context is class, then lookup property in its visible extensions.190// This comes before property is looked up in primary class.191if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {192for (const auto *Ext : IDecl->visible_extensions())193if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,194propertyID,195queryKind))196return PD;197}198199DeclContext::lookup_result R = DC->lookup(propertyID);200ObjCPropertyDecl *classProp = nullptr;201for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;202++I)203if (auto *PD = dyn_cast<ObjCPropertyDecl>(*I)) {204// If queryKind is unknown, we return the instance property if one205// exists; otherwise we return the class property.206if ((queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown &&207!PD->isClassProperty()) ||208(queryKind == ObjCPropertyQueryKind::OBJC_PR_query_class &&209PD->isClassProperty()) ||210(queryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance &&211!PD->isClassProperty()))212return PD;213214if (PD->isClassProperty())215classProp = PD;216}217218if (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown)219// We can't find the instance property, return the class property.220return classProp;221222return nullptr;223}224225IdentifierInfo *226ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {227SmallString<128> ivarName;228{229llvm::raw_svector_ostream os(ivarName);230os << '_' << getIdentifier()->getName();231}232return &Ctx.Idents.get(ivarName.str());233}234235ObjCPropertyDecl *ObjCContainerDecl::getProperty(const IdentifierInfo *Id,236bool IsInstance) const {237for (auto *LookupResult : lookup(Id)) {238if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) {239if (Prop->isInstanceProperty() == IsInstance) {240return Prop;241}242}243}244return nullptr;245}246247/// FindPropertyDeclaration - Finds declaration of the property given its name248/// in 'PropertyId' and returns it. It returns 0, if not found.249ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(250const IdentifierInfo *PropertyId,251ObjCPropertyQueryKind QueryKind) const {252// Don't find properties within hidden protocol definitions.253if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) {254if (const ObjCProtocolDecl *Def = Proto->getDefinition())255if (!Def->isUnconditionallyVisible())256return nullptr;257}258259// Search the extensions of a class first; they override what's in260// the class itself.261if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) {262for (const auto *Ext : ClassDecl->visible_extensions()) {263if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind))264return P;265}266}267268if (ObjCPropertyDecl *PD =269ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,270QueryKind))271return PD;272273switch (getKind()) {274default:275break;276case Decl::ObjCProtocol: {277const auto *PID = cast<ObjCProtocolDecl>(this);278for (const auto *I : PID->protocols())279if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,280QueryKind))281return P;282break;283}284case Decl::ObjCInterface: {285const auto *OID = cast<ObjCInterfaceDecl>(this);286// Look through categories (but not extensions; they were handled above).287for (const auto *Cat : OID->visible_categories()) {288if (!Cat->IsClassExtension())289if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(290PropertyId, QueryKind))291return P;292}293294// Look through protocols.295for (const auto *I : OID->all_referenced_protocols())296if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,297QueryKind))298return P;299300// Finally, check the super class.301if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())302return superClass->FindPropertyDeclaration(PropertyId, QueryKind);303break;304}305case Decl::ObjCCategory: {306const auto *OCD = cast<ObjCCategoryDecl>(this);307// Look through protocols.308if (!OCD->IsClassExtension())309for (const auto *I : OCD->protocols())310if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,311QueryKind))312return P;313break;314}315}316return nullptr;317}318319void ObjCInterfaceDecl::anchor() {}320321ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const {322// If this particular declaration has a type parameter list, return it.323if (ObjCTypeParamList *written = getTypeParamListAsWritten())324return written;325326// If there is a definition, return its type parameter list.327if (const ObjCInterfaceDecl *def = getDefinition())328return def->getTypeParamListAsWritten();329330// Otherwise, look at previous declarations to determine whether any331// of them has a type parameter list, skipping over those332// declarations that do not.333for (const ObjCInterfaceDecl *decl = getMostRecentDecl(); decl;334decl = decl->getPreviousDecl()) {335if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten())336return written;337}338339return nullptr;340}341342void ObjCInterfaceDecl::setTypeParamList(ObjCTypeParamList *TPL) {343TypeParamList = TPL;344if (!TPL)345return;346// Set the declaration context of each of the type parameters.347for (auto *typeParam : *TypeParamList)348typeParam->setDeclContext(this);349}350351ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const {352// FIXME: Should make sure no callers ever do this.353if (!hasDefinition())354return nullptr;355356if (data().ExternallyCompleted)357LoadExternalDefinition();358359if (const ObjCObjectType *superType = getSuperClassType()) {360if (ObjCInterfaceDecl *superDecl = superType->getInterface()) {361if (ObjCInterfaceDecl *superDef = superDecl->getDefinition())362return superDef;363364return superDecl;365}366}367368return nullptr;369}370371SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const {372if (TypeSourceInfo *superTInfo = getSuperClassTInfo())373return superTInfo->getTypeLoc().getBeginLoc();374375return SourceLocation();376}377378/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property379/// with name 'PropertyId' in the primary class; including those in protocols380/// (direct or indirect) used by the primary class.381ObjCPropertyDecl *ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(382const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const {383// FIXME: Should make sure no callers ever do this.384if (!hasDefinition())385return nullptr;386387if (data().ExternallyCompleted)388LoadExternalDefinition();389390if (ObjCPropertyDecl *PD =391ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId,392QueryKind))393return PD;394395// Look through protocols.396for (const auto *I : all_referenced_protocols())397if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId,398QueryKind))399return P;400401return nullptr;402}403404void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM) const {405for (auto *Prop : properties()) {406PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;407}408for (const auto *Ext : known_extensions()) {409const ObjCCategoryDecl *ClassExt = Ext;410for (auto *Prop : ClassExt->properties()) {411PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;412}413}414for (const auto *PI : all_referenced_protocols())415PI->collectPropertiesToImplement(PM);416// Note, the properties declared only in class extensions are still copied417// into the main @interface's property list, and therefore we don't418// explicitly, have to search class extension properties.419}420421bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {422const ObjCInterfaceDecl *Class = this;423while (Class) {424if (Class->hasAttr<ArcWeakrefUnavailableAttr>())425return true;426Class = Class->getSuperClass();427}428return false;429}430431const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {432const ObjCInterfaceDecl *Class = this;433while (Class) {434if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())435return Class;436Class = Class->getSuperClass();437}438return nullptr;439}440441void ObjCInterfaceDecl::mergeClassExtensionProtocolList(442ObjCProtocolDecl *const* ExtList, unsigned ExtNum,443ASTContext &C) {444if (data().ExternallyCompleted)445LoadExternalDefinition();446447if (data().AllReferencedProtocols.empty() &&448data().ReferencedProtocols.empty()) {449data().AllReferencedProtocols.set(ExtList, ExtNum, C);450return;451}452453// Check for duplicate protocol in class's protocol list.454// This is O(n*m). But it is extremely rare and number of protocols in455// class or its extension are very few.456SmallVector<ObjCProtocolDecl *, 8> ProtocolRefs;457for (unsigned i = 0; i < ExtNum; i++) {458bool protocolExists = false;459ObjCProtocolDecl *ProtoInExtension = ExtList[i];460for (auto *Proto : all_referenced_protocols()) {461if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {462protocolExists = true;463break;464}465}466// Do we want to warn on a protocol in extension class which467// already exist in the class? Probably not.468if (!protocolExists)469ProtocolRefs.push_back(ProtoInExtension);470}471472if (ProtocolRefs.empty())473return;474475// Merge ProtocolRefs into class's protocol list;476ProtocolRefs.append(all_referenced_protocol_begin(),477all_referenced_protocol_end());478479data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);480}481482const ObjCInterfaceDecl *483ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {484const ObjCInterfaceDecl *IFace = this;485while (IFace) {486if (IFace->hasDesignatedInitializers())487return IFace;488if (!IFace->inheritsDesignatedInitializers())489break;490IFace = IFace->getSuperClass();491}492return nullptr;493}494495static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {496for (const auto *MD : D->instance_methods()) {497if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())498return true;499}500for (const auto *Ext : D->visible_extensions()) {501for (const auto *MD : Ext->instance_methods()) {502if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())503return true;504}505}506if (const auto *ImplD = D->getImplementation()) {507for (const auto *MD : ImplD->instance_methods()) {508if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())509return true;510}511}512return false;513}514515bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {516switch (data().InheritedDesignatedInitializers) {517case DefinitionData::IDI_Inherited:518return true;519case DefinitionData::IDI_NotInherited:520return false;521case DefinitionData::IDI_Unknown:522// If the class introduced initializers we conservatively assume that we523// don't know if any of them is a designated initializer to avoid possible524// misleading warnings.525if (isIntroducingInitializers(this)) {526data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;527} else {528if (auto SuperD = getSuperClass()) {529data().InheritedDesignatedInitializers =530SuperD->declaresOrInheritsDesignatedInitializers() ?531DefinitionData::IDI_Inherited :532DefinitionData::IDI_NotInherited;533} else {534data().InheritedDesignatedInitializers =535DefinitionData::IDI_NotInherited;536}537}538assert(data().InheritedDesignatedInitializers539!= DefinitionData::IDI_Unknown);540return data().InheritedDesignatedInitializers ==541DefinitionData::IDI_Inherited;542}543544llvm_unreachable("unexpected InheritedDesignatedInitializers value");545}546547void ObjCInterfaceDecl::getDesignatedInitializers(548llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {549// Check for a complete definition and recover if not so.550if (!isThisDeclarationADefinition())551return;552if (data().ExternallyCompleted)553LoadExternalDefinition();554555const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();556if (!IFace)557return;558559for (const auto *MD : IFace->instance_methods())560if (MD->isThisDeclarationADesignatedInitializer())561Methods.push_back(MD);562for (const auto *Ext : IFace->visible_extensions()) {563for (const auto *MD : Ext->instance_methods())564if (MD->isThisDeclarationADesignatedInitializer())565Methods.push_back(MD);566}567}568569bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,570const ObjCMethodDecl **InitMethod) const {571bool HasCompleteDef = isThisDeclarationADefinition();572// During deserialization the data record for the ObjCInterfaceDecl could573// be made invariant by reusing the canonical decl. Take this into account574// when checking for the complete definition.575if (!HasCompleteDef && getCanonicalDecl()->hasDefinition() &&576getCanonicalDecl()->getDefinition() == getDefinition())577HasCompleteDef = true;578579// Check for a complete definition and recover if not so.580if (!HasCompleteDef)581return false;582583if (data().ExternallyCompleted)584LoadExternalDefinition();585586const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();587if (!IFace)588return false;589590if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {591if (MD->isThisDeclarationADesignatedInitializer()) {592if (InitMethod)593*InitMethod = MD;594return true;595}596}597for (const auto *Ext : IFace->visible_extensions()) {598if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {599if (MD->isThisDeclarationADesignatedInitializer()) {600if (InitMethod)601*InitMethod = MD;602return true;603}604}605}606return false;607}608609void ObjCInterfaceDecl::allocateDefinitionData() {610assert(!hasDefinition() && "ObjC class already has a definition");611Data.setPointer(new (getASTContext()) DefinitionData());612Data.getPointer()->Definition = this;613}614615void ObjCInterfaceDecl::startDefinition() {616allocateDefinitionData();617618// Update all of the declarations with a pointer to the definition.619for (auto *RD : redecls()) {620if (RD != this)621RD->Data = Data;622}623}624625void ObjCInterfaceDecl::startDuplicateDefinitionForComparison() {626Data.setPointer(nullptr);627allocateDefinitionData();628// Don't propagate data to other redeclarations.629}630631void ObjCInterfaceDecl::mergeDuplicateDefinitionWithCommon(632const ObjCInterfaceDecl *Definition) {633Data = Definition->Data;634}635636ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,637ObjCInterfaceDecl *&clsDeclared) {638// FIXME: Should make sure no callers ever do this.639if (!hasDefinition())640return nullptr;641642if (data().ExternallyCompleted)643LoadExternalDefinition();644645ObjCInterfaceDecl* ClassDecl = this;646while (ClassDecl != nullptr) {647if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {648clsDeclared = ClassDecl;649return I;650}651652for (const auto *Ext : ClassDecl->visible_extensions()) {653if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {654clsDeclared = ClassDecl;655return I;656}657}658659ClassDecl = ClassDecl->getSuperClass();660}661return nullptr;662}663664/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super665/// class whose name is passed as argument. If it is not one of the super classes666/// the it returns NULL.667ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(668const IdentifierInfo*ICName) {669// FIXME: Should make sure no callers ever do this.670if (!hasDefinition())671return nullptr;672673if (data().ExternallyCompleted)674LoadExternalDefinition();675676ObjCInterfaceDecl* ClassDecl = this;677while (ClassDecl != nullptr) {678if (ClassDecl->getIdentifier() == ICName)679return ClassDecl;680ClassDecl = ClassDecl->getSuperClass();681}682return nullptr;683}684685ObjCProtocolDecl *686ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {687for (auto *P : all_referenced_protocols())688if (P->lookupProtocolNamed(Name))689return P;690ObjCInterfaceDecl *SuperClass = getSuperClass();691return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;692}693694/// lookupMethod - This method returns an instance/class method by looking in695/// the class, its categories, and its super classes (using a linear search).696/// When argument category "C" is specified, any implicit method found697/// in this category is ignored.698ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,699bool isInstance,700bool shallowCategoryLookup,701bool followSuper,702const ObjCCategoryDecl *C) const703{704// FIXME: Should make sure no callers ever do this.705if (!hasDefinition())706return nullptr;707708const ObjCInterfaceDecl* ClassDecl = this;709ObjCMethodDecl *MethodDecl = nullptr;710711if (data().ExternallyCompleted)712LoadExternalDefinition();713714while (ClassDecl) {715// 1. Look through primary class.716if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))717return MethodDecl;718719// 2. Didn't find one yet - now look through categories.720for (const auto *Cat : ClassDecl->visible_categories())721if ((MethodDecl = Cat->getMethod(Sel, isInstance)))722if (C != Cat || !MethodDecl->isImplicit())723return MethodDecl;724725// 3. Didn't find one yet - look through primary class's protocols.726for (const auto *I : ClassDecl->protocols())727if ((MethodDecl = I->lookupMethod(Sel, isInstance)))728return MethodDecl;729730// 4. Didn't find one yet - now look through categories' protocols731if (!shallowCategoryLookup)732for (const auto *Cat : ClassDecl->visible_categories()) {733// Didn't find one yet - look through protocols.734const ObjCList<ObjCProtocolDecl> &Protocols =735Cat->getReferencedProtocols();736for (auto *Protocol : Protocols)737if ((MethodDecl = Protocol->lookupMethod(Sel, isInstance)))738if (C != Cat || !MethodDecl->isImplicit())739return MethodDecl;740}741742743if (!followSuper)744return nullptr;745746// 5. Get to the super class (if any).747ClassDecl = ClassDecl->getSuperClass();748}749return nullptr;750}751752// Will search "local" class/category implementations for a method decl.753// If failed, then we search in class's root for an instance method.754// Returns 0 if no method is found.755ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(756const Selector &Sel,757bool Instance) const {758// FIXME: Should make sure no callers ever do this.759if (!hasDefinition())760return nullptr;761762if (data().ExternallyCompleted)763LoadExternalDefinition();764765ObjCMethodDecl *Method = nullptr;766if (ObjCImplementationDecl *ImpDecl = getImplementation())767Method = Instance ? ImpDecl->getInstanceMethod(Sel)768: ImpDecl->getClassMethod(Sel);769770// Look through local category implementations associated with the class.771if (!Method)772Method = getCategoryMethod(Sel, Instance);773774// Before we give up, check if the selector is an instance method.775// But only in the root. This matches gcc's behavior and what the776// runtime expects.777if (!Instance && !Method && !getSuperClass()) {778Method = lookupInstanceMethod(Sel);779// Look through local category implementations associated780// with the root class.781if (!Method)782Method = lookupPrivateMethod(Sel, true);783}784785if (!Method && getSuperClass())786return getSuperClass()->lookupPrivateMethod(Sel, Instance);787return Method;788}789790unsigned ObjCInterfaceDecl::getODRHash() {791assert(hasDefinition() && "ODRHash only for records with definitions");792793// Previously calculated hash is stored in DefinitionData.794if (hasODRHash())795return data().ODRHash;796797// Only calculate hash on first call of getODRHash per record.798ODRHash Hasher;799Hasher.AddObjCInterfaceDecl(getDefinition());800data().ODRHash = Hasher.CalculateHash();801setHasODRHash(true);802803return data().ODRHash;804}805806bool ObjCInterfaceDecl::hasODRHash() const {807if (!hasDefinition())808return false;809return data().HasODRHash;810}811812void ObjCInterfaceDecl::setHasODRHash(bool HasHash) {813assert(hasDefinition() && "Cannot set ODRHash without definition");814data().HasODRHash = HasHash;815}816817//===----------------------------------------------------------------------===//818// ObjCMethodDecl819//===----------------------------------------------------------------------===//820821ObjCMethodDecl::ObjCMethodDecl(822SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo,823QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl,824bool isInstance, bool isVariadic, bool isPropertyAccessor,825bool isSynthesizedAccessorStub, bool isImplicitlyDeclared, bool isDefined,826ObjCImplementationControl impControl, bool HasRelatedResultType)827: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),828DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),829DeclEndLoc(endLoc) {830831// Initialized the bits stored in DeclContext.832ObjCMethodDeclBits.Family =833static_cast<ObjCMethodFamily>(InvalidObjCMethodFamily);834setInstanceMethod(isInstance);835setVariadic(isVariadic);836setPropertyAccessor(isPropertyAccessor);837setSynthesizedAccessorStub(isSynthesizedAccessorStub);838setDefined(isDefined);839setIsRedeclaration(false);840setHasRedeclaration(false);841setDeclImplementation(impControl);842setObjCDeclQualifier(OBJC_TQ_None);843setRelatedResultType(HasRelatedResultType);844setSelLocsKind(SelLoc_StandardNoSpace);845setOverriding(false);846setHasSkippedBody(false);847848setImplicit(isImplicitlyDeclared);849}850851ObjCMethodDecl *ObjCMethodDecl::Create(852ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,853Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,854DeclContext *contextDecl, bool isInstance, bool isVariadic,855bool isPropertyAccessor, bool isSynthesizedAccessorStub,856bool isImplicitlyDeclared, bool isDefined,857ObjCImplementationControl impControl, bool HasRelatedResultType) {858return new (C, contextDecl) ObjCMethodDecl(859beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,860isVariadic, isPropertyAccessor, isSynthesizedAccessorStub,861isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType);862}863864ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C,865GlobalDeclID ID) {866return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),867Selector(), QualType(), nullptr, nullptr);868}869870bool ObjCMethodDecl::isDirectMethod() const {871return hasAttr<ObjCDirectAttr>() &&872!getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;873}874875bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {876return getMethodFamily() == OMF_init &&877hasAttr<ObjCDesignatedInitializerAttr>();878}879880bool ObjCMethodDecl::definedInNSObject(const ASTContext &Ctx) const {881if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext()))882return PD->getIdentifier() == Ctx.getNSObjectName();883if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext()))884return ID->getIdentifier() == Ctx.getNSObjectName();885return false;886}887888bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(889const ObjCMethodDecl **InitMethod) const {890if (getMethodFamily() != OMF_init)891return false;892const DeclContext *DC = getDeclContext();893if (isa<ObjCProtocolDecl>(DC))894return false;895if (const ObjCInterfaceDecl *ID = getClassInterface())896return ID->isDesignatedInitializer(getSelector(), InitMethod);897return false;898}899900bool ObjCMethodDecl::hasParamDestroyedInCallee() const {901for (auto *param : parameters()) {902if (param->isDestroyedInCallee())903return true;904}905return false;906}907908Stmt *ObjCMethodDecl::getBody() const {909return Body.get(getASTContext().getExternalSource());910}911912void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {913assert(PrevMethod);914getASTContext().setObjCMethodRedeclaration(PrevMethod, this);915setIsRedeclaration(true);916PrevMethod->setHasRedeclaration(true);917}918919void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,920ArrayRef<ParmVarDecl*> Params,921ArrayRef<SourceLocation> SelLocs) {922ParamsAndSelLocs = nullptr;923NumParams = Params.size();924if (Params.empty() && SelLocs.empty())925return;926927static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation),928"Alignment not sufficient for SourceLocation");929930unsigned Size = sizeof(ParmVarDecl *) * NumParams +931sizeof(SourceLocation) * SelLocs.size();932ParamsAndSelLocs = C.Allocate(Size);933std::uninitialized_copy(Params.begin(), Params.end(), getParams());934std::uninitialized_copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());935}936937void ObjCMethodDecl::getSelectorLocs(938SmallVectorImpl<SourceLocation> &SelLocs) const {939for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)940SelLocs.push_back(getSelectorLoc(i));941}942943void ObjCMethodDecl::setMethodParams(ASTContext &C,944ArrayRef<ParmVarDecl*> Params,945ArrayRef<SourceLocation> SelLocs) {946assert((!SelLocs.empty() || isImplicit()) &&947"No selector locs for non-implicit method");948if (isImplicit())949return setParamsAndSelLocs(C, Params, std::nullopt);950951setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params,952DeclEndLoc));953if (getSelLocsKind() != SelLoc_NonStandard)954return setParamsAndSelLocs(C, Params, std::nullopt);955956setParamsAndSelLocs(C, Params, SelLocs);957}958959/// A definition will return its interface declaration.960/// An interface declaration will return its definition.961/// Otherwise it will return itself.962ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {963ASTContext &Ctx = getASTContext();964ObjCMethodDecl *Redecl = nullptr;965if (hasRedeclaration())966Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));967if (Redecl)968return Redecl;969970auto *CtxD = cast<Decl>(getDeclContext());971972if (!CtxD->isInvalidDecl()) {973if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {974if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))975if (!ImplD->isInvalidDecl())976Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());977978} else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {979if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))980if (!ImplD->isInvalidDecl())981Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());982983} else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {984if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())985if (!IFD->isInvalidDecl())986Redecl = IFD->getMethod(getSelector(), isInstanceMethod());987988} else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {989if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())990if (!CatD->isInvalidDecl())991Redecl = CatD->getMethod(getSelector(), isInstanceMethod());992}993}994995// Ensure that the discovered method redeclaration has a valid declaration996// context. Used to prevent infinite loops when iterating redeclarations in997// a partially invalid AST.998if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl())999Redecl = nullptr;10001001if (!Redecl && isRedeclaration()) {1002// This is the last redeclaration, go back to the first method.1003return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),1004isInstanceMethod(),1005/*AllowHidden=*/true);1006}10071008return Redecl ? Redecl : this;1009}10101011ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {1012auto *CtxD = cast<Decl>(getDeclContext());1013const auto &Sel = getSelector();10141015if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {1016if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) {1017// When the container is the ObjCImplementationDecl (the primary1018// @implementation), then the canonical Decl is either in1019// the class Interface, or in any of its extension.1020//1021// So when we don't find it in the ObjCInterfaceDecl,1022// sift through extensions too.1023if (ObjCMethodDecl *MD = IFD->getMethod(Sel, isInstanceMethod()))1024return MD;1025for (auto *Ext : IFD->known_extensions())1026if (ObjCMethodDecl *MD = Ext->getMethod(Sel, isInstanceMethod()))1027return MD;1028}1029} else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) {1030if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())1031if (ObjCMethodDecl *MD = CatD->getMethod(Sel, isInstanceMethod()))1032return MD;1033}10341035if (isRedeclaration()) {1036// It is possible that we have not done deserializing the ObjCMethod yet.1037ObjCMethodDecl *MD =1038cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),1039/*AllowHidden=*/true);1040return MD ? MD : this;1041}10421043return this;1044}10451046SourceLocation ObjCMethodDecl::getEndLoc() const {1047if (Stmt *Body = getBody())1048return Body->getEndLoc();1049return DeclEndLoc;1050}10511052ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {1053auto family = static_cast<ObjCMethodFamily>(ObjCMethodDeclBits.Family);1054if (family != static_cast<unsigned>(InvalidObjCMethodFamily))1055return family;10561057// Check for an explicit attribute.1058if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {1059// The unfortunate necessity of mapping between enums here is due1060// to the attributes framework.1061switch (attr->getFamily()) {1062case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;1063case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;1064case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;1065case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;1066case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;1067case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;1068}1069ObjCMethodDeclBits.Family = family;1070return family;1071}10721073family = getSelector().getMethodFamily();1074switch (family) {1075case OMF_None: break;10761077// init only has a conventional meaning for an instance method, and1078// it has to return an object.1079case OMF_init:1080if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())1081family = OMF_None;1082break;10831084// alloc/copy/new have a conventional meaning for both class and1085// instance methods, but they require an object return.1086case OMF_alloc:1087case OMF_copy:1088case OMF_mutableCopy:1089case OMF_new:1090if (!getReturnType()->isObjCObjectPointerType())1091family = OMF_None;1092break;10931094// These selectors have a conventional meaning only for instance methods.1095case OMF_dealloc:1096case OMF_finalize:1097case OMF_retain:1098case OMF_release:1099case OMF_autorelease:1100case OMF_retainCount:1101case OMF_self:1102if (!isInstanceMethod())1103family = OMF_None;1104break;11051106case OMF_initialize:1107if (isInstanceMethod() || !getReturnType()->isVoidType())1108family = OMF_None;1109break;11101111case OMF_performSelector:1112if (!isInstanceMethod() || !getReturnType()->isObjCIdType())1113family = OMF_None;1114else {1115unsigned noParams = param_size();1116if (noParams < 1 || noParams > 3)1117family = OMF_None;1118else {1119ObjCMethodDecl::param_type_iterator it = param_type_begin();1120QualType ArgT = (*it);1121if (!ArgT->isObjCSelType()) {1122family = OMF_None;1123break;1124}1125while (--noParams) {1126it++;1127ArgT = (*it);1128if (!ArgT->isObjCIdType()) {1129family = OMF_None;1130break;1131}1132}1133}1134}1135break;11361137}11381139// Cache the result.1140ObjCMethodDeclBits.Family = family;1141return family;1142}11431144QualType ObjCMethodDecl::getSelfType(ASTContext &Context,1145const ObjCInterfaceDecl *OID,1146bool &selfIsPseudoStrong,1147bool &selfIsConsumed) const {1148QualType selfTy;1149selfIsPseudoStrong = false;1150selfIsConsumed = false;1151if (isInstanceMethod()) {1152// There may be no interface context due to error in declaration1153// of the interface (which has been reported). Recover gracefully.1154if (OID) {1155selfTy = Context.getObjCInterfaceType(OID);1156selfTy = Context.getObjCObjectPointerType(selfTy);1157} else {1158selfTy = Context.getObjCIdType();1159}1160} else // we have a factory method.1161selfTy = Context.getObjCClassType();11621163if (Context.getLangOpts().ObjCAutoRefCount) {1164if (isInstanceMethod()) {1165selfIsConsumed = hasAttr<NSConsumesSelfAttr>();11661167// 'self' is always __strong. It's actually pseudo-strong except1168// in init methods (or methods labeled ns_consumes_self), though.1169Qualifiers qs;1170qs.setObjCLifetime(Qualifiers::OCL_Strong);1171selfTy = Context.getQualifiedType(selfTy, qs);11721173// In addition, 'self' is const unless this is an init method.1174if (getMethodFamily() != OMF_init && !selfIsConsumed) {1175selfTy = selfTy.withConst();1176selfIsPseudoStrong = true;1177}1178}1179else {1180assert(isClassMethod());1181// 'self' is always const in class methods.1182selfTy = selfTy.withConst();1183selfIsPseudoStrong = true;1184}1185}1186return selfTy;1187}11881189void ObjCMethodDecl::createImplicitParams(ASTContext &Context,1190const ObjCInterfaceDecl *OID) {1191bool selfIsPseudoStrong, selfIsConsumed;1192QualType selfTy =1193getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed);1194auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(),1195&Context.Idents.get("self"), selfTy,1196ImplicitParamKind::ObjCSelf);1197setSelfDecl(Self);11981199if (selfIsConsumed)1200Self->addAttr(NSConsumedAttr::CreateImplicit(Context));12011202if (selfIsPseudoStrong)1203Self->setARCPseudoStrong(true);12041205setCmdDecl(ImplicitParamDecl::Create(1206Context, this, SourceLocation(), &Context.Idents.get("_cmd"),1207Context.getObjCSelType(), ImplicitParamKind::ObjCCmd));1208}12091210ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {1211if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))1212return ID;1213if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))1214return CD->getClassInterface();1215if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))1216return IMD->getClassInterface();1217if (isa<ObjCProtocolDecl>(getDeclContext()))1218return nullptr;1219llvm_unreachable("unknown method context");1220}12211222ObjCCategoryDecl *ObjCMethodDecl::getCategory() {1223if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))1224return CD;1225if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))1226return IMD->getCategoryDecl();1227return nullptr;1228}12291230SourceRange ObjCMethodDecl::getReturnTypeSourceRange() const {1231const auto *TSI = getReturnTypeSourceInfo();1232if (TSI)1233return TSI->getTypeLoc().getSourceRange();1234return SourceRange();1235}12361237QualType ObjCMethodDecl::getSendResultType() const {1238ASTContext &Ctx = getASTContext();1239return getReturnType().getNonLValueExprType(Ctx)1240.substObjCTypeArgs(Ctx, {}, ObjCSubstitutionContext::Result);1241}12421243QualType ObjCMethodDecl::getSendResultType(QualType receiverType) const {1244// FIXME: Handle related result types here.12451246return getReturnType().getNonLValueExprType(getASTContext())1247.substObjCMemberType(receiverType, getDeclContext(),1248ObjCSubstitutionContext::Result);1249}12501251static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,1252const ObjCMethodDecl *Method,1253SmallVectorImpl<const ObjCMethodDecl *> &Methods,1254bool MovedToSuper) {1255if (!Container)1256return;12571258// In categories look for overridden methods from protocols. A method from1259// category is not "overridden" since it is considered as the "same" method1260// (same USR) as the one from the interface.1261if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {1262// Check whether we have a matching method at this category but only if we1263// are at the super class level.1264if (MovedToSuper)1265if (ObjCMethodDecl *1266Overridden = Container->getMethod(Method->getSelector(),1267Method->isInstanceMethod(),1268/*AllowHidden=*/true))1269if (Method != Overridden) {1270// We found an override at this category; there is no need to look1271// into its protocols.1272Methods.push_back(Overridden);1273return;1274}12751276for (const auto *P : Category->protocols())1277CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);1278return;1279}12801281// Check whether we have a matching method at this level.1282if (const ObjCMethodDecl *1283Overridden = Container->getMethod(Method->getSelector(),1284Method->isInstanceMethod(),1285/*AllowHidden=*/true))1286if (Method != Overridden) {1287// We found an override at this level; there is no need to look1288// into other protocols or categories.1289Methods.push_back(Overridden);1290return;1291}12921293if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){1294for (const auto *P : Protocol->protocols())1295CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);1296}12971298if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {1299for (const auto *P : Interface->protocols())1300CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);13011302for (const auto *Cat : Interface->known_categories())1303CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);13041305if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())1306return CollectOverriddenMethodsRecurse(Super, Method, Methods,1307/*MovedToSuper=*/true);1308}1309}13101311static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,1312const ObjCMethodDecl *Method,1313SmallVectorImpl<const ObjCMethodDecl *> &Methods) {1314CollectOverriddenMethodsRecurse(Container, Method, Methods,1315/*MovedToSuper=*/false);1316}13171318static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,1319SmallVectorImpl<const ObjCMethodDecl *> &overridden) {1320assert(Method->isOverriding());13211322if (const auto *ProtD =1323dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {1324CollectOverriddenMethods(ProtD, Method, overridden);13251326} else if (const auto *IMD =1327dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {1328const ObjCInterfaceDecl *ID = IMD->getClassInterface();1329if (!ID)1330return;1331// Start searching for overridden methods using the method from the1332// interface as starting point.1333if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),1334Method->isInstanceMethod(),1335/*AllowHidden=*/true))1336Method = IFaceMeth;1337CollectOverriddenMethods(ID, Method, overridden);13381339} else if (const auto *CatD =1340dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {1341const ObjCInterfaceDecl *ID = CatD->getClassInterface();1342if (!ID)1343return;1344// Start searching for overridden methods using the method from the1345// interface as starting point.1346if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),1347Method->isInstanceMethod(),1348/*AllowHidden=*/true))1349Method = IFaceMeth;1350CollectOverriddenMethods(ID, Method, overridden);13511352} else {1353CollectOverriddenMethods(1354dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),1355Method, overridden);1356}1357}13581359void ObjCMethodDecl::getOverriddenMethods(1360SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {1361const ObjCMethodDecl *Method = this;13621363if (Method->isRedeclaration()) {1364Method = cast<ObjCContainerDecl>(Method->getDeclContext())1365->getMethod(Method->getSelector(), Method->isInstanceMethod(),1366/*AllowHidden=*/true);1367}13681369if (Method->isOverriding()) {1370collectOverriddenMethodsSlow(Method, Overridden);1371assert(!Overridden.empty() &&1372"ObjCMethodDecl's overriding bit is not as expected");1373}1374}13751376const ObjCPropertyDecl *1377ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {1378Selector Sel = getSelector();1379unsigned NumArgs = Sel.getNumArgs();1380if (NumArgs > 1)1381return nullptr;13821383if (isPropertyAccessor()) {1384const auto *Container = cast<ObjCContainerDecl>(getParent());1385// For accessor stubs, go back to the interface.1386if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container))1387if (isSynthesizedAccessorStub())1388Container = ImplDecl->getClassInterface();13891390bool IsGetter = (NumArgs == 0);1391bool IsInstance = isInstanceMethod();13921393/// Local function that attempts to find a matching property within the1394/// given Objective-C container.1395auto findMatchingProperty =1396[&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {1397if (IsInstance) {1398for (const auto *I : Container->instance_properties()) {1399Selector NextSel = IsGetter ? I->getGetterName()1400: I->getSetterName();1401if (NextSel == Sel)1402return I;1403}1404} else {1405for (const auto *I : Container->class_properties()) {1406Selector NextSel = IsGetter ? I->getGetterName()1407: I->getSetterName();1408if (NextSel == Sel)1409return I;1410}1411}14121413return nullptr;1414};14151416// Look in the container we were given.1417if (const auto *Found = findMatchingProperty(Container))1418return Found;14191420// If we're in a category or extension, look in the main class.1421const ObjCInterfaceDecl *ClassDecl = nullptr;1422if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {1423ClassDecl = Category->getClassInterface();1424if (const auto *Found = findMatchingProperty(ClassDecl))1425return Found;1426} else {1427// Determine whether the container is a class.1428ClassDecl = cast<ObjCInterfaceDecl>(Container);1429}1430assert(ClassDecl && "Failed to find main class");14311432// If we have a class, check its visible extensions.1433for (const auto *Ext : ClassDecl->visible_extensions()) {1434if (Ext == Container)1435continue;1436if (const auto *Found = findMatchingProperty(Ext))1437return Found;1438}14391440assert(isSynthesizedAccessorStub() && "expected an accessor stub");14411442for (const auto *Cat : ClassDecl->known_categories()) {1443if (Cat == Container)1444continue;1445if (const auto *Found = findMatchingProperty(Cat))1446return Found;1447}14481449llvm_unreachable("Marked as a property accessor but no property found!");1450}14511452if (!CheckOverrides)1453return nullptr;14541455using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;14561457OverridesTy Overrides;1458getOverriddenMethods(Overrides);1459for (const auto *Override : Overrides)1460if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(false))1461return Prop;14621463return nullptr;1464}14651466//===----------------------------------------------------------------------===//1467// ObjCTypeParamDecl1468//===----------------------------------------------------------------------===//14691470void ObjCTypeParamDecl::anchor() {}14711472ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc,1473ObjCTypeParamVariance variance,1474SourceLocation varianceLoc,1475unsigned index,1476SourceLocation nameLoc,1477IdentifierInfo *name,1478SourceLocation colonLoc,1479TypeSourceInfo *boundInfo) {1480auto *TPDecl =1481new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,1482nameLoc, name, colonLoc, boundInfo);1483QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});1484TPDecl->setTypeForDecl(TPType.getTypePtr());1485return TPDecl;1486}14871488ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx,1489GlobalDeclID ID) {1490return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr,1491ObjCTypeParamVariance::Invariant,1492SourceLocation(), 0, SourceLocation(),1493nullptr, SourceLocation(), nullptr);1494}14951496SourceRange ObjCTypeParamDecl::getSourceRange() const {1497SourceLocation startLoc = VarianceLoc;1498if (startLoc.isInvalid())1499startLoc = getLocation();15001501if (hasExplicitBound()) {1502return SourceRange(startLoc,1503getTypeSourceInfo()->getTypeLoc().getEndLoc());1504}15051506return SourceRange(startLoc);1507}15081509//===----------------------------------------------------------------------===//1510// ObjCTypeParamList1511//===----------------------------------------------------------------------===//1512ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,1513ArrayRef<ObjCTypeParamDecl *> typeParams,1514SourceLocation rAngleLoc)1515: Brackets(lAngleLoc, rAngleLoc), NumParams(typeParams.size()) {1516std::copy(typeParams.begin(), typeParams.end(), begin());1517}15181519ObjCTypeParamList *ObjCTypeParamList::create(1520ASTContext &ctx,1521SourceLocation lAngleLoc,1522ArrayRef<ObjCTypeParamDecl *> typeParams,1523SourceLocation rAngleLoc) {1524void *mem =1525ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()),1526alignof(ObjCTypeParamList));1527return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc);1528}15291530void ObjCTypeParamList::gatherDefaultTypeArgs(1531SmallVectorImpl<QualType> &typeArgs) const {1532typeArgs.reserve(size());1533for (auto *typeParam : *this)1534typeArgs.push_back(typeParam->getUnderlyingType());1535}15361537//===----------------------------------------------------------------------===//1538// ObjCInterfaceDecl1539//===----------------------------------------------------------------------===//15401541ObjCInterfaceDecl *ObjCInterfaceDecl::Create(1542const ASTContext &C, DeclContext *DC, SourceLocation atLoc,1543const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,1544ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal) {1545auto *Result = new (C, DC)1546ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl,1547isInternal);1548Result->Data.setInt(!C.getLangOpts().Modules);1549C.getObjCInterfaceType(Result, PrevDecl);1550return Result;1551}15521553ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,1554GlobalDeclID ID) {1555auto *Result = new (C, ID)1556ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,1557SourceLocation(), nullptr, false);1558Result->Data.setInt(!C.getLangOpts().Modules);1559return Result;1560}15611562ObjCInterfaceDecl::ObjCInterfaceDecl(1563const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,1564const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,1565SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal)1566: ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),1567redeclarable_base(C) {1568setPreviousDecl(PrevDecl);15691570// Copy the 'data' pointer over.1571if (PrevDecl)1572Data = PrevDecl->Data;15731574setImplicit(IsInternal);15751576setTypeParamList(typeParamList);1577}15781579void ObjCInterfaceDecl::LoadExternalDefinition() const {1580assert(data().ExternallyCompleted && "Class is not externally completed");1581data().ExternallyCompleted = false;1582getASTContext().getExternalSource()->CompleteType(1583const_cast<ObjCInterfaceDecl *>(this));1584}15851586void ObjCInterfaceDecl::setExternallyCompleted() {1587assert(getASTContext().getExternalSource() &&1588"Class can't be externally completed without an external source");1589assert(hasDefinition() &&1590"Forward declarations can't be externally completed");1591data().ExternallyCompleted = true;1592}15931594void ObjCInterfaceDecl::setHasDesignatedInitializers() {1595// Check for a complete definition and recover if not so.1596if (!isThisDeclarationADefinition())1597return;1598data().HasDesignatedInitializers = true;1599}16001601bool ObjCInterfaceDecl::hasDesignatedInitializers() const {1602// Check for a complete definition and recover if not so.1603if (!isThisDeclarationADefinition())1604return false;1605if (data().ExternallyCompleted)1606LoadExternalDefinition();16071608return data().HasDesignatedInitializers;1609}16101611StringRef1612ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {1613if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())1614return ObjCRTName->getMetadataName();16151616return getName();1617}16181619StringRef1620ObjCImplementationDecl::getObjCRuntimeNameAsString() const {1621if (ObjCInterfaceDecl *ID =1622const_cast<ObjCImplementationDecl*>(this)->getClassInterface())1623return ID->getObjCRuntimeNameAsString();16241625return getName();1626}16271628ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {1629if (const ObjCInterfaceDecl *Def = getDefinition()) {1630if (data().ExternallyCompleted)1631LoadExternalDefinition();16321633return getASTContext().getObjCImplementation(1634const_cast<ObjCInterfaceDecl*>(Def));1635}16361637// FIXME: Should make sure no callers ever do this.1638return nullptr;1639}16401641void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {1642getASTContext().setObjCImplementation(getDefinition(), ImplD);1643}16441645namespace {16461647struct SynthesizeIvarChunk {1648uint64_t Size;1649ObjCIvarDecl *Ivar;16501651SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)1652: Size(size), Ivar(ivar) {}1653};16541655bool operator<(const SynthesizeIvarChunk & LHS,1656const SynthesizeIvarChunk &RHS) {1657return LHS.Size < RHS.Size;1658}16591660} // namespace16611662/// all_declared_ivar_begin - return first ivar declared in this class,1663/// its extensions and its implementation. Lazily build the list on first1664/// access.1665///1666/// Caveat: The list returned by this method reflects the current1667/// state of the parser. The cache will be updated for every ivar1668/// added by an extension or the implementation when they are1669/// encountered.1670/// See also ObjCIvarDecl::Create().1671ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {1672// FIXME: Should make sure no callers ever do this.1673if (!hasDefinition())1674return nullptr;16751676ObjCIvarDecl *curIvar = nullptr;1677if (!data().IvarList) {1678// Force ivar deserialization upfront, before building IvarList.1679(void)ivar_empty();1680for (const auto *Ext : known_extensions()) {1681(void)Ext->ivar_empty();1682}1683if (!ivar_empty()) {1684ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();1685data().IvarList = *I; ++I;1686for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)1687curIvar->setNextIvar(*I);1688}16891690for (const auto *Ext : known_extensions()) {1691if (!Ext->ivar_empty()) {1692ObjCCategoryDecl::ivar_iterator1693I = Ext->ivar_begin(),1694E = Ext->ivar_end();1695if (!data().IvarList) {1696data().IvarList = *I; ++I;1697curIvar = data().IvarList;1698}1699for ( ;I != E; curIvar = *I, ++I)1700curIvar->setNextIvar(*I);1701}1702}1703data().IvarListMissingImplementation = true;1704}17051706// cached and complete!1707if (!data().IvarListMissingImplementation)1708return data().IvarList;17091710if (ObjCImplementationDecl *ImplDecl = getImplementation()) {1711data().IvarListMissingImplementation = false;1712if (!ImplDecl->ivar_empty()) {1713SmallVector<SynthesizeIvarChunk, 16> layout;1714for (auto *IV : ImplDecl->ivars()) {1715if (IV->getSynthesize() && !IV->isInvalidDecl()) {1716layout.push_back(SynthesizeIvarChunk(1717IV->getASTContext().getTypeSize(IV->getType()), IV));1718continue;1719}1720if (!data().IvarList)1721data().IvarList = IV;1722else1723curIvar->setNextIvar(IV);1724curIvar = IV;1725}17261727if (!layout.empty()) {1728// Order synthesized ivars by their size.1729llvm::stable_sort(layout);1730unsigned Ix = 0, EIx = layout.size();1731if (!data().IvarList) {1732data().IvarList = layout[0].Ivar; Ix++;1733curIvar = data().IvarList;1734}1735for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)1736curIvar->setNextIvar(layout[Ix].Ivar);1737}1738}1739}1740return data().IvarList;1741}17421743/// FindCategoryDeclaration - Finds category declaration in the list of1744/// categories for this class and returns it. Name of the category is passed1745/// in 'CategoryId'. If category not found, return 0;1746///1747ObjCCategoryDecl *ObjCInterfaceDecl::FindCategoryDeclaration(1748const IdentifierInfo *CategoryId) const {1749// FIXME: Should make sure no callers ever do this.1750if (!hasDefinition())1751return nullptr;17521753if (data().ExternallyCompleted)1754LoadExternalDefinition();17551756for (auto *Cat : visible_categories())1757if (Cat->getIdentifier() == CategoryId)1758return Cat;17591760return nullptr;1761}17621763ObjCMethodDecl *1764ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {1765for (const auto *Cat : visible_categories()) {1766if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())1767if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))1768return MD;1769}17701771return nullptr;1772}17731774ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {1775for (const auto *Cat : visible_categories()) {1776if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())1777if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))1778return MD;1779}17801781return nullptr;1782}17831784/// ClassImplementsProtocol - Checks that 'lProto' protocol1785/// has been implemented in IDecl class, its super class or categories (if1786/// lookupCategory is true).1787bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,1788bool lookupCategory,1789bool RHSIsQualifiedID) {1790if (!hasDefinition())1791return false;17921793ObjCInterfaceDecl *IDecl = this;1794// 1st, look up the class.1795for (auto *PI : IDecl->protocols()){1796if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))1797return true;1798// This is dubious and is added to be compatible with gcc. In gcc, it is1799// also allowed assigning a protocol-qualified 'id' type to a LHS object1800// when protocol in qualified LHS is in list of protocols in the rhs 'id'1801// object. This IMO, should be a bug.1802// FIXME: Treat this as an extension, and flag this as an error when GCC1803// extensions are not enabled.1804if (RHSIsQualifiedID &&1805getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))1806return true;1807}18081809// 2nd, look up the category.1810if (lookupCategory)1811for (const auto *Cat : visible_categories()) {1812for (auto *PI : Cat->protocols())1813if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))1814return true;1815}18161817// 3rd, look up the super class(s)1818if (IDecl->getSuperClass())1819return1820IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,1821RHSIsQualifiedID);18221823return false;1824}18251826//===----------------------------------------------------------------------===//1827// ObjCIvarDecl1828//===----------------------------------------------------------------------===//18291830void ObjCIvarDecl::anchor() {}18311832ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,1833SourceLocation StartLoc,1834SourceLocation IdLoc,1835const IdentifierInfo *Id, QualType T,1836TypeSourceInfo *TInfo, AccessControl ac,1837Expr *BW, bool synthesized) {1838if (DC) {1839// Ivar's can only appear in interfaces, implementations (via synthesized1840// properties), and class extensions (via direct declaration, or synthesized1841// properties).1842//1843// FIXME: This should really be asserting this:1844// (isa<ObjCCategoryDecl>(DC) &&1845// cast<ObjCCategoryDecl>(DC)->IsClassExtension()))1846// but unfortunately we sometimes place ivars into non-class extension1847// categories on error. This breaks an AST invariant, and should not be1848// fixed.1849assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||1850isa<ObjCCategoryDecl>(DC)) &&1851"Invalid ivar decl context!");1852// Once a new ivar is created in any of class/class-extension/implementation1853// decl contexts, the previously built IvarList must be rebuilt.1854auto *ID = dyn_cast<ObjCInterfaceDecl>(DC);1855if (!ID) {1856if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC))1857ID = IM->getClassInterface();1858else1859ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();1860}1861ID->setIvarList(nullptr);1862}18631864return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,1865synthesized);1866}18671868ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {1869return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),1870nullptr, QualType(), nullptr,1871ObjCIvarDecl::None, nullptr, false);1872}18731874ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() {1875auto *DC = cast<ObjCContainerDecl>(getDeclContext());18761877switch (DC->getKind()) {1878default:1879case ObjCCategoryImpl:1880case ObjCProtocol:1881llvm_unreachable("invalid ivar container!");18821883// Ivars can only appear in class extension categories.1884case ObjCCategory: {1885auto *CD = cast<ObjCCategoryDecl>(DC);1886assert(CD->IsClassExtension() && "invalid container for ivar!");1887return CD->getClassInterface();1888}18891890case ObjCImplementation:1891return cast<ObjCImplementationDecl>(DC)->getClassInterface();18921893case ObjCInterface:1894return cast<ObjCInterfaceDecl>(DC);1895}1896}18971898QualType ObjCIvarDecl::getUsageType(QualType objectType) const {1899return getType().substObjCMemberType(objectType, getDeclContext(),1900ObjCSubstitutionContext::Property);1901}19021903//===----------------------------------------------------------------------===//1904// ObjCAtDefsFieldDecl1905//===----------------------------------------------------------------------===//19061907void ObjCAtDefsFieldDecl::anchor() {}19081909ObjCAtDefsFieldDecl1910*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,1911SourceLocation StartLoc, SourceLocation IdLoc,1912IdentifierInfo *Id, QualType T, Expr *BW) {1913return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);1914}19151916ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,1917GlobalDeclID ID) {1918return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),1919SourceLocation(), nullptr, QualType(),1920nullptr);1921}19221923//===----------------------------------------------------------------------===//1924// ObjCProtocolDecl1925//===----------------------------------------------------------------------===//19261927void ObjCProtocolDecl::anchor() {}19281929ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,1930IdentifierInfo *Id, SourceLocation nameLoc,1931SourceLocation atStartLoc,1932ObjCProtocolDecl *PrevDecl)1933: ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),1934redeclarable_base(C) {1935setPreviousDecl(PrevDecl);1936if (PrevDecl)1937Data = PrevDecl->Data;1938}19391940ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,1941IdentifierInfo *Id,1942SourceLocation nameLoc,1943SourceLocation atStartLoc,1944ObjCProtocolDecl *PrevDecl) {1945auto *Result =1946new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);1947Result->Data.setInt(!C.getLangOpts().Modules);1948return Result;1949}19501951ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,1952GlobalDeclID ID) {1953ObjCProtocolDecl *Result =1954new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),1955SourceLocation(), nullptr);1956Result->Data.setInt(!C.getLangOpts().Modules);1957return Result;1958}19591960bool ObjCProtocolDecl::isNonRuntimeProtocol() const {1961return hasAttr<ObjCNonRuntimeProtocolAttr>();1962}19631964void ObjCProtocolDecl::getImpliedProtocols(1965llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const {1966std::queue<const ObjCProtocolDecl *> WorkQueue;1967WorkQueue.push(this);19681969while (!WorkQueue.empty()) {1970const auto *PD = WorkQueue.front();1971WorkQueue.pop();1972for (const auto *Parent : PD->protocols()) {1973const auto *Can = Parent->getCanonicalDecl();1974auto Result = IPs.insert(Can);1975if (Result.second)1976WorkQueue.push(Parent);1977}1978}1979}19801981ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {1982ObjCProtocolDecl *PDecl = this;19831984if (Name == getIdentifier())1985return PDecl;19861987for (auto *I : protocols())1988if ((PDecl = I->lookupProtocolNamed(Name)))1989return PDecl;19901991return nullptr;1992}19931994// lookupMethod - Lookup a instance/class method in the protocol and protocols1995// it inherited.1996ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,1997bool isInstance) const {1998ObjCMethodDecl *MethodDecl = nullptr;19992000// If there is no definition or the definition is hidden, we don't find2001// anything.2002const ObjCProtocolDecl *Def = getDefinition();2003if (!Def || !Def->isUnconditionallyVisible())2004return nullptr;20052006if ((MethodDecl = getMethod(Sel, isInstance)))2007return MethodDecl;20082009for (const auto *I : protocols())2010if ((MethodDecl = I->lookupMethod(Sel, isInstance)))2011return MethodDecl;2012return nullptr;2013}20142015void ObjCProtocolDecl::allocateDefinitionData() {2016assert(!Data.getPointer() && "Protocol already has a definition!");2017Data.setPointer(new (getASTContext()) DefinitionData);2018Data.getPointer()->Definition = this;2019Data.getPointer()->HasODRHash = false;2020}20212022void ObjCProtocolDecl::startDefinition() {2023allocateDefinitionData();20242025// Update all of the declarations with a pointer to the definition.2026for (auto *RD : redecls())2027RD->Data = this->Data;2028}20292030void ObjCProtocolDecl::startDuplicateDefinitionForComparison() {2031Data.setPointer(nullptr);2032allocateDefinitionData();2033// Don't propagate data to other redeclarations.2034}20352036void ObjCProtocolDecl::mergeDuplicateDefinitionWithCommon(2037const ObjCProtocolDecl *Definition) {2038Data = Definition->Data;2039}20402041void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM) const {2042if (const ObjCProtocolDecl *PDecl = getDefinition()) {2043for (auto *Prop : PDecl->properties()) {2044// Insert into PM if not there already.2045PM.insert(std::make_pair(2046std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()),2047Prop));2048}2049// Scan through protocol's protocols.2050for (const auto *PI : PDecl->protocols())2051PI->collectPropertiesToImplement(PM);2052}2053}20542055void ObjCProtocolDecl::collectInheritedProtocolProperties(2056const ObjCPropertyDecl *Property, ProtocolPropertySet &PS,2057PropertyDeclOrder &PO) const {2058if (const ObjCProtocolDecl *PDecl = getDefinition()) {2059if (!PS.insert(PDecl).second)2060return;2061for (auto *Prop : PDecl->properties()) {2062if (Prop == Property)2063continue;2064if (Prop->getIdentifier() == Property->getIdentifier()) {2065PO.push_back(Prop);2066return;2067}2068}2069// Scan through protocol's protocols which did not have a matching property.2070for (const auto *PI : PDecl->protocols())2071PI->collectInheritedProtocolProperties(Property, PS, PO);2072}2073}20742075StringRef2076ObjCProtocolDecl::getObjCRuntimeNameAsString() const {2077if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())2078return ObjCRTName->getMetadataName();20792080return getName();2081}20822083unsigned ObjCProtocolDecl::getODRHash() {2084assert(hasDefinition() && "ODRHash only for records with definitions");20852086// Previously calculated hash is stored in DefinitionData.2087if (hasODRHash())2088return data().ODRHash;20892090// Only calculate hash on first call of getODRHash per record.2091ODRHash Hasher;2092Hasher.AddObjCProtocolDecl(getDefinition());2093data().ODRHash = Hasher.CalculateHash();2094setHasODRHash(true);20952096return data().ODRHash;2097}20982099bool ObjCProtocolDecl::hasODRHash() const {2100if (!hasDefinition())2101return false;2102return data().HasODRHash;2103}21042105void ObjCProtocolDecl::setHasODRHash(bool HasHash) {2106assert(hasDefinition() && "Cannot set ODRHash without definition");2107data().HasODRHash = HasHash;2108}21092110//===----------------------------------------------------------------------===//2111// ObjCCategoryDecl2112//===----------------------------------------------------------------------===//21132114void ObjCCategoryDecl::anchor() {}21152116ObjCCategoryDecl::ObjCCategoryDecl(2117DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc,2118SourceLocation CategoryNameLoc, const IdentifierInfo *Id,2119ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList,2120SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc)2121: ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),2122ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),2123IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {2124setTypeParamList(typeParamList);2125}21262127ObjCCategoryDecl *ObjCCategoryDecl::Create(2128ASTContext &C, DeclContext *DC, SourceLocation AtLoc,2129SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,2130const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,2131ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,2132SourceLocation IvarRBraceLoc) {2133auto *CatDecl =2134new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,2135IDecl, typeParamList, IvarLBraceLoc,2136IvarRBraceLoc);2137if (IDecl) {2138// Link this category into its class's category list.2139CatDecl->NextClassCategory = IDecl->getCategoryListRaw();2140if (IDecl->hasDefinition()) {2141IDecl->setCategoryListRaw(CatDecl);2142if (ASTMutationListener *L = C.getASTMutationListener())2143L->AddedObjCCategoryToInterface(CatDecl, IDecl);2144}2145}21462147return CatDecl;2148}21492150ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,2151GlobalDeclID ID) {2152return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),2153SourceLocation(), SourceLocation(),2154nullptr, nullptr, nullptr);2155}21562157ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {2158return getASTContext().getObjCImplementation(2159const_cast<ObjCCategoryDecl*>(this));2160}21612162void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {2163getASTContext().setObjCImplementation(this, ImplD);2164}21652166void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) {2167TypeParamList = TPL;2168if (!TPL)2169return;2170// Set the declaration context of each of the type parameters.2171for (auto *typeParam : *TypeParamList)2172typeParam->setDeclContext(this);2173}21742175//===----------------------------------------------------------------------===//2176// ObjCCategoryImplDecl2177//===----------------------------------------------------------------------===//21782179void ObjCCategoryImplDecl::anchor() {}21802181ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create(2182ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,2183ObjCInterfaceDecl *ClassInterface, SourceLocation nameLoc,2184SourceLocation atStartLoc, SourceLocation CategoryNameLoc) {2185if (ClassInterface && ClassInterface->hasDefinition())2186ClassInterface = ClassInterface->getDefinition();2187return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,2188atStartLoc, CategoryNameLoc);2189}21902191ObjCCategoryImplDecl *2192ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {2193return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,2194SourceLocation(), SourceLocation(),2195SourceLocation());2196}21972198ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {2199// The class interface might be NULL if we are working with invalid code.2200if (const ObjCInterfaceDecl *ID = getClassInterface())2201return ID->FindCategoryDeclaration(getIdentifier());2202return nullptr;2203}22042205void ObjCImplDecl::anchor() {}22062207void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {2208// FIXME: The context should be correct before we get here.2209property->setLexicalDeclContext(this);2210addDecl(property);2211}22122213void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {2214ASTContext &Ctx = getASTContext();22152216if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) {2217if (IFace)2218Ctx.setObjCImplementation(IFace, ImplD);22192220} else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {2221if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))2222Ctx.setObjCImplementation(CD, ImplD);2223}22242225ClassInterface = IFace;2226}22272228/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of2229/// properties implemented in this \@implementation block and returns2230/// the implemented property that uses it.2231ObjCPropertyImplDecl *ObjCImplDecl::2232FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {2233for (auto *PID : property_impls())2234if (PID->getPropertyIvarDecl() &&2235PID->getPropertyIvarDecl()->getIdentifier() == ivarId)2236return PID;2237return nullptr;2238}22392240/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl2241/// added to the list of those properties \@synthesized/\@dynamic in this2242/// category \@implementation block.2243ObjCPropertyImplDecl *ObjCImplDecl::2244FindPropertyImplDecl(IdentifierInfo *Id,2245ObjCPropertyQueryKind QueryKind) const {2246ObjCPropertyImplDecl *ClassPropImpl = nullptr;2247for (auto *PID : property_impls())2248// If queryKind is unknown, we return the instance property if one2249// exists; otherwise we return the class property.2250if (PID->getPropertyDecl()->getIdentifier() == Id) {2251if ((QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown &&2252!PID->getPropertyDecl()->isClassProperty()) ||2253(QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_class &&2254PID->getPropertyDecl()->isClassProperty()) ||2255(QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance &&2256!PID->getPropertyDecl()->isClassProperty()))2257return PID;22582259if (PID->getPropertyDecl()->isClassProperty())2260ClassPropImpl = PID;2261}22622263if (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown)2264// We can't find the instance property, return the class property.2265return ClassPropImpl;22662267return nullptr;2268}22692270raw_ostream &clang::operator<<(raw_ostream &OS,2271const ObjCCategoryImplDecl &CID) {2272OS << CID.getName();2273return OS;2274}22752276//===----------------------------------------------------------------------===//2277// ObjCImplementationDecl2278//===----------------------------------------------------------------------===//22792280void ObjCImplementationDecl::anchor() {}22812282ObjCImplementationDecl *2283ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,2284ObjCInterfaceDecl *ClassInterface,2285ObjCInterfaceDecl *SuperDecl,2286SourceLocation nameLoc,2287SourceLocation atStartLoc,2288SourceLocation superLoc,2289SourceLocation IvarLBraceLoc,2290SourceLocation IvarRBraceLoc) {2291if (ClassInterface && ClassInterface->hasDefinition())2292ClassInterface = ClassInterface->getDefinition();2293return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,2294nameLoc, atStartLoc, superLoc,2295IvarLBraceLoc, IvarRBraceLoc);2296}22972298ObjCImplementationDecl *2299ObjCImplementationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {2300return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,2301SourceLocation(), SourceLocation());2302}23032304void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,2305CXXCtorInitializer ** initializers,2306unsigned numInitializers) {2307if (numInitializers > 0) {2308NumIvarInitializers = numInitializers;2309auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers];2310memcpy(ivarInitializers, initializers,2311numInitializers * sizeof(CXXCtorInitializer*));2312IvarInitializers = ivarInitializers;2313}2314}23152316ObjCImplementationDecl::init_const_iterator2317ObjCImplementationDecl::init_begin() const {2318return IvarInitializers.get(getASTContext().getExternalSource());2319}23202321raw_ostream &clang::operator<<(raw_ostream &OS,2322const ObjCImplementationDecl &ID) {2323OS << ID.getName();2324return OS;2325}23262327//===----------------------------------------------------------------------===//2328// ObjCCompatibleAliasDecl2329//===----------------------------------------------------------------------===//23302331void ObjCCompatibleAliasDecl::anchor() {}23322333ObjCCompatibleAliasDecl *2334ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,2335SourceLocation L,2336IdentifierInfo *Id,2337ObjCInterfaceDecl* AliasedClass) {2338return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);2339}23402341ObjCCompatibleAliasDecl *2342ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {2343return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),2344nullptr, nullptr);2345}23462347//===----------------------------------------------------------------------===//2348// ObjCPropertyDecl2349//===----------------------------------------------------------------------===//23502351void ObjCPropertyDecl::anchor() {}23522353ObjCPropertyDecl *2354ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,2355const IdentifierInfo *Id, SourceLocation AtLoc,2356SourceLocation LParenLoc, QualType T,2357TypeSourceInfo *TSI, PropertyControl propControl) {2358return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI,2359propControl);2360}23612362ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,2363GlobalDeclID ID) {2364return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,2365SourceLocation(), SourceLocation(),2366QualType(), nullptr, None);2367}23682369QualType ObjCPropertyDecl::getUsageType(QualType objectType) const {2370return DeclType.substObjCMemberType(objectType, getDeclContext(),2371ObjCSubstitutionContext::Property);2372}23732374bool ObjCPropertyDecl::isDirectProperty() const {2375return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) &&2376!getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;2377}23782379//===----------------------------------------------------------------------===//2380// ObjCPropertyImplDecl2381//===----------------------------------------------------------------------===//23822383ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,2384DeclContext *DC,2385SourceLocation atLoc,2386SourceLocation L,2387ObjCPropertyDecl *property,2388Kind PK,2389ObjCIvarDecl *ivar,2390SourceLocation ivarLoc) {2391return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,2392ivarLoc);2393}23942395ObjCPropertyImplDecl *2396ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {2397return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),2398SourceLocation(), nullptr, Dynamic,2399nullptr, SourceLocation());2400}24012402SourceRange ObjCPropertyImplDecl::getSourceRange() const {2403SourceLocation EndLoc = getLocation();2404if (IvarLoc.isValid())2405EndLoc = IvarLoc;24062407return SourceRange(AtLoc, EndLoc);2408}240924102411