]> granicus.if.org Git - clang/commitdiff
Fix a bunch of crashes that occur in (attempted) handling of objc properties.
authorChris Lattner <sabre@nondot.org>
Mon, 21 Jul 2008 04:59:05 +0000 (04:59 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 21 Jul 2008 04:59:05 +0000 (04:59 +0000)
This code would previously crash on x.y where x is 'id'.

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

lib/Sema/SemaExpr.cpp

index 3c5a467edcf199dd2e83d251fb1b93cfcfe880ca..13f7ff9fb711bbce69f60489c4434a4fe3eb1934 100644 (file)
@@ -616,7 +616,8 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
                           MemberLoc, MemberType);
   }
   
-  // Handle access to Objective C instance variables, such as "Obj->ivar".
+  // Handle access to Objective-C instance variables, such as "Obj->ivar" and
+  // (*Obj).ivar.
   if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) {
     if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member))
       return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, 
@@ -626,47 +627,39 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
                 BaseExpr->getSourceRange(), SourceRange(MemberLoc));
   }
   
-  // Handle property access.
-  if (isObjCObjectPointerType(BaseType)) {
-    const PointerType *pointerType = BaseType->getAsPointerType();
-    BaseType = pointerType->getPointeeType();
-    ObjCInterfaceDecl *IFace;
-    QualType CanonType = BaseType.getCanonicalType();
-    if (isa<ObjCInterfaceType>(CanonType))
-      IFace = dyn_cast<ObjCInterfaceType>(CanonType)->getDecl();
-    else
-      IFace = dyn_cast<ObjCQualifiedInterfaceType>(CanonType)->getDecl();
-    if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&Member))
-      return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, 
-                                 OpKind==tok::arrow);
-    // Check for properties.
-    if (OpKind==tok::period) {
-      // Before we look for explicit property declarations, we check for
-      // nullary methods (which allow '.' notation).
-      Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
-      ObjCMethodDecl *MD = IFace->lookupInstanceMethod(Sel);
-      if (MD) 
-        return new ObjCPropertyRefExpr(MD, MD->getResultType(), 
-                                       MemberLoc, BaseExpr);
-      // FIXME: Need to deal with setter methods that take 1 argument. E.g.:
-      // @interface NSBundle : NSObject {}
-      // - (NSString *)bundlePath;
-      // - (void)setBundlePath:(NSString *)x;
-      // @end
-      // void someMethod() { frameworkBundle.bundlePath = 0; }
-      //
-      ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member);
-      
-      if (!PD) { // Lastly, check protocols on qualified interfaces.
-        if (ObjCQualifiedInterfaceType *QIT = 
-            dyn_cast<ObjCQualifiedInterfaceType>(CanonType)) {
-          for (unsigned i = 0; i < QIT->getNumProtocols(); i++)
-            if ((PD = QIT->getProtocols(i)->FindPropertyDeclaration(&Member)))
-              break;
-        }
-      }
-      if (PD)
-        return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr);
+  // Handle Objective-C property access, which is "Obj.property" where Obj is a
+  // pointer to a (potentially qualified) interface type.
+  const PointerType *PTy;
+  const ObjCInterfaceType *IFTy;
+  if (OpKind == tok::period && (PTy = BaseType->getAsPointerType()) &&
+      (IFTy = PTy->getPointeeType()->getAsObjCInterfaceType())) {
+    ObjCInterfaceDecl *IFace = IFTy->getDecl();
+    
+    // Before we look for explicit property declarations, we check for
+    // nullary methods (which allow '.' notation).
+    Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
+    
+    if (ObjCMethodDecl *MD = IFace->lookupInstanceMethod(Sel))
+      return new ObjCPropertyRefExpr(MD, MD->getResultType(), 
+                                     MemberLoc, BaseExpr);
+    
+    // FIXME: Need to deal with setter methods that take 1 argument. E.g.:
+    // @interface NSBundle : NSObject {}
+    // - (NSString *)bundlePath;
+    // - (void)setBundlePath:(NSString *)x;
+    // @end
+    // void someMethod() { frameworkBundle.bundlePath = 0; }
+    //
+    if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member))
+      return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr);
+    
+    // Lastly, check protocols on qualified interfaces.
+    if (const ObjCQualifiedInterfaceType *QIT = 
+          dyn_cast<ObjCQualifiedInterfaceType>(IFTy)) {
+      for (unsigned i = 0; i != QIT->getNumProtocols(); ++i)
+        if (ObjCPropertyDecl *PD =
+              QIT->getProtocols(i)->FindPropertyDeclaration(&Member))
+          return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc,BaseExpr);
     }
   }