diff options
| author | 2020-08-03 15:06:44 +0000 | |
|---|---|---|
| committer | 2020-08-03 15:06:44 +0000 | |
| commit | b64793999546ed8adebaeebd9d8345d18db8927d (patch) | |
| tree | 4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/tools/clang/lib/AST/DeclObjC.cpp | |
| parent | Add support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff) | |
| download | wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip | |
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/AST/DeclObjC.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/AST/DeclObjC.cpp | 2272 |
1 files changed, 0 insertions, 2272 deletions
diff --git a/gnu/llvm/tools/clang/lib/AST/DeclObjC.cpp b/gnu/llvm/tools/clang/lib/AST/DeclObjC.cpp deleted file mode 100644 index 1ed7fc71b02..00000000000 --- a/gnu/llvm/tools/clang/lib/AST/DeclObjC.cpp +++ /dev/null @@ -1,2272 +0,0 @@ -//===- DeclObjC.cpp - ObjC Declaration AST Node Implementation ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Objective-C related Decl classes. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/DeclObjC.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/ASTMutationListener.h" -#include "clang/AST/Attr.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclBase.h" -#include "clang/AST/Stmt.h" -#include "clang/AST/Type.h" -#include "clang/AST/TypeLoc.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/LLVM.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/SourceLocation.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> -#include <cassert> -#include <cstdint> -#include <cstring> -#include <utility> - -using namespace clang; - -//===----------------------------------------------------------------------===// -// ObjCListBase -//===----------------------------------------------------------------------===// - -void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) { - List = nullptr; - if (Elts == 0) return; // Setting to an empty list is a noop. - - List = new (Ctx) void*[Elts]; - NumElts = Elts; - memcpy(List, InList, sizeof(void*)*Elts); -} - -void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, - const SourceLocation *Locs, ASTContext &Ctx) { - if (Elts == 0) - return; - - Locations = new (Ctx) SourceLocation[Elts]; - memcpy(Locations, Locs, sizeof(SourceLocation) * Elts); - set(InList, Elts, Ctx); -} - -//===----------------------------------------------------------------------===// -// ObjCInterfaceDecl -//===----------------------------------------------------------------------===// - -ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC, - IdentifierInfo *Id, SourceLocation nameLoc, - SourceLocation atStartLoc) - : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) { - setAtStartLoc(atStartLoc); -} - -void ObjCContainerDecl::anchor() {} - -/// getIvarDecl - This method looks up an ivar in this ContextDecl. -/// -ObjCIvarDecl * -ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const { - lookup_result R = lookup(Id); - for (lookup_iterator Ivar = R.begin(), IvarEnd = R.end(); - Ivar != IvarEnd; ++Ivar) { - if (auto *ivar = dyn_cast<ObjCIvarDecl>(*Ivar)) - return ivar; - } - return nullptr; -} - -// Get the local instance/class method declared in this interface. -ObjCMethodDecl * -ObjCContainerDecl::getMethod(Selector Sel, bool isInstance, - bool AllowHidden) const { - // If this context is a hidden protocol definition, don't find any - // methods there. - if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) { - if (const ObjCProtocolDecl *Def = Proto->getDefinition()) - if (Def->isHidden() && !AllowHidden) - return nullptr; - } - - // Since instance & class methods can have the same name, the loop below - // ensures we get the correct method. - // - // @interface Whatever - // - (int) class_method; - // + (float) class_method; - // @end - lookup_result R = lookup(Sel); - for (lookup_iterator Meth = R.begin(), MethEnd = R.end(); - Meth != MethEnd; ++Meth) { - auto *MD = dyn_cast<ObjCMethodDecl>(*Meth); - if (MD && MD->isInstanceMethod() == isInstance) - return MD; - } - return nullptr; -} - -/// This routine returns 'true' if a user declared setter method was -/// found in the class, its protocols, its super classes or categories. -/// It also returns 'true' if one of its categories has declared a 'readwrite' -/// property. This is because, user must provide a setter method for the -/// category's 'readwrite' property. -bool ObjCContainerDecl::HasUserDeclaredSetterMethod( - const ObjCPropertyDecl *Property) const { - Selector Sel = Property->getSetterName(); - lookup_result R = lookup(Sel); - for (lookup_iterator Meth = R.begin(), MethEnd = R.end(); - Meth != MethEnd; ++Meth) { - auto *MD = dyn_cast<ObjCMethodDecl>(*Meth); - if (MD && MD->isInstanceMethod() && !MD->isImplicit()) - return true; - } - - if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) { - // Also look into categories, including class extensions, looking - // for a user declared instance method. - for (const auto *Cat : ID->visible_categories()) { - if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel)) - if (!MD->isImplicit()) - return true; - if (Cat->IsClassExtension()) - continue; - // Also search through the categories looking for a 'readwrite' - // declaration of this property. If one found, presumably a setter will - // be provided (properties declared in categories will not get - // auto-synthesized). - for (const auto *P : Cat->properties()) - if (P->getIdentifier() == Property->getIdentifier()) { - if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) - return true; - break; - } - } - - // Also look into protocols, for a user declared instance method. - for (const auto *Proto : ID->all_referenced_protocols()) - if (Proto->HasUserDeclaredSetterMethod(Property)) - return true; - - // And in its super class. - ObjCInterfaceDecl *OSC = ID->getSuperClass(); - while (OSC) { - if (OSC->HasUserDeclaredSetterMethod(Property)) - return true; - OSC = OSC->getSuperClass(); - } - } - if (const auto *PD = dyn_cast<ObjCProtocolDecl>(this)) - for (const auto *PI : PD->protocols()) - if (PI->HasUserDeclaredSetterMethod(Property)) - return true; - return false; -} - -ObjCPropertyDecl * -ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC, - const IdentifierInfo *propertyID, - ObjCPropertyQueryKind queryKind) { - // If this context is a hidden protocol definition, don't find any - // property. - if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(DC)) { - if (const ObjCProtocolDecl *Def = Proto->getDefinition()) - if (Def->isHidden()) - return nullptr; - } - - // If context is class, then lookup property in its visible extensions. - // This comes before property is looked up in primary class. - if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) { - for (const auto *Ext : IDecl->visible_extensions()) - if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext, - propertyID, - queryKind)) - return PD; - } - - DeclContext::lookup_result R = DC->lookup(propertyID); - ObjCPropertyDecl *classProp = nullptr; - for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; - ++I) - if (auto *PD = dyn_cast<ObjCPropertyDecl>(*I)) { - // If queryKind is unknown, we return the instance property if one - // exists; otherwise we return the class property. - if ((queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown && - !PD->isClassProperty()) || - (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_class && - PD->isClassProperty()) || - (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance && - !PD->isClassProperty())) - return PD; - - if (PD->isClassProperty()) - classProp = PD; - } - - if (queryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown) - // We can't find the instance property, return the class property. - return classProp; - - return nullptr; -} - -IdentifierInfo * -ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const { - SmallString<128> ivarName; - { - llvm::raw_svector_ostream os(ivarName); - os << '_' << getIdentifier()->getName(); - } - return &Ctx.Idents.get(ivarName.str()); -} - -/// FindPropertyDeclaration - Finds declaration of the property given its name -/// in 'PropertyId' and returns it. It returns 0, if not found. -ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( - const IdentifierInfo *PropertyId, - ObjCPropertyQueryKind QueryKind) const { - // Don't find properties within hidden protocol definitions. - if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(this)) { - if (const ObjCProtocolDecl *Def = Proto->getDefinition()) - if (Def->isHidden()) - return nullptr; - } - - // Search the extensions of a class first; they override what's in - // the class itself. - if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) { - for (const auto *Ext : ClassDecl->visible_extensions()) { - if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind)) - return P; - } - } - - if (ObjCPropertyDecl *PD = - ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId, - QueryKind)) - return PD; - - switch (getKind()) { - default: - break; - case Decl::ObjCProtocol: { - const auto *PID = cast<ObjCProtocolDecl>(this); - for (const auto *I : PID->protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) - return P; - break; - } - case Decl::ObjCInterface: { - const auto *OID = cast<ObjCInterfaceDecl>(this); - // Look through categories (but not extensions; they were handled above). - for (const auto *Cat : OID->visible_categories()) { - if (!Cat->IsClassExtension()) - if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration( - PropertyId, QueryKind)) - return P; - } - - // Look through protocols. - for (const auto *I : OID->all_referenced_protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) - return P; - - // Finally, check the super class. - if (const ObjCInterfaceDecl *superClass = OID->getSuperClass()) - return superClass->FindPropertyDeclaration(PropertyId, QueryKind); - break; - } - case Decl::ObjCCategory: { - const auto *OCD = cast<ObjCCategoryDecl>(this); - // Look through protocols. - if (!OCD->IsClassExtension()) - for (const auto *I : OCD->protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) - return P; - break; - } - } - return nullptr; -} - -void ObjCInterfaceDecl::anchor() {} - -ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const { - // If this particular declaration has a type parameter list, return it. - if (ObjCTypeParamList *written = getTypeParamListAsWritten()) - return written; - - // If there is a definition, return its type parameter list. - if (const ObjCInterfaceDecl *def = getDefinition()) - return def->getTypeParamListAsWritten(); - - // Otherwise, look at previous declarations to determine whether any - // of them has a type parameter list, skipping over those - // declarations that do not. - for (const ObjCInterfaceDecl *decl = getMostRecentDecl(); decl; - decl = decl->getPreviousDecl()) { - if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten()) - return written; - } - - return nullptr; -} - -void ObjCInterfaceDecl::setTypeParamList(ObjCTypeParamList *TPL) { - TypeParamList = TPL; - if (!TPL) - return; - // Set the declaration context of each of the type parameters. - for (auto *typeParam : *TypeParamList) - typeParam->setDeclContext(this); -} - -ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const { - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - if (const ObjCObjectType *superType = getSuperClassType()) { - if (ObjCInterfaceDecl *superDecl = superType->getInterface()) { - if (ObjCInterfaceDecl *superDef = superDecl->getDefinition()) - return superDef; - - return superDecl; - } - } - - return nullptr; -} - -SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const { - if (TypeSourceInfo *superTInfo = getSuperClassTInfo()) - return superTInfo->getTypeLoc().getBeginLoc(); - - return SourceLocation(); -} - -/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property -/// with name 'PropertyId' in the primary class; including those in protocols -/// (direct or indirect) used by the primary class. -ObjCPropertyDecl * -ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( - IdentifierInfo *PropertyId, - ObjCPropertyQueryKind QueryKind) const { - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - if (ObjCPropertyDecl *PD = - ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId, - QueryKind)) - return PD; - - // Look through protocols. - for (const auto *I : all_referenced_protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) - return P; - - return nullptr; -} - -void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM, - PropertyDeclOrder &PO) const { - for (auto *Prop : properties()) { - PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop; - PO.push_back(Prop); - } - for (const auto *Ext : known_extensions()) { - const ObjCCategoryDecl *ClassExt = Ext; - for (auto *Prop : ClassExt->properties()) { - PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop; - PO.push_back(Prop); - } - } - for (const auto *PI : all_referenced_protocols()) - PI->collectPropertiesToImplement(PM, PO); - // Note, the properties declared only in class extensions are still copied - // into the main @interface's property list, and therefore we don't - // explicitly, have to search class extension properties. -} - -bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const { - const ObjCInterfaceDecl *Class = this; - while (Class) { - if (Class->hasAttr<ArcWeakrefUnavailableAttr>()) - return true; - Class = Class->getSuperClass(); - } - return false; -} - -const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const { - const ObjCInterfaceDecl *Class = this; - while (Class) { - if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>()) - return Class; - Class = Class->getSuperClass(); - } - return nullptr; -} - -void ObjCInterfaceDecl::mergeClassExtensionProtocolList( - ObjCProtocolDecl *const* ExtList, unsigned ExtNum, - ASTContext &C) { - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - if (data().AllReferencedProtocols.empty() && - data().ReferencedProtocols.empty()) { - data().AllReferencedProtocols.set(ExtList, ExtNum, C); - return; - } - - // Check for duplicate protocol in class's protocol list. - // This is O(n*m). But it is extremely rare and number of protocols in - // class or its extension are very few. - SmallVector<ObjCProtocolDecl *, 8> ProtocolRefs; - for (unsigned i = 0; i < ExtNum; i++) { - bool protocolExists = false; - ObjCProtocolDecl *ProtoInExtension = ExtList[i]; - for (auto *Proto : all_referenced_protocols()) { - if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) { - protocolExists = true; - break; - } - } - // Do we want to warn on a protocol in extension class which - // already exist in the class? Probably not. - if (!protocolExists) - ProtocolRefs.push_back(ProtoInExtension); - } - - if (ProtocolRefs.empty()) - return; - - // Merge ProtocolRefs into class's protocol list; - ProtocolRefs.append(all_referenced_protocol_begin(), - all_referenced_protocol_end()); - - data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C); -} - -const ObjCInterfaceDecl * -ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const { - const ObjCInterfaceDecl *IFace = this; - while (IFace) { - if (IFace->hasDesignatedInitializers()) - return IFace; - if (!IFace->inheritsDesignatedInitializers()) - break; - IFace = IFace->getSuperClass(); - } - return nullptr; -} - -static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) { - for (const auto *MD : D->instance_methods()) { - if (MD->getMethodFamily() == OMF_init && !MD->isOverriding()) - return true; - } - for (const auto *Ext : D->visible_extensions()) { - for (const auto *MD : Ext->instance_methods()) { - if (MD->getMethodFamily() == OMF_init && !MD->isOverriding()) - return true; - } - } - if (const auto *ImplD = D->getImplementation()) { - for (const auto *MD : ImplD->instance_methods()) { - if (MD->getMethodFamily() == OMF_init && !MD->isOverriding()) - return true; - } - } - return false; -} - -bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const { - switch (data().InheritedDesignatedInitializers) { - case DefinitionData::IDI_Inherited: - return true; - case DefinitionData::IDI_NotInherited: - return false; - case DefinitionData::IDI_Unknown: - // If the class introduced initializers we conservatively assume that we - // don't know if any of them is a designated initializer to avoid possible - // misleading warnings. - if (isIntroducingInitializers(this)) { - data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited; - } else { - if (auto SuperD = getSuperClass()) { - data().InheritedDesignatedInitializers = - SuperD->declaresOrInheritsDesignatedInitializers() ? - DefinitionData::IDI_Inherited : - DefinitionData::IDI_NotInherited; - } else { - data().InheritedDesignatedInitializers = - DefinitionData::IDI_NotInherited; - } - } - assert(data().InheritedDesignatedInitializers - != DefinitionData::IDI_Unknown); - return data().InheritedDesignatedInitializers == - DefinitionData::IDI_Inherited; - } - - llvm_unreachable("unexpected InheritedDesignatedInitializers value"); -} - -void ObjCInterfaceDecl::getDesignatedInitializers( - llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const { - // Check for a complete definition and recover if not so. - if (!isThisDeclarationADefinition()) - return; - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers(); - if (!IFace) - return; - - for (const auto *MD : IFace->instance_methods()) - if (MD->isThisDeclarationADesignatedInitializer()) - Methods.push_back(MD); - for (const auto *Ext : IFace->visible_extensions()) { - for (const auto *MD : Ext->instance_methods()) - if (MD->isThisDeclarationADesignatedInitializer()) - Methods.push_back(MD); - } -} - -bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel, - const ObjCMethodDecl **InitMethod) const { - bool HasCompleteDef = isThisDeclarationADefinition(); - // During deserialization the data record for the ObjCInterfaceDecl could - // be made invariant by reusing the canonical decl. Take this into account - // when checking for the complete definition. - if (!HasCompleteDef && getCanonicalDecl()->hasDefinition() && - getCanonicalDecl()->getDefinition() == getDefinition()) - HasCompleteDef = true; - - // Check for a complete definition and recover if not so. - if (!HasCompleteDef) - return false; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers(); - if (!IFace) - return false; - - if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) { - if (MD->isThisDeclarationADesignatedInitializer()) { - if (InitMethod) - *InitMethod = MD; - return true; - } - } - for (const auto *Ext : IFace->visible_extensions()) { - if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) { - if (MD->isThisDeclarationADesignatedInitializer()) { - if (InitMethod) - *InitMethod = MD; - return true; - } - } - } - return false; -} - -void ObjCInterfaceDecl::allocateDefinitionData() { - assert(!hasDefinition() && "ObjC class already has a definition"); - Data.setPointer(new (getASTContext()) DefinitionData()); - Data.getPointer()->Definition = this; - - // Make the type point at the definition, now that we have one. - if (TypeForDecl) - cast<ObjCInterfaceType>(TypeForDecl)->Decl = this; -} - -void ObjCInterfaceDecl::startDefinition() { - allocateDefinitionData(); - - // Update all of the declarations with a pointer to the definition. - for (auto *RD : redecls()) { - if (RD != this) - RD->Data = Data; - } -} - -ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, - ObjCInterfaceDecl *&clsDeclared) { - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - ObjCInterfaceDecl* ClassDecl = this; - while (ClassDecl != nullptr) { - if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) { - clsDeclared = ClassDecl; - return I; - } - - for (const auto *Ext : ClassDecl->visible_extensions()) { - if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) { - clsDeclared = ClassDecl; - return I; - } - } - - ClassDecl = ClassDecl->getSuperClass(); - } - return nullptr; -} - -/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super -/// class whose name is passed as argument. If it is not one of the super classes -/// the it returns NULL. -ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( - const IdentifierInfo*ICName) { - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - ObjCInterfaceDecl* ClassDecl = this; - while (ClassDecl != nullptr) { - if (ClassDecl->getIdentifier() == ICName) - return ClassDecl; - ClassDecl = ClassDecl->getSuperClass(); - } - return nullptr; -} - -ObjCProtocolDecl * -ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) { - for (auto *P : all_referenced_protocols()) - if (P->lookupProtocolNamed(Name)) - return P; - ObjCInterfaceDecl *SuperClass = getSuperClass(); - return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr; -} - -/// lookupMethod - This method returns an instance/class method by looking in -/// the class, its categories, and its super classes (using a linear search). -/// When argument category "C" is specified, any implicit method found -/// in this category is ignored. -ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, - bool isInstance, - bool shallowCategoryLookup, - bool followSuper, - const ObjCCategoryDecl *C) const -{ - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - const ObjCInterfaceDecl* ClassDecl = this; - ObjCMethodDecl *MethodDecl = nullptr; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - while (ClassDecl) { - // 1. Look through primary class. - if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) - return MethodDecl; - - // 2. Didn't find one yet - now look through categories. - for (const auto *Cat : ClassDecl->visible_categories()) - if ((MethodDecl = Cat->getMethod(Sel, isInstance))) - if (C != Cat || !MethodDecl->isImplicit()) - return MethodDecl; - - // 3. Didn't find one yet - look through primary class's protocols. - for (const auto *I : ClassDecl->protocols()) - if ((MethodDecl = I->lookupMethod(Sel, isInstance))) - return MethodDecl; - - // 4. Didn't find one yet - now look through categories' protocols - if (!shallowCategoryLookup) - for (const auto *Cat : ClassDecl->visible_categories()) { - // Didn't find one yet - look through protocols. - const ObjCList<ObjCProtocolDecl> &Protocols = - Cat->getReferencedProtocols(); - for (auto *Protocol : Protocols) - if ((MethodDecl = Protocol->lookupMethod(Sel, isInstance))) - if (C != Cat || !MethodDecl->isImplicit()) - return MethodDecl; - } - - - if (!followSuper) - return nullptr; - - // 5. Get to the super class (if any). - ClassDecl = ClassDecl->getSuperClass(); - } - return nullptr; -} - -// Will search "local" class/category implementations for a method decl. -// If failed, then we search in class's root for an instance method. -// Returns 0 if no method is found. -ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod( - const Selector &Sel, - bool Instance) const { - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - ObjCMethodDecl *Method = nullptr; - if (ObjCImplementationDecl *ImpDecl = getImplementation()) - Method = Instance ? ImpDecl->getInstanceMethod(Sel) - : ImpDecl->getClassMethod(Sel); - - // Look through local category implementations associated with the class. - if (!Method) - Method = getCategoryMethod(Sel, Instance); - - // Before we give up, check if the selector is an instance method. - // But only in the root. This matches gcc's behavior and what the - // runtime expects. - if (!Instance && !Method && !getSuperClass()) { - Method = lookupInstanceMethod(Sel); - // Look through local category implementations associated - // with the root class. - if (!Method) - Method = lookupPrivateMethod(Sel, true); - } - - if (!Method && getSuperClass()) - return getSuperClass()->lookupPrivateMethod(Sel, Instance); - return Method; -} - -//===----------------------------------------------------------------------===// -// ObjCMethodDecl -//===----------------------------------------------------------------------===// - -ObjCMethodDecl::ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, - Selector SelInfo, QualType T, - TypeSourceInfo *ReturnTInfo, - DeclContext *contextDecl, bool isInstance, - bool isVariadic, bool isPropertyAccessor, - bool isImplicitlyDeclared, bool isDefined, - ImplementationControl impControl, - bool HasRelatedResultType) - : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), - DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo), - DeclEndLoc(endLoc) { - - // Initialized the bits stored in DeclContext. - ObjCMethodDeclBits.Family = - static_cast<ObjCMethodFamily>(InvalidObjCMethodFamily); - setInstanceMethod(isInstance); - setVariadic(isVariadic); - setPropertyAccessor(isPropertyAccessor); - setDefined(isDefined); - setIsRedeclaration(false); - setHasRedeclaration(false); - setDeclImplementation(impControl); - setObjCDeclQualifier(OBJC_TQ_None); - setRelatedResultType(HasRelatedResultType); - setSelLocsKind(SelLoc_StandardNoSpace); - setOverriding(false); - setHasSkippedBody(false); - - setImplicit(isImplicitlyDeclared); -} - -ObjCMethodDecl *ObjCMethodDecl::Create( - ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, - Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, - DeclContext *contextDecl, bool isInstance, bool isVariadic, - bool isPropertyAccessor, bool isImplicitlyDeclared, bool isDefined, - ImplementationControl impControl, bool HasRelatedResultType) { - return new (C, contextDecl) ObjCMethodDecl( - beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance, - isVariadic, isPropertyAccessor, isImplicitlyDeclared, isDefined, - impControl, HasRelatedResultType); -} - -ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(), - Selector(), QualType(), nullptr, nullptr); -} - -bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const { - return getMethodFamily() == OMF_init && - hasAttr<ObjCDesignatedInitializerAttr>(); -} - -bool ObjCMethodDecl::definedInNSObject(const ASTContext &Ctx) const { - if (const auto *PD = dyn_cast<const ObjCProtocolDecl>(getDeclContext())) - return PD->getIdentifier() == Ctx.getNSObjectName(); - if (const auto *ID = dyn_cast<const ObjCInterfaceDecl>(getDeclContext())) - return ID->getIdentifier() == Ctx.getNSObjectName(); - return false; -} - -bool ObjCMethodDecl::isDesignatedInitializerForTheInterface( - const ObjCMethodDecl **InitMethod) const { - if (getMethodFamily() != OMF_init) - return false; - const DeclContext *DC = getDeclContext(); - if (isa<ObjCProtocolDecl>(DC)) - return false; - if (const ObjCInterfaceDecl *ID = getClassInterface()) - return ID->isDesignatedInitializer(getSelector(), InitMethod); - return false; -} - -Stmt *ObjCMethodDecl::getBody() const { - return Body.get(getASTContext().getExternalSource()); -} - -void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) { - assert(PrevMethod); - getASTContext().setObjCMethodRedeclaration(PrevMethod, this); - setIsRedeclaration(true); - PrevMethod->setHasRedeclaration(true); -} - -void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C, - ArrayRef<ParmVarDecl*> Params, - ArrayRef<SourceLocation> SelLocs) { - ParamsAndSelLocs = nullptr; - NumParams = Params.size(); - if (Params.empty() && SelLocs.empty()) - return; - - static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation), - "Alignment not sufficient for SourceLocation"); - - unsigned Size = sizeof(ParmVarDecl *) * NumParams + - sizeof(SourceLocation) * SelLocs.size(); - ParamsAndSelLocs = C.Allocate(Size); - std::copy(Params.begin(), Params.end(), getParams()); - std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); -} - -void ObjCMethodDecl::getSelectorLocs( - SmallVectorImpl<SourceLocation> &SelLocs) const { - for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i) - SelLocs.push_back(getSelectorLoc(i)); -} - -void ObjCMethodDecl::setMethodParams(ASTContext &C, - ArrayRef<ParmVarDecl*> Params, - ArrayRef<SourceLocation> SelLocs) { - assert((!SelLocs.empty() || isImplicit()) && - "No selector locs for non-implicit method"); - if (isImplicit()) - return setParamsAndSelLocs(C, Params, llvm::None); - - setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params, - DeclEndLoc)); - if (getSelLocsKind() != SelLoc_NonStandard) - return setParamsAndSelLocs(C, Params, llvm::None); - - setParamsAndSelLocs(C, Params, SelLocs); -} - -/// A definition will return its interface declaration. -/// An interface declaration will return its definition. -/// Otherwise it will return itself. -ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() { - ASTContext &Ctx = getASTContext(); - ObjCMethodDecl *Redecl = nullptr; - if (hasRedeclaration()) - Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this)); - if (Redecl) - return Redecl; - - auto *CtxD = cast<Decl>(getDeclContext()); - - if (!CtxD->isInvalidDecl()) { - if (auto *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) { - if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD)) - if (!ImplD->isInvalidDecl()) - Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); - - } else if (auto *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) { - if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD)) - if (!ImplD->isInvalidDecl()) - Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); - - } else if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { - if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) - if (!IFD->isInvalidDecl()) - Redecl = IFD->getMethod(getSelector(), isInstanceMethod()); - - } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) { - if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) - if (!CatD->isInvalidDecl()) - Redecl = CatD->getMethod(getSelector(), isInstanceMethod()); - } - } - - // Ensure that the discovered method redeclaration has a valid declaration - // context. Used to prevent infinite loops when iterating redeclarations in - // a partially invalid AST. - if (Redecl && cast<Decl>(Redecl->getDeclContext())->isInvalidDecl()) - Redecl = nullptr; - - if (!Redecl && isRedeclaration()) { - // This is the last redeclaration, go back to the first method. - return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(), - isInstanceMethod()); - } - - return Redecl ? Redecl : this; -} - -ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() { - auto *CtxD = cast<Decl>(getDeclContext()); - - if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { - if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) - if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(), - isInstanceMethod())) - return MD; - } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) { - if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) - if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(), - isInstanceMethod())) - return MD; - } - - if (isRedeclaration()) { - // It is possible that we have not done deserializing the ObjCMethod yet. - ObjCMethodDecl *MD = - cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(), - isInstanceMethod()); - return MD ? MD : this; - } - - return this; -} - -SourceLocation ObjCMethodDecl::getEndLoc() const { - if (Stmt *Body = getBody()) - return Body->getEndLoc(); - return DeclEndLoc; -} - -ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const { - auto family = static_cast<ObjCMethodFamily>(ObjCMethodDeclBits.Family); - if (family != static_cast<unsigned>(InvalidObjCMethodFamily)) - return family; - - // Check for an explicit attribute. - if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) { - // The unfortunate necessity of mapping between enums here is due - // to the attributes framework. - switch (attr->getFamily()) { - case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break; - case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break; - case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break; - case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break; - case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break; - case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break; - } - ObjCMethodDeclBits.Family = family; - return family; - } - - family = getSelector().getMethodFamily(); - switch (family) { - case OMF_None: break; - - // init only has a conventional meaning for an instance method, and - // it has to return an object. - case OMF_init: - if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType()) - family = OMF_None; - break; - - // alloc/copy/new have a conventional meaning for both class and - // instance methods, but they require an object return. - case OMF_alloc: - case OMF_copy: - case OMF_mutableCopy: - case OMF_new: - if (!getReturnType()->isObjCObjectPointerType()) - family = OMF_None; - break; - - // These selectors have a conventional meaning only for instance methods. - case OMF_dealloc: - case OMF_finalize: - case OMF_retain: - case OMF_release: - case OMF_autorelease: - case OMF_retainCount: - case OMF_self: - if (!isInstanceMethod()) - family = OMF_None; - break; - - case OMF_initialize: - if (isInstanceMethod() || !getReturnType()->isVoidType()) - family = OMF_None; - break; - - case OMF_performSelector: - if (!isInstanceMethod() || !getReturnType()->isObjCIdType()) - family = OMF_None; - else { - unsigned noParams = param_size(); - if (noParams < 1 || noParams > 3) - family = OMF_None; - else { - ObjCMethodDecl::param_type_iterator it = param_type_begin(); - QualType ArgT = (*it); - if (!ArgT->isObjCSelType()) { - family = OMF_None; - break; - } - while (--noParams) { - it++; - ArgT = (*it); - if (!ArgT->isObjCIdType()) { - family = OMF_None; - break; - } - } - } - } - break; - - } - - // Cache the result. - ObjCMethodDeclBits.Family = family; - return family; -} - -QualType ObjCMethodDecl::getSelfType(ASTContext &Context, - const ObjCInterfaceDecl *OID, - bool &selfIsPseudoStrong, - bool &selfIsConsumed) { - QualType selfTy; - selfIsPseudoStrong = false; - selfIsConsumed = false; - if (isInstanceMethod()) { - // There may be no interface context due to error in declaration - // of the interface (which has been reported). Recover gracefully. - if (OID) { - selfTy = Context.getObjCInterfaceType(OID); - selfTy = Context.getObjCObjectPointerType(selfTy); - } else { - selfTy = Context.getObjCIdType(); - } - } else // we have a factory method. - selfTy = Context.getObjCClassType(); - - if (Context.getLangOpts().ObjCAutoRefCount) { - if (isInstanceMethod()) { - selfIsConsumed = hasAttr<NSConsumesSelfAttr>(); - - // 'self' is always __strong. It's actually pseudo-strong except - // in init methods (or methods labeled ns_consumes_self), though. - Qualifiers qs; - qs.setObjCLifetime(Qualifiers::OCL_Strong); - selfTy = Context.getQualifiedType(selfTy, qs); - - // In addition, 'self' is const unless this is an init method. - if (getMethodFamily() != OMF_init && !selfIsConsumed) { - selfTy = selfTy.withConst(); - selfIsPseudoStrong = true; - } - } - else { - assert(isClassMethod()); - // 'self' is always const in class methods. - selfTy = selfTy.withConst(); - selfIsPseudoStrong = true; - } - } - return selfTy; -} - -void ObjCMethodDecl::createImplicitParams(ASTContext &Context, - const ObjCInterfaceDecl *OID) { - bool selfIsPseudoStrong, selfIsConsumed; - QualType selfTy = - getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed); - auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(), - &Context.Idents.get("self"), selfTy, - ImplicitParamDecl::ObjCSelf); - setSelfDecl(Self); - - if (selfIsConsumed) - Self->addAttr(NSConsumedAttr::CreateImplicit(Context)); - - if (selfIsPseudoStrong) - Self->setARCPseudoStrong(true); - - setCmdDecl(ImplicitParamDecl::Create( - Context, this, SourceLocation(), &Context.Idents.get("_cmd"), - Context.getObjCSelType(), ImplicitParamDecl::ObjCCmd)); -} - -ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() { - if (auto *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext())) - return ID; - if (auto *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext())) - return CD->getClassInterface(); - if (auto *IMD = dyn_cast<ObjCImplDecl>(getDeclContext())) - return IMD->getClassInterface(); - if (isa<ObjCProtocolDecl>(getDeclContext())) - return nullptr; - llvm_unreachable("unknown method context"); -} - -SourceRange ObjCMethodDecl::getReturnTypeSourceRange() const { - const auto *TSI = getReturnTypeSourceInfo(); - if (TSI) - return TSI->getTypeLoc().getSourceRange(); - return SourceRange(); -} - -QualType ObjCMethodDecl::getSendResultType() const { - ASTContext &Ctx = getASTContext(); - return getReturnType().getNonLValueExprType(Ctx) - .substObjCTypeArgs(Ctx, {}, ObjCSubstitutionContext::Result); -} - -QualType ObjCMethodDecl::getSendResultType(QualType receiverType) const { - // FIXME: Handle related result types here. - - return getReturnType().getNonLValueExprType(getASTContext()) - .substObjCMemberType(receiverType, getDeclContext(), - ObjCSubstitutionContext::Result); -} - -static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container, - const ObjCMethodDecl *Method, - SmallVectorImpl<const ObjCMethodDecl *> &Methods, - bool MovedToSuper) { - if (!Container) - return; - - // In categories look for overridden methods from protocols. A method from - // category is not "overridden" since it is considered as the "same" method - // (same USR) as the one from the interface. - if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) { - // Check whether we have a matching method at this category but only if we - // are at the super class level. - if (MovedToSuper) - if (ObjCMethodDecl * - Overridden = Container->getMethod(Method->getSelector(), - Method->isInstanceMethod(), - /*AllowHidden=*/true)) - if (Method != Overridden) { - // We found an override at this category; there is no need to look - // into its protocols. - Methods.push_back(Overridden); - return; - } - - for (const auto *P : Category->protocols()) - CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper); - return; - } - - // Check whether we have a matching method at this level. - if (const ObjCMethodDecl * - Overridden = Container->getMethod(Method->getSelector(), - Method->isInstanceMethod(), - /*AllowHidden=*/true)) - if (Method != Overridden) { - // We found an override at this level; there is no need to look - // into other protocols or categories. - Methods.push_back(Overridden); - return; - } - - if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){ - for (const auto *P : Protocol->protocols()) - CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper); - } - - if (const auto *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) { - for (const auto *P : Interface->protocols()) - CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper); - - for (const auto *Cat : Interface->known_categories()) - CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper); - - if (const ObjCInterfaceDecl *Super = Interface->getSuperClass()) - return CollectOverriddenMethodsRecurse(Super, Method, Methods, - /*MovedToSuper=*/true); - } -} - -static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container, - const ObjCMethodDecl *Method, - SmallVectorImpl<const ObjCMethodDecl *> &Methods) { - CollectOverriddenMethodsRecurse(Container, Method, Methods, - /*MovedToSuper=*/false); -} - -static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method, - SmallVectorImpl<const ObjCMethodDecl *> &overridden) { - assert(Method->isOverriding()); - - if (const auto *ProtD = - dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) { - CollectOverriddenMethods(ProtD, Method, overridden); - - } else if (const auto *IMD = - dyn_cast<ObjCImplDecl>(Method->getDeclContext())) { - const ObjCInterfaceDecl *ID = IMD->getClassInterface(); - if (!ID) - return; - // Start searching for overridden methods using the method from the - // interface as starting point. - if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(), - Method->isInstanceMethod(), - /*AllowHidden=*/true)) - Method = IFaceMeth; - CollectOverriddenMethods(ID, Method, overridden); - - } else if (const auto *CatD = - dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) { - const ObjCInterfaceDecl *ID = CatD->getClassInterface(); - if (!ID) - return; - // Start searching for overridden methods using the method from the - // interface as starting point. - if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(), - Method->isInstanceMethod(), - /*AllowHidden=*/true)) - Method = IFaceMeth; - CollectOverriddenMethods(ID, Method, overridden); - - } else { - CollectOverriddenMethods( - dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()), - Method, overridden); - } -} - -void ObjCMethodDecl::getOverriddenMethods( - SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const { - const ObjCMethodDecl *Method = this; - - if (Method->isRedeclaration()) { - Method = cast<ObjCContainerDecl>(Method->getDeclContext())-> - getMethod(Method->getSelector(), Method->isInstanceMethod()); - } - - if (Method->isOverriding()) { - collectOverriddenMethodsSlow(Method, Overridden); - assert(!Overridden.empty() && - "ObjCMethodDecl's overriding bit is not as expected"); - } -} - -const ObjCPropertyDecl * -ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const { - Selector Sel = getSelector(); - unsigned NumArgs = Sel.getNumArgs(); - if (NumArgs > 1) - return nullptr; - - if (isPropertyAccessor()) { - const auto *Container = cast<ObjCContainerDecl>(getParent()); - bool IsGetter = (NumArgs == 0); - bool IsInstance = isInstanceMethod(); - - /// Local function that attempts to find a matching property within the - /// given Objective-C container. - auto findMatchingProperty = - [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * { - if (IsInstance) { - for (const auto *I : Container->instance_properties()) { - Selector NextSel = IsGetter ? I->getGetterName() - : I->getSetterName(); - if (NextSel == Sel) - return I; - } - } else { - for (const auto *I : Container->class_properties()) { - Selector NextSel = IsGetter ? I->getGetterName() - : I->getSetterName(); - if (NextSel == Sel) - return I; - } - } - - return nullptr; - }; - - // Look in the container we were given. - if (const auto *Found = findMatchingProperty(Container)) - return Found; - - // If we're in a category or extension, look in the main class. - const ObjCInterfaceDecl *ClassDecl = nullptr; - if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) { - ClassDecl = Category->getClassInterface(); - if (const auto *Found = findMatchingProperty(ClassDecl)) - return Found; - } else { - // Determine whether the container is a class. - ClassDecl = dyn_cast<ObjCInterfaceDecl>(Container); - } - - // If we have a class, check its visible extensions. - if (ClassDecl) { - for (const auto *Ext : ClassDecl->visible_extensions()) { - if (Ext == Container) - continue; - - if (const auto *Found = findMatchingProperty(Ext)) - return Found; - } - } - - llvm_unreachable("Marked as a property accessor but no property found!"); - } - - if (!CheckOverrides) - return nullptr; - - using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>; - - OverridesTy Overrides; - getOverriddenMethods(Overrides); - for (const auto *Override : Overrides) - if (const ObjCPropertyDecl *Prop = Override->findPropertyDecl(false)) - return Prop; - - return nullptr; -} - -//===----------------------------------------------------------------------===// -// ObjCTypeParamDecl -//===----------------------------------------------------------------------===// - -void ObjCTypeParamDecl::anchor() {} - -ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, - ObjCTypeParamVariance variance, - SourceLocation varianceLoc, - unsigned index, - SourceLocation nameLoc, - IdentifierInfo *name, - SourceLocation colonLoc, - TypeSourceInfo *boundInfo) { - auto *TPDecl = - new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index, - nameLoc, name, colonLoc, boundInfo); - QualType TPType = ctx.getObjCTypeParamType(TPDecl, {}); - TPDecl->setTypeForDecl(TPType.getTypePtr()); - return TPDecl; -} - -ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, - unsigned ID) { - return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, - ObjCTypeParamVariance::Invariant, - SourceLocation(), 0, SourceLocation(), - nullptr, SourceLocation(), nullptr); -} - -SourceRange ObjCTypeParamDecl::getSourceRange() const { - SourceLocation startLoc = VarianceLoc; - if (startLoc.isInvalid()) - startLoc = getLocation(); - - if (hasExplicitBound()) { - return SourceRange(startLoc, - getTypeSourceInfo()->getTypeLoc().getEndLoc()); - } - - return SourceRange(startLoc); -} - -//===----------------------------------------------------------------------===// -// ObjCTypeParamList -//===----------------------------------------------------------------------===// -ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc, - ArrayRef<ObjCTypeParamDecl *> typeParams, - SourceLocation rAngleLoc) - : NumParams(typeParams.size()) { - Brackets.Begin = lAngleLoc.getRawEncoding(); - Brackets.End = rAngleLoc.getRawEncoding(); - std::copy(typeParams.begin(), typeParams.end(), begin()); -} - -ObjCTypeParamList *ObjCTypeParamList::create( - ASTContext &ctx, - SourceLocation lAngleLoc, - ArrayRef<ObjCTypeParamDecl *> typeParams, - SourceLocation rAngleLoc) { - void *mem = - ctx.Allocate(totalSizeToAlloc<ObjCTypeParamDecl *>(typeParams.size()), - alignof(ObjCTypeParamList)); - return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc); -} - -void ObjCTypeParamList::gatherDefaultTypeArgs( - SmallVectorImpl<QualType> &typeArgs) const { - typeArgs.reserve(size()); - for (auto typeParam : *this) - typeArgs.push_back(typeParam->getUnderlyingType()); -} - -//===----------------------------------------------------------------------===// -// ObjCInterfaceDecl -//===----------------------------------------------------------------------===// - -ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C, - DeclContext *DC, - SourceLocation atLoc, - IdentifierInfo *Id, - ObjCTypeParamList *typeParamList, - ObjCInterfaceDecl *PrevDecl, - SourceLocation ClassLoc, - bool isInternal){ - auto *Result = new (C, DC) - ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl, - isInternal); - Result->Data.setInt(!C.getLangOpts().Modules); - C.getObjCInterfaceType(Result, PrevDecl); - return Result; -} - -ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, - unsigned ID) { - auto *Result = new (C, ID) - ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr, - SourceLocation(), nullptr, false); - Result->Data.setInt(!C.getLangOpts().Modules); - return Result; -} - -ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, - SourceLocation AtLoc, IdentifierInfo *Id, - ObjCTypeParamList *typeParamList, - SourceLocation CLoc, - ObjCInterfaceDecl *PrevDecl, - bool IsInternal) - : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc), - redeclarable_base(C) { - setPreviousDecl(PrevDecl); - - // Copy the 'data' pointer over. - if (PrevDecl) - Data = PrevDecl->Data; - - setImplicit(IsInternal); - - setTypeParamList(typeParamList); -} - -void ObjCInterfaceDecl::LoadExternalDefinition() const { - assert(data().ExternallyCompleted && "Class is not externally completed"); - data().ExternallyCompleted = false; - getASTContext().getExternalSource()->CompleteType( - const_cast<ObjCInterfaceDecl *>(this)); -} - -void ObjCInterfaceDecl::setExternallyCompleted() { - assert(getASTContext().getExternalSource() && - "Class can't be externally completed without an external source"); - assert(hasDefinition() && - "Forward declarations can't be externally completed"); - data().ExternallyCompleted = true; -} - -void ObjCInterfaceDecl::setHasDesignatedInitializers() { - // Check for a complete definition and recover if not so. - if (!isThisDeclarationADefinition()) - return; - data().HasDesignatedInitializers = true; -} - -bool ObjCInterfaceDecl::hasDesignatedInitializers() const { - // Check for a complete definition and recover if not so. - if (!isThisDeclarationADefinition()) - return false; - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - return data().HasDesignatedInitializers; -} - -StringRef -ObjCInterfaceDecl::getObjCRuntimeNameAsString() const { - if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>()) - return ObjCRTName->getMetadataName(); - - return getName(); -} - -StringRef -ObjCImplementationDecl::getObjCRuntimeNameAsString() const { - if (ObjCInterfaceDecl *ID = - const_cast<ObjCImplementationDecl*>(this)->getClassInterface()) - return ID->getObjCRuntimeNameAsString(); - - return getName(); -} - -ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { - if (const ObjCInterfaceDecl *Def = getDefinition()) { - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - return getASTContext().getObjCImplementation( - const_cast<ObjCInterfaceDecl*>(Def)); - } - - // FIXME: Should make sure no callers ever do this. - return nullptr; -} - -void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) { - getASTContext().setObjCImplementation(getDefinition(), ImplD); -} - -namespace { - -struct SynthesizeIvarChunk { - uint64_t Size; - ObjCIvarDecl *Ivar; - - SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar) - : Size(size), Ivar(ivar) {} -}; - -bool operator<(const SynthesizeIvarChunk & LHS, - const SynthesizeIvarChunk &RHS) { - return LHS.Size < RHS.Size; -} - -} // namespace - -/// all_declared_ivar_begin - return first ivar declared in this class, -/// its extensions and its implementation. Lazily build the list on first -/// access. -/// -/// Caveat: The list returned by this method reflects the current -/// state of the parser. The cache will be updated for every ivar -/// added by an extension or the implementation when they are -/// encountered. -/// See also ObjCIvarDecl::Create(). -ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - ObjCIvarDecl *curIvar = nullptr; - if (!data().IvarList) { - if (!ivar_empty()) { - ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end(); - data().IvarList = *I; ++I; - for (curIvar = data().IvarList; I != E; curIvar = *I, ++I) - curIvar->setNextIvar(*I); - } - - for (const auto *Ext : known_extensions()) { - if (!Ext->ivar_empty()) { - ObjCCategoryDecl::ivar_iterator - I = Ext->ivar_begin(), - E = Ext->ivar_end(); - if (!data().IvarList) { - data().IvarList = *I; ++I; - curIvar = data().IvarList; - } - for ( ;I != E; curIvar = *I, ++I) - curIvar->setNextIvar(*I); - } - } - data().IvarListMissingImplementation = true; - } - - // cached and complete! - if (!data().IvarListMissingImplementation) - return data().IvarList; - - if (ObjCImplementationDecl *ImplDecl = getImplementation()) { - data().IvarListMissingImplementation = false; - if (!ImplDecl->ivar_empty()) { - SmallVector<SynthesizeIvarChunk, 16> layout; - for (auto *IV : ImplDecl->ivars()) { - if (IV->getSynthesize() && !IV->isInvalidDecl()) { - layout.push_back(SynthesizeIvarChunk( - IV->getASTContext().getTypeSize(IV->getType()), IV)); - continue; - } - if (!data().IvarList) - data().IvarList = IV; - else - curIvar->setNextIvar(IV); - curIvar = IV; - } - - if (!layout.empty()) { - // Order synthesized ivars by their size. - std::stable_sort(layout.begin(), layout.end()); - unsigned Ix = 0, EIx = layout.size(); - if (!data().IvarList) { - data().IvarList = layout[0].Ivar; Ix++; - curIvar = data().IvarList; - } - for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++) - curIvar->setNextIvar(layout[Ix].Ivar); - } - } - } - return data().IvarList; -} - -/// FindCategoryDeclaration - Finds category declaration in the list of -/// categories for this class and returns it. Name of the category is passed -/// in 'CategoryId'. If category not found, return 0; -/// -ObjCCategoryDecl * -ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { - // FIXME: Should make sure no callers ever do this. - if (!hasDefinition()) - return nullptr; - - if (data().ExternallyCompleted) - LoadExternalDefinition(); - - for (auto *Cat : visible_categories()) - if (Cat->getIdentifier() == CategoryId) - return Cat; - - return nullptr; -} - -ObjCMethodDecl * -ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const { - for (const auto *Cat : visible_categories()) { - if (ObjCCategoryImplDecl *Impl = Cat->getImplementation()) - if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel)) - return MD; - } - - return nullptr; -} - -ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const { - for (const auto *Cat : visible_categories()) { - if (ObjCCategoryImplDecl *Impl = Cat->getImplementation()) - if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel)) - return MD; - } - - return nullptr; -} - -/// ClassImplementsProtocol - Checks that 'lProto' protocol -/// has been implemented in IDecl class, its super class or categories (if -/// lookupCategory is true). -bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto, - bool lookupCategory, - bool RHSIsQualifiedID) { - if (!hasDefinition()) - return false; - - ObjCInterfaceDecl *IDecl = this; - // 1st, look up the class. - for (auto *PI : IDecl->protocols()){ - if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI)) - return true; - // This is dubious and is added to be compatible with gcc. In gcc, it is - // also allowed assigning a protocol-qualified 'id' type to a LHS object - // when protocol in qualified LHS is in list of protocols in the rhs 'id' - // object. This IMO, should be a bug. - // FIXME: Treat this as an extension, and flag this as an error when GCC - // extensions are not enabled. - if (RHSIsQualifiedID && - getASTContext().ProtocolCompatibleWithProtocol(PI, lProto)) - return true; - } - - // 2nd, look up the category. - if (lookupCategory) - for (const auto *Cat : visible_categories()) { - for (auto *PI : Cat->protocols()) - if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI)) - return true; - } - - // 3rd, look up the super class(s) - if (IDecl->getSuperClass()) - return - IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory, - RHSIsQualifiedID); - - return false; -} - -//===----------------------------------------------------------------------===// -// ObjCIvarDecl -//===----------------------------------------------------------------------===// - -void ObjCIvarDecl::anchor() {} - -ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, - SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, - AccessControl ac, Expr *BW, - bool synthesized) { - if (DC) { - // Ivar's can only appear in interfaces, implementations (via synthesized - // properties), and class extensions (via direct declaration, or synthesized - // properties). - // - // FIXME: This should really be asserting this: - // (isa<ObjCCategoryDecl>(DC) && - // cast<ObjCCategoryDecl>(DC)->IsClassExtension())) - // but unfortunately we sometimes place ivars into non-class extension - // categories on error. This breaks an AST invariant, and should not be - // fixed. - assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) || - isa<ObjCCategoryDecl>(DC)) && - "Invalid ivar decl context!"); - // Once a new ivar is created in any of class/class-extension/implementation - // decl contexts, the previously built IvarList must be rebuilt. - auto *ID = dyn_cast<ObjCInterfaceDecl>(DC); - if (!ID) { - if (auto *IM = dyn_cast<ObjCImplementationDecl>(DC)) - ID = IM->getClassInterface(); - else - ID = cast<ObjCCategoryDecl>(DC)->getClassInterface(); - } - ID->setIvarList(nullptr); - } - - return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW, - synthesized); -} - -ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), - nullptr, QualType(), nullptr, - ObjCIvarDecl::None, nullptr, false); -} - -const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const { - const auto *DC = cast<ObjCContainerDecl>(getDeclContext()); - - switch (DC->getKind()) { - default: - case ObjCCategoryImpl: - case ObjCProtocol: - llvm_unreachable("invalid ivar container!"); - - // Ivars can only appear in class extension categories. - case ObjCCategory: { - const auto *CD = cast<ObjCCategoryDecl>(DC); - assert(CD->IsClassExtension() && "invalid container for ivar!"); - return CD->getClassInterface(); - } - - case ObjCImplementation: - return cast<ObjCImplementationDecl>(DC)->getClassInterface(); - - case ObjCInterface: - return cast<ObjCInterfaceDecl>(DC); - } -} - -QualType ObjCIvarDecl::getUsageType(QualType objectType) const { - return getType().substObjCMemberType(objectType, getDeclContext(), - ObjCSubstitutionContext::Property); -} - -//===----------------------------------------------------------------------===// -// ObjCAtDefsFieldDecl -//===----------------------------------------------------------------------===// - -void ObjCAtDefsFieldDecl::anchor() {} - -ObjCAtDefsFieldDecl -*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, QualType T, Expr *BW) { - return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW); -} - -ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { - return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(), - SourceLocation(), nullptr, QualType(), - nullptr); -} - -//===----------------------------------------------------------------------===// -// ObjCProtocolDecl -//===----------------------------------------------------------------------===// - -void ObjCProtocolDecl::anchor() {} - -ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC, - IdentifierInfo *Id, SourceLocation nameLoc, - SourceLocation atStartLoc, - ObjCProtocolDecl *PrevDecl) - : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), - redeclarable_base(C) { - setPreviousDecl(PrevDecl); - if (PrevDecl) - Data = PrevDecl->Data; -} - -ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, - IdentifierInfo *Id, - SourceLocation nameLoc, - SourceLocation atStartLoc, - ObjCProtocolDecl *PrevDecl) { - auto *Result = - new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl); - Result->Data.setInt(!C.getLangOpts().Modules); - return Result; -} - -ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { - ObjCProtocolDecl *Result = - new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), - SourceLocation(), nullptr); - Result->Data.setInt(!C.getLangOpts().Modules); - return Result; -} - -ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) { - ObjCProtocolDecl *PDecl = this; - - if (Name == getIdentifier()) - return PDecl; - - for (auto *I : protocols()) - if ((PDecl = I->lookupProtocolNamed(Name))) - return PDecl; - - return nullptr; -} - -// lookupMethod - Lookup a instance/class method in the protocol and protocols -// it inherited. -ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel, - bool isInstance) const { - ObjCMethodDecl *MethodDecl = nullptr; - - // If there is no definition or the definition is hidden, we don't find - // anything. - const ObjCProtocolDecl *Def = getDefinition(); - if (!Def || Def->isHidden()) - return nullptr; - - if ((MethodDecl = getMethod(Sel, isInstance))) - return MethodDecl; - - for (const auto *I : protocols()) - if ((MethodDecl = I->lookupMethod(Sel, isInstance))) - return MethodDecl; - return nullptr; -} - -void ObjCProtocolDecl::allocateDefinitionData() { - assert(!Data.getPointer() && "Protocol already has a definition!"); - Data.setPointer(new (getASTContext()) DefinitionData); - Data.getPointer()->Definition = this; -} - -void ObjCProtocolDecl::startDefinition() { - allocateDefinitionData(); - - // Update all of the declarations with a pointer to the definition. - for (auto *RD : redecls()) - RD->Data = this->Data; -} - -void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM, - PropertyDeclOrder &PO) const { - if (const ObjCProtocolDecl *PDecl = getDefinition()) { - for (auto *Prop : PDecl->properties()) { - // Insert into PM if not there already. - PM.insert(std::make_pair( - std::make_pair(Prop->getIdentifier(), Prop->isClassProperty()), - Prop)); - PO.push_back(Prop); - } - // Scan through protocol's protocols. - for (const auto *PI : PDecl->protocols()) - PI->collectPropertiesToImplement(PM, PO); - } -} - -void ObjCProtocolDecl::collectInheritedProtocolProperties( - const ObjCPropertyDecl *Property, ProtocolPropertySet &PS, - PropertyDeclOrder &PO) const { - if (const ObjCProtocolDecl *PDecl = getDefinition()) { - if (!PS.insert(PDecl).second) - return; - for (auto *Prop : PDecl->properties()) { - if (Prop == Property) - continue; - if (Prop->getIdentifier() == Property->getIdentifier()) { - PO.push_back(Prop); - return; - } - } - // Scan through protocol's protocols which did not have a matching property. - for (const auto *PI : PDecl->protocols()) - PI->collectInheritedProtocolProperties(Property, PS, PO); - } -} - -StringRef -ObjCProtocolDecl::getObjCRuntimeNameAsString() const { - if (const auto *ObjCRTName = getAttr<ObjCRuntimeNameAttr>()) - return ObjCRTName->getMetadataName(); - - return getName(); -} - -//===----------------------------------------------------------------------===// -// ObjCCategoryDecl -//===----------------------------------------------------------------------===// - -void ObjCCategoryDecl::anchor() {} - -ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, - SourceLocation ClassNameLoc, - SourceLocation CategoryNameLoc, - IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, - ObjCTypeParamList *typeParamList, - SourceLocation IvarLBraceLoc, - SourceLocation IvarRBraceLoc) - : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), - ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc), - IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { - setTypeParamList(typeParamList); -} - -ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation AtLoc, - SourceLocation ClassNameLoc, - SourceLocation CategoryNameLoc, - IdentifierInfo *Id, - ObjCInterfaceDecl *IDecl, - ObjCTypeParamList *typeParamList, - SourceLocation IvarLBraceLoc, - SourceLocation IvarRBraceLoc) { - auto *CatDecl = - new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id, - IDecl, typeParamList, IvarLBraceLoc, - IvarRBraceLoc); - if (IDecl) { - // Link this category into its class's category list. - CatDecl->NextClassCategory = IDecl->getCategoryListRaw(); - if (IDecl->hasDefinition()) { - IDecl->setCategoryListRaw(CatDecl); - if (ASTMutationListener *L = C.getASTMutationListener()) - L->AddedObjCCategoryToInterface(CatDecl, IDecl); - } - } - - return CatDecl; -} - -ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { - return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), - SourceLocation(), SourceLocation(), - nullptr, nullptr, nullptr); -} - -ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const { - return getASTContext().getObjCImplementation( - const_cast<ObjCCategoryDecl*>(this)); -} - -void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) { - getASTContext().setObjCImplementation(this, ImplD); -} - -void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) { - TypeParamList = TPL; - if (!TPL) - return; - // Set the declaration context of each of the type parameters. - for (auto *typeParam : *TypeParamList) - typeParam->setDeclContext(this); -} - -//===----------------------------------------------------------------------===// -// ObjCCategoryImplDecl -//===----------------------------------------------------------------------===// - -void ObjCCategoryImplDecl::anchor() {} - -ObjCCategoryImplDecl * -ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC, - IdentifierInfo *Id, - ObjCInterfaceDecl *ClassInterface, - SourceLocation nameLoc, - SourceLocation atStartLoc, - SourceLocation CategoryNameLoc) { - if (ClassInterface && ClassInterface->hasDefinition()) - ClassInterface = ClassInterface->getDefinition(); - return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc, - atStartLoc, CategoryNameLoc); -} - -ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { - return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr, - SourceLocation(), SourceLocation(), - SourceLocation()); -} - -ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const { - // The class interface might be NULL if we are working with invalid code. - if (const ObjCInterfaceDecl *ID = getClassInterface()) - return ID->FindCategoryDeclaration(getIdentifier()); - return nullptr; -} - -void ObjCImplDecl::anchor() {} - -void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) { - // FIXME: The context should be correct before we get here. - property->setLexicalDeclContext(this); - addDecl(property); -} - -void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) { - ASTContext &Ctx = getASTContext(); - - if (auto *ImplD = dyn_cast_or_null<ObjCImplementationDecl>(this)) { - if (IFace) - Ctx.setObjCImplementation(IFace, ImplD); - - } else if (auto *ImplD = dyn_cast_or_null<ObjCCategoryImplDecl>(this)) { - if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier())) - Ctx.setObjCImplementation(CD, ImplD); - } - - ClassInterface = IFace; -} - -/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of -/// properties implemented in this \@implementation block and returns -/// the implemented property that uses it. -ObjCPropertyImplDecl *ObjCImplDecl:: -FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { - for (auto *PID : property_impls()) - if (PID->getPropertyIvarDecl() && - PID->getPropertyIvarDecl()->getIdentifier() == ivarId) - return PID; - return nullptr; -} - -/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl -/// added to the list of those properties \@synthesized/\@dynamic in this -/// category \@implementation block. -ObjCPropertyImplDecl *ObjCImplDecl:: -FindPropertyImplDecl(IdentifierInfo *Id, - ObjCPropertyQueryKind QueryKind) const { - ObjCPropertyImplDecl *ClassPropImpl = nullptr; - for (auto *PID : property_impls()) - // If queryKind is unknown, we return the instance property if one - // exists; otherwise we return the class property. - if (PID->getPropertyDecl()->getIdentifier() == Id) { - if ((QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown && - !PID->getPropertyDecl()->isClassProperty()) || - (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_class && - PID->getPropertyDecl()->isClassProperty()) || - (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_instance && - !PID->getPropertyDecl()->isClassProperty())) - return PID; - - if (PID->getPropertyDecl()->isClassProperty()) - ClassPropImpl = PID; - } - - if (QueryKind == ObjCPropertyQueryKind::OBJC_PR_query_unknown) - // We can't find the instance property, return the class property. - return ClassPropImpl; - - return nullptr; -} - -raw_ostream &clang::operator<<(raw_ostream &OS, - const ObjCCategoryImplDecl &CID) { - OS << CID.getName(); - return OS; -} - -//===----------------------------------------------------------------------===// -// ObjCImplementationDecl -//===----------------------------------------------------------------------===// - -void ObjCImplementationDecl::anchor() {} - -ObjCImplementationDecl * -ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, - ObjCInterfaceDecl *ClassInterface, - ObjCInterfaceDecl *SuperDecl, - SourceLocation nameLoc, - SourceLocation atStartLoc, - SourceLocation superLoc, - SourceLocation IvarLBraceLoc, - SourceLocation IvarRBraceLoc) { - if (ClassInterface && ClassInterface->hasDefinition()) - ClassInterface = ClassInterface->getDefinition(); - return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl, - nameLoc, atStartLoc, superLoc, - IvarLBraceLoc, IvarRBraceLoc); -} - -ObjCImplementationDecl * -ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr, - SourceLocation(), SourceLocation()); -} - -void ObjCImplementationDecl::setIvarInitializers(ASTContext &C, - CXXCtorInitializer ** initializers, - unsigned numInitializers) { - if (numInitializers > 0) { - NumIvarInitializers = numInitializers; - auto **ivarInitializers = new (C) CXXCtorInitializer*[NumIvarInitializers]; - memcpy(ivarInitializers, initializers, - numInitializers * sizeof(CXXCtorInitializer*)); - IvarInitializers = ivarInitializers; - } -} - -ObjCImplementationDecl::init_const_iterator -ObjCImplementationDecl::init_begin() const { - return IvarInitializers.get(getASTContext().getExternalSource()); -} - -raw_ostream &clang::operator<<(raw_ostream &OS, - const ObjCImplementationDecl &ID) { - OS << ID.getName(); - return OS; -} - -//===----------------------------------------------------------------------===// -// ObjCCompatibleAliasDecl -//===----------------------------------------------------------------------===// - -void ObjCCompatibleAliasDecl::anchor() {} - -ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, - ObjCInterfaceDecl* AliasedClass) { - return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass); -} - -ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(), - nullptr, nullptr); -} - -//===----------------------------------------------------------------------===// -// ObjCPropertyDecl -//===----------------------------------------------------------------------===// - -void ObjCPropertyDecl::anchor() {} - -ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, - SourceLocation AtLoc, - SourceLocation LParenLoc, - QualType T, - TypeSourceInfo *TSI, - PropertyControl propControl) { - return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T, TSI, - propControl); -} - -ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { - return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr, - SourceLocation(), SourceLocation(), - QualType(), nullptr, None); -} - -QualType ObjCPropertyDecl::getUsageType(QualType objectType) const { - return DeclType.substObjCMemberType(objectType, getDeclContext(), - ObjCSubstitutionContext::Property); -} - -//===----------------------------------------------------------------------===// -// ObjCPropertyImplDecl -//===----------------------------------------------------------------------===// - -ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, - DeclContext *DC, - SourceLocation atLoc, - SourceLocation L, - ObjCPropertyDecl *property, - Kind PK, - ObjCIvarDecl *ivar, - SourceLocation ivarLoc) { - return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar, - ivarLoc); -} - -ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, - unsigned ID) { - return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(), - SourceLocation(), nullptr, Dynamic, - nullptr, SourceLocation()); -} - -SourceRange ObjCPropertyImplDecl::getSourceRange() const { - SourceLocation EndLoc = getLocation(); - if (IvarLoc.isValid()) - EndLoc = IvarLoc; - - return SourceRange(AtLoc, EndLoc); -} |
