CGExprComplex.cpp revision 154440e6a8fa6ac5bca395876d79b530b39a2c1c
19f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
29f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//
39f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//                     The LLVM Compiler Infrastructure
49f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//
59f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// This file is distributed under the University of Illinois Open Source
69f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// License. See LICENSE.TXT for details.
79f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//
89f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//===----------------------------------------------------------------------===//
99f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//
109f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// This contains code to emit Expr nodes with complex types as LLVM code.
114cd2ad15b43f21d641330b4b09961af08646445eDuncan Sands//
124cd2ad15b43f21d641330b4b09961af08646445eDuncan Sands//===----------------------------------------------------------------------===//
134cd2ad15b43f21d641330b4b09961af08646445eDuncan Sands
14ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands#include "CodeGenFunction.h"
15ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands#include "CodeGenModule.h"
16ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands#include "clang/AST/ASTContext.h"
179f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner#include "clang/AST/StmtVisitor.h"
189f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner#include "llvm/Constants.h"
199f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner#include "llvm/Function.h"
20a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands#include "llvm/ADT/SmallString.h"
21a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands#include "llvm/Support/Compiler.h"
229f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnerusing namespace clang;
239f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnerusing namespace CodeGen;
241845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
25d70d1a5c44609af091f6fc3e29193f9f4756a74fDuncan Sands//===----------------------------------------------------------------------===//
26d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner//                        Complex Expression Emitter
271845009290e4d804ad377927bd8a08cca3036adcDuncan Sands//===----------------------------------------------------------------------===//
28e60d79faf7ef7bc4847f9e5d067af00b98dced7bDuncan Sands
299f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnertypedef CodeGenFunction::ComplexPairTy ComplexPairTy;
30d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner
319f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnernamespace  {
32124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sandsclass VISIBILITY_HIDDEN ComplexExprEmitter
33a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
34a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  CodeGenFunction &CGF;
35a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  CGBuilderTy &Builder;
36a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  // True is we should ignore the value of a
37a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  bool IgnoreReal;
3882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  bool IgnoreImag;
3982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  // True if we should ignore the value of a=b
40a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  bool IgnoreRealAssign;
411845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  bool IgnoreImagAssign;
42a74a58c83be492b7d5b7383656f049909394cff4Duncan Sandspublic:
431845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false,
4482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                     bool irn=false, bool iin=false)
4582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
4682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    IgnoreRealAssign(irn), IgnoreImagAssign(iin) {
4782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  }
481845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
491845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
501845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  //===--------------------------------------------------------------------===//
511845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  //                               Utilities
521845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  //===--------------------------------------------------------------------===//
531845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
541845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  bool TestAndClearIgnoreReal() {
551845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    bool I = IgnoreReal;
561845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    IgnoreReal = false;
571845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    return I;
581845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  }
591845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  bool TestAndClearIgnoreImag() {
601845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    bool I = IgnoreImag;
611845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    IgnoreImag = false;
621845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    return I;
631845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  }
641845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  bool TestAndClearIgnoreRealAssign() {
651845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    bool I = IgnoreRealAssign;
661845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    IgnoreRealAssign = false;
671845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    return I;
68a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  }
693421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  bool TestAndClearIgnoreImagAssign() {
703421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    bool I = IgnoreImagAssign;
713421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    IgnoreImagAssign = false;
723421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return I;
733421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
743421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
75e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer  /// EmitLoadOfLValue - Given an expression with complex type that represents a
763421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  /// value l-value, this method emits the address of the l-value, then loads
77e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer  /// and returns the result.
783421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy EmitLoadOfLValue(const Expr *E) {
793421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    LValue LV = CGF.EmitLValue(E);
803421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    if (LV.isSimple())
813421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands      return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
823421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
833421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    if (LV.isPropertyRef())
843421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands      return CGF.EmitObjCPropertyGet(LV.getPropertyRefExpr()).getComplexVal();
853421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
863421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    assert(LV.isKVCRef() && "Unknown LValue type!");
873421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return CGF.EmitObjCPropertyGet(LV.getKVCRefExpr()).getComplexVal();
883421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
893421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
903421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
913421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  /// the real and imaginary pieces.
92124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
93124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands
94a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  /// EmitStoreOfComplex - Store the specified real/imag parts into the
953421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  /// specified value pointer.
96a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
973421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
98a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
99a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
100a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands                                         QualType DestType);
1013421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
102a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  //===--------------------------------------------------------------------===//
1033421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  //                            Visitor Methods
1043421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  //===--------------------------------------------------------------------===//
1053421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
1063421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitStmt(Stmt *S) {
1073421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    S->dump(CGF.getContext().getSourceManager());
1083421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    assert(0 && "Stmt can't have complex result type!");
1093421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return ComplexPairTy();
1103421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
1113421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitExpr(Expr *S);
1123421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
1133421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
1143421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
1153421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  // l-values.
116124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
117124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
118a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands    return EmitLoadOfLValue(E);
1193421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
120a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
1213421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return EmitLoadOfLValue(E);
122a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  }
123a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy VisitObjCImplctSetterGetterRefExpr(
124a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands                               ObjCImplctSetterGetterRefExpr *E) {
1253421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return EmitLoadOfLValue(E);
126a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  }
1273421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
1283421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return CGF.EmitObjCMessageExpr(E).getComplexVal();
1293421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
1303421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
1313421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
1323421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
1333421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  // FIXME: CompoundLiteralExpr
1343421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
1353421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
1363421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
1373421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    // Unlike for scalars, we don't have to worry about function->ptr demotion
138e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer    // here.
1393421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return EmitCast(E->getSubExpr(), E->getType());
140e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer  }
1413421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitCastExpr(CastExpr *E) {
1423421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return EmitCast(E->getSubExpr(), E->getType());
1433421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
1443421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitCallExpr(const CallExpr *E);
1453421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitStmtExpr(const StmtExpr *E);
1463421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
1473421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  // Operators.
1483421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
1493421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands                                   bool isInc, bool isPre);
1503421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
1513421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return VisitPrePostIncDec(E, false, false);
1523421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
15382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
15482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    return VisitPrePostIncDec(E, true, false);
1553421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
1563421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
1573421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return VisitPrePostIncDec(E, false, true);
1583421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
159124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
160124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    return VisitPrePostIncDec(E, true, true);
1613421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
1623421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
1633421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitUnaryPlus     (const UnaryOperator *E) {
1643421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    TestAndClearIgnoreReal();
1651cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands    TestAndClearIgnoreImag();
1661cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands    TestAndClearIgnoreRealAssign();
167124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    TestAndClearIgnoreImagAssign();
168a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands    return Visit(E->getSubExpr());
169124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  }
170a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy VisitUnaryMinus    (const UnaryOperator *E);
1713421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitUnaryNot      (const UnaryOperator *E);
172a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  // LNot,Real,Imag never return complex.
173a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
1743421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return Visit(E->getSubExpr());
175a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  }
1763421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
1773421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return Visit(DAE->getExpr());
1783421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
1793421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
1803421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return CGF.EmitCXXExprWithTemporaries(E).getComplexVal();
1813421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  }
182124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
183124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    assert(E->getType()->isAnyComplexType() && "Expected complex type!");
1843421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    QualType Elem = E->getType()->getAsComplexType()->getElementType();
1853421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    llvm::Constant *Null =
1863421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands                       llvm::Constant::getNullValue(CGF.ConvertType(Elem));
1873421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return ComplexPairTy(Null, Null);
1881cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands  }
1891cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands  ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
190124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    assert(E->getType()->isAnyComplexType() && "Expected complex type!");
191a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands    QualType Elem = E->getType()->getAsComplexType()->getElementType();
192124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    llvm::Constant *Null =
193a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands                       llvm::Constant::getNullValue(CGF.ConvertType(Elem));
1943421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    return ComplexPairTy(Null, Null);
195a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  }
196a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands
1973421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  struct BinOpInfo {
198a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands    ComplexPairTy LHS;
1993421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    ComplexPairTy RHS;
2003421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands    QualType Ty;  // Computation Type.
2013421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  };
2023421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
2033421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  BinOpInfo EmitBinOps(const BinaryOperator *E);
2043421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
2053421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands                                   ComplexPairTy (ComplexExprEmitter::*Func)
2063421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands                                   (const BinOpInfo &));
207e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer
208566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
209566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy EmitBinSub(const BinOpInfo &Op);
210566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy EmitBinMul(const BinOpInfo &Op);
211e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer  ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
212566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
213566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinMul(const BinaryOperator *E) {
214566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    return EmitBinMul(EmitBinOps(E));
215566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
216566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
217566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    return EmitBinAdd(EmitBinOps(E));
218566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
219566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinSub(const BinaryOperator *E) {
220566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    return EmitBinSub(EmitBinOps(E));
221566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
222566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
223566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    return EmitBinDiv(EmitBinOps(E));
224566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
225566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
226566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  // Compound assignments.
227566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
228566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
229566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
230566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
231124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
232566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
233a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
234a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
235566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
236a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
237566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
238566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
239566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
240566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  // GCC rejects rem/and/or/xor for integer complex.
241566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  // Logical and/or always return int, never complex.
242566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
243566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  // No comparisons produce a complex result.
244566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinAssign     (const BinaryOperator *E);
245566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitBinComma      (const BinaryOperator *E);
246566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
247566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
248566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
249566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
250124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands
251566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  ComplexPairTy VisitInitListExpr(InitListExpr *E);
252a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands
253a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  ComplexPairTy VisitVAArgExpr(VAArgExpr *E);
254566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands};
255a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands}  // end anonymous namespace.
256566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
257566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands//===----------------------------------------------------------------------===//
258566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands//                                Utilities
259566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands//===----------------------------------------------------------------------===//
260566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
261566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
262566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// load the real and imaginary pieces, returning them as Real/Imag.
263566edb04b890cebca8f2eefa37af7371a1e756c9Duncan SandsComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
264566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands                                                    bool isVolatile) {
265566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  llvm::SmallString<64> Name(SrcPtr->getName().begin(),
266566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands                             SrcPtr->getName().end());
267566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
268566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  llvm::Value *Real=0, *Imag=0;
269566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
270566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  if (!IgnoreReal) {
271566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    Name += ".realp";
272566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    llvm::Value *RealPtr = Builder.CreateStructGEP(SrcPtr, 0, Name.c_str());
273124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands
274566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    Name.pop_back();  // .realp -> .real
275a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands    Real = Builder.CreateLoad(RealPtr, isVolatile, Name.c_str());
276a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands    Name.resize(Name.size()-4); // .real -> .imagp
277566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
278a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands
279566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  if (!IgnoreImag) {
280566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    Name += "imagp";
281566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
282566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    llvm::Value *ImagPtr = Builder.CreateStructGEP(SrcPtr, 1, Name.c_str());
283566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
284566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    Name.pop_back();  // .imagp -> .imag
285566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands    Imag = Builder.CreateLoad(ImagPtr, isVolatile, Name.c_str());
286566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  }
287566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  return ComplexPairTy(Real, Imag);
288566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands}
289566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
290566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// EmitStoreOfComplex - Store the specified real/imag parts into the
291566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// specified value pointer.
292124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sandsvoid ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
293566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands                                            bool isVolatile) {
294a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
295a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
296566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
297a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands  Builder.CreateStore(Val.first, RealPtr, isVolatile);
298566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  Builder.CreateStore(Val.second, ImagPtr, isVolatile);
299566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands}
300566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
301566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
302566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands
303566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands//===----------------------------------------------------------------------===//
304b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands//                            Visitor Methods
305b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands//===----------------------------------------------------------------------===//
306b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
307b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
308b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  CGF.ErrorUnsupported(E, "complex expression");
3091845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  const llvm::Type *EltTy =
3101845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
3111845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  llvm::Value *U = llvm::UndefValue::get(EltTy);
3120312a93693abc2eb682b2b101c889959888fd883Duncan Sands  return ComplexPairTy(U, U);
3130312a93693abc2eb682b2b101c889959888fd883Duncan Sands}
3140312a93693abc2eb682b2b101c889959888fd883Duncan Sands
3150312a93693abc2eb682b2b101c889959888fd883Duncan SandsComplexPairTy ComplexExprEmitter::
316b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsVisitImaginaryLiteral(const ImaginaryLiteral *IL) {
317b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
318b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  return
319b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands        ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
320b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands}
321b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
322b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
323b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
324b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  if (E->getCallReturnType()->isReferenceType())
325b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands    return EmitLoadOfLValue(E);
326b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
327b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  return CGF.EmitCallExpr(E).getComplexVal();
3281845009290e4d804ad377927bd8a08cca3036adcDuncan Sands}
3291845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
330b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
3311845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
3321845009290e4d804ad377927bd8a08cca3036adcDuncan Sands}
333b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
334b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
3357cf85e74e3885005ca8e5fdb155fa5351e255b85Duncan SandsComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
336124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands                                                           QualType SrcType,
337124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands                                                           QualType DestType) {
338b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // Get the src/dest element type.
339b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  SrcType = SrcType->getAsComplexType()->getElementType();
340b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  DestType = DestType->getAsComplexType()->getElementType();
341b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
342b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // C99 6.3.1.6: When a value of complex type is converted to another
343b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // complex type, both the real and imaginary parts follow the conversion
344b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // rules for the corresponding real types.
345b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
346b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
347b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  return Val;
348124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands}
349b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
350b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
351b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // Two cases here: cast from (complex to complex) and (scalar to complex).
352b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  if (Op->getType()->isAnyComplexType())
353b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands    return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
354b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
355b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // C99 6.3.1.7: When a value of real type is converted to a complex type, the
356b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // real part of the complex result value is determined by the rules of
357b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // conversion to the corresponding real type and the imaginary part of the
358b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // complex result value is a positive zero or an unsigned zero.
359b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  llvm::Value *Elt = CGF.EmitScalarExpr(Op);
360b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
361b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // Convert the input element to the element type of the complex.
362b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  DestTy = DestTy->getAsComplexType()->getElementType();
363b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
364b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
365124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  // Return (realval, 0).
366124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
367b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands}
368b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
369124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan SandsComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
370124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands                                                     bool isInc, bool isPre) {
371b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  LValue LV = CGF.EmitLValue(E->getSubExpr());
372b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(),
373b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands                                          LV.isVolatileQualified());
374b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
375b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  llvm::Value *NextVal;
376b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  if (isa<llvm::IntegerType>(InVal.first->getType())) {
377b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands    uint64_t AmountVal = isInc ? 1 : -1;
378b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands    NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal, true);
379b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
380b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands    // Add the inc/dec to the real part.
381b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands    NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
382b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  } else {
383a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    QualType ElemTy = E->getType()->getAsComplexType()->getElementType();
3841845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    llvm::APFloat FVal(CGF.getContext().getFloatTypeSemantics(ElemTy), 1);
385a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    if (!isInc)
3860312a93693abc2eb682b2b101c889959888fd883Duncan Sands      FVal.changeSign();
3870312a93693abc2eb682b2b101c889959888fd883Duncan Sands    NextVal = llvm::ConstantFP::get(CGF.getLLVMContext(), FVal);
3880312a93693abc2eb682b2b101c889959888fd883Duncan Sands
3890312a93693abc2eb682b2b101c889959888fd883Duncan Sands    // Add the inc/dec to the real part.
390b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands    NextVal = Builder.CreateFAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
391b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  }
392b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
393b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  ComplexPairTy IncVal(NextVal, InVal.second);
394b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
395b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // Store the updated result through the lvalue.
396b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  EmitStoreOfComplex(IncVal, LV.getAddress(), LV.isVolatileQualified());
397b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
398b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // If this is a postinc, return the value read from memory, otherwise use the
399b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  // updated value.
4001845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  return isPre ? IncVal : InVal;
401a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands}
402b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
4031845009290e4d804ad377927bd8a08cca3036adcDuncan SandsComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
404a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  TestAndClearIgnoreReal();
405b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  TestAndClearIgnoreImag();
406b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  TestAndClearIgnoreRealAssign();
407124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  TestAndClearIgnoreImagAssign();
408b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  ComplexPairTy Op = Visit(E->getSubExpr());
409b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands
410b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  llvm::Value *ResR, *ResI;
411b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands  if (Op.first->getType()->isFloatingPoint()) {
412a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResR = Builder.CreateFNeg(Op.first,  "neg.r");
413a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResI = Builder.CreateFNeg(Op.second, "neg.i");
414a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  } else {
415a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResR = Builder.CreateNeg(Op.first,  "neg.r");
416a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResI = Builder.CreateNeg(Op.second, "neg.i");
4171845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  }
4181845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  return ComplexPairTy(ResR, ResI);
4190312a93693abc2eb682b2b101c889959888fd883Duncan Sands}
4200312a93693abc2eb682b2b101c889959888fd883Duncan Sands
4210312a93693abc2eb682b2b101c889959888fd883Duncan SandsComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
4220312a93693abc2eb682b2b101c889959888fd883Duncan Sands  TestAndClearIgnoreReal();
423a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  TestAndClearIgnoreImag();
424a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  TestAndClearIgnoreRealAssign();
425a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  TestAndClearIgnoreImagAssign();
4261845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  // ~(a+ib) = a + i*-b
4271845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  ComplexPairTy Op = Visit(E->getSubExpr());
4281845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  llvm::Value *ResI;
429a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  if (Op.second->getType()->isFloatingPoint())
430a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResI = Builder.CreateFNeg(Op.second, "conj.i");
431a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  else
4321845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    ResI = Builder.CreateNeg(Op.second, "conj.i");
4331845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
4341845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  return ComplexPairTy(Op.first, ResI);
435a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands}
436a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
437a74a58c83be492b7d5b7383656f049909394cff4Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
438a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  llvm::Value *ResR, *ResI;
439a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
440552008946530e01efdad15044e1f621883d14a3aDuncan Sands  if (Op.LHS.first->getType()->isFloatingPoint()) {
441ff10341183adf74760e6118a55cbd1debf50f90fDuncan Sands    ResR = Builder.CreateFAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
442552008946530e01efdad15044e1f621883d14a3aDuncan Sands    ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
443a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  } else {
4441845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    ResR = Builder.CreateAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
4451845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
446a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  }
447a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  return ComplexPairTy(ResR, ResI);
448a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands}
449a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
450a74a58c83be492b7d5b7383656f049909394cff4Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
451a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  llvm::Value *ResR, *ResI;
452a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  if (Op.LHS.first->getType()->isFloatingPoint()) {
453a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResR = Builder.CreateFSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
454a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
455a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  } else {
456a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResR = Builder.CreateSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
457a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
458a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  }
459a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  return ComplexPairTy(ResR, ResI);
460a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands}
4611845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
4621845009290e4d804ad377927bd8a08cca3036adcDuncan Sands
4630312a93693abc2eb682b2b101c889959888fd883Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
4640312a93693abc2eb682b2b101c889959888fd883Duncan Sands  using llvm::Value;
4650312a93693abc2eb682b2b101c889959888fd883Duncan Sands  Value *ResR, *ResI;
4660312a93693abc2eb682b2b101c889959888fd883Duncan Sands
467a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  if (Op.LHS.first->getType()->isFloatingPoint()) {
468a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");
469a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr");
470a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResR  = Builder.CreateFSub(ResRl, ResRr, "mul.r");
471a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
472a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il");
473a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");
474a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    ResI  = Builder.CreateFAdd(ResIl, ResIr, "mul.i");
4751845009290e4d804ad377927bd8a08cca3036adcDuncan Sands  } else {
4761845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
4771845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
4781845009290e4d804ad377927bd8a08cca3036adcDuncan Sands    ResR  = Builder.CreateSub(ResRl, ResRr, "mul.r");
479a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
480a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
481a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
482552008946530e01efdad15044e1f621883d14a3aDuncan Sands    ResI  = Builder.CreateAdd(ResIl, ResIr, "mul.i");
483ff10341183adf74760e6118a55cbd1debf50f90fDuncan Sands  }
484552008946530e01efdad15044e1f621883d14a3aDuncan Sands  return ComplexPairTy(ResR, ResI);
4851845009290e4d804ad377927bd8a08cca3036adcDuncan Sands}
486a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
487a74a58c83be492b7d5b7383656f049909394cff4Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
488a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
489a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
490a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
491a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands
492a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  llvm::Value *DSTr, *DSTi;
493a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands  if (Op.LHS.first->getType()->isFloatingPoint()) {
494a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
495a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands    llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr, "tmp"); // a*c
4968aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner    llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi, "tmp"); // b*d
497d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner    llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2, "tmp"); // ac+bd
498ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands
499ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands    llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr, "tmp"); // c*c
500ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands    llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi, "tmp"); // d*d
501d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner    llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5, "tmp"); // cc+dd
502d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner
503d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner    llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr, "tmp"); // b*c
5048aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner    llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi, "tmp"); // a*d
5058aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner    llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8, "tmp"); // bc-ad
5068aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner
50712a86f5b3199e72e6d967781acc76340f5920e46Duncan Sands    DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
5088aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner    DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
5098aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner  } else {
5108aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner    // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
51112a86f5b3199e72e6d967781acc76340f5920e46Duncan Sands    llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
512fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
513fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
514fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
51512a86f5b3199e72e6d967781acc76340f5920e46Duncan Sands    llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
516fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
517fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
518fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
519fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
520fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
521fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
522ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands
523124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    if (Op.Ty->getAsComplexType()->getElementType()->isUnsignedIntegerType()) {
524124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands      DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
525124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands      DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
526fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands    } else {
527fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands      DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
528fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands      DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
529124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands    }
530124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  }
531fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
53287689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands  return ComplexPairTy(DSTr, DSTi);
53382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands}
53475d289ed6201e82718343d7a36d2a2fa082f6217Duncan Sands
53507f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan SandsComplexExprEmitter::BinOpInfo
53607f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan SandsComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
53782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  TestAndClearIgnoreReal();
538566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  TestAndClearIgnoreImag();
539566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  TestAndClearIgnoreRealAssign();
540566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  TestAndClearIgnoreImagAssign();
541566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  BinOpInfo Ops;
542566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands  Ops.LHS = Visit(E->getLHS());
5433421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  Ops.RHS = Visit(E->getRHS());
5443421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  Ops.Ty = E->getType();
5453421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  return Ops;
5463421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands}
5473421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
54887689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands
54987689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands// Compound assignments.
55087689cfc54993959adb20b89a56bc58aad18ca56Duncan SandsComplexPairTy ComplexExprEmitter::
55187689cfc54993959adb20b89a56bc58aad18ca56Duncan SandsEmitCompoundAssign(const CompoundAssignOperator *E,
55287689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands                   ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
55387689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands  TestAndClearIgnoreReal();
55487689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands  TestAndClearIgnoreImag();
55587689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands  bool ignreal = TestAndClearIgnoreRealAssign();
55687689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands  bool ignimag = TestAndClearIgnoreImagAssign();
5578aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner  QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
5588aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner
5598aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner  BinOpInfo OpInfo;
560ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands
561ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands  // Load the RHS and LHS operands.
562ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands  // __block variables need to have the rhs evaluated first, plus this should
563ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands  // improve codegen a little.  It is possible for the RHS to be complex or
564ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands  // scalar.
565fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  OpInfo.Ty = E->getComputationResultType();
566fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
567ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands
5683421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  LValue LHSLV = CGF.EmitLValue(E->getLHS());
569ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands
570fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
571fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  // We know the LHS is a complex lvalue.
572fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  OpInfo.LHS=EmitLoadOfComplex(LHSLV.getAddress(),LHSLV.isVolatileQualified());
573fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  OpInfo.LHS=EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty);
574fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
575fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  // Expand the binary operator.
576fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  ComplexPairTy Result = (this->*Func)(OpInfo);
577fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
578fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  // Truncate the result back to the LHS type.
579fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
580fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
581fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  // Store the result value into the LHS lvalue.
582fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified());
583fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  // And now return the LHS
584fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  IgnoreReal = ignreal;
585fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  IgnoreImag = ignimag;
586fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  IgnoreRealAssign = ignreal;
587124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands  IgnoreImagAssign = ignimag;
588fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  return EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified());
589fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands}
590fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands
591fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan SandsComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
592b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  TestAndClearIgnoreReal();
593fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands  TestAndClearIgnoreImag();
594fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands  bool ignreal = TestAndClearIgnoreRealAssign();
595fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands  bool ignimag = TestAndClearIgnoreImagAssign();
596fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands  assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
597b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands         CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
598b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands         "Invalid assignment");
599b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  // Emit the RHS.
600b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  ComplexPairTy Val = Visit(E->getRHS());
601b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
602b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  // Compute the address to store into.
603b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  LValue LHS = CGF.EmitLValue(E->getLHS());
604b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
605b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  // Store into it, if simple.
606b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  if (LHS.isSimple()) {
607b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
608b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
609b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    // And now return the LHS
610b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    IgnoreReal = ignreal;
611b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    IgnoreImag = ignimag;
612b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    IgnoreRealAssign = ignreal;
613b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    IgnoreImagAssign = ignimag;
614b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
615b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  }
616b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
617b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  // Otherwise we must have a property setter (no complex vector/bitfields).
618b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  if (LHS.isPropertyRef())
619b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val));
62082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  else
621b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands    CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val));
622b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
623b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  // There is no reload after a store through a method, but we need to restore
624b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  // the Ignore* flags.
625b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  IgnoreReal = ignreal;
626b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  IgnoreImag = ignimag;
627b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  IgnoreRealAssign = ignreal;
628b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  IgnoreImagAssign = ignimag;
629b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  return Val;
630b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands}
631b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
632b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan SandsComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
633b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  CGF.EmitStmt(E->getLHS());
634b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  CGF.EnsureInsertPoint();
635b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  return Visit(E->getRHS());
636b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands}
637b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
638b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan SandsComplexPairTy ComplexExprEmitter::
639b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan SandsVisitConditionalOperator(const ConditionalOperator *E) {
640b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  TestAndClearIgnoreReal();
641b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  TestAndClearIgnoreImag();
642b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  TestAndClearIgnoreRealAssign();
643b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  TestAndClearIgnoreImagAssign();
644b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
645b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
646b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
647b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
648c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands  llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
649c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands  Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
650c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands
651b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  CGF.EmitBlock(LHSBlock);
652c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands
653c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands  // Handle the GNU extension for missing LHS.
654c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands  assert(E->getLHS() && "Must have LHS for complex value");
655c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands
656c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands  ComplexPairTy LHS = Visit(E->getLHS());
657c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands  LHSBlock = Builder.GetInsertBlock();
658c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands  CGF.EmitBranch(ContBlock);
6593421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
6603421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  CGF.EmitBlock(RHSBlock);
6613421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands
6623421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  ComplexPairTy RHS = Visit(E->getRHS());
6633421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands  RHSBlock = Builder.GetInsertBlock();
664b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  CGF.EmitBranch(ContBlock);
665b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
666b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  CGF.EmitBlock(ContBlock);
667b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands
668b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands  // Create a PHI node for the real part.
669fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
670fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  RealPN->reserveOperandSpace(2);
671fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  RealPN->addIncoming(LHS.first, LHSBlock);
672fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  RealPN->addIncoming(RHS.first, RHSBlock);
673fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
674fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  // Create a PHI node for the imaginary part.
675fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
676fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  ImagPN->reserveOperandSpace(2);
677fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  ImagPN->addIncoming(LHS.second, LHSBlock);
678fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  ImagPN->addIncoming(RHS.second, RHSBlock);
679fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands
680fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands  return ComplexPairTy(RealPN, ImagPN);
681ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands}
682ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands
683ee9a2e322af96accc9e55ed6373c0057453714b1Duncan SandsComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
684ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands  return Visit(E->getChosenSubExpr(CGF.getContext()));
685ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands}
68682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
68782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
68882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    bool Ignore = TestAndClearIgnoreReal();
68982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    (void)Ignore;
69082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    assert (Ignore == false && "init list ignored");
69182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    Ignore = TestAndClearIgnoreImag();
69282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    (void)Ignore;
69382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    assert (Ignore == false && "init list ignored");
69482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  if (E->getNumInits())
69582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    return Visit(E->getInit(0));
69682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
69782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  // Empty init list intializes to null
69882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  QualType Ty = E->getType()->getAsComplexType()->getElementType();
69982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  const llvm::Type* LTy = CGF.ConvertType(Ty);
70082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
70182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  return ComplexPairTy(zeroConstant, zeroConstant);
70282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands}
70382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
70482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
70582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr());
70682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType());
70782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
70882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  if (!ArgPtr) {
70982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    CGF.ErrorUnsupported(E, "complex va_arg expression");
71082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    const llvm::Type *EltTy =
71182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands      CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
71282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    llvm::Value *U = llvm::UndefValue::get(EltTy);
7131895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands    return ComplexPairTy(U, U);
7141895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands  }
7151895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands
7161895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands  // FIXME Volatility.
7171895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands  return EmitLoadOfComplex(ArgPtr, false);
7181895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands}
7191895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands
7201895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands//===----------------------------------------------------------------------===//
7211895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands//                         Entry Point into this File
7225413880654585f01ea9880f24f07f27c8da56ba8Nick Lewycky//===----------------------------------------------------------------------===//
72375d289ed6201e82718343d7a36d2a2fa082f6217Duncan Sands
72407f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan Sands/// EmitComplexExpr - Emit the computation of the specified expression of
72507f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan Sands/// complex type, ignoring the result.
72682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal,
72782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                                               bool IgnoreImag, bool IgnoreRealAssign, bool IgnoreImagAssign) {
72882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  assert(E && E->getType()->isAnyComplexType() &&
72982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands         "Invalid complex expression to emit");
73082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
73182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag, IgnoreRealAssign,
73282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                            IgnoreImagAssign)
73382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands    .Visit(const_cast<Expr*>(E));
73482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands}
73582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
73682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// EmitComplexExprIntoAddr - Emit the computation of the specified expression
73782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// of complex type, storing into the specified Value*.
73882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sandsvoid CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
73982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                                              llvm::Value *DestAddr,
74082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                                              bool DestIsVolatile) {
74182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  assert(E && E->getType()->isAnyComplexType() &&
74282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands         "Invalid complex expression to emit");
74382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  ComplexExprEmitter Emitter(*this);
74482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
74582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile);
74682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands}
74782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
74882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// StoreComplexToAddr - Store a complex number into the specified address.
74982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sandsvoid CodeGenFunction::StoreComplexToAddr(ComplexPairTy V,
75082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                                         llvm::Value *DestAddr,
75182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                                         bool DestIsVolatile) {
75282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile);
75382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands}
75482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands
75582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// LoadComplexFromAddr - Load a complex number from the specified address.
75682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr,
75782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands                                                   bool SrcIsVolatile) {
75882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands  return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile);
759593faa53fa6d89841e601cc4571d143a6a05f0b4Duncan Sands}
760593faa53fa6d89841e601cc4571d143a6a05f0b4Duncan Sands