1*700637cbSDimitry Andric #include "CIRGenBuilder.h"
2*700637cbSDimitry Andric #include "CIRGenFunction.h"
3*700637cbSDimitry Andric
4*700637cbSDimitry Andric #include "clang/AST/StmtVisitor.h"
5*700637cbSDimitry Andric
6*700637cbSDimitry Andric using namespace clang;
7*700637cbSDimitry Andric using namespace clang::CIRGen;
8*700637cbSDimitry Andric
9*700637cbSDimitry Andric namespace {
10*700637cbSDimitry Andric class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
11*700637cbSDimitry Andric CIRGenFunction &cgf;
12*700637cbSDimitry Andric CIRGenBuilderTy &builder;
13*700637cbSDimitry Andric
14*700637cbSDimitry Andric public:
ComplexExprEmitter(CIRGenFunction & cgf)15*700637cbSDimitry Andric explicit ComplexExprEmitter(CIRGenFunction &cgf)
16*700637cbSDimitry Andric : cgf(cgf), builder(cgf.getBuilder()) {}
17*700637cbSDimitry Andric
18*700637cbSDimitry Andric //===--------------------------------------------------------------------===//
19*700637cbSDimitry Andric // Utilities
20*700637cbSDimitry Andric //===--------------------------------------------------------------------===//
21*700637cbSDimitry Andric
22*700637cbSDimitry Andric LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val);
23*700637cbSDimitry Andric
24*700637cbSDimitry Andric mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy);
25*700637cbSDimitry Andric
26*700637cbSDimitry Andric mlir::Value emitConstant(const CIRGenFunction::ConstantEmission &constant,
27*700637cbSDimitry Andric Expr *e);
28*700637cbSDimitry Andric
29*700637cbSDimitry Andric /// Given an expression with complex type that represents a value l-value,
30*700637cbSDimitry Andric /// this method emits the address of the l-value, then loads and returns the
31*700637cbSDimitry Andric /// result.
emitLoadOfLValue(const Expr * e)32*700637cbSDimitry Andric mlir::Value emitLoadOfLValue(const Expr *e) {
33*700637cbSDimitry Andric return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc());
34*700637cbSDimitry Andric }
35*700637cbSDimitry Andric
36*700637cbSDimitry Andric mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);
37*700637cbSDimitry Andric /// Store the specified real/imag parts into the
38*700637cbSDimitry Andric /// specified value pointer.
39*700637cbSDimitry Andric void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
40*700637cbSDimitry Andric bool isInit);
41*700637cbSDimitry Andric
42*700637cbSDimitry Andric mlir::Value
43*700637cbSDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
44*700637cbSDimitry Andric mlir::Value VisitArraySubscriptExpr(Expr *e);
45*700637cbSDimitry Andric mlir::Value VisitBinAssign(const BinaryOperator *e);
46*700637cbSDimitry Andric mlir::Value VisitBinComma(const BinaryOperator *e);
47*700637cbSDimitry Andric mlir::Value VisitCallExpr(const CallExpr *e);
48*700637cbSDimitry Andric mlir::Value VisitCastExpr(CastExpr *e);
49*700637cbSDimitry Andric mlir::Value VisitChooseExpr(ChooseExpr *e);
50*700637cbSDimitry Andric mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e);
51*700637cbSDimitry Andric mlir::Value VisitDeclRefExpr(DeclRefExpr *e);
52*700637cbSDimitry Andric mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *e);
53*700637cbSDimitry Andric mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e);
54*700637cbSDimitry Andric mlir::Value VisitInitListExpr(const InitListExpr *e);
55*700637cbSDimitry Andric mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il);
56*700637cbSDimitry Andric mlir::Value VisitParenExpr(ParenExpr *e);
57*700637cbSDimitry Andric mlir::Value
58*700637cbSDimitry Andric VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
59*700637cbSDimitry Andric mlir::Value VisitUnaryDeref(const Expr *e);
60*700637cbSDimitry Andric
61*700637cbSDimitry Andric struct BinOpInfo {
62*700637cbSDimitry Andric mlir::Location loc;
63*700637cbSDimitry Andric mlir::Value lhs{};
64*700637cbSDimitry Andric mlir::Value rhs{};
65*700637cbSDimitry Andric QualType ty{}; // Computation Type.
66*700637cbSDimitry Andric FPOptions fpFeatures{};
67*700637cbSDimitry Andric };
68*700637cbSDimitry Andric
69*700637cbSDimitry Andric BinOpInfo emitBinOps(const BinaryOperator *e,
70*700637cbSDimitry Andric QualType promotionTy = QualType());
71*700637cbSDimitry Andric
72*700637cbSDimitry Andric mlir::Value emitPromoted(const Expr *e, QualType promotionTy);
73*700637cbSDimitry Andric
74*700637cbSDimitry Andric mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy);
75*700637cbSDimitry Andric
76*700637cbSDimitry Andric mlir::Value emitBinAdd(const BinOpInfo &op);
77*700637cbSDimitry Andric mlir::Value emitBinSub(const BinOpInfo &op);
78*700637cbSDimitry Andric
getPromotionType(QualType ty,bool isDivOpCode=false)79*700637cbSDimitry Andric QualType getPromotionType(QualType ty, bool isDivOpCode = false) {
80*700637cbSDimitry Andric if (auto *complexTy = ty->getAs<ComplexType>()) {
81*700637cbSDimitry Andric QualType elementTy = complexTy->getElementType();
82*700637cbSDimitry Andric if (isDivOpCode && elementTy->isFloatingType() &&
83*700637cbSDimitry Andric cgf.getLangOpts().getComplexRange() ==
84*700637cbSDimitry Andric LangOptions::ComplexRangeKind::CX_Promoted) {
85*700637cbSDimitry Andric cgf.cgm.errorNYI("HigherPrecisionTypeForComplexArithmetic");
86*700637cbSDimitry Andric return QualType();
87*700637cbSDimitry Andric }
88*700637cbSDimitry Andric
89*700637cbSDimitry Andric if (elementTy.UseExcessPrecision(cgf.getContext()))
90*700637cbSDimitry Andric return cgf.getContext().getComplexType(cgf.getContext().FloatTy);
91*700637cbSDimitry Andric }
92*700637cbSDimitry Andric
93*700637cbSDimitry Andric if (ty.UseExcessPrecision(cgf.getContext()))
94*700637cbSDimitry Andric return cgf.getContext().FloatTy;
95*700637cbSDimitry Andric return QualType();
96*700637cbSDimitry Andric }
97*700637cbSDimitry Andric
98*700637cbSDimitry Andric #define HANDLEBINOP(OP) \
99*700637cbSDimitry Andric mlir::Value VisitBin##OP(const BinaryOperator *e) { \
100*700637cbSDimitry Andric QualType promotionTy = getPromotionType( \
101*700637cbSDimitry Andric e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \
102*700637cbSDimitry Andric mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \
103*700637cbSDimitry Andric if (!promotionTy.isNull()) \
104*700637cbSDimitry Andric cgf.cgm.errorNYI("Binop emitUnPromotedValue"); \
105*700637cbSDimitry Andric return result; \
106*700637cbSDimitry Andric }
107*700637cbSDimitry Andric
108*700637cbSDimitry Andric HANDLEBINOP(Add)
109*700637cbSDimitry Andric HANDLEBINOP(Sub)
110*700637cbSDimitry Andric #undef HANDLEBINOP
111*700637cbSDimitry Andric };
112*700637cbSDimitry Andric } // namespace
113*700637cbSDimitry Andric
getComplexType(QualType type)114*700637cbSDimitry Andric static const ComplexType *getComplexType(QualType type) {
115*700637cbSDimitry Andric type = type.getCanonicalType();
116*700637cbSDimitry Andric if (const ComplexType *comp = dyn_cast<ComplexType>(type))
117*700637cbSDimitry Andric return comp;
118*700637cbSDimitry Andric return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
119*700637cbSDimitry Andric }
120*700637cbSDimitry Andric
emitBinAssignLValue(const BinaryOperator * e,mlir::Value & value)121*700637cbSDimitry Andric LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e,
122*700637cbSDimitry Andric mlir::Value &value) {
123*700637cbSDimitry Andric assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),
124*700637cbSDimitry Andric e->getRHS()->getType()) &&
125*700637cbSDimitry Andric "Invalid assignment");
126*700637cbSDimitry Andric
127*700637cbSDimitry Andric // Emit the RHS. __block variables need the RHS evaluated first.
128*700637cbSDimitry Andric value = Visit(e->getRHS());
129*700637cbSDimitry Andric
130*700637cbSDimitry Andric // Compute the address to store into.
131*700637cbSDimitry Andric LValue lhs = cgf.emitLValue(e->getLHS());
132*700637cbSDimitry Andric
133*700637cbSDimitry Andric // Store the result value into the LHS lvalue.
134*700637cbSDimitry Andric emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs, /*isInit*/ false);
135*700637cbSDimitry Andric return lhs;
136*700637cbSDimitry Andric }
137*700637cbSDimitry Andric
emitCast(CastKind ck,Expr * op,QualType destTy)138*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
139*700637cbSDimitry Andric QualType destTy) {
140*700637cbSDimitry Andric switch (ck) {
141*700637cbSDimitry Andric case CK_NoOp:
142*700637cbSDimitry Andric case CK_LValueToRValue:
143*700637cbSDimitry Andric return Visit(op);
144*700637cbSDimitry Andric default:
145*700637cbSDimitry Andric break;
146*700637cbSDimitry Andric }
147*700637cbSDimitry Andric cgf.cgm.errorNYI("ComplexType Cast");
148*700637cbSDimitry Andric return {};
149*700637cbSDimitry Andric }
150*700637cbSDimitry Andric
emitConstant(const CIRGenFunction::ConstantEmission & constant,Expr * e)151*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::emitConstant(
152*700637cbSDimitry Andric const CIRGenFunction::ConstantEmission &constant, Expr *e) {
153*700637cbSDimitry Andric assert(constant && "not a constant");
154*700637cbSDimitry Andric if (constant.isReference())
155*700637cbSDimitry Andric return emitLoadOfLValue(constant.getReferenceLValue(cgf, e),
156*700637cbSDimitry Andric e->getExprLoc());
157*700637cbSDimitry Andric
158*700637cbSDimitry Andric mlir::TypedAttr valueAttr = constant.getValue();
159*700637cbSDimitry Andric return builder.getConstant(cgf.getLoc(e->getSourceRange()), valueAttr);
160*700637cbSDimitry Andric }
161*700637cbSDimitry Andric
emitLoadOfLValue(LValue lv,SourceLocation loc)162*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
163*700637cbSDimitry Andric SourceLocation loc) {
164*700637cbSDimitry Andric assert(lv.isSimple() && "non-simple complex l-value?");
165*700637cbSDimitry Andric if (lv.getType()->isAtomicType())
166*700637cbSDimitry Andric cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");
167*700637cbSDimitry Andric
168*700637cbSDimitry Andric const Address srcAddr = lv.getAddress();
169*700637cbSDimitry Andric return builder.createLoad(cgf.getLoc(loc), srcAddr);
170*700637cbSDimitry Andric }
171*700637cbSDimitry Andric
emitStoreOfComplex(mlir::Location loc,mlir::Value val,LValue lv,bool isInit)172*700637cbSDimitry Andric void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
173*700637cbSDimitry Andric LValue lv, bool isInit) {
174*700637cbSDimitry Andric if (lv.getType()->isAtomicType() ||
175*700637cbSDimitry Andric (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {
176*700637cbSDimitry Andric cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV");
177*700637cbSDimitry Andric return;
178*700637cbSDimitry Andric }
179*700637cbSDimitry Andric
180*700637cbSDimitry Andric const Address destAddr = lv.getAddress();
181*700637cbSDimitry Andric builder.createStore(loc, val, destAddr);
182*700637cbSDimitry Andric }
183*700637cbSDimitry Andric
VisitAbstractConditionalOperator(const AbstractConditionalOperator * e)184*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
185*700637cbSDimitry Andric const AbstractConditionalOperator *e) {
186*700637cbSDimitry Andric mlir::Value condValue = Visit(e->getCond());
187*700637cbSDimitry Andric mlir::Location loc = cgf.getLoc(e->getSourceRange());
188*700637cbSDimitry Andric
189*700637cbSDimitry Andric return builder
190*700637cbSDimitry Andric .create<cir::TernaryOp>(
191*700637cbSDimitry Andric loc, condValue,
192*700637cbSDimitry Andric /*thenBuilder=*/
193*700637cbSDimitry Andric [&](mlir::OpBuilder &b, mlir::Location loc) {
194*700637cbSDimitry Andric mlir::Value trueValue = Visit(e->getTrueExpr());
195*700637cbSDimitry Andric b.create<cir::YieldOp>(loc, trueValue);
196*700637cbSDimitry Andric },
197*700637cbSDimitry Andric /*elseBuilder=*/
198*700637cbSDimitry Andric [&](mlir::OpBuilder &b, mlir::Location loc) {
199*700637cbSDimitry Andric mlir::Value falseValue = Visit(e->getFalseExpr());
200*700637cbSDimitry Andric b.create<cir::YieldOp>(loc, falseValue);
201*700637cbSDimitry Andric })
202*700637cbSDimitry Andric .getResult();
203*700637cbSDimitry Andric }
204*700637cbSDimitry Andric
VisitArraySubscriptExpr(Expr * e)205*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitArraySubscriptExpr(Expr *e) {
206*700637cbSDimitry Andric return emitLoadOfLValue(e);
207*700637cbSDimitry Andric }
208*700637cbSDimitry Andric
VisitBinAssign(const BinaryOperator * e)209*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) {
210*700637cbSDimitry Andric mlir::Value value;
211*700637cbSDimitry Andric LValue lv = emitBinAssignLValue(e, value);
212*700637cbSDimitry Andric
213*700637cbSDimitry Andric // The result of an assignment in C is the assigned r-value.
214*700637cbSDimitry Andric if (!cgf.getLangOpts().CPlusPlus)
215*700637cbSDimitry Andric return value;
216*700637cbSDimitry Andric
217*700637cbSDimitry Andric // If the lvalue is non-volatile, return the computed value of the
218*700637cbSDimitry Andric // assignment.
219*700637cbSDimitry Andric if (!lv.isVolatile())
220*700637cbSDimitry Andric return value;
221*700637cbSDimitry Andric
222*700637cbSDimitry Andric return emitLoadOfLValue(lv, e->getExprLoc());
223*700637cbSDimitry Andric }
224*700637cbSDimitry Andric
VisitBinComma(const BinaryOperator * e)225*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) {
226*700637cbSDimitry Andric cgf.emitIgnoredExpr(e->getLHS());
227*700637cbSDimitry Andric return Visit(e->getRHS());
228*700637cbSDimitry Andric }
229*700637cbSDimitry Andric
VisitCallExpr(const CallExpr * e)230*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
231*700637cbSDimitry Andric if (e->getCallReturnType(cgf.getContext())->isReferenceType())
232*700637cbSDimitry Andric return emitLoadOfLValue(e);
233*700637cbSDimitry Andric
234*700637cbSDimitry Andric return cgf.emitCallExpr(e).getValue();
235*700637cbSDimitry Andric }
236*700637cbSDimitry Andric
VisitCastExpr(CastExpr * e)237*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitCastExpr(CastExpr *e) {
238*700637cbSDimitry Andric if (const auto *ece = dyn_cast<ExplicitCastExpr>(e)) {
239*700637cbSDimitry Andric // Bind VLAs in the cast type.
240*700637cbSDimitry Andric if (ece->getType()->isVariablyModifiedType()) {
241*700637cbSDimitry Andric cgf.cgm.errorNYI("VisitCastExpr Bind VLAs in the cast type");
242*700637cbSDimitry Andric return {};
243*700637cbSDimitry Andric }
244*700637cbSDimitry Andric }
245*700637cbSDimitry Andric
246*700637cbSDimitry Andric if (e->changesVolatileQualification())
247*700637cbSDimitry Andric return emitLoadOfLValue(e);
248*700637cbSDimitry Andric
249*700637cbSDimitry Andric return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
250*700637cbSDimitry Andric }
251*700637cbSDimitry Andric
VisitChooseExpr(ChooseExpr * e)252*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {
253*700637cbSDimitry Andric return Visit(e->getChosenSubExpr());
254*700637cbSDimitry Andric }
255*700637cbSDimitry Andric
256*700637cbSDimitry Andric mlir::Value
VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr * e)257*700637cbSDimitry Andric ComplexExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
258*700637cbSDimitry Andric mlir::Location loc = cgf.getLoc(e->getExprLoc());
259*700637cbSDimitry Andric mlir::Type complexTy = cgf.convertType(e->getType());
260*700637cbSDimitry Andric return builder.getNullValue(complexTy, loc);
261*700637cbSDimitry Andric }
262*700637cbSDimitry Andric
VisitDeclRefExpr(DeclRefExpr * e)263*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) {
264*700637cbSDimitry Andric if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e))
265*700637cbSDimitry Andric return emitConstant(constant, e);
266*700637cbSDimitry Andric return emitLoadOfLValue(e);
267*700637cbSDimitry Andric }
268*700637cbSDimitry Andric
269*700637cbSDimitry Andric mlir::Value
VisitGenericSelectionExpr(GenericSelectionExpr * e)270*700637cbSDimitry Andric ComplexExprEmitter::VisitGenericSelectionExpr(GenericSelectionExpr *e) {
271*700637cbSDimitry Andric return Visit(e->getResultExpr());
272*700637cbSDimitry Andric }
273*700637cbSDimitry Andric
VisitImplicitCastExpr(ImplicitCastExpr * e)274*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *e) {
275*700637cbSDimitry Andric // Unlike for scalars, we don't have to worry about function->ptr demotion
276*700637cbSDimitry Andric // here.
277*700637cbSDimitry Andric if (e->changesVolatileQualification())
278*700637cbSDimitry Andric return emitLoadOfLValue(e);
279*700637cbSDimitry Andric return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
280*700637cbSDimitry Andric }
281*700637cbSDimitry Andric
VisitInitListExpr(const InitListExpr * e)282*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitInitListExpr(const InitListExpr *e) {
283*700637cbSDimitry Andric mlir::Location loc = cgf.getLoc(e->getExprLoc());
284*700637cbSDimitry Andric if (e->getNumInits() == 2) {
285*700637cbSDimitry Andric mlir::Value real = cgf.emitScalarExpr(e->getInit(0));
286*700637cbSDimitry Andric mlir::Value imag = cgf.emitScalarExpr(e->getInit(1));
287*700637cbSDimitry Andric return builder.createComplexCreate(loc, real, imag);
288*700637cbSDimitry Andric }
289*700637cbSDimitry Andric
290*700637cbSDimitry Andric if (e->getNumInits() == 1) {
291*700637cbSDimitry Andric cgf.cgm.errorNYI("Create Complex with InitList with size 1");
292*700637cbSDimitry Andric return {};
293*700637cbSDimitry Andric }
294*700637cbSDimitry Andric
295*700637cbSDimitry Andric assert(e->getNumInits() == 0 && "Unexpected number of inits");
296*700637cbSDimitry Andric mlir::Type complexTy = cgf.convertType(e->getType());
297*700637cbSDimitry Andric return builder.getNullValue(complexTy, loc);
298*700637cbSDimitry Andric }
299*700637cbSDimitry Andric
300*700637cbSDimitry Andric mlir::Value
VisitImaginaryLiteral(const ImaginaryLiteral * il)301*700637cbSDimitry Andric ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
302*700637cbSDimitry Andric auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType()));
303*700637cbSDimitry Andric mlir::Type elementTy = ty.getElementType();
304*700637cbSDimitry Andric mlir::Location loc = cgf.getLoc(il->getExprLoc());
305*700637cbSDimitry Andric
306*700637cbSDimitry Andric mlir::TypedAttr realValueAttr;
307*700637cbSDimitry Andric mlir::TypedAttr imagValueAttr;
308*700637cbSDimitry Andric
309*700637cbSDimitry Andric if (mlir::isa<cir::IntType>(elementTy)) {
310*700637cbSDimitry Andric llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue();
311*700637cbSDimitry Andric realValueAttr = cir::IntAttr::get(elementTy, 0);
312*700637cbSDimitry Andric imagValueAttr = cir::IntAttr::get(elementTy, imagValue);
313*700637cbSDimitry Andric } else {
314*700637cbSDimitry Andric assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&
315*700637cbSDimitry Andric "Expected complex element type to be floating-point");
316*700637cbSDimitry Andric
317*700637cbSDimitry Andric llvm::APFloat imagValue =
318*700637cbSDimitry Andric cast<FloatingLiteral>(il->getSubExpr())->getValue();
319*700637cbSDimitry Andric realValueAttr = cir::FPAttr::get(
320*700637cbSDimitry Andric elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));
321*700637cbSDimitry Andric imagValueAttr = cir::FPAttr::get(elementTy, imagValue);
322*700637cbSDimitry Andric }
323*700637cbSDimitry Andric
324*700637cbSDimitry Andric auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
325*700637cbSDimitry Andric return builder.create<cir::ConstantOp>(loc, complexAttr);
326*700637cbSDimitry Andric }
327*700637cbSDimitry Andric
VisitParenExpr(ParenExpr * e)328*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitParenExpr(ParenExpr *e) {
329*700637cbSDimitry Andric return Visit(e->getSubExpr());
330*700637cbSDimitry Andric }
331*700637cbSDimitry Andric
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * e)332*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr(
333*700637cbSDimitry Andric SubstNonTypeTemplateParmExpr *e) {
334*700637cbSDimitry Andric return Visit(e->getReplacement());
335*700637cbSDimitry Andric }
336*700637cbSDimitry Andric
VisitUnaryDeref(const Expr * e)337*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) {
338*700637cbSDimitry Andric return emitLoadOfLValue(e);
339*700637cbSDimitry Andric }
340*700637cbSDimitry Andric
emitPromoted(const Expr * e,QualType promotionTy)341*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
342*700637cbSDimitry Andric QualType promotionTy) {
343*700637cbSDimitry Andric e = e->IgnoreParens();
344*700637cbSDimitry Andric if (const auto *bo = dyn_cast<BinaryOperator>(e)) {
345*700637cbSDimitry Andric switch (bo->getOpcode()) {
346*700637cbSDimitry Andric #define HANDLE_BINOP(OP) \
347*700637cbSDimitry Andric case BO_##OP: \
348*700637cbSDimitry Andric return emitBin##OP(emitBinOps(bo, promotionTy));
349*700637cbSDimitry Andric HANDLE_BINOP(Add)
350*700637cbSDimitry Andric HANDLE_BINOP(Sub)
351*700637cbSDimitry Andric #undef HANDLE_BINOP
352*700637cbSDimitry Andric default:
353*700637cbSDimitry Andric break;
354*700637cbSDimitry Andric }
355*700637cbSDimitry Andric } else if (isa<UnaryOperator>(e)) {
356*700637cbSDimitry Andric cgf.cgm.errorNYI("emitPromoted UnaryOperator");
357*700637cbSDimitry Andric return {};
358*700637cbSDimitry Andric }
359*700637cbSDimitry Andric
360*700637cbSDimitry Andric mlir::Value result = Visit(const_cast<Expr *>(e));
361*700637cbSDimitry Andric if (!promotionTy.isNull())
362*700637cbSDimitry Andric cgf.cgm.errorNYI("emitPromoted emitPromotedValue");
363*700637cbSDimitry Andric
364*700637cbSDimitry Andric return result;
365*700637cbSDimitry Andric }
366*700637cbSDimitry Andric
367*700637cbSDimitry Andric mlir::Value
emitPromotedComplexOperand(const Expr * e,QualType promotionTy)368*700637cbSDimitry Andric ComplexExprEmitter::emitPromotedComplexOperand(const Expr *e,
369*700637cbSDimitry Andric QualType promotionTy) {
370*700637cbSDimitry Andric if (e->getType()->isAnyComplexType()) {
371*700637cbSDimitry Andric if (!promotionTy.isNull())
372*700637cbSDimitry Andric return cgf.emitPromotedComplexExpr(e, promotionTy);
373*700637cbSDimitry Andric return Visit(const_cast<Expr *>(e));
374*700637cbSDimitry Andric }
375*700637cbSDimitry Andric
376*700637cbSDimitry Andric cgf.cgm.errorNYI("emitPromotedComplexOperand non-complex type");
377*700637cbSDimitry Andric return {};
378*700637cbSDimitry Andric }
379*700637cbSDimitry Andric
380*700637cbSDimitry Andric ComplexExprEmitter::BinOpInfo
emitBinOps(const BinaryOperator * e,QualType promotionTy)381*700637cbSDimitry Andric ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) {
382*700637cbSDimitry Andric BinOpInfo binOpInfo{cgf.getLoc(e->getExprLoc())};
383*700637cbSDimitry Andric binOpInfo.lhs = emitPromotedComplexOperand(e->getLHS(), promotionTy);
384*700637cbSDimitry Andric binOpInfo.rhs = emitPromotedComplexOperand(e->getRHS(), promotionTy);
385*700637cbSDimitry Andric binOpInfo.ty = promotionTy.isNull() ? e->getType() : promotionTy;
386*700637cbSDimitry Andric binOpInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
387*700637cbSDimitry Andric return binOpInfo;
388*700637cbSDimitry Andric }
389*700637cbSDimitry Andric
emitBinAdd(const BinOpInfo & op)390*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) {
391*700637cbSDimitry Andric assert(!cir::MissingFeatures::fastMathFlags());
392*700637cbSDimitry Andric assert(!cir::MissingFeatures::cgFPOptionsRAII());
393*700637cbSDimitry Andric return builder.create<cir::ComplexAddOp>(op.loc, op.lhs, op.rhs);
394*700637cbSDimitry Andric }
395*700637cbSDimitry Andric
emitBinSub(const BinOpInfo & op)396*700637cbSDimitry Andric mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) {
397*700637cbSDimitry Andric assert(!cir::MissingFeatures::fastMathFlags());
398*700637cbSDimitry Andric assert(!cir::MissingFeatures::cgFPOptionsRAII());
399*700637cbSDimitry Andric return builder.create<cir::ComplexSubOp>(op.loc, op.lhs, op.rhs);
400*700637cbSDimitry Andric }
401*700637cbSDimitry Andric
emitComplexAssignmentLValue(const BinaryOperator * e)402*700637cbSDimitry Andric LValue CIRGenFunction::emitComplexAssignmentLValue(const BinaryOperator *e) {
403*700637cbSDimitry Andric assert(e->getOpcode() == BO_Assign && "Expected assign op");
404*700637cbSDimitry Andric
405*700637cbSDimitry Andric mlir::Value value; // ignored
406*700637cbSDimitry Andric LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
407*700637cbSDimitry Andric if (getLangOpts().OpenMP)
408*700637cbSDimitry Andric cgm.errorNYI("emitComplexAssignmentLValue OpenMP");
409*700637cbSDimitry Andric
410*700637cbSDimitry Andric return lvalue;
411*700637cbSDimitry Andric }
412*700637cbSDimitry Andric
emitComplexExpr(const Expr * e)413*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) {
414*700637cbSDimitry Andric assert(e && getComplexType(e->getType()) &&
415*700637cbSDimitry Andric "Invalid complex expression to emit");
416*700637cbSDimitry Andric
417*700637cbSDimitry Andric return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e));
418*700637cbSDimitry Andric }
419*700637cbSDimitry Andric
emitStoreOfComplex(mlir::Location loc,mlir::Value v,LValue dest,bool isInit)420*700637cbSDimitry Andric void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
421*700637cbSDimitry Andric LValue dest, bool isInit) {
422*700637cbSDimitry Andric ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
423*700637cbSDimitry Andric }
424*700637cbSDimitry Andric
emitPromotedComplexExpr(const Expr * e,QualType promotionType)425*700637cbSDimitry Andric mlir::Value CIRGenFunction::emitPromotedComplexExpr(const Expr *e,
426*700637cbSDimitry Andric QualType promotionType) {
427*700637cbSDimitry Andric return ComplexExprEmitter(*this).emitPromoted(e, promotionType);
428*700637cbSDimitry Andric }
429