blob: 3555c8c9b6917cbda565e8a33eea4c5368377c85 [file] [log] [blame]
Chris Lattner566b6ce2007-08-24 02:22:53 +00001//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
Chris Lattnerb6ef18a2007-08-21 05:54:00 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattnerb6ef18a2007-08-21 05:54:00 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Expr nodes with complex types as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
Daniel Dunbarde7fb842008-08-11 05:00:27 +000016#include "clang/AST/ASTContext.h"
17#include "clang/AST/StmtVisitor.h"
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000018#include "llvm/Constants.h"
19#include "llvm/Function.h"
Chris Lattner6b5d0bf2007-08-26 22:47:40 +000020#include "llvm/ADT/SmallString.h"
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000021#include "llvm/Support/Compiler.h"
22using namespace clang;
23using namespace CodeGen;
24
25//===----------------------------------------------------------------------===//
Chris Lattner05ba49c2007-08-21 05:54:53 +000026// Complex Expression Emitter
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000027//===----------------------------------------------------------------------===//
28
Chris Lattner58dee102007-08-21 16:57:55 +000029typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000030
31namespace {
32class VISIBILITY_HIDDEN ComplexExprEmitter
33 : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
34 CodeGenFunction &CGF;
Daniel Dunbar45d196b2008-11-01 01:53:16 +000035 CGBuilderTy &Builder;
Mike Stump7f79f9b2009-05-29 15:46:01 +000036 // True is we should ignore the value of a
37 bool IgnoreReal;
38 bool IgnoreImag;
39 // True if we should ignore the value of a=b
40 bool IgnoreRealAssign;
41 bool IgnoreImagAssign;
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000042public:
Mike Stump7f79f9b2009-05-29 15:46:01 +000043 ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false,
44 bool irn=false, bool iin=false)
45 : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
46 IgnoreRealAssign(irn), IgnoreImagAssign(iin) {
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000047 }
48
49
50 //===--------------------------------------------------------------------===//
51 // Utilities
52 //===--------------------------------------------------------------------===//
53
Mike Stump7f79f9b2009-05-29 15:46:01 +000054 bool TestAndClearIgnoreReal() {
55 bool I = IgnoreReal;
56 IgnoreReal = false;
57 return I;
58 }
59 bool TestAndClearIgnoreImag() {
60 bool I = IgnoreImag;
61 IgnoreImag = false;
62 return I;
63 }
64 bool TestAndClearIgnoreRealAssign() {
65 bool I = IgnoreRealAssign;
66 IgnoreRealAssign = false;
67 return I;
68 }
69 bool TestAndClearIgnoreImagAssign() {
70 bool I = IgnoreImagAssign;
71 IgnoreImagAssign = false;
72 return I;
73 }
74
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000075 /// EmitLoadOfLValue - Given an expression with complex type that represents a
76 /// value l-value, this method emits the address of the l-value, then loads
77 /// and returns the result.
Chris Lattner46d7d9f2007-08-21 17:28:34 +000078 ComplexPairTy EmitLoadOfLValue(const Expr *E) {
Chris Lattner76e80332007-08-21 18:02:02 +000079 LValue LV = CGF.EmitLValue(E);
Daniel Dunbar42f963d2009-06-10 04:38:50 +000080 if (LV.isSimple())
81 return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
82
83 if (LV.isPropertyRef())
84 return CGF.EmitObjCPropertyGet(LV.getPropertyRefExpr()).getComplexVal();
85
86 assert(LV.isKVCRef() && "Unknown LValue type!");
87 return CGF.EmitObjCPropertyGet(LV.getKVCRefExpr()).getComplexVal();
Chris Lattner46d7d9f2007-08-21 17:28:34 +000088 }
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000089
Chris Lattner46d7d9f2007-08-21 17:28:34 +000090 /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
91 /// the real and imaginary pieces.
Chris Lattner76e80332007-08-21 18:02:02 +000092 ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
Chris Lattner46d7d9f2007-08-21 17:28:34 +000093
94 /// EmitStoreOfComplex - Store the specified real/imag parts into the
95 /// specified value pointer.
Chris Lattner76e80332007-08-21 18:02:02 +000096 void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000097
Chris Lattnerab340c22007-08-26 22:09:01 +000098 /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
99 ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
100 QualType DestType);
101
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000102 //===--------------------------------------------------------------------===//
103 // Visitor Methods
104 //===--------------------------------------------------------------------===//
Chris Lattner776c6492007-08-21 18:51:13 +0000105
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000106 ComplexPairTy VisitStmt(Stmt *S) {
Ted Kremenek7a9d49f2007-12-11 21:27:55 +0000107 S->dump(CGF.getContext().getSourceManager());
Chris Lattner776c6492007-08-21 18:51:13 +0000108 assert(0 && "Stmt can't have complex result type!");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000109 return ComplexPairTy();
110 }
Chris Lattner776c6492007-08-21 18:51:13 +0000111 ComplexPairTy VisitExpr(Expr *S);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000112 ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
Chris Lattnerd272ff02007-08-26 05:57:57 +0000113 ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
Chris Lattnerdb68f1b2007-08-26 03:51:12 +0000114
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000115 // l-values.
Chris Lattnerd272ff02007-08-26 05:57:57 +0000116 ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
Daniel Dunbar42f963d2009-06-10 04:38:50 +0000117 ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
118 return EmitLoadOfLValue(E);
119 }
120 ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
121 return EmitLoadOfLValue(E);
122 }
123 ComplexPairTy VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
124 return EmitLoadOfLValue(E);
125 }
126 ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
127 return CGF.EmitObjCMessageExpr(E).getComplexVal();
128 }
Chris Lattner8bcd7232007-08-21 18:03:58 +0000129 ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattnerd272ff02007-08-26 05:57:57 +0000130 ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000131
Chris Lattnere73e8e22007-08-21 22:33:41 +0000132 // FIXME: CompoundLiteralExpr
Chris Lattnerd272ff02007-08-26 05:57:57 +0000133
134 ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
135 ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
136 // Unlike for scalars, we don't have to worry about function->ptr demotion
137 // here.
138 return EmitCast(E->getSubExpr(), E->getType());
139 }
140 ComplexPairTy VisitCastExpr(CastExpr *E) {
141 return EmitCast(E->getSubExpr(), E->getType());
142 }
Chris Lattner419d25e2007-08-23 21:38:16 +0000143 ComplexPairTy VisitCallExpr(const CallExpr *E);
Chris Lattner7e20d092007-08-31 22:51:38 +0000144 ComplexPairTy VisitStmtExpr(const StmtExpr *E);
145
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000146 // Operators.
Chris Lattner3070f982007-08-21 22:25:29 +0000147 ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
148 bool isInc, bool isPre);
149 ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
150 return VisitPrePostIncDec(E, false, false);
151 }
152 ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
153 return VisitPrePostIncDec(E, true, false);
154 }
155 ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
156 return VisitPrePostIncDec(E, false, true);
157 }
158 ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
159 return VisitPrePostIncDec(E, true, true);
160 }
161 ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattnerfa2b9c92007-08-21 20:08:23 +0000162 ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) {
Mike Stump7f79f9b2009-05-29 15:46:01 +0000163 TestAndClearIgnoreReal();
164 TestAndClearIgnoreImag();
165 TestAndClearIgnoreRealAssign();
166 TestAndClearIgnoreImagAssign();
Chris Lattnerfa2b9c92007-08-21 20:08:23 +0000167 return Visit(E->getSubExpr());
168 }
169 ComplexPairTy VisitUnaryMinus (const UnaryOperator *E);
Chris Lattnere98a11c2007-08-21 20:41:44 +0000170 ComplexPairTy VisitUnaryNot (const UnaryOperator *E);
Sebastian Redl05189992008-11-11 17:56:53 +0000171 // LNot,Real,Imag never return complex.
Chris Lattnere98a11c2007-08-21 20:41:44 +0000172 ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
173 return Visit(E->getSubExpr());
174 }
Chris Lattner04421082008-04-08 04:40:51 +0000175 ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
176 return Visit(DAE->getExpr());
177 }
Anders Carlsson4b76b4f2009-05-31 00:12:05 +0000178 ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
179 return CGF.EmitCXXExprWithTemporaries(E).getComplexVal();
180 }
Argyrios Kyrtzidis7267f782008-08-23 19:35:47 +0000181 ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
182 assert(E->getType()->isAnyComplexType() && "Expected complex type!");
183 QualType Elem = E->getType()->getAsComplexType()->getElementType();
184 llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
185 return ComplexPairTy(Null, Null);
186 }
Douglas Gregor3498bdb2009-01-29 17:44:32 +0000187 ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
188 assert(E->getType()->isAnyComplexType() && "Expected complex type!");
189 QualType Elem = E->getType()->getAsComplexType()->getElementType();
190 llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
191 return ComplexPairTy(Null, Null);
192 }
Chris Lattnere98a11c2007-08-21 20:41:44 +0000193
Chris Lattnerab340c22007-08-26 22:09:01 +0000194 struct BinOpInfo {
195 ComplexPairTy LHS;
196 ComplexPairTy RHS;
197 QualType Ty; // Computation Type.
198 };
199
200 BinOpInfo EmitBinOps(const BinaryOperator *E);
201 ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
202 ComplexPairTy (ComplexExprEmitter::*Func)
203 (const BinOpInfo &));
204
205 ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
206 ComplexPairTy EmitBinSub(const BinOpInfo &Op);
207 ComplexPairTy EmitBinMul(const BinOpInfo &Op);
208 ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
209
210 ComplexPairTy VisitBinMul(const BinaryOperator *E) {
211 return EmitBinMul(EmitBinOps(E));
212 }
213 ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
214 return EmitBinAdd(EmitBinOps(E));
215 }
216 ComplexPairTy VisitBinSub(const BinaryOperator *E) {
217 return EmitBinSub(EmitBinOps(E));
218 }
219 ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
220 return EmitBinDiv(EmitBinOps(E));
221 }
222
223 // Compound assignments.
224 ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
225 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
226 }
227 ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
228 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
229 }
230 ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
231 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
232 }
233 ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
234 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
235 }
236
Chris Lattner612c40c2007-08-26 21:27:07 +0000237 // GCC rejects rem/and/or/xor for integer complex.
Chris Lattner4034edb2007-08-21 17:12:50 +0000238 // Logical and/or always return int, never complex.
Chris Lattner58dee102007-08-21 16:57:55 +0000239
240 // No comparisons produce a complex result.
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000241 ComplexPairTy VisitBinAssign (const BinaryOperator *E);
Chris Lattner756a4d82007-08-21 17:15:50 +0000242 ComplexPairTy VisitBinComma (const BinaryOperator *E);
243
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000244
245 ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
Chris Lattnerd0b12032007-08-24 02:18:47 +0000246 ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
Eli Friedmanc4777f12008-05-13 23:11:35 +0000247
248 ComplexPairTy VisitInitListExpr(InitListExpr *E);
Daniel Dunbar4e484b82009-02-10 03:03:30 +0000249
250 ComplexPairTy VisitVAArgExpr(VAArgExpr *E);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000251};
252} // end anonymous namespace.
253
254//===----------------------------------------------------------------------===//
255// Utilities
256//===----------------------------------------------------------------------===//
257
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000258/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
259/// load the real and imaginary pieces, returning them as Real/Imag.
Chris Lattner76e80332007-08-21 18:02:02 +0000260ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
261 bool isVolatile) {
Chris Lattner6b5d0bf2007-08-26 22:47:40 +0000262 llvm::SmallString<64> Name(SrcPtr->getNameStart(),
263 SrcPtr->getNameStart()+SrcPtr->getNameLen());
264
Mike Stump7f79f9b2009-05-29 15:46:01 +0000265 llvm::Value *Real=0, *Imag=0;
Chris Lattner6b5d0bf2007-08-26 22:47:40 +0000266
Mike Stump7f79f9b2009-05-29 15:46:01 +0000267 if (!IgnoreReal) {
268 Name += ".realp";
269 llvm::Value *RealPtr = Builder.CreateStructGEP(SrcPtr, 0, Name.c_str());
Ted Kremenekd6278892007-09-04 17:20:08 +0000270
Mike Stump7f79f9b2009-05-29 15:46:01 +0000271 Name.pop_back(); // .realp -> .real
272 Real = Builder.CreateLoad(RealPtr, isVolatile, Name.c_str());
273 Name.resize(Name.size()-4); // .real -> .imagp
274 }
275
276 if (!IgnoreImag) {
277 Name += "imagp";
278
279 llvm::Value *ImagPtr = Builder.CreateStructGEP(SrcPtr, 1, Name.c_str());
280
281 Name.pop_back(); // .imagp -> .imag
282 Imag = Builder.CreateLoad(ImagPtr, isVolatile, Name.c_str());
283 }
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000284 return ComplexPairTy(Real, Imag);
285}
286
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000287/// EmitStoreOfComplex - Store the specified real/imag parts into the
288/// specified value pointer.
Chris Lattner76e80332007-08-21 18:02:02 +0000289void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
290 bool isVolatile) {
Chris Lattner36b6a0a2008-03-19 05:19:41 +0000291 llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
292 llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000293
Chris Lattner76e80332007-08-21 18:02:02 +0000294 Builder.CreateStore(Val.first, RealPtr, isVolatile);
295 Builder.CreateStore(Val.second, ImagPtr, isVolatile);
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000296}
297
298
299
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000300//===----------------------------------------------------------------------===//
301// Visitor Methods
302//===----------------------------------------------------------------------===//
303
Chris Lattner776c6492007-08-21 18:51:13 +0000304ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
Daniel Dunbar488e9932008-08-16 00:56:44 +0000305 CGF.ErrorUnsupported(E, "complex expression");
Chris Lattner776c6492007-08-21 18:51:13 +0000306 const llvm::Type *EltTy =
307 CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
308 llvm::Value *U = llvm::UndefValue::get(EltTy);
309 return ComplexPairTy(U, U);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000310}
311
Chris Lattnerd272ff02007-08-26 05:57:57 +0000312ComplexPairTy ComplexExprEmitter::
313VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
Chris Lattnerdb68f1b2007-08-26 03:51:12 +0000314 llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
315 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
316}
317
318
Chris Lattner419d25e2007-08-23 21:38:16 +0000319ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
Anders Carlssone9f2f452009-05-27 03:37:57 +0000320 if (E->getCallReturnType()->isReferenceType())
321 return EmitLoadOfLValue(E);
322
Chris Lattner9b655512007-08-31 22:49:20 +0000323 return CGF.EmitCallExpr(E).getComplexVal();
Chris Lattner419d25e2007-08-23 21:38:16 +0000324}
325
Chris Lattner7e20d092007-08-31 22:51:38 +0000326ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
327 return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
328}
329
Chris Lattnerab340c22007-08-26 22:09:01 +0000330/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
331ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
332 QualType SrcType,
333 QualType DestType) {
334 // Get the src/dest element type.
Chris Lattner96196622008-07-26 22:37:01 +0000335 SrcType = SrcType->getAsComplexType()->getElementType();
336 DestType = DestType->getAsComplexType()->getElementType();
Chris Lattnerd272ff02007-08-26 05:57:57 +0000337
Daniel Dunbar56f0d162009-01-29 06:44:03 +0000338 // C99 6.3.1.6: When a value of complex type is converted to another
Daniel Dunbare12d8e32009-01-26 18:02:34 +0000339 // complex type, both the real and imaginary parts follow the conversion
Chris Lattnerab340c22007-08-26 22:09:01 +0000340 // rules for the corresponding real types.
341 Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
342 Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
343 return Val;
344}
345
346ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
Chris Lattnerd272ff02007-08-26 05:57:57 +0000347 // Two cases here: cast from (complex to complex) and (scalar to complex).
Chris Lattner9b2dc282008-04-04 16:54:41 +0000348 if (Op->getType()->isAnyComplexType())
Chris Lattnerab340c22007-08-26 22:09:01 +0000349 return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
350
Chris Lattnerd272ff02007-08-26 05:57:57 +0000351 // C99 6.3.1.7: When a value of real type is converted to a complex type, the
Eli Friedmanc110c542009-03-23 04:08:46 +0000352 // real part of the complex result value is determined by the rules of
Chris Lattnerd272ff02007-08-26 05:57:57 +0000353 // conversion to the corresponding real type and the imaginary part of the
354 // complex result value is a positive zero or an unsigned zero.
355 llvm::Value *Elt = CGF.EmitScalarExpr(Op);
356
357 // Convert the input element to the element type of the complex.
Chris Lattner96196622008-07-26 22:37:01 +0000358 DestTy = DestTy->getAsComplexType()->getElementType();
Chris Lattner3707b252007-08-26 06:48:56 +0000359 Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
Chris Lattnerd272ff02007-08-26 05:57:57 +0000360
361 // Return (realval, 0).
362 return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
363}
364
Chris Lattner3070f982007-08-21 22:25:29 +0000365ComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
366 bool isInc, bool isPre) {
367 LValue LV = CGF.EmitLValue(E->getSubExpr());
Chris Lattner87415d22009-06-17 06:36:24 +0000368 ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(),
369 LV.isVolatileQualified());
Chris Lattner3070f982007-08-21 22:25:29 +0000370
371 llvm::Value *NextVal;
Eli Friedmanc110c542009-03-23 04:08:46 +0000372 if (isa<llvm::IntegerType>(InVal.first->getType())) {
373 uint64_t AmountVal = isInc ? 1 : -1;
374 NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal, true);
Chris Lattner87415d22009-06-17 06:36:24 +0000375
376 // Add the inc/dec to the real part.
377 NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
378
Eli Friedmanc110c542009-03-23 04:08:46 +0000379 } else {
380 QualType ElemTy = E->getType()->getAsComplexType()->getElementType();
381 llvm::APFloat FVal(CGF.getContext().getFloatTypeSemantics(ElemTy), 1);
382 if (!isInc)
383 FVal.changeSign();
384 NextVal = llvm::ConstantFP::get(FVal);
Chris Lattner87415d22009-06-17 06:36:24 +0000385
386 // Add the inc/dec to the real part.
387 NextVal = Builder.CreateFAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
Chris Lattnerca2617c2007-09-13 06:19:18 +0000388 }
Chris Lattner3070f982007-08-21 22:25:29 +0000389
Chris Lattner3070f982007-08-21 22:25:29 +0000390 ComplexPairTy IncVal(NextVal, InVal.second);
391
392 // Store the updated result through the lvalue.
Eli Friedmanc110c542009-03-23 04:08:46 +0000393 EmitStoreOfComplex(IncVal, LV.getAddress(), LV.isVolatileQualified());
Chris Lattner3070f982007-08-21 22:25:29 +0000394
395 // If this is a postinc, return the value read from memory, otherwise use the
396 // updated value.
397 return isPre ? IncVal : InVal;
398}
399
Chris Lattnerfa2b9c92007-08-21 20:08:23 +0000400ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
Mike Stump7f79f9b2009-05-29 15:46:01 +0000401 TestAndClearIgnoreReal();
402 TestAndClearIgnoreImag();
403 TestAndClearIgnoreRealAssign();
404 TestAndClearIgnoreImagAssign();
Chris Lattnerfa2b9c92007-08-21 20:08:23 +0000405 ComplexPairTy Op = Visit(E->getSubExpr());
Chris Lattner87415d22009-06-17 06:36:24 +0000406
407 llvm::Value *ResR, *ResI;
408 if (Op.first->getType()->isFloatingPoint()) {
409 ResR = Builder.CreateFNeg(Op.first, "neg.r");
410 ResI = Builder.CreateFNeg(Op.second, "neg.i");
411 } else {
412 ResR = Builder.CreateNeg(Op.first, "neg.r");
413 ResI = Builder.CreateNeg(Op.second, "neg.i");
414 }
Chris Lattnerfa2b9c92007-08-21 20:08:23 +0000415 return ComplexPairTy(ResR, ResI);
416}
417
Chris Lattnere98a11c2007-08-21 20:41:44 +0000418ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
Mike Stump7f79f9b2009-05-29 15:46:01 +0000419 TestAndClearIgnoreReal();
420 TestAndClearIgnoreImag();
421 TestAndClearIgnoreRealAssign();
422 TestAndClearIgnoreImagAssign();
Chris Lattnere98a11c2007-08-21 20:41:44 +0000423 // ~(a+ib) = a + i*-b
424 ComplexPairTy Op = Visit(E->getSubExpr());
Chris Lattner87415d22009-06-17 06:36:24 +0000425 llvm::Value *ResI;
426 if (Op.second->getType()->isFloatingPoint())
427 ResI = Builder.CreateFNeg(Op.second, "conj.i");
428 else
429 ResI = Builder.CreateNeg(Op.second, "conj.i");
430
Chris Lattnere98a11c2007-08-21 20:41:44 +0000431 return ComplexPairTy(Op.first, ResI);
432}
Chris Lattnerfa2b9c92007-08-21 20:08:23 +0000433
Chris Lattnerab340c22007-08-26 22:09:01 +0000434ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
Chris Lattner87415d22009-06-17 06:36:24 +0000435 llvm::Value *ResR, *ResI;
436
437 if (Op.LHS.first->getType()->isFloatingPoint()) {
438 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r");
439 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
440 } else {
441 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r");
442 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
443 }
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000444 return ComplexPairTy(ResR, ResI);
445}
446
Chris Lattnerab340c22007-08-26 22:09:01 +0000447ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
Chris Lattner87415d22009-06-17 06:36:24 +0000448 llvm::Value *ResR, *ResI;
449 if (Op.LHS.first->getType()->isFloatingPoint()) {
450 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r");
451 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
452 } else {
453 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");
454 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
455 }
Chris Lattner6bc1ade2007-08-23 23:46:33 +0000456 return ComplexPairTy(ResR, ResI);
457}
458
459
Chris Lattnerab340c22007-08-26 22:09:01 +0000460ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
Chris Lattner87415d22009-06-17 06:36:24 +0000461 using llvm::Value;
462 Value *ResR, *ResI;
Chris Lattner2823c192007-08-21 16:34:16 +0000463
Chris Lattner87415d22009-06-17 06:36:24 +0000464 if (Op.LHS.first->getType()->isFloatingPoint()) {
465 Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");
466 Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr");
467 ResR = Builder.CreateFSub(ResRl, ResRr, "mul.r");
468
469 Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il");
470 Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");
471 ResI = Builder.CreateFAdd(ResIl, ResIr, "mul.i");
472 } else {
473 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
474 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
475 ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
476
477 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
478 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
479 ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
480 }
Chris Lattner2823c192007-08-21 16:34:16 +0000481 return ComplexPairTy(ResR, ResI);
482}
483
Chris Lattnerab340c22007-08-26 22:09:01 +0000484ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
485 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
486 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
Chris Lattner3219c5d2007-08-26 21:24:19 +0000487
Chris Lattner3219c5d2007-08-26 21:24:19 +0000488
489 llvm::Value *DSTr, *DSTi;
Chris Lattner87415d22009-06-17 06:36:24 +0000490 if (Op.LHS.first->getType()->isFloatingPoint()) {
491 // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
492 llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr, "tmp"); // a*c
493 llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi, "tmp"); // b*d
494 llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2, "tmp"); // ac+bd
495
496 llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr, "tmp"); // c*c
497 llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi, "tmp"); // d*d
498 llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5, "tmp"); // cc+dd
499
500 llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr, "tmp"); // b*c
501 llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi, "tmp"); // a*d
502 llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8, "tmp"); // bc-ad
503
Chris Lattner3219c5d2007-08-26 21:24:19 +0000504 DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
505 DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
506 } else {
Chris Lattner87415d22009-06-17 06:36:24 +0000507 // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
508 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
509 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
510 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
511
512 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
513 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
514 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
515
516 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
517 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
518 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
519
Chris Lattnerab340c22007-08-26 22:09:01 +0000520 if (Op.Ty->getAsComplexType()->getElementType()->isUnsignedIntegerType()) {
Chris Lattner3219c5d2007-08-26 21:24:19 +0000521 DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
522 DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
523 } else {
524 DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
525 DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
526 }
527 }
528
529 return ComplexPairTy(DSTr, DSTi);
530}
531
Chris Lattnerab340c22007-08-26 22:09:01 +0000532ComplexExprEmitter::BinOpInfo
533ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
Mike Stump7f79f9b2009-05-29 15:46:01 +0000534 TestAndClearIgnoreReal();
535 TestAndClearIgnoreImag();
536 TestAndClearIgnoreRealAssign();
537 TestAndClearIgnoreImagAssign();
Chris Lattnerab340c22007-08-26 22:09:01 +0000538 BinOpInfo Ops;
539 Ops.LHS = Visit(E->getLHS());
540 Ops.RHS = Visit(E->getRHS());
541 Ops.Ty = E->getType();
542 return Ops;
543}
544
545
546// Compound assignments.
547ComplexPairTy ComplexExprEmitter::
548EmitCompoundAssign(const CompoundAssignOperator *E,
549 ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
Mike Stump7f79f9b2009-05-29 15:46:01 +0000550 TestAndClearIgnoreReal();
551 TestAndClearIgnoreImag();
552 bool ignreal = TestAndClearIgnoreRealAssign();
553 bool ignimag = TestAndClearIgnoreImagAssign();
Chris Lattnerab340c22007-08-26 22:09:01 +0000554 QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
Chris Lattnerab340c22007-08-26 22:09:01 +0000555
556 BinOpInfo OpInfo;
Mike Stump7f79f9b2009-05-29 15:46:01 +0000557
558 // Load the RHS and LHS operands.
559 // __block variables need to have the rhs evaluated first, plus this should
560 // improve codegen a little. It is possible for the RHS to be complex or
561 // scalar.
Eli Friedmanab3a8522009-03-28 01:22:36 +0000562 OpInfo.Ty = E->getComputationResultType();
Chris Lattnerab340c22007-08-26 22:09:01 +0000563 OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
564
Mike Stump7f79f9b2009-05-29 15:46:01 +0000565 LValue LHSLV = CGF.EmitLValue(E->getLHS());
566
567
568 // We know the LHS is a complex lvalue.
569 OpInfo.LHS=EmitLoadOfComplex(LHSLV.getAddress(),LHSLV.isVolatileQualified());
570 OpInfo.LHS=EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty);
571
Chris Lattnerab340c22007-08-26 22:09:01 +0000572 // Expand the binary operator.
573 ComplexPairTy Result = (this->*Func)(OpInfo);
574
575 // Truncate the result back to the LHS type.
576 Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
577
578 // Store the result value into the LHS lvalue.
Eli Friedmanc110c542009-03-23 04:08:46 +0000579 EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified());
Mike Stump7f79f9b2009-05-29 15:46:01 +0000580 // And now return the LHS
581 IgnoreReal = ignreal;
582 IgnoreImag = ignimag;
583 IgnoreRealAssign = ignreal;
584 IgnoreImagAssign = ignimag;
585 return EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified());
Chris Lattnerab340c22007-08-26 22:09:01 +0000586}
Chris Lattner3219c5d2007-08-26 21:24:19 +0000587
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000588ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Mike Stump7f79f9b2009-05-29 15:46:01 +0000589 TestAndClearIgnoreReal();
590 TestAndClearIgnoreImag();
591 bool ignreal = TestAndClearIgnoreRealAssign();
592 bool ignimag = TestAndClearIgnoreImagAssign();
Chris Lattner96196622008-07-26 22:37:01 +0000593 assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
594 CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
595 "Invalid assignment");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000596 // Emit the RHS.
597 ComplexPairTy Val = Visit(E->getRHS());
598
599 // Compute the address to store into.
600 LValue LHS = CGF.EmitLValue(E->getLHS());
Daniel Dunbar42f963d2009-06-10 04:38:50 +0000601
602 // Store into it, if simple.
603 if (LHS.isSimple()) {
604 EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
605
606 // And now return the LHS
607 IgnoreReal = ignreal;
608 IgnoreImag = ignimag;
609 IgnoreRealAssign = ignreal;
610 IgnoreImagAssign = ignimag;
611 return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
612 }
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000613
Daniel Dunbar42f963d2009-06-10 04:38:50 +0000614 // Otherwise we must have a property setter (no complex vector/bitfields).
615 if (LHS.isPropertyRef())
616 CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val));
617 else
618 CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val));
619
620 // There is no reload after a store through a method, but we need to restore
621 // the Ignore* flags.
Mike Stump7f79f9b2009-05-29 15:46:01 +0000622 IgnoreReal = ignreal;
623 IgnoreImag = ignimag;
624 IgnoreRealAssign = ignreal;
625 IgnoreImagAssign = ignimag;
Daniel Dunbar42f963d2009-06-10 04:38:50 +0000626 return Val;
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000627}
628
Chris Lattner756a4d82007-08-21 17:15:50 +0000629ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
630 CGF.EmitStmt(E->getLHS());
Daniel Dunbara448fb22008-11-11 23:11:34 +0000631 CGF.EnsureInsertPoint();
Chris Lattner756a4d82007-08-21 17:15:50 +0000632 return Visit(E->getRHS());
633}
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000634
635ComplexPairTy ComplexExprEmitter::
636VisitConditionalOperator(const ConditionalOperator *E) {
Mike Stump7f79f9b2009-05-29 15:46:01 +0000637 TestAndClearIgnoreReal();
638 TestAndClearIgnoreImag();
639 TestAndClearIgnoreRealAssign();
640 TestAndClearIgnoreImagAssign();
Daniel Dunbar9615ecb2008-11-13 01:38:36 +0000641 llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
642 llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
643 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000644
645 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
Chris Lattner5083a532007-08-21 17:39:38 +0000646 Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000647
648 CGF.EmitBlock(LHSBlock);
649
650 // Handle the GNU extension for missing LHS.
Chris Lattner05ba49c2007-08-21 05:54:53 +0000651 assert(E->getLHS() && "Must have LHS for complex value");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000652
653 ComplexPairTy LHS = Visit(E->getLHS());
Chris Lattner5083a532007-08-21 17:39:38 +0000654 LHSBlock = Builder.GetInsertBlock();
Daniel Dunbard57a8712008-11-11 09:41:28 +0000655 CGF.EmitBranch(ContBlock);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000656
657 CGF.EmitBlock(RHSBlock);
658
659 ComplexPairTy RHS = Visit(E->getRHS());
Chris Lattner5083a532007-08-21 17:39:38 +0000660 RHSBlock = Builder.GetInsertBlock();
Daniel Dunbard57a8712008-11-11 09:41:28 +0000661 CGF.EmitBranch(ContBlock);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000662
663 CGF.EmitBlock(ContBlock);
664
665 // Create a PHI node for the real part.
Chris Lattner5083a532007-08-21 17:39:38 +0000666 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000667 RealPN->reserveOperandSpace(2);
668 RealPN->addIncoming(LHS.first, LHSBlock);
669 RealPN->addIncoming(RHS.first, RHSBlock);
670
671 // Create a PHI node for the imaginary part.
Chris Lattner5083a532007-08-21 17:39:38 +0000672 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000673 ImagPN->reserveOperandSpace(2);
674 ImagPN->addIncoming(LHS.second, LHSBlock);
675 ImagPN->addIncoming(RHS.second, RHSBlock);
676
677 return ComplexPairTy(RealPN, ImagPN);
678}
679
Chris Lattnerd0b12032007-08-24 02:18:47 +0000680ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
Eli Friedman79769322009-03-04 05:52:32 +0000681 return Visit(E->getChosenSubExpr(CGF.getContext()));
Chris Lattnerd0b12032007-08-24 02:18:47 +0000682}
683
Eli Friedmanc4777f12008-05-13 23:11:35 +0000684ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
Mike Stump7f79f9b2009-05-29 15:46:01 +0000685 bool Ignore = TestAndClearIgnoreReal();
686 (void)Ignore;
687 assert (Ignore == false && "init list ignored");
688 Ignore = TestAndClearIgnoreImag();
689 (void)Ignore;
690 assert (Ignore == false && "init list ignored");
Eli Friedmanc4777f12008-05-13 23:11:35 +0000691 if (E->getNumInits())
692 return Visit(E->getInit(0));
693
694 // Empty init list intializes to null
695 QualType Ty = E->getType()->getAsComplexType()->getElementType();
696 const llvm::Type* LTy = CGF.ConvertType(Ty);
697 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
698 return ComplexPairTy(zeroConstant, zeroConstant);
699}
700
Daniel Dunbar4e484b82009-02-10 03:03:30 +0000701ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
Daniel Dunbar07855702009-02-11 22:25:55 +0000702 llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr());
Daniel Dunbar4e484b82009-02-10 03:03:30 +0000703 llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType());
704
705 if (!ArgPtr) {
706 CGF.ErrorUnsupported(E, "complex va_arg expression");
707 const llvm::Type *EltTy =
708 CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
709 llvm::Value *U = llvm::UndefValue::get(EltTy);
710 return ComplexPairTy(U, U);
711 }
712
713 // FIXME Volatility.
714 return EmitLoadOfComplex(ArgPtr, false);
715}
716
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000717//===----------------------------------------------------------------------===//
718// Entry Point into this File
719//===----------------------------------------------------------------------===//
720
721/// EmitComplexExpr - Emit the computation of the specified expression of
722/// complex type, ignoring the result.
Mike Stump7f79f9b2009-05-29 15:46:01 +0000723ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal,
724 bool IgnoreImag, bool IgnoreRealAssign, bool IgnoreImagAssign) {
Chris Lattner9b2dc282008-04-04 16:54:41 +0000725 assert(E && E->getType()->isAnyComplexType() &&
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000726 "Invalid complex expression to emit");
727
Mike Stump7f79f9b2009-05-29 15:46:01 +0000728 return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag, IgnoreRealAssign,
729 IgnoreImagAssign)
730 .Visit(const_cast<Expr*>(E));
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000731}
732
Chris Lattner23b1cdb2007-08-23 23:43:33 +0000733/// EmitComplexExprIntoAddr - Emit the computation of the specified expression
734/// of complex type, storing into the specified Value*.
735void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
Chris Lattner190dbe22007-08-26 16:22:13 +0000736 llvm::Value *DestAddr,
737 bool DestIsVolatile) {
Chris Lattner9b2dc282008-04-04 16:54:41 +0000738 assert(E && E->getType()->isAnyComplexType() &&
Chris Lattner23b1cdb2007-08-23 23:43:33 +0000739 "Invalid complex expression to emit");
740 ComplexExprEmitter Emitter(*this);
741 ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
Chris Lattner190dbe22007-08-26 16:22:13 +0000742 Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile);
Chris Lattner23b1cdb2007-08-23 23:43:33 +0000743}
Chris Lattner9b655512007-08-31 22:49:20 +0000744
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000745/// StoreComplexToAddr - Store a complex number into the specified address.
746void CodeGenFunction::StoreComplexToAddr(ComplexPairTy V,
747 llvm::Value *DestAddr,
748 bool DestIsVolatile) {
749 ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile);
750}
751
Chris Lattner9b655512007-08-31 22:49:20 +0000752/// LoadComplexFromAddr - Load a complex number from the specified address.
753ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr,
754 bool SrcIsVolatile) {
755 return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile);
756}