[cfe-commits] r53841 - in /cfe/trunk: include/clang/AST/Type.h lib/Sema/SemaExprObjC.cpp test/Parser/objc-init.m

Chris Lattner sabre at nondot.org
Sun Jul 20 23:12:57 PDT 2008


Author: lattner
Date: Mon Jul 21 01:12:56 2008
New Revision: 53841

URL: http://llvm.org/viewvc/llvm-project?rev=53841&view=rev
Log:
continue cleaning up code, and disable sending a message directly to an
interface.  This fixes a bug where we used to accept:

void test2(NSNumber x) {
	[x METH];
}

which doesn't make sense and GCC rejects.


Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/Parser/objc-init.m

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=53841&r1=53840&r2=53841&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Jul 21 01:12:56 2008
@@ -362,6 +362,10 @@
   const ObjCQualifiedInterfaceType *getAsObjCQualifiedInterfaceType() const;
   const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
 
+  /// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
+  /// interface, return the interface type, otherwise return null.
+  const ObjCInterfaceType *getAsPointerToObjCInterfaceType() const;
+
   
   /// getDesugaredType - Return the specified type with any "sugar" removed from
   /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
@@ -1289,6 +1293,12 @@
 inline const TypedefType* Type::getAsTypedefType() const {
   return dyn_cast<TypedefType>(this);
 }
+inline const ObjCInterfaceType *Type::getAsPointerToObjCInterfaceType() const {
+  if (const PointerType *PT = getAsPointerType())
+    return PT->getPointeeType()->getAsObjCInterfaceType();
+  return 0;
+}
+  
   
 inline bool Type::isFunctionType() const {
   return isa<FunctionType>(CanonicalType.getUnqualifiedType());

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=53841&r1=53840&r2=53841&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Jul 21 01:12:56 2008
@@ -226,14 +226,13 @@
   Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
   Expr *RExpr = static_cast<Expr *>(receiver);
   QualType returnType;
-  ObjCMethodDecl *Method = 0;
 
   QualType receiverType = 
     RExpr->getType().getCanonicalType().getUnqualifiedType();
   
   // Handle messages to id.
   if (receiverType == Context.getObjCIdType().getCanonicalType()) {
-    Method = InstanceMethodPool[Sel].Method;
+    ObjCMethodDecl *Method = InstanceMethodPool[Sel].Method;
     if (!Method)
       Method = FactoryMethodPool[Sel].Method;
     if (!Method) {
@@ -252,6 +251,7 @@
   
   // Handle messages to Class.
   if (receiverType == Context.getObjCClassType().getCanonicalType()) {
+    ObjCMethodDecl *Method = 0;
     if (getCurMethodDecl()) {
       ObjCInterfaceDecl* ClassDecl = getCurMethodDecl()->getClassInterface();
       // If we have an implementation in scope, check "private" methods.
@@ -279,18 +279,14 @@
                                ArgExprs, NumArgs);
   }
   
-  // We allow sending a message to a qualified ID ("id<foo>") to an interface
-  // directly ("[NSNumber foo]") and to a pointer to an interface (an object).
-  if (!isa<ObjCQualifiedIdType>(receiverType) &&
-      !isa<ObjCInterfaceType>(receiverType))
-    if (const PointerType *PTy = receiverType->getAsPointerType())
-      receiverType = PTy->getPointeeType();
-    // else error, invalid receiver.
-  
+  ObjCMethodDecl *Method = 0;
   ObjCInterfaceDecl* ClassDecl = 0;
+  
+  // We allow sending a message to a qualified ID ("id<foo>"), which is ok as 
+  // long as one of the protocols implements the selector (if not, warn).
   if (ObjCQualifiedIdType *QIT = 
            dyn_cast<ObjCQualifiedIdType>(receiverType)) {
-    // search protocols
+    // Search protocols
     for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
       ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
       if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
@@ -300,13 +296,9 @@
       Diag(lbrac, diag::warn_method_not_found_in_protocol, 
            std::string("-"), Sel.getName(),
            SourceRange(lbrac, rbrac));
-  } else {
-    ObjCInterfaceType *OCIReceiver =dyn_cast<ObjCInterfaceType>(receiverType);
-    if (OCIReceiver == 0) {
-      Diag(lbrac, diag::error_bad_receiver_type,
-           RExpr->getType().getAsString());
-      return true;
-    }
+  } else if (const ObjCInterfaceType *OCIReceiver = 
+                receiverType->getAsPointerToObjCInterfaceType()) {
+    // We allow sending a message to a pointer to an interface (an object).
     
     ClassDecl = OCIReceiver->getDecl();
     // FIXME: consider using InstanceMethodPool, since it will be faster
@@ -327,6 +319,10 @@
       Diag(lbrac, diag::warn_method_not_found_in_protocol, 
            std::string("-"), Sel.getName(),
            SourceRange(lbrac, rbrac));
+  } else {
+    Diag(lbrac, diag::error_bad_receiver_type,
+         RExpr->getType().getAsString());
+    return true;
   }
   
   if (!Method) {

Modified: cfe/trunk/test/Parser/objc-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-init.m?rev=53841&r1=53840&r2=53841&view=diff

==============================================================================
--- cfe/trunk/test/Parser/objc-init.m (original)
+++ cfe/trunk/test/Parser/objc-init.m Mon Jul 21 01:12:56 2008
@@ -11,13 +11,16 @@
 }
 
 void test2(NSNumber x) {
+	id objects[] = {[x METH]}; // expected-error {{bad receiver type}}
+}
+
+void test3(NSNumber *x) {
 	id objects[] = {[x METH]};
-	return 0;
 }
 
 
 // rdar://5977581
-void test3() {
+void test4() {
   unsigned x[] = {[NSNumber METH2]+2};
 }
 





More information about the cfe-commits mailing list