diff options
author | Devang Patel <dpatel@apple.com> | 2007-10-24 22:26:28 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2007-10-24 22:26:28 +0000 |
commit | 126a856ecdb6f9285a7858fa5437949a4fd192ab (patch) | |
tree | 4654382320c6d6324871389bed6fc98a06a60422 | |
parent | 1a0965effc6ac7e55b8e2eeff642af9b81110948 (diff) |
Handle
foo()->a = 42;
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43315 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | CodeGen/CGExpr.cpp | 29 | ||||
-rw-r--r-- | test/CodeGen/struct.c | 4 |
2 files changed, 23 insertions, 10 deletions
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index f6e772d52d..b03caaa666 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -384,27 +384,36 @@ EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) { LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { + Expr *BaseExpr = E->getBase(); // FIXME: Handle union members. - if (E->getBase()->getType()->isUnionType()) { + if (BaseExpr->getType()->isUnionType()) { fprintf(stderr, "Unimplemented lvalue expr!\n"); E->dump(getContext().SourceMgr); llvm::Type *Ty = llvm::PointerType::get(ConvertType(E->getType())); return LValue::MakeAddr(llvm::UndefValue::get(Ty)); } - - LValue BaseLV = EmitLValue(E->getBase()); - llvm::Value *BaseValue = BaseLV.getAddress(); + + llvm::Value *BaseValue = NULL; + if (const CallExpr *CE = dyn_cast<CallExpr>(BaseExpr)) { + RValue Base = EmitCallExpr(CE); + BaseValue = Base.getScalarVal(); + } + else { + LValue BaseLV = EmitLValue(BaseExpr); + BaseValue = BaseLV.getAddress(); + + if (E->isArrow()) { + QualType PTy = cast<PointerType>(BaseExpr->getType())->getPointeeType(); + BaseValue = Builder.CreateBitCast(BaseValue, + llvm::PointerType::get(ConvertType(PTy)), + "tmp"); + } + } FieldDecl *Field = E->getMemberDecl(); unsigned idx = CGM.getTypes().getLLVMFieldNo(Field); llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty), llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) }; - if (E->isArrow()) { - QualType PTy = cast<PointerType>(E->getBase()->getType())->getPointeeType(); - BaseValue = Builder.CreateBitCast(BaseValue, - llvm::PointerType::get(ConvertType(PTy)), - "tmp"); - } return LValue::MakeAddr(Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp")); diff --git a/test/CodeGen/struct.c b/test/CodeGen/struct.c index 0091799462..4e73cd47af 100644 --- a/test/CodeGen/struct.c +++ b/test/CodeGen/struct.c @@ -55,3 +55,7 @@ typedef struct NB { void f2() { NB b; } +extern NB *f3(); +void f4() { + f3()->d1 = 42; +} |