diff options
author | Chris Lattner <sabre@nondot.org> | 2007-06-22 18:48:09 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-06-22 18:48:09 +0000 |
commit | 09153c0a8c949909b5dc29671e668a71affee6bb (patch) | |
tree | 06c217109a40b59e8777b060a98f066fefe8ca47 /clang/CodeGen/CGExpr.cpp | |
parent | 3e3a1e9cda72e795547e930968b8b5c006ff8cd5 (diff) | |
download | bcm5719-llvm-09153c0a8c949909b5dc29671e668a71affee6bb.tar.gz bcm5719-llvm-09153c0a8c949909b5dc29671e668a71affee6bb.zip |
Build enough support for aggregates to be able to compile this:
void test(int A, _Complex float Y) {
_Complex float X;
X = X;
}
llvm-svn: 39669
Diffstat (limited to 'clang/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/CodeGen/CGExpr.cpp | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 06e253e3601..1de2ab87e90 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -231,7 +231,16 @@ RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) { // FIXME: this is silly and obviously wrong for non-scalars. assert(!LV.isBitfield()); - return RValue::get(Builder.CreateLoad(LV.getAddress(), "tmp")); + llvm::Value *Ptr = LV.getAddress(); + const llvm::Type *EltTy = + cast<llvm::PointerType>(Ptr->getType())->getElementType(); + + // Simple scalar l-value. + if (EltTy->isFirstClassType()) + return RValue::get(Builder.CreateLoad(Ptr, "tmp")); + + // Otherwise, we have an aggregate lvalue. + return RValue::getAggregate(Ptr); } /// EmitStoreThroughLValue - Store the specified rvalue into the specified @@ -239,20 +248,43 @@ RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) { /// is 'Ty'. void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty) { - // FIXME: This is obviously bogus. assert(!Dst.isBitfield() && "FIXME: Don't support store to bitfield yet"); - assert(Src.isScalar() && "FIXME: Don't support store of aggregate yet"); - // TODO: Handle volatility etc. - llvm::Value *Addr = Dst.getAddress(); - const llvm::Type *SrcTy = Src.getVal()->getType(); - const llvm::Type *AddrTy = - cast<llvm::PointerType>(Addr->getType())->getElementType(); + llvm::Value *DstAddr = Dst.getAddress(); + if (Src.isScalar()) { + // FIXME: Handle volatility etc. + const llvm::Type *SrcTy = Src.getVal()->getType(); + const llvm::Type *AddrTy = + cast<llvm::PointerType>(DstAddr->getType())->getElementType(); + + if (AddrTy != SrcTy) + DstAddr = Builder.CreateBitCast(DstAddr, llvm::PointerType::get(SrcTy), + "storetmp"); + Builder.CreateStore(Src.getVal(), DstAddr); + return; + } + + // Aggregate assignment turns into llvm.memcpy. + const llvm::Type *SBP = llvm::PointerType::get(llvm::Type::Int8Ty); + llvm::Value *SrcAddr = Src.getAggregateAddr(); + + if (DstAddr->getType() != SBP) + DstAddr = Builder.CreateBitCast(DstAddr, SBP, "tmp"); + if (SrcAddr->getType() != SBP) + SrcAddr = Builder.CreateBitCast(SrcAddr, SBP, "tmp"); + + unsigned Align = 1; // FIXME: Compute type alignments. + unsigned Size = 1234; // FIXME: Compute type sizes. + + // FIXME: Handle variable sized types. + const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth); + llvm::Value *SizeVal = llvm::ConstantInt::get(IntPtr, Size); + + llvm::Value *MemCpyOps[4] = { + DstAddr, SrcAddr, SizeVal,llvm::ConstantInt::get(llvm::Type::Int32Ty, Align) + }; - if (AddrTy != SrcTy) - Addr = Builder.CreateBitCast(Addr, llvm::PointerType::get(SrcTy), - "storetmp"); - Builder.CreateStore(Src.getVal(), Addr); + Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, 4); } @@ -402,7 +434,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) { if (ArgVal.isScalar()) Args.push_back(ArgVal.getVal()); else // Pass by-address. FIXME: Set attribute bit on call. - Args.push_back(ArgVal.getAggregateVal()); + Args.push_back(ArgVal.getAggregateAddr()); } llvm::Value *V = Builder.CreateCall(Callee, &Args[0], Args.size()); |