blob: 869e35dac5e846ac8af45689cf26f8f96f91cc2f [file] [log] [blame]
Chris Lattneraf6f5282007-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 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
23// FIXME: Handle volatility!
24void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
25 llvm::Value *SrcPtr, QualType Ty) {
26 // Don't use memcpy for complex numbers.
27 if (Ty->isComplexType()) {
28 llvm::Value *Real, *Imag;
29 EmitLoadOfComplex(RValue::getAggregate(SrcPtr), Real, Imag);
30 EmitStoreOfComplex(Real, Imag, DestPtr);
31 return;
32 }
33
34 // Aggregate assignment turns into llvm.memcpy.
35 const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
36 if (DestPtr->getType() != BP)
37 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
38 if (SrcPtr->getType() != BP)
39 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
40
41 // Get size and alignment info for this aggregate.
42 std::pair<uint64_t, unsigned> TypeInfo =
43 getContext().getTypeInfo(Ty, SourceLocation());
44
45 // FIXME: Handle variable sized types.
46 const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
47
48 llvm::Value *MemCpyOps[4] = {
49 DestPtr, SrcPtr,
50 llvm::ConstantInt::get(IntPtr, TypeInfo.first),
51 llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
52 };
53
54 Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
55}
56
Chris Lattner9c033562007-08-21 04:25:47 +000057//===----------------------------------------------------------------------===//
58// Aggregate Expression Emitter
59//===----------------------------------------------------------------------===//
60
61namespace {
62class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
63 CodeGenFunction &CGF;
64 llvm::Value *DestPtr;
65 bool VolatileDest;
66public:
67 AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
68 : CGF(cgf), DestPtr(destPtr), VolatileDest(volatileDest) {
69 }
70
71 /// EmitAggLoadOfLValue - Given an expression with aggregate type that
72 /// represents a value lvalue, this method emits the address of the lvalue,
73 /// then loads the result into DestPtr.
74 void EmitAggLoadOfLValue(const Expr *E);
75
76 void VisitStmt(Stmt *S) {
77 fprintf(stderr, "Unimplemented agg expr!\n");
78 S->dump();
79 }
80 void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
81
82 // l-values.
83 void VisitDeclRefExpr(DeclRefExpr *DRE) { return EmitAggLoadOfLValue(DRE); }
84 // case Expr::ArraySubscriptExprClass:
85
86 // Operators.
87 // case Expr::UnaryOperatorClass:
88 // case Expr::ImplicitCastExprClass:
89 // case Expr::CastExprClass:
90 // case Expr::CallExprClass:
91 void VisitBinaryOperator(const BinaryOperator *BO);
Chris Lattner03d6fb92007-08-21 04:43:17 +000092 void VisitBinAssign(const BinaryOperator *E);
Chris Lattner9c033562007-08-21 04:25:47 +000093
94
95 void VisitConditionalOperator(const ConditionalOperator *CO);
96 // case Expr::ChooseExprClass:
97};
98} // end anonymous namespace.
99
100
101
Chris Lattner883f6a72007-08-11 00:04:45 +0000102
103/// EmitAggExpr - Emit the computation of the specified expression of
104/// aggregate type. The result is computed into DestPtr. Note that if
105/// DestPtr is null, the value of the aggregate expression is not needed.
106void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
107 bool VolatileDest) {
108 assert(E && hasAggregateLLVMType(E->getType()) &&
109 "Invalid aggregate expression to emit");
110
Chris Lattner9c033562007-08-21 04:25:47 +0000111 AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
Chris Lattner883f6a72007-08-11 00:04:45 +0000112}
113
114/// EmitAggLoadOfLValue - Given an expression with aggregate type that
115/// represents a value lvalue, this method emits the address of the lvalue,
116/// then loads the result into DestPtr.
Chris Lattner9c033562007-08-21 04:25:47 +0000117void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
118 LValue LV = CGF.EmitLValue(E);
Chris Lattner883f6a72007-08-11 00:04:45 +0000119 assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
120 llvm::Value *SrcPtr = LV.getAddress();
121
122 // If the result is ignored, don't copy from the value.
123 if (DestPtr == 0)
124 // FIXME: If the source is volatile, we must read from it.
125 return;
126
Chris Lattner9c033562007-08-21 04:25:47 +0000127 CGF.EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
Chris Lattner883f6a72007-08-11 00:04:45 +0000128}
129
Chris Lattner9c033562007-08-21 04:25:47 +0000130void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
Chris Lattner03d6fb92007-08-21 04:43:17 +0000131 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
132 E->dump();
133#if 0
Chris Lattner883f6a72007-08-11 00:04:45 +0000134 switch (E->getOpcode()) {
135 default:
Chris Lattner883f6a72007-08-11 00:04:45 +0000136 return;
Chris Lattner883f6a72007-08-11 00:04:45 +0000137 case BinaryOperator::Mul:
138 LHS = EmitExpr(E->getLHS());
139 RHS = EmitExpr(E->getRHS());
140 return EmitMul(LHS, RHS, E->getType());
141 case BinaryOperator::Div:
142 LHS = EmitExpr(E->getLHS());
143 RHS = EmitExpr(E->getRHS());
144 return EmitDiv(LHS, RHS, E->getType());
145 case BinaryOperator::Rem:
146 LHS = EmitExpr(E->getLHS());
147 RHS = EmitExpr(E->getRHS());
148 return EmitRem(LHS, RHS, E->getType());
149 case BinaryOperator::Add:
150 LHS = EmitExpr(E->getLHS());
151 RHS = EmitExpr(E->getRHS());
152 if (!E->getType()->isPointerType())
153 return EmitAdd(LHS, RHS, E->getType());
154
155 return EmitPointerAdd(LHS, E->getLHS()->getType(),
156 RHS, E->getRHS()->getType(), E->getType());
157 case BinaryOperator::Sub:
158 LHS = EmitExpr(E->getLHS());
159 RHS = EmitExpr(E->getRHS());
160
161 if (!E->getLHS()->getType()->isPointerType())
162 return EmitSub(LHS, RHS, E->getType());
163
164 return EmitPointerSub(LHS, E->getLHS()->getType(),
165 RHS, E->getRHS()->getType(), E->getType());
166 case BinaryOperator::Shl:
167 LHS = EmitExpr(E->getLHS());
168 RHS = EmitExpr(E->getRHS());
169 return EmitShl(LHS, RHS, E->getType());
170 case BinaryOperator::Shr:
171 LHS = EmitExpr(E->getLHS());
172 RHS = EmitExpr(E->getRHS());
173 return EmitShr(LHS, RHS, E->getType());
174 case BinaryOperator::And:
175 LHS = EmitExpr(E->getLHS());
176 RHS = EmitExpr(E->getRHS());
177 return EmitAnd(LHS, RHS, E->getType());
178 case BinaryOperator::Xor:
179 LHS = EmitExpr(E->getLHS());
180 RHS = EmitExpr(E->getRHS());
181 return EmitXor(LHS, RHS, E->getType());
182 case BinaryOperator::Or :
183 LHS = EmitExpr(E->getLHS());
184 RHS = EmitExpr(E->getRHS());
185 return EmitOr(LHS, RHS, E->getType());
Chris Lattner883f6a72007-08-11 00:04:45 +0000186 case BinaryOperator::MulAssign: {
187 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
188 LValue LHSLV;
189 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
190 LHS = EmitMul(LHS, RHS, CAO->getComputationType());
191 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
192 }
193 case BinaryOperator::DivAssign: {
194 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
195 LValue LHSLV;
196 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
197 LHS = EmitDiv(LHS, RHS, CAO->getComputationType());
198 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
199 }
200 case BinaryOperator::RemAssign: {
201 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
202 LValue LHSLV;
203 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
204 LHS = EmitRem(LHS, RHS, CAO->getComputationType());
205 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
206 }
207 case BinaryOperator::AddAssign: {
208 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
209 LValue LHSLV;
210 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
211 LHS = EmitAdd(LHS, RHS, CAO->getComputationType());
212 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
213 }
214 case BinaryOperator::SubAssign: {
215 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
216 LValue LHSLV;
217 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
218 LHS = EmitSub(LHS, RHS, CAO->getComputationType());
219 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
220 }
221 case BinaryOperator::ShlAssign: {
222 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
223 LValue LHSLV;
224 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
225 LHS = EmitShl(LHS, RHS, CAO->getComputationType());
226 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
227 }
228 case BinaryOperator::ShrAssign: {
229 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
230 LValue LHSLV;
231 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
232 LHS = EmitShr(LHS, RHS, CAO->getComputationType());
233 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
234 }
235 case BinaryOperator::AndAssign: {
236 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
237 LValue LHSLV;
238 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
239 LHS = EmitAnd(LHS, RHS, CAO->getComputationType());
240 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
241 }
242 case BinaryOperator::OrAssign: {
243 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
244 LValue LHSLV;
245 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
246 LHS = EmitOr(LHS, RHS, CAO->getComputationType());
247 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
248 }
249 case BinaryOperator::XorAssign: {
250 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
251 LValue LHSLV;
252 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
253 LHS = EmitXor(LHS, RHS, CAO->getComputationType());
254 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
255 }
256 case BinaryOperator::Comma: return EmitBinaryComma(E);
Chris Lattner883f6a72007-08-11 00:04:45 +0000257 }
Chris Lattner03d6fb92007-08-21 04:43:17 +0000258#endif
Chris Lattner883f6a72007-08-11 00:04:45 +0000259}
260
Chris Lattner03d6fb92007-08-21 04:43:17 +0000261void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Chris Lattner883f6a72007-08-11 00:04:45 +0000262 assert(E->getLHS()->getType().getCanonicalType() ==
263 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
Chris Lattner9c033562007-08-21 04:25:47 +0000264 LValue LHS = CGF.EmitLValue(E->getLHS());
Chris Lattner883f6a72007-08-11 00:04:45 +0000265
266 // Codegen the RHS so that it stores directly into the LHS.
Chris Lattner9c033562007-08-21 04:25:47 +0000267 CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
Chris Lattner883f6a72007-08-11 00:04:45 +0000268
269 // If the result of the assignment is used, copy the RHS there also.
270 if (DestPtr) {
271 assert(0 && "FIXME: Chained agg assignment not implemented yet");
272 }
273}
274
275
Chris Lattner9c033562007-08-21 04:25:47 +0000276void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
Chris Lattner883f6a72007-08-11 00:04:45 +0000277 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
278 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
279 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
280
Chris Lattner9c033562007-08-21 04:25:47 +0000281 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
282 CGF.Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000283
Chris Lattner9c033562007-08-21 04:25:47 +0000284 CGF.EmitBlock(LHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000285
286 // Handle the GNU extension for missing LHS.
287 assert(E->getLHS() && "Must have LHS for aggregate value");
288
Chris Lattner9c033562007-08-21 04:25:47 +0000289 CGF.EmitAggExpr(E->getLHS(), DestPtr, VolatileDest);
290 CGF.Builder.CreateBr(ContBlock);
291 LHSBlock =CGF. Builder.GetInsertBlock();
Chris Lattner883f6a72007-08-11 00:04:45 +0000292
Chris Lattner9c033562007-08-21 04:25:47 +0000293 CGF.EmitBlock(RHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000294
Chris Lattner9c033562007-08-21 04:25:47 +0000295 CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest);
296 CGF.Builder.CreateBr(ContBlock);
297 RHSBlock = CGF.Builder.GetInsertBlock();
Chris Lattner883f6a72007-08-11 00:04:45 +0000298
Chris Lattner9c033562007-08-21 04:25:47 +0000299 CGF.EmitBlock(ContBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000300}