Codegen. support for ObjCIsaExpr AST which until now

was not needed (fixes radar 7453430).

llvm-svn: 90981
This commit is contained in:
Fariborz Jahanian 2009-12-09 19:05:56 +00:00
parent 220b196c94
commit a5fee26d28
3 changed files with 46 additions and 3 deletions

View File

@ -167,6 +167,25 @@ public:
return CGF.EmitObjCMessageExpr(E).getScalarVal();
}
Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
Value *V;
// object->isa or (*object).isa
// Generate code as for: *(Class*)object
Expr *BaseExpr = E->getBase();
if (E->isArrow())
V = EmitLoadOfLValue(BaseExpr);
else
V = EmitLValue(BaseExpr).getAddress();
// build Class* type
const llvm::Type *ClassPtrTy = ConvertType(E->getType());
ClassPtrTy = ClassPtrTy->getPointerTo();
V = Builder.CreateBitCast(V, ClassPtrTy);
LValue LV = LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType()));
V = CGF.EmitLoadOfLValue(LV, E->getType()).getScalarVal();
return V;
}
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
Value *VisitMemberExpr(MemberExpr *E);

View File

@ -2528,8 +2528,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
BaseType->getAs<ObjCObjectPointerType>()) {
if (OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
MemberName.getAsIdentifierInfo()->isStr("isa"))
return Owned(new (Context) ObjCIsaExpr(BaseExpr, false, MemberLoc,
Context.getObjCIdType()));
return Owned(new (Context) ObjCIsaExpr(BaseExpr, true, MemberLoc,
Context.getObjCClassType()));
}
}
// We have an 'id' type. Rather than fall through, we check if this
@ -2888,7 +2888,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
BaseType->isSpecificBuiltinType(BuiltinType::ObjCId) &&
MemberName.getAsIdentifierInfo()->isStr("isa"))
return Owned(new (Context) ObjCIsaExpr(BaseExpr, false, MemberLoc,
Context.getObjCIdType()));
Context.getObjCClassType()));
// Handle 'field access' to vectors, such as 'V.xx'.
if (BaseType->isExtVectorType()) {

View File

@ -0,0 +1,24 @@
// RUN: clang-cc -emit-llvm -o %t %s
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
@interface I
+ (Class) class;
- (void)meth : (id)object;
+ (unsigned char) isSubclassOfClass:(Class)aClass ;
@end
@implementation I
+ (Class) class {return 0;}
+ (unsigned char) isSubclassOfClass:(Class)aClass {return 0;}
- (void)meth : (id)object {
[object->isa isSubclassOfClass:[I class]];
[(*object).isa isSubclassOfClass:[I class]];
}
@end