aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDeclObjC.cpp
diff options
context:
space:
mode:
authorapple-fcloutier <75502309+apple-fcloutier@users.noreply.github.com>2024-10-30 20:34:38 -0700
committerGitHub <noreply@github.com>2024-10-30 20:34:38 -0700
commit97788089988a2ace63d717cadbcfe3443f380f9c (patch)
tree940a661185e34c9b4499e8446d0ef39578f5f141 /clang/lib/Sema/SemaDeclObjC.cpp
parent75aaa312ffa9aa044b84bd1b32491937795c110a (diff)
downloadllvm-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.cpp112
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);
}