Fix a bunch of crashes that occur in (attempted) handling of objc properties.

This code would previously crash on x.y where x is 'id'.

llvm-svn: 53827
This commit is contained in:
Chris Lattner 2008-07-21 04:59:05 +00:00
parent f8f5682998
commit dc420f4866
1 changed files with 35 additions and 42 deletions

View 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);
}
}