blob: 4382fec6a4210f7205b08f12ec083e227e22e52e [file] [log] [blame]
Chris Lattner78ed8402007-08-10 20:13:28 +00001//===--- CGAggExpr.cpp - Emit LLVM Code from Aggregate Expressions --------===//
2//
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 Lattnerbdb8ffb2007-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 Lattnerb50e3902007-08-21 04:25:47 +000019#include "llvm/Support/Compiler.h"
Chris Lattner78ed8402007-08-10 20:13:28 +000020using namespace clang;
21using namespace CodeGen;
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000022
Chris Lattnerb50e3902007-08-21 04:25:47 +000023//===----------------------------------------------------------------------===//
24// Aggregate Expression Emitter
25//===----------------------------------------------------------------------===//
26
27namespace {
28class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
29 CodeGenFunction &CGF;
30 llvm::Value *DestPtr;
31 bool VolatileDest;
32public:
33 AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
34 : CGF(cgf), DestPtr(destPtr), VolatileDest(volatileDest) {
35 }
36
Chris Lattnera7300102007-08-21 04:59:27 +000037 typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
38
39 //===--------------------------------------------------------------------===//
40 // Utilities
41 //===--------------------------------------------------------------------===//
42
Chris Lattnerb50e3902007-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 Lattnera7300102007-08-21 04:59:27 +000048 /// EmitComplexExpr - Emit the specified complex expression, returning the
49 /// real and imaginary values.
50 ComplexPairTy EmitComplexExpr(const Expr *E);
51
52
53 //===--------------------------------------------------------------------===//
54 // Visitor Methods
55 //===--------------------------------------------------------------------===//
56
Chris Lattnerb50e3902007-08-21 04:25:47 +000057 void VisitStmt(Stmt *S) {
58 fprintf(stderr, "Unimplemented agg expr!\n");
59 S->dump();
60 }
61 void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
62
63 // l-values.
64 void VisitDeclRefExpr(DeclRefExpr *DRE) { return EmitAggLoadOfLValue(DRE); }
65 // case Expr::ArraySubscriptExprClass:
66
67 // Operators.
68 // case Expr::UnaryOperatorClass:
69 // case Expr::ImplicitCastExprClass:
70 // case Expr::CastExprClass:
71 // case Expr::CallExprClass:
72 void VisitBinaryOperator(const BinaryOperator *BO);
Chris Lattnera7300102007-08-21 04:59:27 +000073 void VisitBinAdd(const BinaryOperator *E);
Chris Lattner76cb1892007-08-21 04:43:17 +000074 void VisitBinAssign(const BinaryOperator *E);
Chris Lattnerb50e3902007-08-21 04:25:47 +000075
76
77 void VisitConditionalOperator(const ConditionalOperator *CO);
78 // case Expr::ChooseExprClass:
79};
80} // end anonymous namespace.
81
Chris Lattnera7300102007-08-21 04:59:27 +000082//===----------------------------------------------------------------------===//
83// Utilities
84//===----------------------------------------------------------------------===//
Chris Lattnerb50e3902007-08-21 04:25:47 +000085
Chris Lattnera7300102007-08-21 04:59:27 +000086/// EmitComplexExpr - Emit the specified complex expression, returning the
87/// real and imaginary values.
88AggExprEmitter::ComplexPairTy AggExprEmitter::EmitComplexExpr(const Expr *E) {
89 // Create a temporary alloca to hold this result.
90 llvm::Value *TmpPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()));
Chris Lattnerb50e3902007-08-21 04:25:47 +000091
Chris Lattnera7300102007-08-21 04:59:27 +000092 // Emit the expression into TmpPtr.
93 AggExprEmitter(CGF, TmpPtr, false).Visit(const_cast<Expr*>(E));
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000094
Chris Lattnera7300102007-08-21 04:59:27 +000095 // Return the real/imag values by reloading them from the stack.
96 llvm::Value *Real, *Imag;
97 CGF.EmitLoadOfComplex(TmpPtr, Real, Imag);
98 return std::make_pair(Real, Imag);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000099}
100
Chris Lattnera7300102007-08-21 04:59:27 +0000101
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000102/// EmitAggLoadOfLValue - Given an expression with aggregate type that
103/// represents a value lvalue, this method emits the address of the lvalue,
104/// then loads the result into DestPtr.
Chris Lattnerb50e3902007-08-21 04:25:47 +0000105void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
106 LValue LV = CGF.EmitLValue(E);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000107 assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
108 llvm::Value *SrcPtr = LV.getAddress();
109
110 // If the result is ignored, don't copy from the value.
111 if (DestPtr == 0)
112 // FIXME: If the source is volatile, we must read from it.
113 return;
114
Chris Lattnerb50e3902007-08-21 04:25:47 +0000115 CGF.EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000116}
117
Chris Lattnera7300102007-08-21 04:59:27 +0000118//===----------------------------------------------------------------------===//
119// Visitor Methods
120//===----------------------------------------------------------------------===//
121
Chris Lattnerb50e3902007-08-21 04:25:47 +0000122void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
Chris Lattner76cb1892007-08-21 04:43:17 +0000123 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
124 E->dump();
125#if 0
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000126 switch (E->getOpcode()) {
127 default:
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000128 return;
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000129 case BinaryOperator::Mul:
130 LHS = EmitExpr(E->getLHS());
131 RHS = EmitExpr(E->getRHS());
132 return EmitMul(LHS, RHS, E->getType());
133 case BinaryOperator::Div:
134 LHS = EmitExpr(E->getLHS());
135 RHS = EmitExpr(E->getRHS());
136 return EmitDiv(LHS, RHS, E->getType());
137 case BinaryOperator::Rem:
138 LHS = EmitExpr(E->getLHS());
139 RHS = EmitExpr(E->getRHS());
140 return EmitRem(LHS, RHS, E->getType());
141 case BinaryOperator::Add:
142 LHS = EmitExpr(E->getLHS());
143 RHS = EmitExpr(E->getRHS());
144 if (!E->getType()->isPointerType())
145 return EmitAdd(LHS, RHS, E->getType());
146
147 return EmitPointerAdd(LHS, E->getLHS()->getType(),
148 RHS, E->getRHS()->getType(), E->getType());
149 case BinaryOperator::Sub:
150 LHS = EmitExpr(E->getLHS());
151 RHS = EmitExpr(E->getRHS());
152
153 if (!E->getLHS()->getType()->isPointerType())
154 return EmitSub(LHS, RHS, E->getType());
155
156 return EmitPointerSub(LHS, E->getLHS()->getType(),
157 RHS, E->getRHS()->getType(), E->getType());
158 case BinaryOperator::Shl:
159 LHS = EmitExpr(E->getLHS());
160 RHS = EmitExpr(E->getRHS());
161 return EmitShl(LHS, RHS, E->getType());
162 case BinaryOperator::Shr:
163 LHS = EmitExpr(E->getLHS());
164 RHS = EmitExpr(E->getRHS());
165 return EmitShr(LHS, RHS, E->getType());
166 case BinaryOperator::And:
167 LHS = EmitExpr(E->getLHS());
168 RHS = EmitExpr(E->getRHS());
169 return EmitAnd(LHS, RHS, E->getType());
170 case BinaryOperator::Xor:
171 LHS = EmitExpr(E->getLHS());
172 RHS = EmitExpr(E->getRHS());
173 return EmitXor(LHS, RHS, E->getType());
174 case BinaryOperator::Or :
175 LHS = EmitExpr(E->getLHS());
176 RHS = EmitExpr(E->getRHS());
177 return EmitOr(LHS, RHS, E->getType());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000178 case BinaryOperator::MulAssign: {
179 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
180 LValue LHSLV;
181 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
182 LHS = EmitMul(LHS, RHS, CAO->getComputationType());
183 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
184 }
185 case BinaryOperator::DivAssign: {
186 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
187 LValue LHSLV;
188 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
189 LHS = EmitDiv(LHS, RHS, CAO->getComputationType());
190 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
191 }
192 case BinaryOperator::RemAssign: {
193 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
194 LValue LHSLV;
195 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
196 LHS = EmitRem(LHS, RHS, CAO->getComputationType());
197 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
198 }
199 case BinaryOperator::AddAssign: {
200 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
201 LValue LHSLV;
202 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
203 LHS = EmitAdd(LHS, RHS, CAO->getComputationType());
204 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
205 }
206 case BinaryOperator::SubAssign: {
207 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
208 LValue LHSLV;
209 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
210 LHS = EmitSub(LHS, RHS, CAO->getComputationType());
211 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
212 }
213 case BinaryOperator::ShlAssign: {
214 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
215 LValue LHSLV;
216 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
217 LHS = EmitShl(LHS, RHS, CAO->getComputationType());
218 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
219 }
220 case BinaryOperator::ShrAssign: {
221 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
222 LValue LHSLV;
223 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
224 LHS = EmitShr(LHS, RHS, CAO->getComputationType());
225 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
226 }
227 case BinaryOperator::AndAssign: {
228 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
229 LValue LHSLV;
230 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
231 LHS = EmitAnd(LHS, RHS, CAO->getComputationType());
232 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
233 }
234 case BinaryOperator::OrAssign: {
235 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
236 LValue LHSLV;
237 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
238 LHS = EmitOr(LHS, RHS, CAO->getComputationType());
239 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
240 }
241 case BinaryOperator::XorAssign: {
242 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
243 LValue LHSLV;
244 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
245 LHS = EmitXor(LHS, RHS, CAO->getComputationType());
246 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
247 }
248 case BinaryOperator::Comma: return EmitBinaryComma(E);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000249 }
Chris Lattner76cb1892007-08-21 04:43:17 +0000250#endif
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000251}
252
Chris Lattnera7300102007-08-21 04:59:27 +0000253void AggExprEmitter::VisitBinAdd(const BinaryOperator *E) {
254 // This must be a complex number.
255 ComplexPairTy LHS = EmitComplexExpr(E->getLHS());
256 ComplexPairTy RHS = EmitComplexExpr(E->getRHS());
257
258 llvm::Value *ResR = CGF.Builder.CreateAdd(LHS.first, RHS.first, "add.r");
259 llvm::Value *ResI = CGF.Builder.CreateAdd(LHS.second, RHS.second, "add.i");
260
261 CGF.EmitStoreOfComplex(ResR, ResI, DestPtr /*FIXME: Volatile!*/);
262}
263
Chris Lattner76cb1892007-08-21 04:43:17 +0000264void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000265 assert(E->getLHS()->getType().getCanonicalType() ==
266 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
Chris Lattnerb50e3902007-08-21 04:25:47 +0000267 LValue LHS = CGF.EmitLValue(E->getLHS());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000268
269 // Codegen the RHS so that it stores directly into the LHS.
Chris Lattnerb50e3902007-08-21 04:25:47 +0000270 CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000271
272 // If the result of the assignment is used, copy the RHS there also.
273 if (DestPtr) {
274 assert(0 && "FIXME: Chained agg assignment not implemented yet");
275 }
276}
277
278
Chris Lattnerb50e3902007-08-21 04:25:47 +0000279void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000280 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
281 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
282 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
283
Chris Lattnerb50e3902007-08-21 04:25:47 +0000284 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
285 CGF.Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000286
Chris Lattnerb50e3902007-08-21 04:25:47 +0000287 CGF.EmitBlock(LHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000288
289 // Handle the GNU extension for missing LHS.
290 assert(E->getLHS() && "Must have LHS for aggregate value");
291
Chris Lattnerb50e3902007-08-21 04:25:47 +0000292 CGF.EmitAggExpr(E->getLHS(), DestPtr, VolatileDest);
293 CGF.Builder.CreateBr(ContBlock);
294 LHSBlock =CGF. Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000295
Chris Lattnerb50e3902007-08-21 04:25:47 +0000296 CGF.EmitBlock(RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000297
Chris Lattnerb50e3902007-08-21 04:25:47 +0000298 CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest);
299 CGF.Builder.CreateBr(ContBlock);
300 RHSBlock = CGF.Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000301
Chris Lattnerb50e3902007-08-21 04:25:47 +0000302 CGF.EmitBlock(ContBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000303}
Chris Lattnera7300102007-08-21 04:59:27 +0000304
305//===----------------------------------------------------------------------===//
306// Entry Points into this File
307//===----------------------------------------------------------------------===//
308
309/// EmitAggExpr - Emit the computation of the specified expression of
310/// aggregate type. The result is computed into DestPtr. Note that if
311/// DestPtr is null, the value of the aggregate expression is not needed.
312void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
313 bool VolatileDest) {
314 assert(E && hasAggregateLLVMType(E->getType()) &&
315 "Invalid aggregate expression to emit");
316
317 AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
318}
319
320
321// FIXME: Handle volatility!
322void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
323 llvm::Value *SrcPtr, QualType Ty) {
324 // Don't use memcpy for complex numbers.
325 if (Ty->isComplexType()) {
326 llvm::Value *Real, *Imag;
327 EmitLoadOfComplex(SrcPtr, Real, Imag);
328 EmitStoreOfComplex(Real, Imag, DestPtr);
329 return;
330 }
331
332 // Aggregate assignment turns into llvm.memcpy.
333 const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
334 if (DestPtr->getType() != BP)
335 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
336 if (SrcPtr->getType() != BP)
337 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
338
339 // Get size and alignment info for this aggregate.
340 std::pair<uint64_t, unsigned> TypeInfo =
341 getContext().getTypeInfo(Ty, SourceLocation());
342
343 // FIXME: Handle variable sized types.
344 const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
345
346 llvm::Value *MemCpyOps[4] = {
347 DestPtr, SrcPtr,
348 llvm::ConstantInt::get(IntPtr, TypeInfo.first),
349 llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
350 };
351
352 Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
353}