blob: c584b0b7502f4d49d4f101796668f3a3d57cb921 [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 Lattner78ed8402007-08-10 20:13:28 +000019using namespace clang;
20using namespace CodeGen;
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000021
22// FIXME: Handle volatility!
23void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
24 llvm::Value *SrcPtr, QualType Ty) {
25 // Don't use memcpy for complex numbers.
26 if (Ty->isComplexType()) {
27 llvm::Value *Real, *Imag;
28 EmitLoadOfComplex(RValue::getAggregate(SrcPtr), Real, Imag);
29 EmitStoreOfComplex(Real, Imag, DestPtr);
30 return;
31 }
32
33 // Aggregate assignment turns into llvm.memcpy.
34 const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
35 if (DestPtr->getType() != BP)
36 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
37 if (SrcPtr->getType() != BP)
38 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
39
40 // Get size and alignment info for this aggregate.
41 std::pair<uint64_t, unsigned> TypeInfo =
42 getContext().getTypeInfo(Ty, SourceLocation());
43
44 // FIXME: Handle variable sized types.
45 const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
46
47 llvm::Value *MemCpyOps[4] = {
48 DestPtr, SrcPtr,
49 llvm::ConstantInt::get(IntPtr, TypeInfo.first),
50 llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
51 };
52
53 Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
54}
55
56
57/// EmitAggExpr - Emit the computation of the specified expression of
58/// aggregate type. The result is computed into DestPtr. Note that if
59/// DestPtr is null, the value of the aggregate expression is not needed.
60void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
61 bool VolatileDest) {
62 assert(E && hasAggregateLLVMType(E->getType()) &&
63 "Invalid aggregate expression to emit");
64
65 switch (E->getStmtClass()) {
66 default:
67 fprintf(stderr, "Unimplemented agg expr!\n");
68 E->dump();
69 return;
70
71 // l-values.
72 case Expr::DeclRefExprClass:
73 return EmitAggLoadOfLValue(E, DestPtr, VolatileDest);
74// case Expr::ArraySubscriptExprClass:
75// return EmitArraySubscriptExprRV(cast<ArraySubscriptExpr>(E));
76
77 // Operators.
78 case Expr::ParenExprClass:
79 return EmitAggExpr(cast<ParenExpr>(E)->getSubExpr(), DestPtr, VolatileDest);
80// case Expr::UnaryOperatorClass:
81// return EmitUnaryOperator(cast<UnaryOperator>(E));
82// case Expr::ImplicitCastExprClass:
83// return EmitCastExpr(cast<ImplicitCastExpr>(E)->getSubExpr(),E->getType());
84// case Expr::CastExprClass:
85// return EmitCastExpr(cast<CastExpr>(E)->getSubExpr(), E->getType());
86// case Expr::CallExprClass:
87// return EmitCallExpr(cast<CallExpr>(E));
88 case Expr::BinaryOperatorClass:
89 return EmitAggBinaryOperator(cast<BinaryOperator>(E), DestPtr,VolatileDest);
90
91 case Expr::ConditionalOperatorClass:
92 return EmitAggConditionalOperator(cast<ConditionalOperator>(E),
93 DestPtr, VolatileDest);
94// case Expr::ChooseExprClass:
95// return EmitChooseExpr(cast<ChooseExpr>(E));
96 }
97}
98
99/// EmitAggLoadOfLValue - Given an expression with aggregate type that
100/// represents a value lvalue, this method emits the address of the lvalue,
101/// then loads the result into DestPtr.
102void CodeGenFunction::EmitAggLoadOfLValue(const Expr *E, llvm::Value *DestPtr,
103 bool VolatileDest) {
104 LValue LV = EmitLValue(E);
105 assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
106 llvm::Value *SrcPtr = LV.getAddress();
107
108 // If the result is ignored, don't copy from the value.
109 if (DestPtr == 0)
110 // FIXME: If the source is volatile, we must read from it.
111 return;
112
113 EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
114}
115
116void CodeGenFunction::EmitAggBinaryOperator(const BinaryOperator *E,
117 llvm::Value *DestPtr,
118 bool VolatileDest) {
119 switch (E->getOpcode()) {
120 default:
121 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
122 E->dump();
123 return;
124#if 0
125 case BinaryOperator::Mul:
126 LHS = EmitExpr(E->getLHS());
127 RHS = EmitExpr(E->getRHS());
128 return EmitMul(LHS, RHS, E->getType());
129 case BinaryOperator::Div:
130 LHS = EmitExpr(E->getLHS());
131 RHS = EmitExpr(E->getRHS());
132 return EmitDiv(LHS, RHS, E->getType());
133 case BinaryOperator::Rem:
134 LHS = EmitExpr(E->getLHS());
135 RHS = EmitExpr(E->getRHS());
136 return EmitRem(LHS, RHS, E->getType());
137 case BinaryOperator::Add:
138 LHS = EmitExpr(E->getLHS());
139 RHS = EmitExpr(E->getRHS());
140 if (!E->getType()->isPointerType())
141 return EmitAdd(LHS, RHS, E->getType());
142
143 return EmitPointerAdd(LHS, E->getLHS()->getType(),
144 RHS, E->getRHS()->getType(), E->getType());
145 case BinaryOperator::Sub:
146 LHS = EmitExpr(E->getLHS());
147 RHS = EmitExpr(E->getRHS());
148
149 if (!E->getLHS()->getType()->isPointerType())
150 return EmitSub(LHS, RHS, E->getType());
151
152 return EmitPointerSub(LHS, E->getLHS()->getType(),
153 RHS, E->getRHS()->getType(), E->getType());
154 case BinaryOperator::Shl:
155 LHS = EmitExpr(E->getLHS());
156 RHS = EmitExpr(E->getRHS());
157 return EmitShl(LHS, RHS, E->getType());
158 case BinaryOperator::Shr:
159 LHS = EmitExpr(E->getLHS());
160 RHS = EmitExpr(E->getRHS());
161 return EmitShr(LHS, RHS, E->getType());
162 case BinaryOperator::And:
163 LHS = EmitExpr(E->getLHS());
164 RHS = EmitExpr(E->getRHS());
165 return EmitAnd(LHS, RHS, E->getType());
166 case BinaryOperator::Xor:
167 LHS = EmitExpr(E->getLHS());
168 RHS = EmitExpr(E->getRHS());
169 return EmitXor(LHS, RHS, E->getType());
170 case BinaryOperator::Or :
171 LHS = EmitExpr(E->getLHS());
172 RHS = EmitExpr(E->getRHS());
173 return EmitOr(LHS, RHS, E->getType());
174#endif
175 case BinaryOperator::Assign:
176 return EmitAggBinaryAssign(E, DestPtr, VolatileDest);
177
178#if 0
179 case BinaryOperator::MulAssign: {
180 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
181 LValue LHSLV;
182 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
183 LHS = EmitMul(LHS, RHS, CAO->getComputationType());
184 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
185 }
186 case BinaryOperator::DivAssign: {
187 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
188 LValue LHSLV;
189 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
190 LHS = EmitDiv(LHS, RHS, CAO->getComputationType());
191 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
192 }
193 case BinaryOperator::RemAssign: {
194 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
195 LValue LHSLV;
196 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
197 LHS = EmitRem(LHS, RHS, CAO->getComputationType());
198 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
199 }
200 case BinaryOperator::AddAssign: {
201 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
202 LValue LHSLV;
203 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
204 LHS = EmitAdd(LHS, RHS, CAO->getComputationType());
205 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
206 }
207 case BinaryOperator::SubAssign: {
208 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
209 LValue LHSLV;
210 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
211 LHS = EmitSub(LHS, RHS, CAO->getComputationType());
212 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
213 }
214 case BinaryOperator::ShlAssign: {
215 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
216 LValue LHSLV;
217 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
218 LHS = EmitShl(LHS, RHS, CAO->getComputationType());
219 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
220 }
221 case BinaryOperator::ShrAssign: {
222 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
223 LValue LHSLV;
224 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
225 LHS = EmitShr(LHS, RHS, CAO->getComputationType());
226 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
227 }
228 case BinaryOperator::AndAssign: {
229 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
230 LValue LHSLV;
231 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
232 LHS = EmitAnd(LHS, RHS, CAO->getComputationType());
233 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
234 }
235 case BinaryOperator::OrAssign: {
236 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
237 LValue LHSLV;
238 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
239 LHS = EmitOr(LHS, RHS, CAO->getComputationType());
240 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
241 }
242 case BinaryOperator::XorAssign: {
243 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
244 LValue LHSLV;
245 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
246 LHS = EmitXor(LHS, RHS, CAO->getComputationType());
247 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
248 }
249 case BinaryOperator::Comma: return EmitBinaryComma(E);
250#endif
251 }
252}
253
254void CodeGenFunction::EmitAggBinaryAssign(const BinaryOperator *E,
255 llvm::Value *DestPtr,
256 bool VolatileDest) {
257 assert(E->getLHS()->getType().getCanonicalType() ==
258 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
259 LValue LHS = EmitLValue(E->getLHS());
260
261 // Codegen the RHS so that it stores directly into the LHS.
262 EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
263
264 // If the result of the assignment is used, copy the RHS there also.
265 if (DestPtr) {
266 assert(0 && "FIXME: Chained agg assignment not implemented yet");
267 }
268}
269
270
271void CodeGenFunction::EmitAggConditionalOperator(const ConditionalOperator *E,
272 llvm::Value *DestPtr,
273 bool VolatileDest) {
274 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
275 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
276 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
277
278 llvm::Value *Cond = EvaluateExprAsBool(E->getCond());
279 Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
280
281 EmitBlock(LHSBlock);
282
283 // Handle the GNU extension for missing LHS.
284 assert(E->getLHS() && "Must have LHS for aggregate value");
285
286 EmitAggExpr(E->getLHS(), DestPtr, VolatileDest);
287 Builder.CreateBr(ContBlock);
288 LHSBlock = Builder.GetInsertBlock();
289
290 EmitBlock(RHSBlock);
291
292 EmitAggExpr(E->getRHS(), DestPtr, VolatileDest);
293 Builder.CreateBr(ContBlock);
294 RHSBlock = Builder.GetInsertBlock();
295
296 EmitBlock(ContBlock);
297}