Skip to content

Commit 9778808

Browse files
[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
1 parent 75aaa31 commit 9778808

File tree

3 files changed

+69
-59
lines changed

3 files changed

+69
-59
lines changed

clang/include/clang/Sema/SemaObjC.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ class SemaObjC : public SemaBase {
351351
ParsedAttributesView ArgAttrs;
352352
};
353353

354+
ParmVarDecl *ActOnMethodParmDeclaration(Scope *S, ObjCArgInfo &ArgInfo,
355+
int ParamIndex,
356+
bool MethodDefinition);
357+
354358
Decl *ActOnMethodDeclaration(
355359
Scope *S,
356360
SourceLocation BeginLoc, // location of the + or -.
@@ -359,7 +363,7 @@ class SemaObjC : public SemaBase {
359363
ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
360364
// optional arguments. The number of types/arguments is obtained
361365
// from the Sel.getNumArgs().
362-
ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
366+
ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
363367
unsigned CNumArgs, // c-style args
364368
const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind,
365369
bool isVariadic, bool MethodDefinition);

clang/lib/Parse/ParseObjc.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
14541454

14551455
SmallVector<const IdentifierInfo *, 12> KeyIdents;
14561456
SmallVector<SourceLocation, 12> KeyLocs;
1457-
SmallVector<SemaObjC::ObjCArgInfo, 12> ArgInfos;
1457+
SmallVector<ParmVarDecl *, 12> ObjCParamInfo;
14581458
ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
14591459
Scope::FunctionDeclarationScope | Scope::DeclScope);
14601460

@@ -1495,7 +1495,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
14951495
ArgInfo.NameLoc = Tok.getLocation();
14961496
ConsumeToken(); // Eat the identifier.
14971497

1498-
ArgInfos.push_back(ArgInfo);
1498+
ParmVarDecl *Param = Actions.ObjC().ActOnMethodParmDeclaration(
1499+
getCurScope(), ArgInfo, ObjCParamInfo.size(), MethodDefinition);
1500+
ObjCParamInfo.push_back(Param);
14991501
KeyIdents.push_back(SelIdent);
15001502
KeyLocs.push_back(selLoc);
15011503

@@ -1567,8 +1569,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
15671569
&KeyIdents[0]);
15681570
Decl *Result = Actions.ObjC().ActOnMethodDeclaration(
15691571
getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
1570-
Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
1571-
MethodImplKind, isVariadic, MethodDefinition);
1572+
Sel, ObjCParamInfo.data(), CParamInfo.data(), CParamInfo.size(),
1573+
methodAttrs, MethodImplKind, isVariadic, MethodDefinition);
15721574

15731575
PD.complete(Result);
15741576
return Result;

clang/lib/Sema/SemaDeclObjC.cpp

Lines changed: 58 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4720,13 +4720,67 @@ static void checkObjCDirectMethodClashes(Sema &S, ObjCInterfaceDecl *IDecl,
47204720
diagClash(IMD);
47214721
}
47224722

4723+
ParmVarDecl *SemaObjC::ActOnMethodParmDeclaration(Scope *S,
4724+
ObjCArgInfo &ArgInfo,
4725+
int ParamIndex,
4726+
bool MethodDefinition) {
4727+
ASTContext &Context = getASTContext();
4728+
QualType ArgType;
4729+
TypeSourceInfo *DI;
4730+
4731+
if (!ArgInfo.Type) {
4732+
ArgType = Context.getObjCIdType();
4733+
DI = nullptr;
4734+
} else {
4735+
ArgType = SemaRef.GetTypeFromParser(ArgInfo.Type, &DI);
4736+
}
4737+
LookupResult R(SemaRef, ArgInfo.Name, ArgInfo.NameLoc,
4738+
Sema::LookupOrdinaryName,
4739+
SemaRef.forRedeclarationInCurContext());
4740+
SemaRef.LookupName(R, S);
4741+
if (R.isSingleResult()) {
4742+
NamedDecl *PrevDecl = R.getFoundDecl();
4743+
if (S->isDeclScope(PrevDecl)) {
4744+
Diag(ArgInfo.NameLoc,
4745+
(MethodDefinition ? diag::warn_method_param_redefinition
4746+
: diag::warn_method_param_declaration))
4747+
<< ArgInfo.Name;
4748+
Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
4749+
}
4750+
}
4751+
SourceLocation StartLoc =
4752+
DI ? DI->getTypeLoc().getBeginLoc() : ArgInfo.NameLoc;
4753+
4754+
// Temporarily put parameter variables in the translation unit. This is what
4755+
// ActOnParamDeclarator does in the case of C arguments to the Objective-C
4756+
// method too.
4757+
ParmVarDecl *Param = SemaRef.CheckParameter(
4758+
Context.getTranslationUnitDecl(), StartLoc, ArgInfo.NameLoc, ArgInfo.Name,
4759+
ArgType, DI, SC_None);
4760+
Param->setObjCMethodScopeInfo(ParamIndex);
4761+
Param->setObjCDeclQualifier(
4762+
CvtQTToAstBitMask(ArgInfo.DeclSpec.getObjCDeclQualifier()));
4763+
4764+
// Apply the attributes to the parameter.
4765+
SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, ArgInfo.ArgAttrs);
4766+
SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param);
4767+
if (Param->hasAttr<BlocksAttr>()) {
4768+
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
4769+
Param->setInvalidDecl();
4770+
}
4771+
4772+
S->AddDecl(Param);
4773+
SemaRef.IdResolver.AddDecl(Param);
4774+
return Param;
4775+
}
4776+
47234777
Decl *SemaObjC::ActOnMethodDeclaration(
47244778
Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc,
47254779
tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
47264780
ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
47274781
// optional arguments. The number of types/arguments is obtained
47284782
// from the Sel.getNumArgs().
4729-
ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
4783+
ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
47304784
unsigned CNumArgs, // c-style args
47314785
const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodDeclKind,
47324786
bool isVariadic, bool MethodDefinition) {
@@ -4768,60 +4822,10 @@ Decl *SemaObjC::ActOnMethodDeclaration(
47684822
HasRelatedResultType);
47694823

47704824
SmallVector<ParmVarDecl*, 16> Params;
4771-
4772-
for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
4773-
QualType ArgType;
4774-
TypeSourceInfo *DI;
4775-
4776-
if (!ArgInfo[i].Type) {
4777-
ArgType = Context.getObjCIdType();
4778-
DI = nullptr;
4779-
} else {
4780-
ArgType = SemaRef.GetTypeFromParser(ArgInfo[i].Type, &DI);
4781-
}
4782-
4783-
LookupResult R(SemaRef, ArgInfo[i].Name, ArgInfo[i].NameLoc,
4784-
Sema::LookupOrdinaryName,
4785-
SemaRef.forRedeclarationInCurContext());
4786-
SemaRef.LookupName(R, S);
4787-
if (R.isSingleResult()) {
4788-
NamedDecl *PrevDecl = R.getFoundDecl();
4789-
if (S->isDeclScope(PrevDecl)) {
4790-
Diag(ArgInfo[i].NameLoc,
4791-
(MethodDefinition ? diag::warn_method_param_redefinition
4792-
: diag::warn_method_param_declaration))
4793-
<< ArgInfo[i].Name;
4794-
Diag(PrevDecl->getLocation(),
4795-
diag::note_previous_declaration);
4796-
}
4797-
}
4798-
4799-
SourceLocation StartLoc = DI
4800-
? DI->getTypeLoc().getBeginLoc()
4801-
: ArgInfo[i].NameLoc;
4802-
4803-
ParmVarDecl *Param =
4804-
SemaRef.CheckParameter(ObjCMethod, StartLoc, ArgInfo[i].NameLoc,
4805-
ArgInfo[i].Name, ArgType, DI, SC_None);
4806-
4807-
Param->setObjCMethodScopeInfo(i);
4808-
4809-
Param->setObjCDeclQualifier(
4810-
CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
4811-
4812-
// Apply the attributes to the parameter.
4813-
SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param,
4814-
ArgInfo[i].ArgAttrs);
4815-
SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param);
4825+
for (unsigned I = 0; I < Sel.getNumArgs(); ++I) {
4826+
ParmVarDecl *Param = ArgInfo[I];
4827+
Param->setDeclContext(ObjCMethod);
48164828
SemaRef.ProcessAPINotes(Param);
4817-
4818-
if (Param->hasAttr<BlocksAttr>()) {
4819-
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
4820-
Param->setInvalidDecl();
4821-
}
4822-
S->AddDecl(Param);
4823-
SemaRef.IdResolver.AddDecl(Param);
4824-
48254829
Params.push_back(Param);
48264830
}
48274831

0 commit comments

Comments
 (0)