diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/DeclObjC.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/DeclObjC.cpp | 155 |
1 files changed, 127 insertions, 28 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp b/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp index 5f82fcec90e3..962f503306a0 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp +++ b/contrib/llvm-project/clang/lib/AST/DeclObjC.cpp @@ -16,6 +16,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/ODRHash.h" #include "clang/AST/Stmt.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" @@ -23,7 +24,6 @@ #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" @@ -232,6 +232,18 @@ ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const { return &Ctx.Idents.get(ivarName.str()); } +ObjCPropertyDecl *ObjCContainerDecl::getProperty(const IdentifierInfo *Id, + bool IsInstance) const { + for (auto *LookupResult : lookup(Id)) { + if (auto *Prop = dyn_cast<ObjCPropertyDecl>(LookupResult)) { + if (Prop->isInstanceProperty() == IsInstance) { + return Prop; + } + } + } + return nullptr; +} + /// FindPropertyDeclaration - Finds declaration of the property given its name /// in 'PropertyId' and returns it. It returns 0, if not found. ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( @@ -391,21 +403,18 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( return nullptr; } -void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM, - PropertyDeclOrder &PO) const { +void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM) 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); + PI->collectPropertiesToImplement(PM); // 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. @@ -603,10 +612,6 @@ 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() { @@ -619,6 +624,17 @@ void ObjCInterfaceDecl::startDefinition() { } } +void ObjCInterfaceDecl::startDuplicateDefinitionForComparison() { + Data.setPointer(nullptr); + allocateDefinitionData(); + // Don't propagate data to other redeclarations. +} + +void ObjCInterfaceDecl::mergeDuplicateDefinitionWithCommon( + const ObjCInterfaceDecl *Definition) { + Data = Definition->Data; +} + ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { // FIXME: Should make sure no callers ever do this. @@ -773,6 +789,33 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod( return Method; } +unsigned ObjCInterfaceDecl::getODRHash() { + assert(hasDefinition() && "ODRHash only for records with definitions"); + + // Previously calculated hash is stored in DefinitionData. + if (hasODRHash()) + return data().ODRHash; + + // Only calculate hash on first call of getODRHash per record. + ODRHash Hasher; + Hasher.AddObjCInterfaceDecl(getDefinition()); + data().ODRHash = Hasher.CalculateHash(); + setHasODRHash(true); + + return data().ODRHash; +} + +bool ObjCInterfaceDecl::hasODRHash() const { + if (!hasDefinition()) + return false; + return data().HasODRHash; +} + +void ObjCInterfaceDecl::setHasODRHash(bool HasHash) { + assert(hasDefinition() && "Cannot set ODRHash without definition"); + data().HasODRHash = HasHash; +} + //===----------------------------------------------------------------------===// // ObjCMethodDecl //===----------------------------------------------------------------------===// @@ -782,7 +825,7 @@ ObjCMethodDecl::ObjCMethodDecl( QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance, bool isVariadic, bool isPropertyAccessor, bool isSynthesizedAccessorStub, bool isImplicitlyDeclared, bool isDefined, - ImplementationControl impControl, bool HasRelatedResultType) + ObjCImplementationControl impControl, bool HasRelatedResultType) : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo), DeclEndLoc(endLoc) { @@ -812,8 +855,8 @@ ObjCMethodDecl *ObjCMethodDecl::Create( Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance, bool isVariadic, bool isPropertyAccessor, bool isSynthesizedAccessorStub, - bool isImplicitlyDeclared, bool isDefined, ImplementationControl impControl, - bool HasRelatedResultType) { + bool isImplicitlyDeclared, bool isDefined, + ObjCImplementationControl impControl, bool HasRelatedResultType) { return new (C, contextDecl) ObjCMethodDecl( beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, @@ -826,7 +869,8 @@ ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { } bool ObjCMethodDecl::isDirectMethod() const { - return hasAttr<ObjCDirectAttr>(); + return hasAttr<ObjCDirectAttr>() && + !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting; } bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const { @@ -854,6 +898,14 @@ bool ObjCMethodDecl::isDesignatedInitializerForTheInterface( return false; } +bool ObjCMethodDecl::hasParamDestroyedInCallee() const { + for (auto *param : parameters()) { + if (param->isDestroyedInCallee()) + return true; + } + return false; +} + Stmt *ObjCMethodDecl::getBody() const { return Body.get(getASTContext().getExternalSource()); } @@ -879,8 +931,8 @@ void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C, 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()); + std::uninitialized_copy(Params.begin(), Params.end(), getParams()); + std::uninitialized_copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); } void ObjCMethodDecl::getSelectorLocs( @@ -895,12 +947,12 @@ void ObjCMethodDecl::setMethodParams(ASTContext &C, assert((!SelLocs.empty() || isImplicit()) && "No selector locs for non-implicit method"); if (isImplicit()) - return setParamsAndSelLocs(C, Params, llvm::None); + return setParamsAndSelLocs(C, Params, std::nullopt); setSelLocsKind(hasStandardSelectorLocs(getSelector(), SelLocs, Params, DeclEndLoc)); if (getSelLocsKind() != SelLoc_NonStandard) - return setParamsAndSelLocs(C, Params, llvm::None); + return setParamsAndSelLocs(C, Params, std::nullopt); setParamsAndSelLocs(C, Params, SelLocs); } @@ -1142,7 +1194,7 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context, getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed); auto *Self = ImplicitParamDecl::Create(Context, this, SourceLocation(), &Context.Idents.get("self"), selfTy, - ImplicitParamDecl::ObjCSelf); + ImplicitParamKind::ObjCSelf); setSelfDecl(Self); if (selfIsConsumed) @@ -1153,7 +1205,7 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context, setCmdDecl(ImplicitParamDecl::Create( Context, this, SourceLocation(), &Context.Idents.get("_cmd"), - Context.getObjCSelType(), ImplicitParamDecl::ObjCCmd)); + Context.getObjCSelType(), ImplicitParamKind::ObjCCmd)); } ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() { @@ -1479,7 +1531,7 @@ ObjCTypeParamList *ObjCTypeParamList::create( void ObjCTypeParamList::gatherDefaultTypeArgs( SmallVectorImpl<QualType> &typeArgs) const { typeArgs.reserve(size()); - for (auto typeParam : *this) + for (auto *typeParam : *this) typeArgs.push_back(typeParam->getUnderlyingType()); } @@ -1630,6 +1682,11 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { ObjCIvarDecl *curIvar = nullptr; if (!data().IvarList) { + // Force ivar deserialization upfront, before building IvarList. + (void)ivar_empty(); + for (const auto *Ext : known_extensions()) { + (void)Ext->ivar_empty(); + } if (!ivar_empty()) { ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end(); data().IvarList = *I; ++I; @@ -1821,8 +1878,8 @@ ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { ObjCIvarDecl::None, nullptr, false); } -const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const { - const auto *DC = cast<ObjCContainerDecl>(getDeclContext()); +ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() { + auto *DC = cast<ObjCContainerDecl>(getDeclContext()); switch (DC->getKind()) { default: @@ -1832,7 +1889,7 @@ const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const { // Ivars can only appear in class extension categories. case ObjCCategory: { - const auto *CD = cast<ObjCCategoryDecl>(DC); + auto *CD = cast<ObjCCategoryDecl>(DC); assert(CD->IsClassExtension() && "invalid container for ivar!"); return CD->getClassInterface(); } @@ -1966,6 +2023,7 @@ void ObjCProtocolDecl::allocateDefinitionData() { assert(!Data.getPointer() && "Protocol already has a definition!"); Data.setPointer(new (getASTContext()) DefinitionData); Data.getPointer()->Definition = this; + Data.getPointer()->HasODRHash = false; } void ObjCProtocolDecl::startDefinition() { @@ -1976,19 +2034,28 @@ void ObjCProtocolDecl::startDefinition() { RD->Data = this->Data; } -void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM, - PropertyDeclOrder &PO) const { +void ObjCProtocolDecl::startDuplicateDefinitionForComparison() { + Data.setPointer(nullptr); + allocateDefinitionData(); + // Don't propagate data to other redeclarations. +} + +void ObjCProtocolDecl::mergeDuplicateDefinitionWithCommon( + const ObjCProtocolDecl *Definition) { + Data = Definition->Data; +} + +void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM) 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); + PI->collectPropertiesToImplement(PM); } } @@ -2020,6 +2087,33 @@ ObjCProtocolDecl::getObjCRuntimeNameAsString() const { return getName(); } +unsigned ObjCProtocolDecl::getODRHash() { + assert(hasDefinition() && "ODRHash only for records with definitions"); + + // Previously calculated hash is stored in DefinitionData. + if (hasODRHash()) + return data().ODRHash; + + // Only calculate hash on first call of getODRHash per record. + ODRHash Hasher; + Hasher.AddObjCProtocolDecl(getDefinition()); + data().ODRHash = Hasher.CalculateHash(); + setHasODRHash(true); + + return data().ODRHash; +} + +bool ObjCProtocolDecl::hasODRHash() const { + if (!hasDefinition()) + return false; + return data().HasODRHash; +} + +void ObjCProtocolDecl::setHasODRHash(bool HasHash) { + assert(hasDefinition() && "Cannot set ODRHash without definition"); + data().HasODRHash = HasHash; +} + //===----------------------------------------------------------------------===// // ObjCCategoryDecl //===----------------------------------------------------------------------===// @@ -2295,6 +2389,11 @@ QualType ObjCPropertyDecl::getUsageType(QualType objectType) const { ObjCSubstitutionContext::Property); } +bool ObjCPropertyDecl::isDirectProperty() const { + return (PropertyAttributes & ObjCPropertyAttribute::kind_direct) && + !getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting; +} + //===----------------------------------------------------------------------===// // ObjCPropertyImplDecl //===----------------------------------------------------------------------===// |