diff options
author | Chris Lattner <sabre@nondot.org> | 2008-03-30 23:03:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-03-30 23:03:07 +0000 |
commit | 391d77a26382dddf25da73e29fc1fa5aaaea4c6f (patch) | |
tree | b842c678fe95a0feed12419eb419e091d22fff49 /lib/CodeGen/CGExpr.cpp | |
parent | a7b402dc258bf38ab5e206dbf4916a69d3ee3cc8 (diff) |
Add initial support for objc codegen for methods, ivars, and the
etoile runtime, patch by David Chisnall!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48969 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 1642e2d3ee..12900e8b9d 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -82,6 +82,7 @@ RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc, LValue CodeGenFunction::EmitLValue(const Expr *E) { switch (E->getStmtClass()) { default: { + printf("Statement class: %d\n", E->getStmtClass()); WarnUnsupported(E, "l-value expression"); llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType())); return LValue::MakeAddr(llvm::UndefValue::get(Ty)); @@ -94,6 +95,9 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { return EmitPreDefinedLValue(cast<PreDefinedExpr>(E)); case Expr::StringLiteralClass: return EmitStringLiteralLValue(cast<StringLiteral>(E)); + + case Expr::ObjCIvarRefExprClass: + return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E)); case Expr::UnaryOperatorClass: return EmitUnaryOpLValue(cast<UnaryOperator>(E)); @@ -555,6 +559,41 @@ LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) { return LValue::MakeAddr(RV.getAggregateAddr()); } +LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { + // Objective-C objects are traditionally C structures with their layout + // defined at compile-time. In some implementations, their layout is not + // defined until run time in order to allow instance variables to be added to + // a class without recompiling all of the subclasses. If this is the case + // then the CGObjCRuntime subclass must return true to LateBoundIvars and + // implement the lookup itself. + if(CGM.getObjCRuntime()->LateBoundIVars()) { + assert(0 && "FIXME: Implement support for late-bound instance variables"); + return LValue(); // Not reached. + } + else { + // Get a structure type for the object + QualType ExprTy = E->getBase()->getType(); + const llvm::Type *ObjectType = ConvertType(ExprTy); + //TODO: Add a special case for isa (index 0) + // Work out which index the ivar is + const ObjCIvarDecl *Decl = E->getDecl(); + unsigned Index = CGM.getTypes().getLLVMFieldNo(Decl); + + // Get object pointer + llvm::Value * Object = EmitLValue(E->getBase()).getAddress(); + // Coerce object pointer to correct type. + if (Object->getType() != ObjectType) { + Object = Builder.CreateBitCast(Object, ObjectType); + } + // Get the correct element + llvm::Value * Element = Builder.CreateStructGEP(Object, + Index, + Decl->getName()); + // Element = Builder.CreateLoad(Element); + return LValue::MakeAddr(Element); + } +} + RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, Expr *const *ArgExprs, unsigned NumArgs) { // The callee type will always be a pointer to function type, get the function |