diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp index d376880a40e8..60253a82e93a 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp @@ -1066,6 +1066,11 @@ Decl *Sema::ActOnStartClassInterface( ProcessDeclAttributeList(TUScope, IDecl, AttrList); AddPragmaAttributes(TUScope, IDecl); + + // Merge attributes from previous declarations. + if (PrevIDecl) + mergeDeclAttributes(IDecl, PrevIDecl); + PushOnScopeChains(IDecl, TUScope); // Start the definition of this class. If we're in a redefinition case, there @@ -1581,7 +1586,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( DS.SetRangeEnd(loc); // Form the declarator. - Declarator D(DS, DeclaratorContext::TypeNameContext); + Declarator D(DS, DeclaratorContext::TypeName); // If we have a typedef of an Objective-C class type that is missing a '*', // add the '*'. @@ -2122,7 +2127,12 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, // Add ivar's to class's DeclContext. for (unsigned i = 0, e = numIvars; i != e; ++i) { ivars[i]->setLexicalDeclContext(ImpDecl); - IDecl->makeDeclVisibleInContext(ivars[i]); + // In a 'fragile' runtime the ivar was added to the implicit + // ObjCInterfaceDecl while in a 'non-fragile' runtime the ivar is + // only in the ObjCImplementationDecl. In the non-fragile case the ivar + // therefore also needs to be propagated to the ObjCInterfaceDecl. + if (!LangOpts.ObjCRuntime.isFragile()) + IDecl->makeDeclVisibleInContext(ivars[i]); ImpDecl->addDecl(ivars[i]); } @@ -3120,6 +3130,9 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, IdentLocs[i]); IDecl->setAtEndRange(IdentLocs[i]); + if (PrevIDecl) + mergeDeclAttributes(IDecl, PrevIDecl); + PushOnScopeChains(IDecl, TUScope); CheckObjCDeclScope(IDecl); DeclsInGroup.push_back(IDecl); @@ -3899,6 +3912,55 @@ static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) { } } +static void DiagnoseCategoryDirectMembersProtocolConformance( + Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl); + +static void DiagnoseCategoryDirectMembersProtocolConformance( + Sema &S, ObjCCategoryDecl *CDecl, + const llvm::iterator_range<ObjCProtocolList::iterator> &Protocols) { + for (auto *PI : Protocols) + DiagnoseCategoryDirectMembersProtocolConformance(S, PI, CDecl); +} + +static void DiagnoseCategoryDirectMembersProtocolConformance( + Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl) { + if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition()) + PDecl = PDecl->getDefinition(); + + llvm::SmallVector<const Decl *, 4> DirectMembers; + const auto *IDecl = CDecl->getClassInterface(); + for (auto *MD : PDecl->methods()) { + if (!MD->isPropertyAccessor()) { + if (const auto *CMD = + IDecl->getMethod(MD->getSelector(), MD->isInstanceMethod())) { + if (CMD->isDirectMethod()) + DirectMembers.push_back(CMD); + } + } + } + for (auto *PD : PDecl->properties()) { + if (const auto *CPD = IDecl->FindPropertyVisibleInPrimaryClass( + PD->getIdentifier(), + PD->isClassProperty() + ? ObjCPropertyQueryKind::OBJC_PR_query_class + : ObjCPropertyQueryKind::OBJC_PR_query_instance)) { + if (CPD->isDirectProperty()) + DirectMembers.push_back(CPD); + } + } + if (!DirectMembers.empty()) { + S.Diag(CDecl->getLocation(), diag::err_objc_direct_protocol_conformance) + << CDecl->IsClassExtension() << CDecl << PDecl << IDecl; + for (const auto *MD : DirectMembers) + S.Diag(MD->getLocation(), diag::note_direct_member_here); + return; + } + + // Check on this protocols's referenced protocols, recursively. + DiagnoseCategoryDirectMembersProtocolConformance(S, CDecl, + PDecl->protocols()); +} + // Note: For class/category implementations, allMethods is always null. Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, ArrayRef<DeclGroupPtrTy> allTUVars) { @@ -3922,15 +3984,11 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, if (auto *OID = dyn_cast<ObjCImplementationDecl>(CurContext)) { for (auto PropImpl : OID->property_impls()) { if (auto *Getter = PropImpl->getGetterMethodDecl()) - if (Getter->isSynthesizedAccessorStub()) { - OID->makeDeclVisibleInContext(Getter); + if (Getter->isSynthesizedAccessorStub()) OID->addDecl(Getter); - } if (auto *Setter = PropImpl->getSetterMethodDecl()) - if (Setter->isSynthesizedAccessorStub()) { - OID->makeDeclVisibleInContext(Setter); + if (Setter->isSynthesizedAccessorStub()) OID->addDecl(Setter); - } } } @@ -4003,6 +4061,8 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, ObjCInterfaceDecl *CCPrimary = C->getClassInterface(); DiagnoseClassExtensionDupMethods(C, CCPrimary); } + + DiagnoseCategoryDirectMembersProtocolConformance(*this, C, C->protocols()); } if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) { if (CDecl->getIdentifier()) |