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 | d68df206201a9d23d3f7b81e3cab5ced002a0773 (patch) | |
tree | 25f1bd0b4215d50e0faaa222fde08e4f425987a5 | |
parent | a4a972e32de0467051318b7b86518ee309aac1cf (diff) | |
download | bcm5719-llvm-d68df206201a9d23d3f7b81e3cab5ced002a0773.tar.gz bcm5719-llvm-d68df206201a9d23d3f7b81e3cab5ced002a0773.zip |
Handle
foo()->a = 42;
llvm-svn: 43315
-rw-r--r-- | clang/CodeGen/CGExpr.cpp | 29 | ||||
-rw-r--r-- | clang/test/CodeGen/struct.c | 4 |
2 files changed, 23 insertions, 10 deletions
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index f6e772d52df..b03caaa6666 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/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/clang/test/CodeGen/struct.c b/clang/test/CodeGen/struct.c index 00917994629..4e73cd47af0 100644 --- a/clang/test/CodeGen/struct.c +++ b/clang/test/CodeGen/struct.c @@ -55,3 +55,7 @@ typedef struct NB { void f2() { NB b; } +extern NB *f3(); +void f4() { + f3()->d1 = 42; +} |