Skip to content

Commit b065b0e

Browse files
[ObjC] Insert method parameters in scope as they are parsed
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. rdar://138596211
1 parent 8a51690 commit b065b0e

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
@@ -363,6 +363,10 @@ class SemaObjC : public SemaBase {
363363
ParsedAttributesView ArgAttrs;
364364
};
365365

366+
ParmVarDecl *ActOnMethodParmDeclaration(Scope *S, ObjCArgInfo &ArgInfo,
367+
int ParamIndex,
368+
bool MethodDefinition);
369+
366370
Decl *ActOnMethodDeclaration(
367371
Scope *S,
368372
SourceLocation BeginLoc, // location of the + or -.
@@ -371,7 +375,7 @@ class SemaObjC : public SemaBase {
371375
ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
372376
// optional arguments. The number of types/arguments is obtained
373377
// from the Sel.getNumArgs().
374-
ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
378+
ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
375379
unsigned CNumArgs, // c-style args
376380
const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind,
377381
bool isVariadic, bool MethodDefinition);

clang/lib/Parse/ParseObjc.cpp

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

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

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

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

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

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

clang/lib/Sema/SemaDeclObjC.cpp

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

4773+
ParmVarDecl *SemaObjC::ActOnMethodParmDeclaration(Scope *S,
4774+
ObjCArgInfo &ArgInfo,
4775+
int ParamIndex,
4776+
bool MethodDefinition) {
4777+
ASTContext &Context = getASTContext();
4778+
QualType ArgType;
4779+
TypeSourceInfo *DI;
4780+
4781+
if (!ArgInfo.Type) {
4782+
ArgType = Context.getObjCIdType();
4783+
DI = nullptr;
4784+
} else {
4785+
ArgType = SemaRef.GetTypeFromParser(ArgInfo.Type, &DI);
4786+
}
4787+
LookupResult R(SemaRef, ArgInfo.Name, ArgInfo.NameLoc,
4788+
Sema::LookupOrdinaryName,
4789+
SemaRef.forRedeclarationInCurContext());
4790+
SemaRef.LookupName(R, S);
4791+
if (R.isSingleResult()) {
4792+
NamedDecl *PrevDecl = R.getFoundDecl();
4793+
if (S->isDeclScope(PrevDecl)) {
4794+
Diag(ArgInfo.NameLoc,
4795+
(MethodDefinition ? diag::warn_method_param_redefinition
4796+
: diag::warn_method_param_declaration))
4797+
<< ArgInfo.Name;
4798+
Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
4799+
}
4800+
}
4801+
SourceLocation StartLoc =
4802+
DI ? DI->getTypeLoc().getBeginLoc() : ArgInfo.NameLoc;
4803+
4804+
// Temporarily put parameter variables in the translation unit. This is what
4805+
// ActOnParamDeclarator does in the case of C arguments to the Objective-C
4806+
// method too.
4807+
ParmVarDecl *Param = SemaRef.CheckParameter(
4808+
Context.getTranslationUnitDecl(), StartLoc, ArgInfo.NameLoc, ArgInfo.Name,
4809+
ArgType, DI, SC_None);
4810+
Param->setObjCMethodScopeInfo(ParamIndex);
4811+
Param->setObjCDeclQualifier(
4812+
CvtQTToAstBitMask(ArgInfo.DeclSpec.getObjCDeclQualifier()));
4813+
4814+
// Apply the attributes to the parameter.
4815+
SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param, ArgInfo.ArgAttrs);
4816+
SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param);
4817+
if (Param->hasAttr<BlocksAttr>()) {
4818+
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
4819+
Param->setInvalidDecl();
4820+
}
4821+
4822+
S->AddDecl(Param);
4823+
SemaRef.IdResolver.AddDecl(Param);
4824+
return Param;
4825+
}
4826+
47734827
Decl *SemaObjC::ActOnMethodDeclaration(
47744828
Scope *S, SourceLocation MethodLoc, SourceLocation EndLoc,
47754829
tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
47764830
ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
47774831
// optional arguments. The number of types/arguments is obtained
47784832
// from the Sel.getNumArgs().
4779-
ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
4833+
ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
47804834
unsigned CNumArgs, // c-style args
47814835
const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodDeclKind,
47824836
bool isVariadic, bool MethodDefinition) {
@@ -4818,60 +4872,10 @@ Decl *SemaObjC::ActOnMethodDeclaration(
48184872
HasRelatedResultType);
48194873

48204874
SmallVector<ParmVarDecl*, 16> Params;
4821-
4822-
for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
4823-
QualType ArgType;
4824-
TypeSourceInfo *DI;
4825-
4826-
if (!ArgInfo[i].Type) {
4827-
ArgType = Context.getObjCIdType();
4828-
DI = nullptr;
4829-
} else {
4830-
ArgType = SemaRef.GetTypeFromParser(ArgInfo[i].Type, &DI);
4831-
}
4832-
4833-
LookupResult R(SemaRef, ArgInfo[i].Name, ArgInfo[i].NameLoc,
4834-
Sema::LookupOrdinaryName,
4835-
SemaRef.forRedeclarationInCurContext());
4836-
SemaRef.LookupName(R, S);
4837-
if (R.isSingleResult()) {
4838-
NamedDecl *PrevDecl = R.getFoundDecl();
4839-
if (S->isDeclScope(PrevDecl)) {
4840-
Diag(ArgInfo[i].NameLoc,
4841-
(MethodDefinition ? diag::warn_method_param_redefinition
4842-
: diag::warn_method_param_declaration))
4843-
<< ArgInfo[i].Name;
4844-
Diag(PrevDecl->getLocation(),
4845-
diag::note_previous_declaration);
4846-
}
4847-
}
4848-
4849-
SourceLocation StartLoc = DI
4850-
? DI->getTypeLoc().getBeginLoc()
4851-
: ArgInfo[i].NameLoc;
4852-
4853-
ParmVarDecl *Param =
4854-
SemaRef.CheckParameter(ObjCMethod, StartLoc, ArgInfo[i].NameLoc,
4855-
ArgInfo[i].Name, ArgType, DI, SC_None);
4856-
4857-
Param->setObjCMethodScopeInfo(i);
4858-
4859-
Param->setObjCDeclQualifier(
4860-
CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
4861-
4862-
// Apply the attributes to the parameter.
4863-
SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, Param,
4864-
ArgInfo[i].ArgAttrs);
4865-
SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param);
4875+
for (unsigned I = 0; I < Sel.getNumArgs(); ++I) {
4876+
ParmVarDecl *Param = ArgInfo[I];
4877+
Param->setDeclContext(ObjCMethod);
48664878
SemaRef.ProcessAPINotes(Param);
4867-
4868-
if (Param->hasAttr<BlocksAttr>()) {
4869-
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
4870-
Param->setInvalidDecl();
4871-
}
4872-
S->AddDecl(Param);
4873-
SemaRef.IdResolver.AddDecl(Param);
4874-
48754879
Params.push_back(Param);
48764880
}
48774881

0 commit comments

Comments
 (0)