]> granicus.if.org Git - clang/commitdiff
Improve the 'cannot pass objc interface by value' diagnostic:
authorChris Lattner <sabre@nondot.org>
Sat, 11 Apr 2009 19:08:56 +0000 (19:08 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 11 Apr 2009 19:08:56 +0000 (19:08 +0000)
1) improve localizability by not passing english strings in.
2) improve location for arguments.
3) print the objc type being passed.

Before:
method-bad-param.m:15:1: error: Objective-C type cannot be passed by value
-(void) my_method:(foo) my_param
^

after:
method-bad-param.m:15:25: error: Objective-C interface type 'foo' cannot be passed by value
-(void) my_method:(foo) my_param
                        ^

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
test/Parser/objc-init.m
test/SemaObjC/invalid-objc-decls-1.m
test/SemaObjC/method-bad-param.m

index 11a16a279f53262b1574fc467f2d3e6b16155d56..1ed8098ad36f449de05a4b0212b53170cedd8353 100644 (file)
@@ -107,8 +107,8 @@ def err_builtin_definition : Error<"definition of builtin function %0">;
 def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">;
 def err_statically_allocated_object : Error<
   "Objective-C type cannot be statically allocated">;
-def err_object_cannot_be_by_value : Error<
-  "Objective-C type cannot be %0 by value">;
+def err_object_cannot_be_passed_returned_by_value : Error<
+  "Objective-C interface type %1 cannot be %select{returned|passed}0 by value">;
 def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
 def warn_pragma_pack_invalid_alignment : Warning<
   "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
index 474c1e490e43c3648e8d603d279abb1b51ce9393..5fe44d30893a692057515732a439329ba403b901 100644 (file)
@@ -2705,8 +2705,8 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
   // Parameter declarators cannot be interface types. All ObjC objects are
   // passed by reference.
   if (T->isObjCInterfaceType()) {
-    Diag(D.getIdentifierLoc(), diag::err_object_cannot_be_by_value) 
-         << "passed";
+    Diag(D.getIdentifierLoc(),
+         diag::err_object_cannot_be_passed_returned_by_value) << 1 << T;
     New->setInvalidDecl();
   }
 
index d12fe63df19f1deeb383e6f2846b900f57bb1866..7d4e6026a19cafa0bb401cb7f2bfb6eedbc8bc1b 100644 (file)
@@ -1415,8 +1415,8 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
     // Methods cannot return interface types. All ObjC objects are
     // passed by reference.
     if (resultDeclType->isObjCInterfaceType()) {
-      Diag(MethodLoc, diag::err_object_cannot_be_by_value)
-           << "returned";
+      Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
+        << 0 << resultDeclType;
       return DeclPtrTy();
     }
   } else // get the type for "id".
@@ -1435,38 +1435,37 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
   
   for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
     // FIXME: arg->AttrList must be stored too!
-    QualType argType, originalArgType;
+    QualType ArgType, UnpromotedArgType;
     
     if (ArgInfo[i].Type == 0) {
-      argType = Context.getObjCIdType();
+      UnpromotedArgType = ArgType = Context.getObjCIdType();
     } else {
-      argType = QualType::getFromOpaquePtr(ArgInfo[i].Type);
+      UnpromotedArgType = ArgType = QualType::getFromOpaquePtr(ArgInfo[i].Type);
       // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
-      if (argType->isArrayType())  { // (char *[]) -> (char **)
-        originalArgType = argType;
-        argType = Context.getArrayDecayedType(argType);
-      } else if (argType->isFunctionType())
-        argType = Context.getPointerType(argType);
-      else if (argType->isObjCInterfaceType()) {
-        // FIXME: improve message to include type!
-        Diag(MethodLoc, diag::err_object_cannot_be_by_value)
-             << "passed";
+      if (ArgType->isArrayType())  { // (char *[]) -> (char **)
+        ArgType = Context.getArrayDecayedType(ArgType);
+      } else if (ArgType->isFunctionType())
+        ArgType = Context.getPointerType(ArgType);
+      else if (ArgType->isObjCInterfaceType()) {
+        Diag(ArgInfo[i].NameLoc,
+             diag::err_object_cannot_be_passed_returned_by_value)
+           << 1 << ArgType;
         ObjCMethod->setInvalidDecl();
         return DeclPtrTy();
       }
     }
     
     ParmVarDecl* Param;
-    if (originalArgType.isNull())
+    if (ArgType == UnpromotedArgType)
       Param = ParmVarDecl::Create(Context, ObjCMethod,
                                   SourceLocation(/*FIXME*/),
-                                  ArgInfo[i].Name, argType,
+                                  ArgInfo[i].Name, ArgType,
                                   VarDecl::None, 0);
     else
       Param = OriginalParmVarDecl::Create(Context, ObjCMethod,
                                           SourceLocation(/*FIXME*/),
-                                          ArgInfo[i].Name, argType,
-                                          originalArgType,
+                                          ArgInfo[i].Name, ArgType,
+                                          UnpromotedArgType,
                                           VarDecl::None, 0);
     
     Param->setObjCDeclQualifier(
index 8d74dfecbd09c1791e925720a6dbabcf88a2cee5..a91ac9cf285be73917ea25299ae7919e840bacdf 100644 (file)
@@ -14,7 +14,7 @@ void test1() {
        id objects[] = {[NSNumber METH]};
 }
 
-void test2(NSNumber x) { // expected-error {{Objective-C type cannot be passed by value}}
+void test2(NSNumber x) { // expected-error {{Objective-C interface type 'NSNumber' cannot be passed by value}}
        id objects[] = {[x METH]};
 }
 
index b65c061546f7c07612b132350133139518abe44a..1ef22a08516d8c67ea4e9015df689457d3a880e8 100644 (file)
@@ -27,7 +27,7 @@ struct whatever {
 }
 @end
 
-Super foo(Super parm1) { // expected-error{{Objective-C type cannot be passed by value}}
+Super foo(Super parm1) { // expected-error{{Objective-C interface type 'Super' cannot be passed by value}}
        Super p1; // expected-error{{Objective-C type cannot be statically allocated}}
        return p1;
 }
index 23fc675a4e9297a846c4cdb4be0209e2a89fdd8e..3667427d1a34f18f73884d40208d3acc20c66791 100644 (file)
@@ -7,16 +7,17 @@
 @end
 
 @interface bar
--(void) my_method:(foo) my_param; // expected-error {{Objective-C type cannot be passed by value}}
-- (foo)cccccc:(long)ddddd;  // expected-error {{Objective-C type cannot be returned by value}}
+-(void) my_method:(foo) my_param; // expected-error {{Objective-C interface type 'foo' cannot be passed by value}}
+- (foo)cccccc:(long)ddddd;  // expected-error {{Objective-C interface type 'foo' cannot be returned by value}}
 @end
 
 @implementation bar
--(void) my_method:(foo) my_param  // expected-error {{Objective-C type cannot be passed by value}}
+-(void) my_method:(foo) my_param  // expected-error {{Objective-C interface type 'foo' cannot be passed by value}}
 {
 }
-- (foo)cccccc:(long)ddddd // expected-error {{Objective-C type cannot be returned by value}}
+- (foo)cccccc:(long)ddddd // expected-error {{Objective-C interface type 'foo' cannot be returned by value}}
 {
 }
 @end
 
+void somefunc(foo x) {} // expected-error {{Objective-C interface type 'foo' cannot be passed by value}}