]> granicus.if.org Git - clang/commitdiff
Patch to implement gcc's cstyle arguments in objc
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 8 Apr 2010 00:30:06 +0000 (00:30 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 8 Apr 2010 00:30:06 +0000 (00:30 +0000)
methods. wip.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100734 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Action.h
lib/Parse/ParseObjc.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/objc-cstyle-args-in-methods.m [new file with mode: 0644]

index 4122aff91ffcbf2b6e5eeb8de8e86190ebbca591..e8901b85d182875c5daf48c2e081d2c057bec98a 100644 (file)
@@ -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,
index 155e3520731abeb3185944efa17f90b8dec85470..cd42aee255cfc9ba7f9a648fec10488b9d2427f2 100644 (file)
@@ -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);
index a6bcc4375e42bc3210475fbdbfd47bb24f1da434..45574b9d6962cc50aa127f6c8b121f039f4f2385 100644 (file)
@@ -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);
 
index 0c47e63d99ebdbaa1dfa4e0405cb42511d4aff9c..b422c83162efc6e260ee0f60c3ccc9d88a12cd59 100644 (file)
@@ -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;
index d5a22ca15fae80d2cf3370beac02f448be5a67d8..99db910a90ef3a7e183b441fc743198378617288 100644 (file)
@@ -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++) {
diff --git a/test/SemaObjC/objc-cstyle-args-in-methods.m b/test/SemaObjC/objc-cstyle-args-in-methods.m
new file mode 100644 (file)
index 0000000..9f75295
--- /dev/null
@@ -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}}
+}