]> granicus.if.org Git - clang/commitdiff
Emit diagnostics for methods not found.
authorSteve Naroff <snaroff@apple.com>
Tue, 16 Oct 2007 20:39:36 +0000 (20:39 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 16 Oct 2007 20:39:36 +0000 (20:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43037 91177308-0d34-0410-b5e6-96231b3b80d8

Sema/SemaExpr.cpp
include/clang/AST/ASTContext.h
include/clang/Basic/DiagnosticKinds.def
test/Sema/method-not-defined.m [new file with mode: 0644]

index 046b92bb076a10d2e1468205f913b8e2e4181abf..daa1a7c141c8172b5dde9db6c5ed8ca3156acadd 100644 (file)
@@ -1930,11 +1930,17 @@ Sema::ExprResult Sema::ActOnClassMessage(
 
   ObjcInterfaceDecl* ClassDecl = getObjCInterfaceDecl(receiverName);
   ObjcMethodDecl *Method = ClassDecl->lookupClassMethod(Sel);
-  assert(Method && "missing method declaration");
-  QualType retType = Method->getMethodType();
+  QualType returnType;
+  if (!Method) {
+    Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(),
+         SourceRange(lbrac, rbrac));
+    returnType = GetObjcIdType();
+  } else {
+    returnType = Method->getMethodType();
+  }
   // Expr *RExpr = global reference to the class symbol...
   Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
-  return new ObjCMessageExpr(receiverName, Sel, retType, lbrac, rbrac,
+  return new ObjCMessageExpr(receiverName, Sel, returnType, lbrac, rbrac,
                              ArgExprs);
 }
 
@@ -1953,9 +1959,13 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
   
   if (receiverType == GetObjcIdType()) {
     ObjcMethodDecl *Method = InstanceMethodPool[Sel].Method;
-    // FIXME: emit a diagnostic. For now, I want a hard error...
-    assert(Method && "missing method declaration");
-    returnType = Method->getMethodType();
+    if (!Method) {
+      Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
+           SourceRange(lbrac, rbrac));
+      returnType = GetObjcIdType();
+    } else {
+      returnType = Method->getMethodType();
+    }
   } else {
     // FIXME (snaroff): checking in this code from Patrick. Needs to be
     // revisited. how do we get the ClassDecl from the receiver expression?
@@ -1968,10 +1978,17 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
            "bad receiver type");
     ObjcInterfaceDecl* ClassDecl = static_cast<ObjcInterfaceType*>(
                                      receiverType.getTypePtr())->getDecl();
+    // FIXME: consider using InstanceMethodPool, since it will be faster
+    // than the following method (which can do *many* linear searches). The
+    // idea is to add class info to InstanceMethodPool...
     ObjcMethodDecl *Method = ClassDecl->lookupInstanceMethod(Sel);
-    // FIXME: emit a diagnostic. For now, I want a hard error...
-    assert(Method && "missing method declaration");
-    returnType = Method->getMethodType();
+    if (!Method) {
+      Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
+           SourceRange(lbrac, rbrac));
+      returnType = GetObjcIdType();
+    } else {
+      returnType = Method->getMethodType();
+    }
   }
   Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
   return new ObjCMessageExpr(RExpr, Sel, returnType, lbrac, rbrac, ArgExprs);
index 090cc52c6720dfa30caf953efddae684d16af1a0..bf0bf55123b8a01b6ca9964836b217999a5a3637 100644 (file)
@@ -157,12 +157,14 @@ public:
   // CURRENTLY UNUSED (10/15/07). ObjCStringLiteral now uses the hook below.
   QualType getCFConstantStringType(); 
   
-  // This setter/getter represents the actual ObjC type for an NSConstantString.
+  // This setter/getter represents the ObjC type for an NSConstantString.
   void setObjcConstantStringInterface(ObjcInterfaceDecl *Decl);
   QualType getObjcConstantStringInterface() const { 
     return ObjcConstantStringType; 
   }
   
+  // This setter/getter repreents the ObjC 'id' type. It is setup lazily, by
+  // Sema.
   void setObjcIdType(TypedefDecl *Decl);
   QualType getObjcIdType() const { return ObjcIdType; }
 
index 5325c025efa4a655276a5eb2c76fa73add3606ab..bad641962b05d9511aba3e648e3f98fd01676df0 100644 (file)
@@ -454,6 +454,8 @@ DIAG(err_conflicting_aliasing_type, ERROR,
      "conflicting types for alias %0'")
 DIAG(err_statically_allocated_object, ERROR,
      "statically allocated Objective-c object '%0'")
+DIAG(warn_method_not_found, WARNING,
+     "method '%0%1' not found (return type defaults to 'id')")
 
 //===----------------------------------------------------------------------===//
 // Semantic Analysis
diff --git a/test/Sema/method-not-defined.m b/test/Sema/method-not-defined.m
new file mode 100644 (file)
index 0000000..adb8a67
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: clang -fsyntax-only -verify %s
+
+typedef struct objc_object *id;
+@interface Foo
+@end
+
+void test() {
+  Foo *fooObj;
+  id obj;
+
+  [[Foo alloc] init]; // expected-warning {{method '+alloc' not found (return type defaults to 'id')}} expected-warning {{method '-init' not found (return type defaults to 'id')}}
+  [fooObj notdefined]; // expected-warning {{method '-notdefined' not found (return type defaults to 'id')}}
+  [obj whatever:1 :2 :3]; // expected-warning {{method '-whatever:::' not found (return type defaults to 'id'))}}
+}