blob: f0601cc5bd265a3934e5f75ef64cb805d311ba47 [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);
92 void VisitBinaryAssign(const BinaryOperator *E);
93
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 Lattner883f6a72007-08-11 00:04:45 +0000131 switch (E->getOpcode()) {
132 default:
133 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
134 E->dump();
135 return;
136#if 0
137 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());
186#endif
Chris Lattner9c033562007-08-21 04:25:47 +0000187 case BinaryOperator::Assign: return VisitBinaryAssign(E);
Chris Lattner883f6a72007-08-11 00:04:45 +0000188
189#if 0
190 case BinaryOperator::MulAssign: {
191 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
192 LValue LHSLV;
193 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
194 LHS = EmitMul(LHS, RHS, CAO->getComputationType());
195 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
196 }
197 case BinaryOperator::DivAssign: {
198 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
199 LValue LHSLV;
200 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
201 LHS = EmitDiv(LHS, RHS, CAO->getComputationType());
202 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
203 }
204 case BinaryOperator::RemAssign: {
205 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
206 LValue LHSLV;
207 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
208 LHS = EmitRem(LHS, RHS, CAO->getComputationType());
209 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
210 }
211 case BinaryOperator::AddAssign: {
212 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
213 LValue LHSLV;
214 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
215 LHS = EmitAdd(LHS, RHS, CAO->getComputationType());
216 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
217 }
218 case BinaryOperator::SubAssign: {
219 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
220 LValue LHSLV;
221 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
222 LHS = EmitSub(LHS, RHS, CAO->getComputationType());
223 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
224 }
225 case BinaryOperator::ShlAssign: {
226 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
227 LValue LHSLV;
228 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
229 LHS = EmitShl(LHS, RHS, CAO->getComputationType());
230 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
231 }
232 case BinaryOperator::ShrAssign: {
233 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
234 LValue LHSLV;
235 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
236 LHS = EmitShr(LHS, RHS, CAO->getComputationType());
237 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
238 }
239 case BinaryOperator::AndAssign: {
240 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
241 LValue LHSLV;
242 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
243 LHS = EmitAnd(LHS, RHS, CAO->getComputationType());
244 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
245 }
246 case BinaryOperator::OrAssign: {
247 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
248 LValue LHSLV;
249 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
250 LHS = EmitOr(LHS, RHS, CAO->getComputationType());
251 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
252 }
253 case BinaryOperator::XorAssign: {
254 const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
255 LValue LHSLV;
256 EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
257 LHS = EmitXor(LHS, RHS, CAO->getComputationType());
258 return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
259 }
260 case BinaryOperator::Comma: return EmitBinaryComma(E);
261#endif
262 }
263}
264
Chris Lattner9c033562007-08-21 04:25:47 +0000265void AggExprEmitter::VisitBinaryAssign(const BinaryOperator *E) {
Chris Lattner883f6a72007-08-11 00:04:45 +0000266 assert(E->getLHS()->getType().getCanonicalType() ==
267 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
Chris Lattner9c033562007-08-21 04:25:47 +0000268 LValue LHS = CGF.EmitLValue(E->getLHS());
Chris Lattner883f6a72007-08-11 00:04:45 +0000269
270 // Codegen the RHS so that it stores directly into the LHS.
Chris Lattner9c033562007-08-21 04:25:47 +0000271 CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
Chris Lattner883f6a72007-08-11 00:04:45 +0000272
273 // If the result of the assignment is used, copy the RHS there also.
274 if (DestPtr) {
275 assert(0 && "FIXME: Chained agg assignment not implemented yet");
276 }
277}
278
279
Chris Lattner9c033562007-08-21 04:25:47 +0000280void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
Chris Lattner883f6a72007-08-11 00:04:45 +0000281 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
282 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
283 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
284
Chris Lattner9c033562007-08-21 04:25:47 +0000285 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
286 CGF.Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000287
Chris Lattner9c033562007-08-21 04:25:47 +0000288 CGF.EmitBlock(LHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000289
290 // Handle the GNU extension for missing LHS.
291 assert(E->getLHS() && "Must have LHS for aggregate value");
292
Chris Lattner9c033562007-08-21 04:25:47 +0000293 CGF.EmitAggExpr(E->getLHS(), DestPtr, VolatileDest);
294 CGF.Builder.CreateBr(ContBlock);
295 LHSBlock =CGF. Builder.GetInsertBlock();
Chris Lattner883f6a72007-08-11 00:04:45 +0000296
Chris Lattner9c033562007-08-21 04:25:47 +0000297 CGF.EmitBlock(RHSBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000298
Chris Lattner9c033562007-08-21 04:25:47 +0000299 CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest);
300 CGF.Builder.CreateBr(ContBlock);
301 RHSBlock = CGF.Builder.GetInsertBlock();
Chris Lattner883f6a72007-08-11 00:04:45 +0000302
Chris Lattner9c033562007-08-21 04:25:47 +0000303 CGF.EmitBlock(ContBlock);
Chris Lattner883f6a72007-08-11 00:04:45 +0000304}