diff options
author | apple-fcloutier <75502309+apple-fcloutier@users.noreply.github.com> | 2024-10-30 20:34:38 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-30 20:34:38 -0700 |
commit | 97788089988a2ace63d717cadbcfe3443f380f9c (patch) | |
tree | 940a661185e34c9b4499e8446d0ef39578f5f141 /clang/lib/Sema/SemaDeclObjC.cpp | |
parent | 75aaa312ffa9aa044b84bd1b32491937795c110a (diff) | |
download | llvm-97788089988a2ace63d717cadbcfe3443f380f9c.zip llvm-97788089988a2ace63d717cadbcfe3443f380f9c.tar.gz llvm-97788089988a2ace63d717cadbcfe3443f380f9c.tar.bz2 |
[ObjC] Insert method parameters in scope as they are parsed (#113745)
Before this change, ParseObjc would call the closing
`MaybeParseAttributes` before it had created Objective-C `ParmVarDecl`
objects (and associated name lookup entries), meaning that you could not
reference Objective-C method parameters in
`__attribute__((diagnose_if))`. This change moves the creation of the
`ParmVarDecl` objects ahead of calling `Sema::ActOnMethodDeclaration` so
that `MaybeParseAttributes` can find them. This is already how it works
for C parameters hanging off of the selector.
This change alone is insufficient to enable `diagnose_if` for
Objective-C methods and effectively is NFC. There will be a follow-up PR
for diagnose_if. This change is still useful for any other work that may
need attributes to reference Objective-C parameters.
rdar://138596211
Diffstat (limited to 'clang/lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 112 |
1 files changed, 58 insertions, 54 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 78acfed..3b19c9b 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -4720,13 +4720,67 @@ static void checkObjCDirectMethodClashes(Sema &S, ObjCInterfaceDecl *IDecl, diagClash(IMD); } +ParmVarDecl *SemaObjC::ActOnMethodParmDeclaration(Scope *S, + ObjCArgInfo &ArgInfo, + int ParamIndex, + bool MethodDefinition) { + ASTContext &Context = getASTContext(); + QualType ArgType; + TypeSourceInfo *DI; + + if (!ArgInfo.Type) { + ArgType = Context.getObjCIdType(); + DI = nullptr; + } else { + ArgType = SemaRef.GetTypeFromParser(ArgInfo.Type, &DI); + } + LookupResult R(SemaRef, ArgInfo.Name, ArgInfo.NameLoc, + Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); + SemaRef.LookupName(R, S); + if (R.isSingleResult()) { + NamedDecl *PrevDecl = R.getFoundDecl(); + if (S->isDeclScope(PrevDecl)) { + Diag(ArgInfo.NameLoc, + (MethodDefinition ? diag::warn_method_param_redefinition + : diag::warn_method_param_declaration)) + << ArgInfo.Name; + Diag(PrevDecl->getLocation(), diag::note_previous_declaration); + } + } + SourceLocation StartLoc = + DI ? DI->getTypeLoc().getBeginLoc() : ArgInfo.NameLoc; + + // Temporarily put parameter variables in the translation unit. This is what + // ActOnParamDeclarator does in the case of C arguments to the Objective-C + // method too. + ParmVarDecl *Param = SemaRef.CheckParameter( + Context.getTranslationUnitDecl(), StartLoc, ArgInfo.NameLoc, ArgInfo.Name, + ArgType, DI, SC_None); + Param->setObjCMethodScopeInfo(ParamIndex); + Param->setObjCDeclQualifier( + CvtQTToAstBitMask(ArgInfo.DeclSpec.getObjCDeclQualifier())); + + // Apply the attributes to the parameter. + SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, ArgInfo.ArgAttrs); + SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param); + if (Param->hasAttr<BlocksAttr>()) { + Diag(Param->getLocation(), diag::err_block_on_nonlocal); + Param->setInvalidDecl(); + } + + S->AddDecl(Param); + SemaRef.IdResolver.AddDecl(Param); + return Param; +} + Decl *SemaObjC::ActOnMethodDeclaration( Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc, tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, ArrayRef<SourceLocation> SelectorLocs, Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). - ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, + ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodDeclKind, bool isVariadic, bool MethodDefinition) { @@ -4768,60 +4822,10 @@ Decl *SemaObjC::ActOnMethodDeclaration( HasRelatedResultType); SmallVector<ParmVarDecl*, 16> Params; - - for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) { - QualType ArgType; - TypeSourceInfo *DI; - - if (!ArgInfo[i].Type) { - ArgType = Context.getObjCIdType(); - DI = nullptr; - } else { - ArgType = SemaRef.GetTypeFromParser(ArgInfo[i].Type, &DI); - } - - LookupResult R(SemaRef, ArgInfo[i].Name, ArgInfo[i].NameLoc, - Sema::LookupOrdinaryName, - SemaRef.forRedeclarationInCurContext()); - SemaRef.LookupName(R, S); - if (R.isSingleResult()) { - NamedDecl *PrevDecl = R.getFoundDecl(); - if (S->isDeclScope(PrevDecl)) { - Diag(ArgInfo[i].NameLoc, - (MethodDefinition ? diag::warn_method_param_redefinition - : diag::warn_method_param_declaration)) - << ArgInfo[i].Name; - Diag(PrevDecl->getLocation(), - diag::note_previous_declaration); - } - } - - SourceLocation StartLoc = DI - ? DI->getTypeLoc().getBeginLoc() - : ArgInfo[i].NameLoc; - - ParmVarDecl *Param = - SemaRef.CheckParameter(ObjCMethod, StartLoc, ArgInfo[i].NameLoc, - ArgInfo[i].Name, ArgType, DI, SC_None); - - Param->setObjCMethodScopeInfo(i); - - Param->setObjCDeclQualifier( - CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier())); - - // Apply the attributes to the parameter. - SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, - ArgInfo[i].ArgAttrs); - SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param); + for (unsigned I = 0; I < Sel.getNumArgs(); ++I) { + ParmVarDecl *Param = ArgInfo[I]; + Param->setDeclContext(ObjCMethod); SemaRef.ProcessAPINotes(Param); - - if (Param->hasAttr<BlocksAttr>()) { - Diag(Param->getLocation(), diag::err_block_on_nonlocal); - Param->setInvalidDecl(); - } - S->AddDecl(Param); - SemaRef.IdResolver.AddDecl(Param); - Params.push_back(Param); } |