diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp | 131 |
1 files changed, 103 insertions, 28 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp index b43e5b9..9675730 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp @@ -248,18 +248,41 @@ bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) { return false; } -static void DiagnoseObjCImplementedDeprecations(Sema &S, - NamedDecl *ND, - SourceLocation ImplLoc, - int select) { - if (ND && ND->isDeprecated()) { - S.Diag(ImplLoc, diag::warn_deprecated_def) << select; - if (select == 0) +static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, + SourceLocation ImplLoc) { + if (!ND) + return; + bool IsCategory = false; + AvailabilityResult Availability = ND->getAvailability(); + if (Availability != AR_Deprecated) { + if (isa<ObjCMethodDecl>(ND)) { + if (Availability != AR_Unavailable) + return; + // Warn about implementing unavailable methods. + S.Diag(ImplLoc, diag::warn_unavailable_def); S.Diag(ND->getLocation(), diag::note_method_declared_at) - << ND->getDeclName(); - else - S.Diag(ND->getLocation(), diag::note_previous_decl) << "class"; + << ND->getDeclName(); + return; + } + if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND)) { + if (!CD->getClassInterface()->isDeprecated()) + return; + ND = CD->getClassInterface(); + IsCategory = true; + } else + return; } + S.Diag(ImplLoc, diag::warn_deprecated_def) + << (isa<ObjCMethodDecl>(ND) + ? /*Method*/ 0 + : isa<ObjCCategoryDecl>(ND) || IsCategory ? /*Category*/ 2 + : /*Class*/ 1); + if (isa<ObjCMethodDecl>(ND)) + S.Diag(ND->getLocation(), diag::note_method_declared_at) + << ND->getDeclName(); + else + S.Diag(ND->getLocation(), diag::note_previous_decl) + << (isa<ObjCCategoryDecl>(ND) ? "category" : "class"); } /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global @@ -384,9 +407,7 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { // No need to issue deprecated warning if deprecated mehod in class/category // is being implemented in its own implementation (no overriding is involved). if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef) - DiagnoseObjCImplementedDeprecations(*this, - dyn_cast<NamedDecl>(IMD), - MDecl->getLocation(), 0); + DiagnoseObjCImplementedDeprecations(*this, IMD, MDecl->getLocation()); } if (MDecl->getMethodFamily() == OMF_init) { @@ -457,7 +478,10 @@ static void diagnoseUseOfProtocols(Sema &TheSema, // Diagnose availability in the context of the ObjC container. Sema::ContextRAII SavedContext(TheSema, CD); for (unsigned i = 0; i < NumProtoRefs; ++i) { - (void)TheSema.DiagnoseUseOfDecl(ProtoRefs[i], ProtoLocs[i]); + (void)TheSema.DiagnoseUseOfDecl(ProtoRefs[i], ProtoLocs[i], + /*UnknownObjCClass=*/nullptr, + /*ObjCPropertyAccess=*/false, + /*AvoidPartialAvailabilityChecks=*/true); } } @@ -992,6 +1016,7 @@ ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc, if (AttrList) ProcessDeclAttributeList(TUScope, IDecl, AttrList); + AddPragmaAttributes(TUScope, IDecl); PushOnScopeChains(IDecl, TUScope); // Start the definition of this class. If we're in a redefinition case, there @@ -1175,7 +1200,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, if (AttrList) ProcessDeclAttributeList(TUScope, PDecl, AttrList); - + AddPragmaAttributes(TUScope, PDecl); + // Merge attributes from previous declarations. if (PrevDecl) mergeDeclAttributes(PDecl, PrevDecl); @@ -1705,7 +1731,8 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, if (attrList) ProcessDeclAttributeList(TUScope, PDecl, attrList); - + AddPragmaAttributes(TUScope, PDecl); + if (PrevDecl) mergeDeclAttributes(PDecl, PrevDecl); @@ -1724,7 +1751,8 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, Decl * const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, - SourceLocation EndProtoLoc) { + SourceLocation EndProtoLoc, + AttributeList *AttrList) { ObjCCategoryDecl *CDecl; ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); @@ -1801,6 +1829,10 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, NumProtoRefs, Context); } + if (AttrList) + ProcessDeclAttributeList(TUScope, CDecl, AttrList); + AddPragmaAttributes(TUScope, CDecl); + CheckObjCDeclScope(CDecl); return ActOnObjCContainerStartDefinition(CDecl); } @@ -1842,10 +1874,6 @@ Decl *Sema::ActOnStartCategoryImplementation( // FIXME: PushOnScopeChains? CurContext->addDecl(CDecl); - // If the interface is deprecated/unavailable, warn/error about it. - if (IDecl) - DiagnoseUseOfDecl(IDecl, ClassLoc); - // If the interface has the objc_runtime_visible attribute, we // cannot implement a category for it. if (IDecl && IDecl->hasAttr<ObjCRuntimeVisibleAttr>()) { @@ -1865,9 +1893,8 @@ Decl *Sema::ActOnStartCategoryImplementation( CatIDecl->setImplementation(CDecl); // Warn on implementating category of deprecated class under // -Wdeprecated-implementations flag. - DiagnoseObjCImplementedDeprecations(*this, - dyn_cast<NamedDecl>(IDecl), - CDecl->getLocation(), 2); + DiagnoseObjCImplementedDeprecations(*this, CatIDecl, + CDecl->getLocation()); } } @@ -1948,6 +1975,7 @@ Decl *Sema::ActOnStartClassImplementation( ClassName, /*typeParamList=*/nullptr, /*PrevDecl=*/nullptr, ClassLoc, true); + AddPragmaAttributes(TUScope, IDecl); IDecl->startDefinition(); if (SDecl) { IDecl->setSuperClass(Context.getTrivialTypeSourceInfo( @@ -1986,9 +2014,7 @@ Decl *Sema::ActOnStartClassImplementation( PushOnScopeChains(IMPDecl, TUScope); // Warn on implementating deprecated class under // -Wdeprecated-implementations flag. - DiagnoseObjCImplementedDeprecations(*this, - dyn_cast<NamedDecl>(IDecl), - IMPDecl->getLocation(), 1); + DiagnoseObjCImplementedDeprecations(*this, IDecl, IMPDecl->getLocation()); } // If the superclass has the objc_runtime_visible attribute, we @@ -3037,7 +3063,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, ClassName, TypeParams, PrevIDecl, IdentLocs[i]); IDecl->setAtEndRange(IdentLocs[i]); - + PushOnScopeChains(IDecl, TUScope); CheckObjCDeclScope(IDecl); DeclsInGroup.push_back(IDecl); @@ -4302,6 +4328,49 @@ static void mergeInterfaceMethodToImpl(Sema &S, } } +/// Verify that the method parameters/return value have types that are supported +/// by the x86 target. +static void checkObjCMethodX86VectorTypes(Sema &SemaRef, + const ObjCMethodDecl *Method) { + assert(SemaRef.getASTContext().getTargetInfo().getTriple().getArch() == + llvm::Triple::x86 && + "x86-specific check invoked for a different target"); + SourceLocation Loc; + QualType T; + for (const ParmVarDecl *P : Method->parameters()) { + if (P->getType()->isVectorType()) { + Loc = P->getLocStart(); + T = P->getType(); + break; + } + } + if (Loc.isInvalid()) { + if (Method->getReturnType()->isVectorType()) { + Loc = Method->getReturnTypeSourceRange().getBegin(); + T = Method->getReturnType(); + } else + return; + } + + // Vector parameters/return values are not supported by objc_msgSend on x86 in + // iOS < 9 and macOS < 10.11. + const auto &Triple = SemaRef.getASTContext().getTargetInfo().getTriple(); + VersionTuple AcceptedInVersion; + if (Triple.getOS() == llvm::Triple::IOS) + AcceptedInVersion = VersionTuple(/*Major=*/9); + else if (Triple.isMacOSX()) + AcceptedInVersion = VersionTuple(/*Major=*/10, /*Minor=*/11); + else + return; + if (SemaRef.getASTContext().getTargetInfo().getPlatformMinVersion() >= + AcceptedInVersion) + return; + SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type) + << T << (Method->getReturnType()->isVectorType() ? /*return value*/ 1 + : /*parameter*/ 0) + << (Triple.isMacOSX() ? "macOS 10.11" : "iOS 9"); +} + Decl *Sema::ActOnMethodDeclaration( Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc, @@ -4393,6 +4462,7 @@ Decl *Sema::ActOnMethodDeclaration( // Apply the attributes to the parameter. ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs); + AddPragmaAttributes(TUScope, Param); if (Param->hasAttr<BlocksAttr>()) { Diag(Param->getLocation(), diag::err_block_on_nonlocal); @@ -4423,6 +4493,7 @@ Decl *Sema::ActOnMethodDeclaration( if (AttrList) ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList); + AddPragmaAttributes(TUScope, ObjCMethod); // Add the method now. const ObjCMethodDecl *PrevMethod = nullptr; @@ -4521,6 +4592,10 @@ Decl *Sema::ActOnMethodDeclaration( ObjCMethod->SetRelatedResultType(); } + if (MethodDefinition && + Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) + checkObjCMethodX86VectorTypes(*this, ObjCMethod); + ActOnDocumentableDecl(ObjCMethod); return ObjCMethod; |