diff options
author | Lauro Ramos Venancio <lauro.venancio@gmail.com> | 2008-02-07 19:29:53 +0000 |
---|---|---|
committer | Lauro Ramos Venancio <lauro.venancio@gmail.com> | 2008-02-07 19:29:53 +0000 |
commit | d957aa09333ff428f9675fb9f66dde632c2bcf5d (patch) | |
tree | ca4754ad26061e89ee1e397be42f0afa9f5fea9c /CodeGen/CGExpr.cpp | |
parent | 8432f4b4cdd1707f7f5dc06f35b4597dca252f2c (diff) |
Simplify bitfield codegen.
Fix codegen of struct { short a[3]; int b:15; }.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46859 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CGExpr.cpp')
-rw-r--r-- | CodeGen/CGExpr.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index cb0f42a645..9c7876830c 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -454,7 +454,7 @@ EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) { } LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { - + llvm::Value *V; bool isUnion = false; Expr *BaseExpr = E->getBase(); llvm::Value *BaseValue = NULL; @@ -476,14 +476,27 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { } 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) }; - llvm::Value *V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp"); + + if (Field->isBitField()) { + const llvm::Type * FieldTy = ConvertType(Field->getType()); + const llvm::PointerType * BaseTy = + cast<llvm::PointerType>(BaseValue->getType()); + unsigned AS = BaseTy->getAddressSpace(); + BaseValue = Builder.CreateBitCast(BaseValue, + llvm::PointerType::get(FieldTy, AS), + "tmp"); + V = Builder.CreateGEP(BaseValue, + llvm::ConstantInt::get(llvm::Type::Int32Ty, idx), + "tmp"); + } else { + llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty), + llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) }; + V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp"); + } // Match union field type. - if (isUnion || Field->isBitField()) { + if (isUnion) { const llvm::Type * FieldTy = ConvertType(Field->getType()); const llvm::PointerType * BaseTy = cast<llvm::PointerType>(BaseValue->getType()); |