forked from OSchip/llvm-project
Patch to implement gcc's cstyle arguments in objc
methods. wip. llvm-svn: 100734
This commit is contained in:
parent
79f67a7495
commit
60462098d4
|
@ -2306,7 +2306,7 @@ public:
|
|||
TypeTy *ReturnType, // the method return type.
|
||||
Selector Sel, // a unique name for the method.
|
||||
ObjCArgInfo *ArgInfo, // ArgInfo: Has 'Sel.getNumArgs()' entries.
|
||||
llvm::SmallVectorImpl<Declarator> &Cdecls, // c-style args
|
||||
DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
|
||||
AttributeList *MethodAttrList, // optional
|
||||
// tok::objc_not_keyword, tok::objc_optional, tok::objc_required
|
||||
tok::ObjCKeywordKind impKind,
|
||||
|
|
|
@ -823,7 +823,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
llvm::SmallVector<Declarator, 8> CargNames;
|
||||
llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
|
||||
if (Tok.isNot(tok::colon)) {
|
||||
// If attributes exist after the method, parse them.
|
||||
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
|
||||
|
@ -834,7 +834,9 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
DeclPtrTy Result
|
||||
= Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
|
||||
mType, IDecl, DSRet, ReturnType, Sel,
|
||||
0, CargNames, MethodAttrs.get(),
|
||||
0,
|
||||
CParamInfo.data(), CParamInfo.size(),
|
||||
MethodAttrs.get(),
|
||||
MethodImplKind);
|
||||
PD.complete(Result);
|
||||
return Result;
|
||||
|
@ -897,7 +899,13 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
// Parse the declarator.
|
||||
Declarator ParmDecl(DS, Declarator::PrototypeContext);
|
||||
ParseDeclarator(ParmDecl);
|
||||
CargNames.push_back(ParmDecl);
|
||||
IdentifierInfo *ParmII = ParmDecl.getIdentifier();
|
||||
DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
|
||||
CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
|
||||
ParmDecl.getIdentifierLoc(),
|
||||
Param,
|
||||
0));
|
||||
|
||||
}
|
||||
|
||||
// FIXME: Add support for optional parmameter list...
|
||||
|
@ -913,7 +921,8 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
DeclPtrTy Result
|
||||
= Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
|
||||
mType, IDecl, DSRet, ReturnType, Sel,
|
||||
&ArgInfos[0], CargNames,
|
||||
&ArgInfos[0],
|
||||
CParamInfo.data(), CParamInfo.size(),
|
||||
MethodAttrs.get(),
|
||||
MethodImplKind, isVariadic);
|
||||
PD.complete(Result);
|
||||
|
|
|
@ -3822,7 +3822,7 @@ public:
|
|||
// optional arguments. The number of types/arguments is obtained
|
||||
// from the Sel.getNumArgs().
|
||||
ObjCArgInfo *ArgInfo,
|
||||
llvm::SmallVectorImpl<Declarator> &Cdecls,
|
||||
DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
|
||||
AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
|
||||
bool isVariadic = false);
|
||||
|
||||
|
|
|
@ -1495,7 +1495,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
|
|||
// optional arguments. The number of types/arguments is obtained
|
||||
// from the Sel.getNumArgs().
|
||||
ObjCArgInfo *ArgInfo,
|
||||
llvm::SmallVectorImpl<Declarator> &Cdecls,
|
||||
DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
|
||||
AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
|
||||
bool isVariadic) {
|
||||
Decl *ClassDecl = classDecl.getAs<Decl>();
|
||||
|
@ -1568,7 +1568,26 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
|
|||
Params.push_back(Param);
|
||||
}
|
||||
|
||||
ObjCMethod->setMethodParams(Context, Params.data(), Sel.getNumArgs());
|
||||
for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
|
||||
ParmVarDecl *Param = CParamInfo[i].Param.getAs<ParmVarDecl>();
|
||||
QualType ArgType = Param->getType();
|
||||
if (ArgType.isNull())
|
||||
ArgType = Context.getObjCIdType();
|
||||
else
|
||||
// Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
|
||||
ArgType = adjustParameterType(ArgType);
|
||||
if (ArgType->isObjCInterfaceType()) {
|
||||
Diag(Param->getLocation(),
|
||||
diag::err_object_cannot_be_passed_returned_by_value)
|
||||
<< 1 << ArgType;
|
||||
Param->setInvalidDecl();
|
||||
}
|
||||
Param->setDeclContext(ObjCMethod);
|
||||
IdResolver.RemoveDecl(Param);
|
||||
Params.push_back(Param);
|
||||
}
|
||||
|
||||
ObjCMethod->setMethodParams(Context, Params.data(), Params.size());
|
||||
ObjCMethod->setObjCDeclQualifier(
|
||||
CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
|
||||
const ObjCMethodDecl *PrevMethod = 0;
|
||||
|
|
|
@ -182,7 +182,15 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
|
|||
ReturnType = Method->getResultType();
|
||||
|
||||
unsigned NumNamedArgs = Sel.getNumArgs();
|
||||
assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
|
||||
// Method might have more arguments than selector indicates. This is due
|
||||
// to addition of c-style arguments in method.
|
||||
if (Method->param_size() > Sel.getNumArgs())
|
||||
NumNamedArgs = Method->param_size();
|
||||
// FIXME. This need be cleaned up.
|
||||
if (NumArgs < NumNamedArgs) {
|
||||
Diag(lbrac, diag::err_typecheck_call_too_few_args) << 2;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsError = false;
|
||||
for (unsigned i = 0; i < NumNamedArgs; i++) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
@interface Foo
|
||||
- (id)test:(id)one, id two;
|
||||
- (id)bad:(id)one, id two, double three;
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
- (id)test:(id )one, id two {return two; }
|
||||
- (id)bad:(id)one, id two, double three { return two; }
|
||||
@end
|
||||
|
||||
|
||||
int main() {
|
||||
Foo *foo;
|
||||
[foo test:@"One", @"Two"];
|
||||
[foo bad:@"One", @"Two"]; // expected-error {{too few arguments to method call}}
|
||||
[foo bad:@"One", @"Two", 3.14];
|
||||
[foo bad:@"One", @"Two", 3.14, @"Two"]; // expected-error {{too many arguments to method call}}
|
||||
}
|
Loading…
Reference in New Issue