xref: /minix3/external/bsd/llvm/dist/clang/lib/CodeGen/CGExprComplex.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc // This contains code to emit Expr nodes with complex types as LLVM code.
11*f4a2713aSLionel Sambuc //
12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13*f4a2713aSLionel Sambuc 
14*f4a2713aSLionel Sambuc #include "CodeGenFunction.h"
15*f4a2713aSLionel Sambuc #include "CodeGenModule.h"
16*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
17*f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
18*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
19*f4a2713aSLionel Sambuc #include "llvm/IR/Constants.h"
20*f4a2713aSLionel Sambuc #include "llvm/IR/Function.h"
21*f4a2713aSLionel Sambuc #include <algorithm>
22*f4a2713aSLionel Sambuc using namespace clang;
23*f4a2713aSLionel Sambuc using namespace CodeGen;
24*f4a2713aSLionel Sambuc 
25*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
26*f4a2713aSLionel Sambuc //                        Complex Expression Emitter
27*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
28*f4a2713aSLionel Sambuc 
29*f4a2713aSLionel Sambuc typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
30*f4a2713aSLionel Sambuc 
31*f4a2713aSLionel Sambuc /// Return the complex type that we are meant to emit.
32*f4a2713aSLionel Sambuc static const ComplexType *getComplexType(QualType type) {
33*f4a2713aSLionel Sambuc   type = type.getCanonicalType();
34*f4a2713aSLionel Sambuc   if (const ComplexType *comp = dyn_cast<ComplexType>(type)) {
35*f4a2713aSLionel Sambuc     return comp;
36*f4a2713aSLionel Sambuc   } else {
37*f4a2713aSLionel Sambuc     return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
38*f4a2713aSLionel Sambuc   }
39*f4a2713aSLionel Sambuc }
40*f4a2713aSLionel Sambuc 
41*f4a2713aSLionel Sambuc namespace  {
42*f4a2713aSLionel Sambuc class ComplexExprEmitter
43*f4a2713aSLionel Sambuc   : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
44*f4a2713aSLionel Sambuc   CodeGenFunction &CGF;
45*f4a2713aSLionel Sambuc   CGBuilderTy &Builder;
46*f4a2713aSLionel Sambuc   bool IgnoreReal;
47*f4a2713aSLionel Sambuc   bool IgnoreImag;
48*f4a2713aSLionel Sambuc public:
49*f4a2713aSLionel Sambuc   ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false)
50*f4a2713aSLionel Sambuc     : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) {
51*f4a2713aSLionel Sambuc   }
52*f4a2713aSLionel Sambuc 
53*f4a2713aSLionel Sambuc 
54*f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
55*f4a2713aSLionel Sambuc   //                               Utilities
56*f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
57*f4a2713aSLionel Sambuc 
58*f4a2713aSLionel Sambuc   bool TestAndClearIgnoreReal() {
59*f4a2713aSLionel Sambuc     bool I = IgnoreReal;
60*f4a2713aSLionel Sambuc     IgnoreReal = false;
61*f4a2713aSLionel Sambuc     return I;
62*f4a2713aSLionel Sambuc   }
63*f4a2713aSLionel Sambuc   bool TestAndClearIgnoreImag() {
64*f4a2713aSLionel Sambuc     bool I = IgnoreImag;
65*f4a2713aSLionel Sambuc     IgnoreImag = false;
66*f4a2713aSLionel Sambuc     return I;
67*f4a2713aSLionel Sambuc   }
68*f4a2713aSLionel Sambuc 
69*f4a2713aSLionel Sambuc   /// EmitLoadOfLValue - Given an expression with complex type that represents a
70*f4a2713aSLionel Sambuc   /// value l-value, this method emits the address of the l-value, then loads
71*f4a2713aSLionel Sambuc   /// and returns the result.
72*f4a2713aSLionel Sambuc   ComplexPairTy EmitLoadOfLValue(const Expr *E) {
73*f4a2713aSLionel Sambuc     return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc());
74*f4a2713aSLionel Sambuc   }
75*f4a2713aSLionel Sambuc 
76*f4a2713aSLionel Sambuc   ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc);
77*f4a2713aSLionel Sambuc 
78*f4a2713aSLionel Sambuc   /// EmitStoreOfComplex - Store the specified real/imag parts into the
79*f4a2713aSLionel Sambuc   /// specified value pointer.
80*f4a2713aSLionel Sambuc   void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit);
81*f4a2713aSLionel Sambuc 
82*f4a2713aSLionel Sambuc   /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
83*f4a2713aSLionel Sambuc   ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
84*f4a2713aSLionel Sambuc                                          QualType DestType);
85*f4a2713aSLionel Sambuc   /// EmitComplexToComplexCast - Emit a cast from scalar value Val to DestType.
86*f4a2713aSLionel Sambuc   ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
87*f4a2713aSLionel Sambuc                                         QualType DestType);
88*f4a2713aSLionel Sambuc 
89*f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
90*f4a2713aSLionel Sambuc   //                            Visitor Methods
91*f4a2713aSLionel Sambuc   //===--------------------------------------------------------------------===//
92*f4a2713aSLionel Sambuc 
93*f4a2713aSLionel Sambuc   ComplexPairTy Visit(Expr *E) {
94*f4a2713aSLionel Sambuc     return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E);
95*f4a2713aSLionel Sambuc   }
96*f4a2713aSLionel Sambuc 
97*f4a2713aSLionel Sambuc   ComplexPairTy VisitStmt(Stmt *S) {
98*f4a2713aSLionel Sambuc     S->dump(CGF.getContext().getSourceManager());
99*f4a2713aSLionel Sambuc     llvm_unreachable("Stmt can't have complex result type!");
100*f4a2713aSLionel Sambuc   }
101*f4a2713aSLionel Sambuc   ComplexPairTy VisitExpr(Expr *S);
102*f4a2713aSLionel Sambuc   ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
103*f4a2713aSLionel Sambuc   ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
104*f4a2713aSLionel Sambuc     return Visit(GE->getResultExpr());
105*f4a2713aSLionel Sambuc   }
106*f4a2713aSLionel Sambuc   ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
107*f4a2713aSLionel Sambuc   ComplexPairTy
108*f4a2713aSLionel Sambuc   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) {
109*f4a2713aSLionel Sambuc     return Visit(PE->getReplacement());
110*f4a2713aSLionel Sambuc   }
111*f4a2713aSLionel Sambuc 
112*f4a2713aSLionel Sambuc   // l-values.
113*f4a2713aSLionel Sambuc   ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
114*f4a2713aSLionel Sambuc     if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
115*f4a2713aSLionel Sambuc       if (result.isReference())
116*f4a2713aSLionel Sambuc         return EmitLoadOfLValue(result.getReferenceLValue(CGF, E),
117*f4a2713aSLionel Sambuc                                 E->getExprLoc());
118*f4a2713aSLionel Sambuc 
119*f4a2713aSLionel Sambuc       llvm::Constant *pair = result.getValue();
120*f4a2713aSLionel Sambuc       return ComplexPairTy(pair->getAggregateElement(0U),
121*f4a2713aSLionel Sambuc                            pair->getAggregateElement(1U));
122*f4a2713aSLionel Sambuc     }
123*f4a2713aSLionel Sambuc     return EmitLoadOfLValue(E);
124*f4a2713aSLionel Sambuc   }
125*f4a2713aSLionel Sambuc   ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
126*f4a2713aSLionel Sambuc     return EmitLoadOfLValue(E);
127*f4a2713aSLionel Sambuc   }
128*f4a2713aSLionel Sambuc   ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
129*f4a2713aSLionel Sambuc     return CGF.EmitObjCMessageExpr(E).getComplexVal();
130*f4a2713aSLionel Sambuc   }
131*f4a2713aSLionel Sambuc   ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
132*f4a2713aSLionel Sambuc   ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
133*f4a2713aSLionel Sambuc   ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) {
134*f4a2713aSLionel Sambuc     if (E->isGLValue())
135*f4a2713aSLionel Sambuc       return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc());
136*f4a2713aSLionel Sambuc     return CGF.getOpaqueRValueMapping(E).getComplexVal();
137*f4a2713aSLionel Sambuc   }
138*f4a2713aSLionel Sambuc 
139*f4a2713aSLionel Sambuc   ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) {
140*f4a2713aSLionel Sambuc     return CGF.EmitPseudoObjectRValue(E).getComplexVal();
141*f4a2713aSLionel Sambuc   }
142*f4a2713aSLionel Sambuc 
143*f4a2713aSLionel Sambuc   // FIXME: CompoundLiteralExpr
144*f4a2713aSLionel Sambuc 
145*f4a2713aSLionel Sambuc   ComplexPairTy EmitCast(CastExpr::CastKind CK, Expr *Op, QualType DestTy);
146*f4a2713aSLionel Sambuc   ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
147*f4a2713aSLionel Sambuc     // Unlike for scalars, we don't have to worry about function->ptr demotion
148*f4a2713aSLionel Sambuc     // here.
149*f4a2713aSLionel Sambuc     return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
150*f4a2713aSLionel Sambuc   }
151*f4a2713aSLionel Sambuc   ComplexPairTy VisitCastExpr(CastExpr *E) {
152*f4a2713aSLionel Sambuc     return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
153*f4a2713aSLionel Sambuc   }
154*f4a2713aSLionel Sambuc   ComplexPairTy VisitCallExpr(const CallExpr *E);
155*f4a2713aSLionel Sambuc   ComplexPairTy VisitStmtExpr(const StmtExpr *E);
156*f4a2713aSLionel Sambuc 
157*f4a2713aSLionel Sambuc   // Operators.
158*f4a2713aSLionel Sambuc   ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
159*f4a2713aSLionel Sambuc                                    bool isInc, bool isPre) {
160*f4a2713aSLionel Sambuc     LValue LV = CGF.EmitLValue(E->getSubExpr());
161*f4a2713aSLionel Sambuc     return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre);
162*f4a2713aSLionel Sambuc   }
163*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
164*f4a2713aSLionel Sambuc     return VisitPrePostIncDec(E, false, false);
165*f4a2713aSLionel Sambuc   }
166*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
167*f4a2713aSLionel Sambuc     return VisitPrePostIncDec(E, true, false);
168*f4a2713aSLionel Sambuc   }
169*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
170*f4a2713aSLionel Sambuc     return VisitPrePostIncDec(E, false, true);
171*f4a2713aSLionel Sambuc   }
172*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
173*f4a2713aSLionel Sambuc     return VisitPrePostIncDec(E, true, true);
174*f4a2713aSLionel Sambuc   }
175*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
176*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryPlus     (const UnaryOperator *E) {
177*f4a2713aSLionel Sambuc     TestAndClearIgnoreReal();
178*f4a2713aSLionel Sambuc     TestAndClearIgnoreImag();
179*f4a2713aSLionel Sambuc     return Visit(E->getSubExpr());
180*f4a2713aSLionel Sambuc   }
181*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryMinus    (const UnaryOperator *E);
182*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryNot      (const UnaryOperator *E);
183*f4a2713aSLionel Sambuc   // LNot,Real,Imag never return complex.
184*f4a2713aSLionel Sambuc   ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
185*f4a2713aSLionel Sambuc     return Visit(E->getSubExpr());
186*f4a2713aSLionel Sambuc   }
187*f4a2713aSLionel Sambuc   ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
188*f4a2713aSLionel Sambuc     return Visit(DAE->getExpr());
189*f4a2713aSLionel Sambuc   }
190*f4a2713aSLionel Sambuc   ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
191*f4a2713aSLionel Sambuc     CodeGenFunction::CXXDefaultInitExprScope Scope(CGF);
192*f4a2713aSLionel Sambuc     return Visit(DIE->getExpr());
193*f4a2713aSLionel Sambuc   }
194*f4a2713aSLionel Sambuc   ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) {
195*f4a2713aSLionel Sambuc     CGF.enterFullExpression(E);
196*f4a2713aSLionel Sambuc     CodeGenFunction::RunCleanupsScope Scope(CGF);
197*f4a2713aSLionel Sambuc     return Visit(E->getSubExpr());
198*f4a2713aSLionel Sambuc   }
199*f4a2713aSLionel Sambuc   ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
200*f4a2713aSLionel Sambuc     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
201*f4a2713aSLionel Sambuc     QualType Elem = E->getType()->castAs<ComplexType>()->getElementType();
202*f4a2713aSLionel Sambuc     llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
203*f4a2713aSLionel Sambuc     return ComplexPairTy(Null, Null);
204*f4a2713aSLionel Sambuc   }
205*f4a2713aSLionel Sambuc   ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
206*f4a2713aSLionel Sambuc     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
207*f4a2713aSLionel Sambuc     QualType Elem = E->getType()->castAs<ComplexType>()->getElementType();
208*f4a2713aSLionel Sambuc     llvm::Constant *Null =
209*f4a2713aSLionel Sambuc                        llvm::Constant::getNullValue(CGF.ConvertType(Elem));
210*f4a2713aSLionel Sambuc     return ComplexPairTy(Null, Null);
211*f4a2713aSLionel Sambuc   }
212*f4a2713aSLionel Sambuc 
213*f4a2713aSLionel Sambuc   struct BinOpInfo {
214*f4a2713aSLionel Sambuc     ComplexPairTy LHS;
215*f4a2713aSLionel Sambuc     ComplexPairTy RHS;
216*f4a2713aSLionel Sambuc     QualType Ty;  // Computation Type.
217*f4a2713aSLionel Sambuc   };
218*f4a2713aSLionel Sambuc 
219*f4a2713aSLionel Sambuc   BinOpInfo EmitBinOps(const BinaryOperator *E);
220*f4a2713aSLionel Sambuc   LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
221*f4a2713aSLionel Sambuc                                   ComplexPairTy (ComplexExprEmitter::*Func)
222*f4a2713aSLionel Sambuc                                   (const BinOpInfo &),
223*f4a2713aSLionel Sambuc                                   RValue &Val);
224*f4a2713aSLionel Sambuc   ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
225*f4a2713aSLionel Sambuc                                    ComplexPairTy (ComplexExprEmitter::*Func)
226*f4a2713aSLionel Sambuc                                    (const BinOpInfo &));
227*f4a2713aSLionel Sambuc 
228*f4a2713aSLionel Sambuc   ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
229*f4a2713aSLionel Sambuc   ComplexPairTy EmitBinSub(const BinOpInfo &Op);
230*f4a2713aSLionel Sambuc   ComplexPairTy EmitBinMul(const BinOpInfo &Op);
231*f4a2713aSLionel Sambuc   ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
232*f4a2713aSLionel Sambuc 
233*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
234*f4a2713aSLionel Sambuc     return EmitBinAdd(EmitBinOps(E));
235*f4a2713aSLionel Sambuc   }
236*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinSub(const BinaryOperator *E) {
237*f4a2713aSLionel Sambuc     return EmitBinSub(EmitBinOps(E));
238*f4a2713aSLionel Sambuc   }
239*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinMul(const BinaryOperator *E) {
240*f4a2713aSLionel Sambuc     return EmitBinMul(EmitBinOps(E));
241*f4a2713aSLionel Sambuc   }
242*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
243*f4a2713aSLionel Sambuc     return EmitBinDiv(EmitBinOps(E));
244*f4a2713aSLionel Sambuc   }
245*f4a2713aSLionel Sambuc 
246*f4a2713aSLionel Sambuc   // Compound assignments.
247*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
248*f4a2713aSLionel Sambuc     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
249*f4a2713aSLionel Sambuc   }
250*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
251*f4a2713aSLionel Sambuc     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
252*f4a2713aSLionel Sambuc   }
253*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
254*f4a2713aSLionel Sambuc     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
255*f4a2713aSLionel Sambuc   }
256*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
257*f4a2713aSLionel Sambuc     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
258*f4a2713aSLionel Sambuc   }
259*f4a2713aSLionel Sambuc 
260*f4a2713aSLionel Sambuc   // GCC rejects rem/and/or/xor for integer complex.
261*f4a2713aSLionel Sambuc   // Logical and/or always return int, never complex.
262*f4a2713aSLionel Sambuc 
263*f4a2713aSLionel Sambuc   // No comparisons produce a complex result.
264*f4a2713aSLionel Sambuc 
265*f4a2713aSLionel Sambuc   LValue EmitBinAssignLValue(const BinaryOperator *E,
266*f4a2713aSLionel Sambuc                              ComplexPairTy &Val);
267*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinAssign     (const BinaryOperator *E);
268*f4a2713aSLionel Sambuc   ComplexPairTy VisitBinComma      (const BinaryOperator *E);
269*f4a2713aSLionel Sambuc 
270*f4a2713aSLionel Sambuc 
271*f4a2713aSLionel Sambuc   ComplexPairTy
272*f4a2713aSLionel Sambuc   VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
273*f4a2713aSLionel Sambuc   ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
274*f4a2713aSLionel Sambuc 
275*f4a2713aSLionel Sambuc   ComplexPairTy VisitInitListExpr(InitListExpr *E);
276*f4a2713aSLionel Sambuc 
277*f4a2713aSLionel Sambuc   ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
278*f4a2713aSLionel Sambuc     return EmitLoadOfLValue(E);
279*f4a2713aSLionel Sambuc   }
280*f4a2713aSLionel Sambuc 
281*f4a2713aSLionel Sambuc   ComplexPairTy VisitVAArgExpr(VAArgExpr *E);
282*f4a2713aSLionel Sambuc 
283*f4a2713aSLionel Sambuc   ComplexPairTy VisitAtomicExpr(AtomicExpr *E) {
284*f4a2713aSLionel Sambuc     return CGF.EmitAtomicExpr(E).getComplexVal();
285*f4a2713aSLionel Sambuc   }
286*f4a2713aSLionel Sambuc };
287*f4a2713aSLionel Sambuc }  // end anonymous namespace.
288*f4a2713aSLionel Sambuc 
289*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
290*f4a2713aSLionel Sambuc //                                Utilities
291*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
292*f4a2713aSLionel Sambuc 
293*f4a2713aSLionel Sambuc /// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to
294*f4a2713aSLionel Sambuc /// load the real and imaginary pieces, returning them as Real/Imag.
295*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue,
296*f4a2713aSLionel Sambuc                                                    SourceLocation loc) {
297*f4a2713aSLionel Sambuc   assert(lvalue.isSimple() && "non-simple complex l-value?");
298*f4a2713aSLionel Sambuc   if (lvalue.getType()->isAtomicType())
299*f4a2713aSLionel Sambuc     return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal();
300*f4a2713aSLionel Sambuc 
301*f4a2713aSLionel Sambuc   llvm::Value *SrcPtr = lvalue.getAddress();
302*f4a2713aSLionel Sambuc   bool isVolatile = lvalue.isVolatileQualified();
303*f4a2713aSLionel Sambuc   unsigned AlignR = lvalue.getAlignment().getQuantity();
304*f4a2713aSLionel Sambuc   ASTContext &C = CGF.getContext();
305*f4a2713aSLionel Sambuc   QualType ComplexTy = lvalue.getType();
306*f4a2713aSLionel Sambuc   unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity();
307*f4a2713aSLionel Sambuc   unsigned AlignI = std::min(AlignR, ComplexAlign);
308*f4a2713aSLionel Sambuc 
309*f4a2713aSLionel Sambuc   llvm::Value *Real=0, *Imag=0;
310*f4a2713aSLionel Sambuc 
311*f4a2713aSLionel Sambuc   if (!IgnoreReal || isVolatile) {
312*f4a2713aSLionel Sambuc     llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,
313*f4a2713aSLionel Sambuc                                                  SrcPtr->getName() + ".realp");
314*f4a2713aSLionel Sambuc     Real = Builder.CreateAlignedLoad(RealP, AlignR, isVolatile,
315*f4a2713aSLionel Sambuc                                      SrcPtr->getName() + ".real");
316*f4a2713aSLionel Sambuc   }
317*f4a2713aSLionel Sambuc 
318*f4a2713aSLionel Sambuc   if (!IgnoreImag || isVolatile) {
319*f4a2713aSLionel Sambuc     llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1,
320*f4a2713aSLionel Sambuc                                                  SrcPtr->getName() + ".imagp");
321*f4a2713aSLionel Sambuc     Imag = Builder.CreateAlignedLoad(ImagP, AlignI, isVolatile,
322*f4a2713aSLionel Sambuc                                      SrcPtr->getName() + ".imag");
323*f4a2713aSLionel Sambuc   }
324*f4a2713aSLionel Sambuc   return ComplexPairTy(Real, Imag);
325*f4a2713aSLionel Sambuc }
326*f4a2713aSLionel Sambuc 
327*f4a2713aSLionel Sambuc /// EmitStoreOfComplex - Store the specified real/imag parts into the
328*f4a2713aSLionel Sambuc /// specified value pointer.
329*f4a2713aSLionel Sambuc void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val,
330*f4a2713aSLionel Sambuc                                             LValue lvalue,
331*f4a2713aSLionel Sambuc                                             bool isInit) {
332*f4a2713aSLionel Sambuc   if (lvalue.getType()->isAtomicType())
333*f4a2713aSLionel Sambuc     return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit);
334*f4a2713aSLionel Sambuc 
335*f4a2713aSLionel Sambuc   llvm::Value *Ptr = lvalue.getAddress();
336*f4a2713aSLionel Sambuc   llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
337*f4a2713aSLionel Sambuc   llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
338*f4a2713aSLionel Sambuc   unsigned AlignR = lvalue.getAlignment().getQuantity();
339*f4a2713aSLionel Sambuc   ASTContext &C = CGF.getContext();
340*f4a2713aSLionel Sambuc   QualType ComplexTy = lvalue.getType();
341*f4a2713aSLionel Sambuc   unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity();
342*f4a2713aSLionel Sambuc   unsigned AlignI = std::min(AlignR, ComplexAlign);
343*f4a2713aSLionel Sambuc 
344*f4a2713aSLionel Sambuc   Builder.CreateAlignedStore(Val.first, RealPtr, AlignR,
345*f4a2713aSLionel Sambuc                              lvalue.isVolatileQualified());
346*f4a2713aSLionel Sambuc   Builder.CreateAlignedStore(Val.second, ImagPtr, AlignI,
347*f4a2713aSLionel Sambuc                              lvalue.isVolatileQualified());
348*f4a2713aSLionel Sambuc }
349*f4a2713aSLionel Sambuc 
350*f4a2713aSLionel Sambuc 
351*f4a2713aSLionel Sambuc 
352*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
353*f4a2713aSLionel Sambuc //                            Visitor Methods
354*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
355*f4a2713aSLionel Sambuc 
356*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
357*f4a2713aSLionel Sambuc   CGF.ErrorUnsupported(E, "complex expression");
358*f4a2713aSLionel Sambuc   llvm::Type *EltTy =
359*f4a2713aSLionel Sambuc     CGF.ConvertType(getComplexType(E->getType())->getElementType());
360*f4a2713aSLionel Sambuc   llvm::Value *U = llvm::UndefValue::get(EltTy);
361*f4a2713aSLionel Sambuc   return ComplexPairTy(U, U);
362*f4a2713aSLionel Sambuc }
363*f4a2713aSLionel Sambuc 
364*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::
365*f4a2713aSLionel Sambuc VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
366*f4a2713aSLionel Sambuc   llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
367*f4a2713aSLionel Sambuc   return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
368*f4a2713aSLionel Sambuc }
369*f4a2713aSLionel Sambuc 
370*f4a2713aSLionel Sambuc 
371*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
372*f4a2713aSLionel Sambuc   if (E->getCallReturnType()->isReferenceType())
373*f4a2713aSLionel Sambuc     return EmitLoadOfLValue(E);
374*f4a2713aSLionel Sambuc 
375*f4a2713aSLionel Sambuc   return CGF.EmitCallExpr(E).getComplexVal();
376*f4a2713aSLionel Sambuc }
377*f4a2713aSLionel Sambuc 
378*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
379*f4a2713aSLionel Sambuc   CodeGenFunction::StmtExprEvaluation eval(CGF);
380*f4a2713aSLionel Sambuc   llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true);
381*f4a2713aSLionel Sambuc   assert(RetAlloca && "Expected complex return value");
382*f4a2713aSLionel Sambuc   return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()),
383*f4a2713aSLionel Sambuc                           E->getExprLoc());
384*f4a2713aSLionel Sambuc }
385*f4a2713aSLionel Sambuc 
386*f4a2713aSLionel Sambuc /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
387*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
388*f4a2713aSLionel Sambuc                                                            QualType SrcType,
389*f4a2713aSLionel Sambuc                                                            QualType DestType) {
390*f4a2713aSLionel Sambuc   // Get the src/dest element type.
391*f4a2713aSLionel Sambuc   SrcType = SrcType->castAs<ComplexType>()->getElementType();
392*f4a2713aSLionel Sambuc   DestType = DestType->castAs<ComplexType>()->getElementType();
393*f4a2713aSLionel Sambuc 
394*f4a2713aSLionel Sambuc   // C99 6.3.1.6: When a value of complex type is converted to another
395*f4a2713aSLionel Sambuc   // complex type, both the real and imaginary parts follow the conversion
396*f4a2713aSLionel Sambuc   // rules for the corresponding real types.
397*f4a2713aSLionel Sambuc   Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
398*f4a2713aSLionel Sambuc   Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
399*f4a2713aSLionel Sambuc   return Val;
400*f4a2713aSLionel Sambuc }
401*f4a2713aSLionel Sambuc 
402*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
403*f4a2713aSLionel Sambuc                                                           QualType SrcType,
404*f4a2713aSLionel Sambuc                                                           QualType DestType) {
405*f4a2713aSLionel Sambuc   // Convert the input element to the element type of the complex.
406*f4a2713aSLionel Sambuc   DestType = DestType->castAs<ComplexType>()->getElementType();
407*f4a2713aSLionel Sambuc   Val = CGF.EmitScalarConversion(Val, SrcType, DestType);
408*f4a2713aSLionel Sambuc 
409*f4a2713aSLionel Sambuc   // Return (realval, 0).
410*f4a2713aSLionel Sambuc   return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
411*f4a2713aSLionel Sambuc }
412*f4a2713aSLionel Sambuc 
413*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
414*f4a2713aSLionel Sambuc                                            QualType DestTy) {
415*f4a2713aSLionel Sambuc   switch (CK) {
416*f4a2713aSLionel Sambuc   case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
417*f4a2713aSLionel Sambuc 
418*f4a2713aSLionel Sambuc   // Atomic to non-atomic casts may be more than a no-op for some platforms and
419*f4a2713aSLionel Sambuc   // for some types.
420*f4a2713aSLionel Sambuc   case CK_AtomicToNonAtomic:
421*f4a2713aSLionel Sambuc   case CK_NonAtomicToAtomic:
422*f4a2713aSLionel Sambuc   case CK_NoOp:
423*f4a2713aSLionel Sambuc   case CK_LValueToRValue:
424*f4a2713aSLionel Sambuc   case CK_UserDefinedConversion:
425*f4a2713aSLionel Sambuc     return Visit(Op);
426*f4a2713aSLionel Sambuc 
427*f4a2713aSLionel Sambuc   case CK_LValueBitCast: {
428*f4a2713aSLionel Sambuc     LValue origLV = CGF.EmitLValue(Op);
429*f4a2713aSLionel Sambuc     llvm::Value *V = origLV.getAddress();
430*f4a2713aSLionel Sambuc     V = Builder.CreateBitCast(V,
431*f4a2713aSLionel Sambuc                     CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));
432*f4a2713aSLionel Sambuc     return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy,
433*f4a2713aSLionel Sambuc                                                origLV.getAlignment()),
434*f4a2713aSLionel Sambuc                             Op->getExprLoc());
435*f4a2713aSLionel Sambuc   }
436*f4a2713aSLionel Sambuc 
437*f4a2713aSLionel Sambuc   case CK_BitCast:
438*f4a2713aSLionel Sambuc   case CK_BaseToDerived:
439*f4a2713aSLionel Sambuc   case CK_DerivedToBase:
440*f4a2713aSLionel Sambuc   case CK_UncheckedDerivedToBase:
441*f4a2713aSLionel Sambuc   case CK_Dynamic:
442*f4a2713aSLionel Sambuc   case CK_ToUnion:
443*f4a2713aSLionel Sambuc   case CK_ArrayToPointerDecay:
444*f4a2713aSLionel Sambuc   case CK_FunctionToPointerDecay:
445*f4a2713aSLionel Sambuc   case CK_NullToPointer:
446*f4a2713aSLionel Sambuc   case CK_NullToMemberPointer:
447*f4a2713aSLionel Sambuc   case CK_BaseToDerivedMemberPointer:
448*f4a2713aSLionel Sambuc   case CK_DerivedToBaseMemberPointer:
449*f4a2713aSLionel Sambuc   case CK_MemberPointerToBoolean:
450*f4a2713aSLionel Sambuc   case CK_ReinterpretMemberPointer:
451*f4a2713aSLionel Sambuc   case CK_ConstructorConversion:
452*f4a2713aSLionel Sambuc   case CK_IntegralToPointer:
453*f4a2713aSLionel Sambuc   case CK_PointerToIntegral:
454*f4a2713aSLionel Sambuc   case CK_PointerToBoolean:
455*f4a2713aSLionel Sambuc   case CK_ToVoid:
456*f4a2713aSLionel Sambuc   case CK_VectorSplat:
457*f4a2713aSLionel Sambuc   case CK_IntegralCast:
458*f4a2713aSLionel Sambuc   case CK_IntegralToBoolean:
459*f4a2713aSLionel Sambuc   case CK_IntegralToFloating:
460*f4a2713aSLionel Sambuc   case CK_FloatingToIntegral:
461*f4a2713aSLionel Sambuc   case CK_FloatingToBoolean:
462*f4a2713aSLionel Sambuc   case CK_FloatingCast:
463*f4a2713aSLionel Sambuc   case CK_CPointerToObjCPointerCast:
464*f4a2713aSLionel Sambuc   case CK_BlockPointerToObjCPointerCast:
465*f4a2713aSLionel Sambuc   case CK_AnyPointerToBlockPointerCast:
466*f4a2713aSLionel Sambuc   case CK_ObjCObjectLValueCast:
467*f4a2713aSLionel Sambuc   case CK_FloatingComplexToReal:
468*f4a2713aSLionel Sambuc   case CK_FloatingComplexToBoolean:
469*f4a2713aSLionel Sambuc   case CK_IntegralComplexToReal:
470*f4a2713aSLionel Sambuc   case CK_IntegralComplexToBoolean:
471*f4a2713aSLionel Sambuc   case CK_ARCProduceObject:
472*f4a2713aSLionel Sambuc   case CK_ARCConsumeObject:
473*f4a2713aSLionel Sambuc   case CK_ARCReclaimReturnedObject:
474*f4a2713aSLionel Sambuc   case CK_ARCExtendBlockObject:
475*f4a2713aSLionel Sambuc   case CK_CopyAndAutoreleaseBlockObject:
476*f4a2713aSLionel Sambuc   case CK_BuiltinFnToFnPtr:
477*f4a2713aSLionel Sambuc   case CK_ZeroToOCLEvent:
478*f4a2713aSLionel Sambuc     llvm_unreachable("invalid cast kind for complex value");
479*f4a2713aSLionel Sambuc 
480*f4a2713aSLionel Sambuc   case CK_FloatingRealToComplex:
481*f4a2713aSLionel Sambuc   case CK_IntegralRealToComplex:
482*f4a2713aSLionel Sambuc     return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op),
483*f4a2713aSLionel Sambuc                                    Op->getType(), DestTy);
484*f4a2713aSLionel Sambuc 
485*f4a2713aSLionel Sambuc   case CK_FloatingComplexCast:
486*f4a2713aSLionel Sambuc   case CK_FloatingComplexToIntegralComplex:
487*f4a2713aSLionel Sambuc   case CK_IntegralComplexCast:
488*f4a2713aSLionel Sambuc   case CK_IntegralComplexToFloatingComplex:
489*f4a2713aSLionel Sambuc     return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
490*f4a2713aSLionel Sambuc   }
491*f4a2713aSLionel Sambuc 
492*f4a2713aSLionel Sambuc   llvm_unreachable("unknown cast resulting in complex value");
493*f4a2713aSLionel Sambuc }
494*f4a2713aSLionel Sambuc 
495*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
496*f4a2713aSLionel Sambuc   TestAndClearIgnoreReal();
497*f4a2713aSLionel Sambuc   TestAndClearIgnoreImag();
498*f4a2713aSLionel Sambuc   ComplexPairTy Op = Visit(E->getSubExpr());
499*f4a2713aSLionel Sambuc 
500*f4a2713aSLionel Sambuc   llvm::Value *ResR, *ResI;
501*f4a2713aSLionel Sambuc   if (Op.first->getType()->isFloatingPointTy()) {
502*f4a2713aSLionel Sambuc     ResR = Builder.CreateFNeg(Op.first,  "neg.r");
503*f4a2713aSLionel Sambuc     ResI = Builder.CreateFNeg(Op.second, "neg.i");
504*f4a2713aSLionel Sambuc   } else {
505*f4a2713aSLionel Sambuc     ResR = Builder.CreateNeg(Op.first,  "neg.r");
506*f4a2713aSLionel Sambuc     ResI = Builder.CreateNeg(Op.second, "neg.i");
507*f4a2713aSLionel Sambuc   }
508*f4a2713aSLionel Sambuc   return ComplexPairTy(ResR, ResI);
509*f4a2713aSLionel Sambuc }
510*f4a2713aSLionel Sambuc 
511*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
512*f4a2713aSLionel Sambuc   TestAndClearIgnoreReal();
513*f4a2713aSLionel Sambuc   TestAndClearIgnoreImag();
514*f4a2713aSLionel Sambuc   // ~(a+ib) = a + i*-b
515*f4a2713aSLionel Sambuc   ComplexPairTy Op = Visit(E->getSubExpr());
516*f4a2713aSLionel Sambuc   llvm::Value *ResI;
517*f4a2713aSLionel Sambuc   if (Op.second->getType()->isFloatingPointTy())
518*f4a2713aSLionel Sambuc     ResI = Builder.CreateFNeg(Op.second, "conj.i");
519*f4a2713aSLionel Sambuc   else
520*f4a2713aSLionel Sambuc     ResI = Builder.CreateNeg(Op.second, "conj.i");
521*f4a2713aSLionel Sambuc 
522*f4a2713aSLionel Sambuc   return ComplexPairTy(Op.first, ResI);
523*f4a2713aSLionel Sambuc }
524*f4a2713aSLionel Sambuc 
525*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
526*f4a2713aSLionel Sambuc   llvm::Value *ResR, *ResI;
527*f4a2713aSLionel Sambuc 
528*f4a2713aSLionel Sambuc   if (Op.LHS.first->getType()->isFloatingPointTy()) {
529*f4a2713aSLionel Sambuc     ResR = Builder.CreateFAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
530*f4a2713aSLionel Sambuc     ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
531*f4a2713aSLionel Sambuc   } else {
532*f4a2713aSLionel Sambuc     ResR = Builder.CreateAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
533*f4a2713aSLionel Sambuc     ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
534*f4a2713aSLionel Sambuc   }
535*f4a2713aSLionel Sambuc   return ComplexPairTy(ResR, ResI);
536*f4a2713aSLionel Sambuc }
537*f4a2713aSLionel Sambuc 
538*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
539*f4a2713aSLionel Sambuc   llvm::Value *ResR, *ResI;
540*f4a2713aSLionel Sambuc   if (Op.LHS.first->getType()->isFloatingPointTy()) {
541*f4a2713aSLionel Sambuc     ResR = Builder.CreateFSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
542*f4a2713aSLionel Sambuc     ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
543*f4a2713aSLionel Sambuc   } else {
544*f4a2713aSLionel Sambuc     ResR = Builder.CreateSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
545*f4a2713aSLionel Sambuc     ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
546*f4a2713aSLionel Sambuc   }
547*f4a2713aSLionel Sambuc   return ComplexPairTy(ResR, ResI);
548*f4a2713aSLionel Sambuc }
549*f4a2713aSLionel Sambuc 
550*f4a2713aSLionel Sambuc 
551*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
552*f4a2713aSLionel Sambuc   using llvm::Value;
553*f4a2713aSLionel Sambuc   Value *ResR, *ResI;
554*f4a2713aSLionel Sambuc 
555*f4a2713aSLionel Sambuc   if (Op.LHS.first->getType()->isFloatingPointTy()) {
556*f4a2713aSLionel Sambuc     Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");
557*f4a2713aSLionel Sambuc     Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr");
558*f4a2713aSLionel Sambuc     ResR  = Builder.CreateFSub(ResRl, ResRr, "mul.r");
559*f4a2713aSLionel Sambuc 
560*f4a2713aSLionel Sambuc     Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il");
561*f4a2713aSLionel Sambuc     Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");
562*f4a2713aSLionel Sambuc     ResI  = Builder.CreateFAdd(ResIl, ResIr, "mul.i");
563*f4a2713aSLionel Sambuc   } else {
564*f4a2713aSLionel Sambuc     Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
565*f4a2713aSLionel Sambuc     Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
566*f4a2713aSLionel Sambuc     ResR  = Builder.CreateSub(ResRl, ResRr, "mul.r");
567*f4a2713aSLionel Sambuc 
568*f4a2713aSLionel Sambuc     Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
569*f4a2713aSLionel Sambuc     Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
570*f4a2713aSLionel Sambuc     ResI  = Builder.CreateAdd(ResIl, ResIr, "mul.i");
571*f4a2713aSLionel Sambuc   }
572*f4a2713aSLionel Sambuc   return ComplexPairTy(ResR, ResI);
573*f4a2713aSLionel Sambuc }
574*f4a2713aSLionel Sambuc 
575*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
576*f4a2713aSLionel Sambuc   llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
577*f4a2713aSLionel Sambuc   llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
578*f4a2713aSLionel Sambuc 
579*f4a2713aSLionel Sambuc 
580*f4a2713aSLionel Sambuc   llvm::Value *DSTr, *DSTi;
581*f4a2713aSLionel Sambuc   if (Op.LHS.first->getType()->isFloatingPointTy()) {
582*f4a2713aSLionel Sambuc     // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
583*f4a2713aSLionel Sambuc     llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr); // a*c
584*f4a2713aSLionel Sambuc     llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi); // b*d
585*f4a2713aSLionel Sambuc     llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2); // ac+bd
586*f4a2713aSLionel Sambuc 
587*f4a2713aSLionel Sambuc     llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr); // c*c
588*f4a2713aSLionel Sambuc     llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi); // d*d
589*f4a2713aSLionel Sambuc     llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5); // cc+dd
590*f4a2713aSLionel Sambuc 
591*f4a2713aSLionel Sambuc     llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr); // b*c
592*f4a2713aSLionel Sambuc     llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi); // a*d
593*f4a2713aSLionel Sambuc     llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8); // bc-ad
594*f4a2713aSLionel Sambuc 
595*f4a2713aSLionel Sambuc     DSTr = Builder.CreateFDiv(Tmp3, Tmp6);
596*f4a2713aSLionel Sambuc     DSTi = Builder.CreateFDiv(Tmp9, Tmp6);
597*f4a2713aSLionel Sambuc   } else {
598*f4a2713aSLionel Sambuc     // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
599*f4a2713aSLionel Sambuc     llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c
600*f4a2713aSLionel Sambuc     llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d
601*f4a2713aSLionel Sambuc     llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd
602*f4a2713aSLionel Sambuc 
603*f4a2713aSLionel Sambuc     llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c
604*f4a2713aSLionel Sambuc     llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d
605*f4a2713aSLionel Sambuc     llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd
606*f4a2713aSLionel Sambuc 
607*f4a2713aSLionel Sambuc     llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c
608*f4a2713aSLionel Sambuc     llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d
609*f4a2713aSLionel Sambuc     llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad
610*f4a2713aSLionel Sambuc 
611*f4a2713aSLionel Sambuc     if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) {
612*f4a2713aSLionel Sambuc       DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
613*f4a2713aSLionel Sambuc       DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
614*f4a2713aSLionel Sambuc     } else {
615*f4a2713aSLionel Sambuc       DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
616*f4a2713aSLionel Sambuc       DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
617*f4a2713aSLionel Sambuc     }
618*f4a2713aSLionel Sambuc   }
619*f4a2713aSLionel Sambuc 
620*f4a2713aSLionel Sambuc   return ComplexPairTy(DSTr, DSTi);
621*f4a2713aSLionel Sambuc }
622*f4a2713aSLionel Sambuc 
623*f4a2713aSLionel Sambuc ComplexExprEmitter::BinOpInfo
624*f4a2713aSLionel Sambuc ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
625*f4a2713aSLionel Sambuc   TestAndClearIgnoreReal();
626*f4a2713aSLionel Sambuc   TestAndClearIgnoreImag();
627*f4a2713aSLionel Sambuc   BinOpInfo Ops;
628*f4a2713aSLionel Sambuc   Ops.LHS = Visit(E->getLHS());
629*f4a2713aSLionel Sambuc   Ops.RHS = Visit(E->getRHS());
630*f4a2713aSLionel Sambuc   Ops.Ty = E->getType();
631*f4a2713aSLionel Sambuc   return Ops;
632*f4a2713aSLionel Sambuc }
633*f4a2713aSLionel Sambuc 
634*f4a2713aSLionel Sambuc 
635*f4a2713aSLionel Sambuc LValue ComplexExprEmitter::
636*f4a2713aSLionel Sambuc EmitCompoundAssignLValue(const CompoundAssignOperator *E,
637*f4a2713aSLionel Sambuc           ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&),
638*f4a2713aSLionel Sambuc                          RValue &Val) {
639*f4a2713aSLionel Sambuc   TestAndClearIgnoreReal();
640*f4a2713aSLionel Sambuc   TestAndClearIgnoreImag();
641*f4a2713aSLionel Sambuc   QualType LHSTy = E->getLHS()->getType();
642*f4a2713aSLionel Sambuc 
643*f4a2713aSLionel Sambuc   BinOpInfo OpInfo;
644*f4a2713aSLionel Sambuc 
645*f4a2713aSLionel Sambuc   // Load the RHS and LHS operands.
646*f4a2713aSLionel Sambuc   // __block variables need to have the rhs evaluated first, plus this should
647*f4a2713aSLionel Sambuc   // improve codegen a little.
648*f4a2713aSLionel Sambuc   OpInfo.Ty = E->getComputationResultType();
649*f4a2713aSLionel Sambuc 
650*f4a2713aSLionel Sambuc   // The RHS should have been converted to the computation type.
651*f4a2713aSLionel Sambuc   assert(OpInfo.Ty->isAnyComplexType());
652*f4a2713aSLionel Sambuc   assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty,
653*f4a2713aSLionel Sambuc                                                  E->getRHS()->getType()));
654*f4a2713aSLionel Sambuc   OpInfo.RHS = Visit(E->getRHS());
655*f4a2713aSLionel Sambuc 
656*f4a2713aSLionel Sambuc   LValue LHS = CGF.EmitLValue(E->getLHS());
657*f4a2713aSLionel Sambuc 
658*f4a2713aSLionel Sambuc   // Load from the l-value and convert it.
659*f4a2713aSLionel Sambuc   if (LHSTy->isAnyComplexType()) {
660*f4a2713aSLionel Sambuc     ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, E->getExprLoc());
661*f4a2713aSLionel Sambuc     OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
662*f4a2713aSLionel Sambuc   } else {
663*f4a2713aSLionel Sambuc     llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, E->getExprLoc());
664*f4a2713aSLionel Sambuc     OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
665*f4a2713aSLionel Sambuc   }
666*f4a2713aSLionel Sambuc 
667*f4a2713aSLionel Sambuc   // Expand the binary operator.
668*f4a2713aSLionel Sambuc   ComplexPairTy Result = (this->*Func)(OpInfo);
669*f4a2713aSLionel Sambuc 
670*f4a2713aSLionel Sambuc   // Truncate the result and store it into the LHS lvalue.
671*f4a2713aSLionel Sambuc   if (LHSTy->isAnyComplexType()) {
672*f4a2713aSLionel Sambuc     ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
673*f4a2713aSLionel Sambuc     EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
674*f4a2713aSLionel Sambuc     Val = RValue::getComplex(ResVal);
675*f4a2713aSLionel Sambuc   } else {
676*f4a2713aSLionel Sambuc     llvm::Value *ResVal =
677*f4a2713aSLionel Sambuc         CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy);
678*f4a2713aSLionel Sambuc     CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
679*f4a2713aSLionel Sambuc     Val = RValue::get(ResVal);
680*f4a2713aSLionel Sambuc   }
681*f4a2713aSLionel Sambuc 
682*f4a2713aSLionel Sambuc   return LHS;
683*f4a2713aSLionel Sambuc }
684*f4a2713aSLionel Sambuc 
685*f4a2713aSLionel Sambuc // Compound assignments.
686*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::
687*f4a2713aSLionel Sambuc EmitCompoundAssign(const CompoundAssignOperator *E,
688*f4a2713aSLionel Sambuc                    ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
689*f4a2713aSLionel Sambuc   RValue Val;
690*f4a2713aSLionel Sambuc   LValue LV = EmitCompoundAssignLValue(E, Func, Val);
691*f4a2713aSLionel Sambuc 
692*f4a2713aSLionel Sambuc   // The result of an assignment in C is the assigned r-value.
693*f4a2713aSLionel Sambuc   if (!CGF.getLangOpts().CPlusPlus)
694*f4a2713aSLionel Sambuc     return Val.getComplexVal();
695*f4a2713aSLionel Sambuc 
696*f4a2713aSLionel Sambuc   // If the lvalue is non-volatile, return the computed value of the assignment.
697*f4a2713aSLionel Sambuc   if (!LV.isVolatileQualified())
698*f4a2713aSLionel Sambuc     return Val.getComplexVal();
699*f4a2713aSLionel Sambuc 
700*f4a2713aSLionel Sambuc   return EmitLoadOfLValue(LV, E->getExprLoc());
701*f4a2713aSLionel Sambuc }
702*f4a2713aSLionel Sambuc 
703*f4a2713aSLionel Sambuc LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E,
704*f4a2713aSLionel Sambuc                                                ComplexPairTy &Val) {
705*f4a2713aSLionel Sambuc   assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
706*f4a2713aSLionel Sambuc                                                  E->getRHS()->getType()) &&
707*f4a2713aSLionel Sambuc          "Invalid assignment");
708*f4a2713aSLionel Sambuc   TestAndClearIgnoreReal();
709*f4a2713aSLionel Sambuc   TestAndClearIgnoreImag();
710*f4a2713aSLionel Sambuc 
711*f4a2713aSLionel Sambuc   // Emit the RHS.  __block variables need the RHS evaluated first.
712*f4a2713aSLionel Sambuc   Val = Visit(E->getRHS());
713*f4a2713aSLionel Sambuc 
714*f4a2713aSLionel Sambuc   // Compute the address to store into.
715*f4a2713aSLionel Sambuc   LValue LHS = CGF.EmitLValue(E->getLHS());
716*f4a2713aSLionel Sambuc 
717*f4a2713aSLionel Sambuc   // Store the result value into the LHS lvalue.
718*f4a2713aSLionel Sambuc   EmitStoreOfComplex(Val, LHS, /*isInit*/ false);
719*f4a2713aSLionel Sambuc 
720*f4a2713aSLionel Sambuc   return LHS;
721*f4a2713aSLionel Sambuc }
722*f4a2713aSLionel Sambuc 
723*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
724*f4a2713aSLionel Sambuc   ComplexPairTy Val;
725*f4a2713aSLionel Sambuc   LValue LV = EmitBinAssignLValue(E, Val);
726*f4a2713aSLionel Sambuc 
727*f4a2713aSLionel Sambuc   // The result of an assignment in C is the assigned r-value.
728*f4a2713aSLionel Sambuc   if (!CGF.getLangOpts().CPlusPlus)
729*f4a2713aSLionel Sambuc     return Val;
730*f4a2713aSLionel Sambuc 
731*f4a2713aSLionel Sambuc   // If the lvalue is non-volatile, return the computed value of the assignment.
732*f4a2713aSLionel Sambuc   if (!LV.isVolatileQualified())
733*f4a2713aSLionel Sambuc     return Val;
734*f4a2713aSLionel Sambuc 
735*f4a2713aSLionel Sambuc   return EmitLoadOfLValue(LV, E->getExprLoc());
736*f4a2713aSLionel Sambuc }
737*f4a2713aSLionel Sambuc 
738*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
739*f4a2713aSLionel Sambuc   CGF.EmitIgnoredExpr(E->getLHS());
740*f4a2713aSLionel Sambuc   return Visit(E->getRHS());
741*f4a2713aSLionel Sambuc }
742*f4a2713aSLionel Sambuc 
743*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::
744*f4a2713aSLionel Sambuc VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
745*f4a2713aSLionel Sambuc   TestAndClearIgnoreReal();
746*f4a2713aSLionel Sambuc   TestAndClearIgnoreImag();
747*f4a2713aSLionel Sambuc   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
748*f4a2713aSLionel Sambuc   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
749*f4a2713aSLionel Sambuc   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
750*f4a2713aSLionel Sambuc 
751*f4a2713aSLionel Sambuc   // Bind the common expression if necessary.
752*f4a2713aSLionel Sambuc   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
753*f4a2713aSLionel Sambuc 
754*f4a2713aSLionel Sambuc   CodeGenFunction::ConditionalEvaluation eval(CGF);
755*f4a2713aSLionel Sambuc   CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
756*f4a2713aSLionel Sambuc 
757*f4a2713aSLionel Sambuc   eval.begin(CGF);
758*f4a2713aSLionel Sambuc   CGF.EmitBlock(LHSBlock);
759*f4a2713aSLionel Sambuc   ComplexPairTy LHS = Visit(E->getTrueExpr());
760*f4a2713aSLionel Sambuc   LHSBlock = Builder.GetInsertBlock();
761*f4a2713aSLionel Sambuc   CGF.EmitBranch(ContBlock);
762*f4a2713aSLionel Sambuc   eval.end(CGF);
763*f4a2713aSLionel Sambuc 
764*f4a2713aSLionel Sambuc   eval.begin(CGF);
765*f4a2713aSLionel Sambuc   CGF.EmitBlock(RHSBlock);
766*f4a2713aSLionel Sambuc   ComplexPairTy RHS = Visit(E->getFalseExpr());
767*f4a2713aSLionel Sambuc   RHSBlock = Builder.GetInsertBlock();
768*f4a2713aSLionel Sambuc   CGF.EmitBlock(ContBlock);
769*f4a2713aSLionel Sambuc   eval.end(CGF);
770*f4a2713aSLionel Sambuc 
771*f4a2713aSLionel Sambuc   // Create a PHI node for the real part.
772*f4a2713aSLionel Sambuc   llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r");
773*f4a2713aSLionel Sambuc   RealPN->addIncoming(LHS.first, LHSBlock);
774*f4a2713aSLionel Sambuc   RealPN->addIncoming(RHS.first, RHSBlock);
775*f4a2713aSLionel Sambuc 
776*f4a2713aSLionel Sambuc   // Create a PHI node for the imaginary part.
777*f4a2713aSLionel Sambuc   llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i");
778*f4a2713aSLionel Sambuc   ImagPN->addIncoming(LHS.second, LHSBlock);
779*f4a2713aSLionel Sambuc   ImagPN->addIncoming(RHS.second, RHSBlock);
780*f4a2713aSLionel Sambuc 
781*f4a2713aSLionel Sambuc   return ComplexPairTy(RealPN, ImagPN);
782*f4a2713aSLionel Sambuc }
783*f4a2713aSLionel Sambuc 
784*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
785*f4a2713aSLionel Sambuc   return Visit(E->getChosenSubExpr());
786*f4a2713aSLionel Sambuc }
787*f4a2713aSLionel Sambuc 
788*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
789*f4a2713aSLionel Sambuc     bool Ignore = TestAndClearIgnoreReal();
790*f4a2713aSLionel Sambuc     (void)Ignore;
791*f4a2713aSLionel Sambuc     assert (Ignore == false && "init list ignored");
792*f4a2713aSLionel Sambuc     Ignore = TestAndClearIgnoreImag();
793*f4a2713aSLionel Sambuc     (void)Ignore;
794*f4a2713aSLionel Sambuc     assert (Ignore == false && "init list ignored");
795*f4a2713aSLionel Sambuc 
796*f4a2713aSLionel Sambuc   if (E->getNumInits() == 2) {
797*f4a2713aSLionel Sambuc     llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0));
798*f4a2713aSLionel Sambuc     llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1));
799*f4a2713aSLionel Sambuc     return ComplexPairTy(Real, Imag);
800*f4a2713aSLionel Sambuc   } else if (E->getNumInits() == 1) {
801*f4a2713aSLionel Sambuc     return Visit(E->getInit(0));
802*f4a2713aSLionel Sambuc   }
803*f4a2713aSLionel Sambuc 
804*f4a2713aSLionel Sambuc   // Empty init list intializes to null
805*f4a2713aSLionel Sambuc   assert(E->getNumInits() == 0 && "Unexpected number of inits");
806*f4a2713aSLionel Sambuc   QualType Ty = E->getType()->castAs<ComplexType>()->getElementType();
807*f4a2713aSLionel Sambuc   llvm::Type* LTy = CGF.ConvertType(Ty);
808*f4a2713aSLionel Sambuc   llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
809*f4a2713aSLionel Sambuc   return ComplexPairTy(zeroConstant, zeroConstant);
810*f4a2713aSLionel Sambuc }
811*f4a2713aSLionel Sambuc 
812*f4a2713aSLionel Sambuc ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
813*f4a2713aSLionel Sambuc   llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr());
814*f4a2713aSLionel Sambuc   llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType());
815*f4a2713aSLionel Sambuc 
816*f4a2713aSLionel Sambuc   if (!ArgPtr) {
817*f4a2713aSLionel Sambuc     CGF.ErrorUnsupported(E, "complex va_arg expression");
818*f4a2713aSLionel Sambuc     llvm::Type *EltTy =
819*f4a2713aSLionel Sambuc       CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType());
820*f4a2713aSLionel Sambuc     llvm::Value *U = llvm::UndefValue::get(EltTy);
821*f4a2713aSLionel Sambuc     return ComplexPairTy(U, U);
822*f4a2713aSLionel Sambuc   }
823*f4a2713aSLionel Sambuc 
824*f4a2713aSLionel Sambuc   return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(ArgPtr, E->getType()),
825*f4a2713aSLionel Sambuc                           E->getExprLoc());
826*f4a2713aSLionel Sambuc }
827*f4a2713aSLionel Sambuc 
828*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
829*f4a2713aSLionel Sambuc //                         Entry Point into this File
830*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
831*f4a2713aSLionel Sambuc 
832*f4a2713aSLionel Sambuc /// EmitComplexExpr - Emit the computation of the specified expression of
833*f4a2713aSLionel Sambuc /// complex type, ignoring the result.
834*f4a2713aSLionel Sambuc ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal,
835*f4a2713aSLionel Sambuc                                                bool IgnoreImag) {
836*f4a2713aSLionel Sambuc   assert(E && getComplexType(E->getType()) &&
837*f4a2713aSLionel Sambuc          "Invalid complex expression to emit");
838*f4a2713aSLionel Sambuc 
839*f4a2713aSLionel Sambuc   return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag)
840*f4a2713aSLionel Sambuc     .Visit(const_cast<Expr*>(E));
841*f4a2713aSLionel Sambuc }
842*f4a2713aSLionel Sambuc 
843*f4a2713aSLionel Sambuc void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest,
844*f4a2713aSLionel Sambuc                                                 bool isInit) {
845*f4a2713aSLionel Sambuc   assert(E && getComplexType(E->getType()) &&
846*f4a2713aSLionel Sambuc          "Invalid complex expression to emit");
847*f4a2713aSLionel Sambuc   ComplexExprEmitter Emitter(*this);
848*f4a2713aSLionel Sambuc   ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
849*f4a2713aSLionel Sambuc   Emitter.EmitStoreOfComplex(Val, dest, isInit);
850*f4a2713aSLionel Sambuc }
851*f4a2713aSLionel Sambuc 
852*f4a2713aSLionel Sambuc /// EmitStoreOfComplex - Store a complex number into the specified l-value.
853*f4a2713aSLionel Sambuc void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest,
854*f4a2713aSLionel Sambuc                                          bool isInit) {
855*f4a2713aSLionel Sambuc   ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit);
856*f4a2713aSLionel Sambuc }
857*f4a2713aSLionel Sambuc 
858*f4a2713aSLionel Sambuc /// EmitLoadOfComplex - Load a complex number from the specified address.
859*f4a2713aSLionel Sambuc ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src,
860*f4a2713aSLionel Sambuc                                                  SourceLocation loc) {
861*f4a2713aSLionel Sambuc   return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
862*f4a2713aSLionel Sambuc }
863*f4a2713aSLionel Sambuc 
864*f4a2713aSLionel Sambuc LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) {
865*f4a2713aSLionel Sambuc   assert(E->getOpcode() == BO_Assign);
866*f4a2713aSLionel Sambuc   ComplexPairTy Val; // ignored
867*f4a2713aSLionel Sambuc   return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
868*f4a2713aSLionel Sambuc }
869*f4a2713aSLionel Sambuc 
870*f4a2713aSLionel Sambuc typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)(
871*f4a2713aSLionel Sambuc     const ComplexExprEmitter::BinOpInfo &);
872*f4a2713aSLionel Sambuc 
873*f4a2713aSLionel Sambuc static CompoundFunc getComplexOp(BinaryOperatorKind Op) {
874*f4a2713aSLionel Sambuc   switch (Op) {
875*f4a2713aSLionel Sambuc   case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul;
876*f4a2713aSLionel Sambuc   case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv;
877*f4a2713aSLionel Sambuc   case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub;
878*f4a2713aSLionel Sambuc   case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd;
879*f4a2713aSLionel Sambuc   default:
880*f4a2713aSLionel Sambuc     llvm_unreachable("unexpected complex compound assignment");
881*f4a2713aSLionel Sambuc   }
882*f4a2713aSLionel Sambuc }
883*f4a2713aSLionel Sambuc 
884*f4a2713aSLionel Sambuc LValue CodeGenFunction::
885*f4a2713aSLionel Sambuc EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
886*f4a2713aSLionel Sambuc   CompoundFunc Op = getComplexOp(E->getOpcode());
887*f4a2713aSLionel Sambuc   RValue Val;
888*f4a2713aSLionel Sambuc   return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
889*f4a2713aSLionel Sambuc }
890*f4a2713aSLionel Sambuc 
891*f4a2713aSLionel Sambuc LValue CodeGenFunction::
892*f4a2713aSLionel Sambuc EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E,
893*f4a2713aSLionel Sambuc                                      llvm::Value *&Result) {
894*f4a2713aSLionel Sambuc   CompoundFunc Op = getComplexOp(E->getOpcode());
895*f4a2713aSLionel Sambuc   RValue Val;
896*f4a2713aSLionel Sambuc   LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
897*f4a2713aSLionel Sambuc   Result = Val.getScalarVal();
898*f4a2713aSLionel Sambuc   return Ret;
899*f4a2713aSLionel Sambuc }
900