diff options
Diffstat (limited to 'clang')
-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; +} |