diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp | 308 |
1 files changed, 164 insertions, 144 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp index e0f8c6e92d5a..bb0d0cd2030b 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaDeclObjC.cpp @@ -296,7 +296,7 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, RealizedPlatform = S.Context.getTargetInfo().getPlatformName(); // Warn about implementing unavailable methods, unless the unavailable // is for an app extension. - if (RealizedPlatform.endswith("_app_extension")) + if (RealizedPlatform.ends_with("_app_extension")) return; S.Diag(ImplLoc, diag::warn_unavailable_def); S.Diag(ND->getLocation(), diag::note_method_declared_at) @@ -611,7 +611,7 @@ ActOnSuperClassOfClassInterface(Scope *S, } } - if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) { + if (!isa_and_nonnull<TypedefNameDecl>(PrevDecl)) { if (!SuperClassDecl) Diag(SuperLoc, diag::err_undef_superclass) << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); @@ -782,7 +782,7 @@ ObjCTypeParamList *Sema::actOnObjCTypeParamList(Scope *S, // scope until later (after the instance variable block), but we want the // diagnostics to occur right after we parse the type parameter list. llvm::SmallDenseMap<IdentifierInfo *, ObjCTypeParamDecl *> knownParams; - for (auto typeParam : typeParams) { + for (auto *typeParam : typeParams) { auto known = knownParams.find(typeParam->getIdentifier()); if (known != knownParams.end()) { Diag(typeParam->getLocation(), diag::err_objc_type_param_redecl) @@ -803,7 +803,7 @@ ObjCTypeParamList *Sema::actOnObjCTypeParamList(Scope *S, } void Sema::popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList) { - for (auto typeParam : *typeParamList) { + for (auto *typeParam : *typeParamList) { if (!typeParam->isInvalidDecl()) { S->RemoveDecl(typeParam); IdResolver.RemoveDecl(typeParam); @@ -971,14 +971,14 @@ static bool checkTypeParamListConsistency(Sema &S, return false; } -Decl *Sema::ActOnStartClassInterface( +ObjCInterfaceDecl *Sema::ActOnStartClassInterface( Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, IdentifierInfo *SuperName, SourceLocation SuperLoc, ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, - const ParsedAttributesView &AttrList) { + const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody) { assert(ClassName && "Missing class identifier"); // Check for another declaration kind with the same name. @@ -1029,7 +1029,7 @@ Decl *Sema::ActOnStartClassInterface( // Clone the type parameter list. SmallVector<ObjCTypeParamDecl *, 4> clonedTypeParams; - for (auto typeParam : *prevTypeParamList) { + for (auto *typeParam : *prevTypeParamList) { clonedTypeParams.push_back( ObjCTypeParamDecl::Create( Context, @@ -1057,10 +1057,16 @@ Decl *Sema::ActOnStartClassInterface( if (PrevIDecl) { // Class already seen. Was it a definition? if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) { - Diag(AtInterfaceLoc, diag::err_duplicate_class_def) - << PrevIDecl->getDeclName(); - Diag(Def->getLocation(), diag::note_previous_definition); - IDecl->setInvalidDecl(); + if (SkipBody && !hasVisibleDefinition(Def)) { + SkipBody->CheckSameAsPrevious = true; + SkipBody->New = IDecl; + SkipBody->Previous = Def; + } else { + Diag(AtInterfaceLoc, diag::err_duplicate_class_def) + << PrevIDecl->getDeclName(); + Diag(Def->getLocation(), diag::note_previous_definition); + IDecl->setInvalidDecl(); + } } } @@ -1075,7 +1081,9 @@ Decl *Sema::ActOnStartClassInterface( // Start the definition of this class. If we're in a redefinition case, there // may already be a definition, so we'll end up adding to it. - if (!IDecl->hasDefinition()) + if (SkipBody && SkipBody->CheckSameAsPrevious) + IDecl->startDuplicateDefinitionForComparison(); + else if (!IDecl->hasDefinition()) IDecl->startDefinition(); if (SuperName) { @@ -1100,7 +1108,8 @@ Decl *Sema::ActOnStartClassInterface( } CheckObjCDeclScope(IDecl); - return ActOnObjCContainerStartDefinition(IDecl); + ActOnObjCContainerStartDefinition(IDecl); + return IDecl; } /// ActOnTypedefedProtocols - this action finds protocol list as part of the @@ -1208,11 +1217,11 @@ bool Sema::CheckForwardProtocolDeclarationForCircularDependency( return res; } -Decl *Sema::ActOnStartProtocolInterface( +ObjCProtocolDecl *Sema::ActOnStartProtocolInterface( SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, - const ParsedAttributesView &AttrList) { + const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody) { bool err = false; // FIXME: Deal with AttrList. assert(ProtocolName && "Missing protocol identifier"); @@ -1220,23 +1229,29 @@ Decl *Sema::ActOnStartProtocolInterface( forRedeclarationInCurContext()); ObjCProtocolDecl *PDecl = nullptr; if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) { - // If we already have a definition, complain. - Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName; - Diag(Def->getLocation(), diag::note_previous_definition); - // Create a new protocol that is completely distinct from previous // declarations, and do not make this protocol available for name lookup. // That way, we'll end up completely ignoring the duplicate. // FIXME: Can we turn this into an error? PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, ProtocolLoc, AtProtoInterfaceLoc, - /*PrevDecl=*/nullptr); + /*PrevDecl=*/Def); + + if (SkipBody && !hasVisibleDefinition(Def)) { + SkipBody->CheckSameAsPrevious = true; + SkipBody->New = PDecl; + SkipBody->Previous = Def; + } else { + // If we already have a definition, complain. + Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName; + Diag(Def->getLocation(), diag::note_previous_definition); + } // If we are using modules, add the decl to the context in order to // serialize something meaningful. if (getLangOpts().Modules) PushOnScopeChains(PDecl, TUScope); - PDecl->startDefinition(); + PDecl->startDuplicateDefinitionForComparison(); } else { if (PrevDecl) { // Check for circular dependencies among protocol declarations. This can @@ -1272,7 +1287,8 @@ Decl *Sema::ActOnStartProtocolInterface( } CheckObjCDeclScope(PDecl); - return ActOnObjCContainerStartDefinition(PDecl); + ActOnObjCContainerStartDefinition(PDecl); + return PDecl; } static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, @@ -1500,7 +1516,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( llvm::SmallPtrSet<ObjCProtocolDecl*, 8> knownProtocols; Context.CollectInheritedProtocols(baseClass, knownProtocols); bool allProtocolsDeclared = true; - for (auto proto : protocols) { + for (auto *proto : protocols) { if (knownProtocols.count(static_cast<ObjCProtocolDecl *>(proto)) == 0) { allProtocolsDeclared = false; break; @@ -1586,7 +1602,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( DS.SetRangeEnd(loc); // Form the declarator. - Declarator D(DS, DeclaratorContext::TypeName); + Declarator D(DS, ParsedAttributesView::none(), DeclaratorContext::TypeName); // If we have a typedef of an Objective-C class type that is missing a '*', // add the '*'. @@ -1607,7 +1623,7 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers( } // Convert this to a type. - return ActOnTypeName(S, D); + return ActOnTypeName(D); }; // Local function that updates the declaration specifiers with @@ -1799,7 +1815,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, return BuildDeclaratorGroup(DeclsInGroup); } -Decl *Sema::ActOnStartCategoryInterface( +ObjCCategoryDecl *Sema::ActOnStartCategoryInterface( SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, IdentifierInfo *CategoryName, SourceLocation CategoryLoc, @@ -1826,7 +1842,8 @@ Decl *Sema::ActOnStartCategoryInterface( if (!IDecl) Diag(ClassLoc, diag::err_undef_interface) << ClassName; - return ActOnObjCContainerStartDefinition(CDecl); + ActOnObjCContainerStartDefinition(CDecl); + return CDecl; } if (!CategoryName && IDecl->getImplementation()) { @@ -1889,17 +1906,17 @@ Decl *Sema::ActOnStartCategoryInterface( } CheckObjCDeclScope(CDecl); - return ActOnObjCContainerStartDefinition(CDecl); + ActOnObjCContainerStartDefinition(CDecl); + return CDecl; } /// ActOnStartCategoryImplementation - Perform semantic checks on the /// category implementation declaration and build an ObjCCategoryImplDecl /// object. -Decl *Sema::ActOnStartCategoryImplementation( - SourceLocation AtCatImplLoc, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *CatName, SourceLocation CatLoc, - const ParsedAttributesView &Attrs) { +ObjCCategoryImplDecl *Sema::ActOnStartCategoryImplementation( + SourceLocation AtCatImplLoc, IdentifierInfo *ClassName, + SourceLocation ClassLoc, IdentifierInfo *CatName, SourceLocation CatLoc, + const ParsedAttributesView &Attrs) { ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); ObjCCategoryDecl *CatIDecl = nullptr; if (IDecl && IDecl->hasDefinition()) { @@ -1958,15 +1975,14 @@ Decl *Sema::ActOnStartCategoryImplementation( } CheckObjCDeclScope(CDecl); - return ActOnObjCContainerStartDefinition(CDecl); + ActOnObjCContainerStartDefinition(CDecl); + return CDecl; } -Decl *Sema::ActOnStartClassImplementation( - SourceLocation AtClassImplLoc, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *SuperClassname, - SourceLocation SuperClassLoc, - const ParsedAttributesView &Attrs) { +ObjCImplementationDecl *Sema::ActOnStartClassImplementation( + SourceLocation AtClassImplLoc, IdentifierInfo *ClassName, + SourceLocation ClassLoc, IdentifierInfo *SuperClassname, + SourceLocation SuperClassLoc, const ParsedAttributesView &Attrs) { ObjCInterfaceDecl *IDecl = nullptr; // Check for another declaration kind with the same name. NamedDecl *PrevDecl @@ -2063,8 +2079,10 @@ Decl *Sema::ActOnStartClassImplementation( ProcessDeclAttributeList(TUScope, IMPDecl, Attrs); AddPragmaAttributes(TUScope, IMPDecl); - if (CheckObjCDeclScope(IMPDecl)) - return ActOnObjCContainerStartDefinition(IMPDecl); + if (CheckObjCDeclScope(IMPDecl)) { + ActOnObjCContainerStartDefinition(IMPDecl); + return IMPDecl; + } // Check that there is no duplicate implementation of this class. if (IDecl->getImplementation()) { @@ -2090,7 +2108,8 @@ Decl *Sema::ActOnStartClassImplementation( << IDecl->getSuperClass()->getDeclName(); } - return ActOnObjCContainerStartDefinition(IMPDecl); + ActOnObjCContainerStartDefinition(IMPDecl); + return IMPDecl; } Sema::DeclGroupPtrTy @@ -2212,9 +2231,8 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count); } -static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc, - ObjCMethodDecl *method, - bool &IncompleteImpl, +static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl, + ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID, NamedDecl *NeededFor = nullptr) { // No point warning no definition of method which is 'unavailable'. @@ -2227,10 +2245,19 @@ static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc, // separate warnings. We will give that approach a try, as that // matches what we do with protocols. { - const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID); + const Sema::SemaDiagnosticBuilder &B = S.Diag(Impl->getLocation(), DiagID); B << method; if (NeededFor) B << NeededFor; + + // Add an empty definition at the end of the @implementation. + std::string FixItStr; + llvm::raw_string_ostream Out(FixItStr); + method->print(Out, Impl->getASTContext().getPrintingPolicy()); + Out << " {\n}\n\n"; + + SourceLocation Loc = Impl->getAtEndRange().getBegin(); + B << FixItHint::CreateInsertion(Loc, FixItStr); } // Issue a note to the original declaration. @@ -2342,21 +2369,17 @@ static bool CheckMethodOverrideReturn(Sema &S, !S.Context.hasSameNullabilityTypeQualifier(MethodImpl->getReturnType(), MethodDecl->getReturnType(), false)) { - auto nullabilityMethodImpl = - *MethodImpl->getReturnType()->getNullability(S.Context); - auto nullabilityMethodDecl = - *MethodDecl->getReturnType()->getNullability(S.Context); - S.Diag(MethodImpl->getLocation(), - diag::warn_conflicting_nullability_attr_overriding_ret_types) - << DiagNullabilityKind( - nullabilityMethodImpl, - ((MethodImpl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) - != 0)) - << DiagNullabilityKind( - nullabilityMethodDecl, - ((MethodDecl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) - != 0)); - S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration); + auto nullabilityMethodImpl = *MethodImpl->getReturnType()->getNullability(); + auto nullabilityMethodDecl = *MethodDecl->getReturnType()->getNullability(); + S.Diag(MethodImpl->getLocation(), + diag::warn_conflicting_nullability_attr_overriding_ret_types) + << DiagNullabilityKind(nullabilityMethodImpl, + ((MethodImpl->getObjCDeclQualifier() & + Decl::OBJC_TQ_CSNullability) != 0)) + << DiagNullabilityKind(nullabilityMethodDecl, + ((MethodDecl->getObjCDeclQualifier() & + Decl::OBJC_TQ_CSNullability) != 0)); + S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration); } if (S.Context.hasSameUnqualifiedType(MethodImpl->getReturnType(), @@ -2434,14 +2457,12 @@ static bool CheckMethodOverrideParam(Sema &S, !S.Context.hasSameNullabilityTypeQualifier(ImplTy, IfaceTy, true)) { S.Diag(ImplVar->getLocation(), diag::warn_conflicting_nullability_attr_overriding_param_types) - << DiagNullabilityKind( - *ImplTy->getNullability(S.Context), - ((ImplVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) - != 0)) - << DiagNullabilityKind( - *IfaceTy->getNullability(S.Context), - ((IfaceVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) - != 0)); + << DiagNullabilityKind(*ImplTy->getNullability(), + ((ImplVar->getObjCDeclQualifier() & + Decl::OBJC_TQ_CSNullability) != 0)) + << DiagNullabilityKind(*IfaceTy->getNullability(), + ((IfaceVar->getObjCDeclQualifier() & + Decl::OBJC_TQ_CSNullability) != 0)); S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration); } if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy)) @@ -2611,10 +2632,11 @@ void Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, // don't issue warning when protocol method is optional because primary // class is not required to implement it and it is safe for protocol // to implement it. - if (MethodDecl->getImplementationControl() == ObjCMethodDecl::Optional) + if (MethodDecl->getImplementationControl() == + ObjCImplementationControl::Optional) return; // don't issue warning when primary class's method is - // depecated/unavailable. + // deprecated/unavailable. if (MethodDecl->hasAttr<UnavailableAttr>() || MethodDecl->hasAttr<DeprecatedAttr>()) return; @@ -2679,14 +2701,10 @@ static void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super, /// CheckProtocolMethodDefs - This routine checks unimplemented methods /// Declared in protocol, and those referenced by it. -static void CheckProtocolMethodDefs(Sema &S, - SourceLocation ImpLoc, - ObjCProtocolDecl *PDecl, - bool& IncompleteImpl, - const Sema::SelectorSet &InsMap, - const Sema::SelectorSet &ClsMap, - ObjCContainerDecl *CDecl, - LazyProtocolNameSet &ProtocolsExplictImpl) { +static void CheckProtocolMethodDefs( + Sema &S, ObjCImplDecl *Impl, ObjCProtocolDecl *PDecl, bool &IncompleteImpl, + const Sema::SelectorSet &InsMap, const Sema::SelectorSet &ClsMap, + ObjCContainerDecl *CDecl, LazyProtocolNameSet &ProtocolsExplictImpl) { ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl); ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() : dyn_cast<ObjCInterfaceDecl>(CDecl); @@ -2711,8 +2729,7 @@ static void CheckProtocolMethodDefs(Sema &S, ProtocolsExplictImpl.reset(new ProtocolNameSet); findProtocolsWithExplicitImpls(Super, *ProtocolsExplictImpl); } - if (ProtocolsExplictImpl->find(PDecl->getIdentifier()) != - ProtocolsExplictImpl->end()) + if (ProtocolsExplictImpl->contains(PDecl->getIdentifier())) return; // If no super class conforms to the protocol, we should not search @@ -2749,46 +2766,43 @@ static void CheckProtocolMethodDefs(Sema &S, // check unimplemented instance methods. if (!NSIDecl) for (auto *method : PDecl->instance_methods()) { - if (method->getImplementationControl() != ObjCMethodDecl::Optional && + if (method->getImplementationControl() != + ObjCImplementationControl::Optional && !method->isPropertyAccessor() && !InsMap.count(method->getSelector()) && - (!Super || !Super->lookupMethod(method->getSelector(), - true /* instance */, - false /* shallowCategory */, - true /* followsSuper */, - nullptr /* category */))) { - // If a method is not implemented in the category implementation but - // has been declared in its primary class, superclass, - // or in one of their protocols, no need to issue the warning. - // This is because method will be implemented in the primary class - // or one of its super class implementation. - - // Ugly, but necessary. Method declared in protocol might have - // have been synthesized due to a property declared in the class which - // uses the protocol. - if (ObjCMethodDecl *MethodInClass = - IDecl->lookupMethod(method->getSelector(), - true /* instance */, - true /* shallowCategoryLookup */, - false /* followSuper */)) - if (C || MethodInClass->isPropertyAccessor()) - continue; - unsigned DIAG = diag::warn_unimplemented_protocol_method; - if (!S.Diags.isIgnored(DIAG, ImpLoc)) { - WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, - PDecl); - } - } + (!Super || !Super->lookupMethod( + method->getSelector(), true /* instance */, + false /* shallowCategory */, true /* followsSuper */, + nullptr /* category */))) { + // If a method is not implemented in the category implementation but + // has been declared in its primary class, superclass, + // or in one of their protocols, no need to issue the warning. + // This is because method will be implemented in the primary class + // or one of its super class implementation. + + // Ugly, but necessary. Method declared in protocol might have + // have been synthesized due to a property declared in the class which + // uses the protocol. + if (ObjCMethodDecl *MethodInClass = IDecl->lookupMethod( + method->getSelector(), true /* instance */, + true /* shallowCategoryLookup */, false /* followSuper */)) + if (C || MethodInClass->isPropertyAccessor()) + continue; + unsigned DIAG = diag::warn_unimplemented_protocol_method; + if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) { + WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl); + } + } } // check unimplemented class methods for (auto *method : PDecl->class_methods()) { - if (method->getImplementationControl() != ObjCMethodDecl::Optional && + if (method->getImplementationControl() != + ObjCImplementationControl::Optional && !ClsMap.count(method->getSelector()) && - (!Super || !Super->lookupMethod(method->getSelector(), - false /* class method */, - false /* shallowCategoryLookup */, - true /* followSuper */, - nullptr /* category */))) { + (!Super || !Super->lookupMethod( + method->getSelector(), false /* class method */, + false /* shallowCategoryLookup */, + true /* followSuper */, nullptr /* category */))) { // See above comment for instance method lookups. if (C && IDecl->lookupMethod(method->getSelector(), false /* class */, @@ -2797,15 +2811,15 @@ static void CheckProtocolMethodDefs(Sema &S, continue; unsigned DIAG = diag::warn_unimplemented_protocol_method; - if (!S.Diags.isIgnored(DIAG, ImpLoc)) { - WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl); + if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) { + WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl); } } } // Check on this protocols's referenced protocols, recursively. for (auto *PI : PDecl->protocols()) - CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap, - CDecl, ProtocolsExplictImpl); + CheckProtocolMethodDefs(S, Impl, PI, IncompleteImpl, InsMap, ClsMap, CDecl, + ProtocolsExplictImpl); } /// MatchAllMethodDeclarations - Check methods declared in interface @@ -2828,7 +2842,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, if (!I->isPropertyAccessor() && !InsMap.count(I->getSelector())) { if (ImmediateClass) - WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, + WarnUndefinedMethod(*this, IMPDecl, I, IncompleteImpl, diag::warn_undef_method_impl); continue; } else { @@ -2858,7 +2872,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, if (!I->isPropertyAccessor() && !ClsMap.count(I->getSelector())) { if (ImmediateClass) - WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, + WarnUndefinedMethod(*this, IMPDecl, I, IncompleteImpl, diag::warn_undef_method_impl); } else { ObjCMethodDecl *ImpMethodDecl = @@ -3025,16 +3039,15 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { for (auto *PI : I->all_referenced_protocols()) - CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl, - InsMap, ClsMap, I, ExplicitImplProtocols); + CheckProtocolMethodDefs(*this, IMPDecl, PI, IncompleteImpl, InsMap, + ClsMap, I, ExplicitImplProtocols); } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) { // For extended class, unimplemented methods in its protocols will // be reported in the primary class. if (!C->IsClassExtension()) { for (auto *P : C->protocols()) - CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P, - IncompleteImpl, InsMap, ClsMap, CDecl, - ExplicitImplProtocols); + CheckProtocolMethodDefs(*this, IMPDecl, P, IncompleteImpl, InsMap, + ClsMap, CDecl, ExplicitImplProtocols); DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, /*SynthesizeProperties=*/false); } @@ -3427,8 +3440,10 @@ void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector()); if (Pos == MethodPool.end()) - Pos = MethodPool.insert(std::make_pair(Method->getSelector(), - GlobalMethods())).first; + Pos = MethodPool + .insert(std::make_pair(Method->getSelector(), + GlobalMethodPool::Lists())) + .first; Method->setDefined(impl); @@ -3636,7 +3651,7 @@ ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) { if (Pos == MethodPool.end()) return nullptr; - GlobalMethods &Methods = Pos->second; + GlobalMethodPool::Lists &Methods = Pos->second; for (const ObjCMethodList *Method = &Methods.first; Method; Method = Method->getNext()) if (Method->getMethod() && @@ -3746,7 +3761,7 @@ Sema::SelectorsForTypoCorrection(Selector Sel, /// DiagnoseDuplicateIvars - /// Check for duplicate ivars in the entire class at the start of -/// \@implementation. This becomes necesssary because class extension can +/// \@implementation. This becomes necessary because class extension can /// add ivars to a class in random order which will not be known until /// class's \@implementation is seen. void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, @@ -3847,7 +3862,7 @@ static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) { // Check if variable sized ivar is in interface and visible to subclasses. if (!isa<ObjCInterfaceDecl>(OCD)) { - for (auto ivar : Ivars) { + for (auto *ivar : Ivars) { if (!ivar->isInvalidDecl() && IsVariableSizedType(ivar->getType())) { S.Diag(ivar->getLocation(), diag::warn_variable_sized_ivar_visibility) << ivar->getDeclName() << ivar->getType(); @@ -3869,7 +3884,7 @@ static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) { if (IvarTy->isIncompleteArrayType()) { S.Diag(ivar->getLocation(), diag::err_flexible_array_not_at_end) << ivar->getDeclName() << IvarTy - << TTK_Class; // Use "class" for Obj-C. + << llvm::to_underlying(TagTypeKind::Class); // Use "class" for Obj-C. IsInvalidIvar = true; } else if (const RecordType *RecordTy = IvarTy->getAs<RecordType>()) { if (RecordTy->getDecl()->hasFlexibleArrayMember()) { @@ -3982,7 +3997,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, // they are overridden by an explicit method that is encountered // later. if (auto *OID = dyn_cast<ObjCImplementationDecl>(CurContext)) { - for (auto PropImpl : OID->property_impls()) { + for (auto *PropImpl : OID->property_impls()) { if (auto *Getter = PropImpl->getGetterMethodDecl()) if (Getter->isSynthesizedAccessorStub()) OID->addDecl(Getter); @@ -4424,6 +4439,11 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ResultTypeCompatibilityKind RTC) { if (!ObjCMethod) return; + auto IsMethodInCurrentClass = [CurrentClass](const ObjCMethodDecl *M) { + // Checking canonical decl works across modules. + return M->getClassInterface()->getCanonicalDecl() == + CurrentClass->getCanonicalDecl(); + }; // Search for overridden methods and merge information down from them. OverrideSearch overrides(*this, ObjCMethod); // Keep track if the method overrides any method in the class's base classes, @@ -4435,8 +4455,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, for (ObjCMethodDecl *overridden : overrides) { if (!hasOverriddenMethodsInBaseOrProtocol) { if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) || - CurrentClass != overridden->getClassInterface() || - overridden->isOverriding()) { + !IsMethodInCurrentClass(overridden) || overridden->isOverriding()) { CheckObjCMethodDirectOverrides(ObjCMethod, overridden); hasOverriddenMethodsInBaseOrProtocol = true; } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) { @@ -4461,7 +4480,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, OverrideSearch overrides(*this, overridden); for (ObjCMethodDecl *SuperOverridden : overrides) { if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) || - CurrentClass != SuperOverridden->getClassInterface()) { + !IsMethodInCurrentClass(SuperOverridden)) { CheckObjCMethodDirectOverrides(ObjCMethod, SuperOverridden); hasOverriddenMethodsInBaseOrProtocol = true; overridden->setOverriding(true); @@ -4525,11 +4544,11 @@ static QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc, QualType prevType, bool prevUsesCSKeyword) { // Determine the nullability of both types. - auto nullability = type->getNullability(S.Context); - auto prevNullability = prevType->getNullability(S.Context); + auto nullability = type->getNullability(); + auto prevNullability = prevType->getNullability(); // Easy case: both have nullability. - if (nullability.hasValue() == prevNullability.hasValue()) { + if (nullability.has_value() == prevNullability.has_value()) { // Neither has nullability; continue. if (!nullability) return type; @@ -4739,8 +4758,9 @@ Decl *Sema::ActOnMethodDeclaration( MethodType == tok::minus, isVariadic, /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false, /*isImplicitlyDeclared=*/false, /*isDefined=*/false, - MethodDeclKind == tok::objc_optional ? ObjCMethodDecl::Optional - : ObjCMethodDecl::Required, + MethodDeclKind == tok::objc_optional + ? ObjCImplementationControl::Optional + : ObjCImplementationControl::Required, HasRelatedResultType); SmallVector<ParmVarDecl*, 16> Params; @@ -4832,7 +4852,7 @@ Decl *Sema::ActOnMethodDeclaration( // If this method overrides a previous @synthesize declaration, // register it with the property. Linear search through all // properties here, because the autosynthesized stub hasn't been - // made visible yet, so it can be overriden by a later + // made visible yet, so it can be overridden by a later // user-specified implementation. for (ObjCPropertyImplDecl *PropertyImpl : ImpDecl->property_impls()) { if (auto *Setter = PropertyImpl->getSetterMethodDecl()) @@ -5191,7 +5211,7 @@ Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { if (getLangOpts().CPlusPlus) CheckExtraCXXDefaultArguments(D); - TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); + TypeSourceInfo *TInfo = GetTypeForDeclarator(D); QualType ExceptionType = TInfo->getType(); VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType, |