blob: 743c2486d3da97854a88207f03e74e6cbb38292b [file] [log] [blame]
Chris Lattner566b6ce2007-08-24 02:22:53 +00001//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
Chris Lattneraf6f5282007-08-10 20:13:28 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Aggregate Expr nodes as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
Chris Lattner883f6a72007-08-11 00:04:45 +000015#include "CodeGenModule.h"
16#include "clang/AST/AST.h"
17#include "llvm/Constants.h"
18#include "llvm/Function.h"
Chris Lattner9c033562007-08-21 04:25:47 +000019#include "llvm/Support/Compiler.h"
Chris Lattneraf6f5282007-08-10 20:13:28 +000020using namespace clang;
21using namespace CodeGen;
Chris Lattner883f6a72007-08-11 00:04:45 +000022
Chris Lattner9c033562007-08-21 04:25:47 +000023//===----------------------------------------------------------------------===//
24// Aggregate Expression Emitter
25//===----------------------------------------------------------------------===//
26
27namespace {
28class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
29 CodeGenFunction &CGF;
Devang Patel50c90342007-10-09 19:49:58 +000030 llvm::LLVMFoldingBuilder &Builder;
Chris Lattner9c033562007-08-21 04:25:47 +000031 llvm::Value *DestPtr;
32 bool VolatileDest;
33public:
34 AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
Chris Lattnerbfc0c1a2007-08-26 23:13:56 +000035 : CGF(cgf), Builder(CGF.Builder),
36 DestPtr(destPtr), VolatileDest(volatileDest) {
Chris Lattner9c033562007-08-21 04:25:47 +000037 }
38
Chris Lattneree755f92007-08-21 04:59:27 +000039 //===--------------------------------------------------------------------===//
40 // Utilities
41 //===--------------------------------------------------------------------===//
42
Chris Lattner9c033562007-08-21 04:25:47 +000043 /// EmitAggLoadOfLValue - Given an expression with aggregate type that
44 /// represents a value lvalue, this method emits the address of the lvalue,
45 /// then loads the result into DestPtr.
46 void EmitAggLoadOfLValue(const Expr *E);
47
Chris Lattnerbfc0c1a2007-08-26 23:13:56 +000048 void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
49 QualType EltTy);
Chris Lattneree755f92007-08-21 04:59:27 +000050
51 //===--------------------------------------------------------------------===//
52 // Visitor Methods
53 //===--------------------------------------------------------------------===//
54
Chris Lattner9c033562007-08-21 04:25:47 +000055 void VisitStmt(Stmt *S) {
56 fprintf(stderr, "Unimplemented agg expr!\n");
Chris Lattner419ea7e2007-09-13 01:17:29 +000057 S->dump(CGF.getContext().SourceMgr);
Chris Lattner9c033562007-08-21 04:25:47 +000058 }
59 void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
60
61 // l-values.
62 void VisitDeclRefExpr(DeclRefExpr *DRE) { return EmitAggLoadOfLValue(DRE); }
63 // case Expr::ArraySubscriptExprClass:
64
65 // Operators.
66 // case Expr::UnaryOperatorClass:
67 // case Expr::ImplicitCastExprClass:
68 // case Expr::CastExprClass:
69 // case Expr::CallExprClass:
Chris Lattnerb2d963f2007-08-31 22:54:14 +000070 void VisitStmtExpr(const StmtExpr *E);
Chris Lattner9c033562007-08-21 04:25:47 +000071 void VisitBinaryOperator(const BinaryOperator *BO);
Chris Lattner03d6fb92007-08-21 04:43:17 +000072 void VisitBinAssign(const BinaryOperator *E);
Chris Lattner9c033562007-08-21 04:25:47 +000073
74
75 void VisitConditionalOperator(const ConditionalOperator *CO);
76 // case Expr::ChooseExprClass:
77};
78} // end anonymous namespace.
79
Chris Lattneree755f92007-08-21 04:59:27 +000080//===----------------------------------------------------------------------===//
81// Utilities
82//===----------------------------------------------------------------------===//
Chris Lattner9c033562007-08-21 04:25:47 +000083
Chris Lattnerbfc0c1a2007-08-26 23:13:56 +000084void AggExprEmitter::EmitAggregateCopy(llvm::Value *DestPtr,
85 llvm::Value *SrcPtr, QualType Ty) {
86 assert(!Ty->isComplexType() && "Shouldn't happen for complex");
87
88 // Aggregate assignment turns into llvm.memcpy.
89 const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
90 if (DestPtr->getType() != BP)
91 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
92 if (SrcPtr->getType() != BP)
93 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
94
95 // Get size and alignment info for this aggregate.
96 std::pair<uint64_t, unsigned> TypeInfo =
97 CGF.getContext().getTypeInfo(Ty, SourceLocation());
98
99 // FIXME: Handle variable sized types.
100 const llvm::Type *IntPtr = llvm::IntegerType::get(CGF.LLVMPointerWidth);
101
102 llvm::Value *MemCpyOps[4] = {
103 DestPtr, SrcPtr,
104 llvm::ConstantInt::get(IntPtr, TypeInfo.first),
105 llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
106 };
107
108 Builder.CreateCall(CGF.CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
109}
110
111
Chris Lattner883f6a72007-08-11 00:04:45 +0000112/// EmitAggLoadOfLValue - Given an expression with aggregate type that
113/// represents a value lvalue, this method emits the address of the lvalue,
114/// then loads the result into DestPtr.
Chris Lattner9c033562007-08-21 04:25:47 +0000115void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
116 LValue LV = CGF.EmitLValue(E);
Chris Lattner883f6a72007-08-11 00:04:45 +0000117 assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
118 llvm::Value *SrcPtr = LV.getAddress();
119
120 // If the result is ignored, don't copy from the value.
121 if (DestPtr == 0)
122 // FIXME: If the source is volatile, we must read from it.
123 return;
124
Chris Lattnerbfc0c1a2007-08-26 23:13:56 +0000125 EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
Chris Lattner883f6a72007-08-11 00:04:45 +0000126}
127
Chris Lattneree755f92007-08-21 04:59:27 +0000128//===----------------------------------------------------------------------===//
129// Visitor Methods
130//===----------------------------------------------------------------------===//
131
Chris Lattnerb2d963f2007-08-31 22:54:14 +0000132void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
133 CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
134}
135
Chris Lattner9c033562007-08-21 04:25:47 +0000136void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
Chris Lattner03d6fb92007-08-21 04:43:17 +0000137 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
Chris Lattner419ea7e2007-09-13 01:17:29 +0000138 E->dump(CGF.getContext().SourceMgr);
Chris Lattneree755f92007-08-21 04:59:27 +0000139}
140
Chris Lattner03d6fb92007-08-21 04:43:17 +0000141void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Chris Lattner883f6a72007-08-11 00:04:45 +0000142 assert(E->getLHS()->getType().getCanonicalType() ==
143 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
Chris Lattner9c033562007-08-21 04:25:47 +0000144 LValue LHS = CGF.EmitLValue(E->getLHS());
Chris Lattner883f6a72007-08-11 00:04:45 +0000145
146 // Codegen the RHS so that it stores directly into the LHS.
Chris Lattner9c033562007-08-21 04:25:47 +0000147 CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
Chris Lattner883f6a72007-08-11 00:04:45 +0000148
149 // If the result of the assignment is used, copy the RHS there also.
150 if (DestPtr) {
151 assert(0 && "FIXME: Chained agg assignment not implemented yet");
152 }
153}
154
Chris Lattner9c033562007-08-21 04:25:47 +0000155void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
Chris Lattner883f6a72007-08-11 00:04:45 +0000156 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
157 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
158 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
159
Chris Lattner9c033562007-08-21 04:25:47 +0000160 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
Chris Lattnerbfc0c1a2007-08-26 23:13:56 +0000161 Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000162
Chris Lattner9c033562007-08-21 04:25:47 +0000163 CGF.EmitBlock(LHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000164
165 // Handle the GNU extension for missing LHS.
166 assert(E->getLHS() && "Must have LHS for aggregate value");
167
Chris Lattnerc748f272007-08-21 05:02:10 +0000168 Visit(E->getLHS());
Chris Lattnerbfc0c1a2007-08-26 23:13:56 +0000169 Builder.CreateBr(ContBlock);
170 LHSBlock = Builder.GetInsertBlock();
Chris Lattner883f6a72007-08-11 00:04:45 +0000171
Chris Lattner9c033562007-08-21 04:25:47 +0000172 CGF.EmitBlock(RHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000173
Chris Lattnerc748f272007-08-21 05:02:10 +0000174 Visit(E->getRHS());
Chris Lattnerbfc0c1a2007-08-26 23:13:56 +0000175 Builder.CreateBr(ContBlock);
176 RHSBlock = Builder.GetInsertBlock();
Chris Lattner883f6a72007-08-11 00:04:45 +0000177
Chris Lattner9c033562007-08-21 04:25:47 +0000178 CGF.EmitBlock(ContBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000179}
Chris Lattneree755f92007-08-21 04:59:27 +0000180
181//===----------------------------------------------------------------------===//
182// Entry Points into this File
183//===----------------------------------------------------------------------===//
184
185/// EmitAggExpr - Emit the computation of the specified expression of
186/// aggregate type. The result is computed into DestPtr. Note that if
187/// DestPtr is null, the value of the aggregate expression is not needed.
188void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
189 bool VolatileDest) {
190 assert(E && hasAggregateLLVMType(E->getType()) &&
191 "Invalid aggregate expression to emit");
192
193 AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
194}