@@ -19,6 +19,13 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
1919 // Utilities
2020 // ===--------------------------------------------------------------------===//
2121
22+ LValue emitBinAssignLValue (const BinaryOperator *e, mlir::Value &val);
23+
24+ mlir::Value emitCast (CastKind ck, Expr *op, QualType destTy);
25+
26+ mlir::Value emitConstant (const CIRGenFunction::ConstantEmission &constant,
27+ Expr *e);
28+
2229 // / Given an expression with complex type that represents a value l-value,
2330 // / this method emits the address of the l-value, then loads and returns the
2431 // / result.
@@ -27,18 +34,18 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
2734 }
2835
2936 mlir::Value emitLoadOfLValue (LValue lv, SourceLocation loc);
30-
3137 // / Store the specified real/imag parts into the
3238 // / specified value pointer.
3339 void emitStoreOfComplex (mlir::Location loc, mlir::Value val, LValue lv,
3440 bool isInit);
3541
42+ mlir::Value VisitBinAssign (const BinaryOperator *e);
3643 mlir::Value VisitCallExpr (const CallExpr *e);
37- mlir::Value VisitInitListExpr (InitListExpr *e);
38-
44+ mlir::Value VisitDeclRefExpr (DeclRefExpr *e);
45+ mlir::Value VisitImplicitCastExpr (ImplicitCastExpr *e);
46+ mlir::Value VisitInitListExpr (const InitListExpr *e);
3947 mlir::Value VisitImaginaryLiteral (const ImaginaryLiteral *il);
4048};
41-
4249} // namespace
4350
4451static const ComplexType *getComplexType (QualType type) {
@@ -48,6 +55,46 @@ static const ComplexType *getComplexType(QualType type) {
4855 return cast<ComplexType>(cast<AtomicType>(type)->getValueType ());
4956}
5057
58+ LValue ComplexExprEmitter::emitBinAssignLValue (const BinaryOperator *e,
59+ mlir::Value &value) {
60+ assert (cgf.getContext ().hasSameUnqualifiedType (e->getLHS ()->getType (),
61+ e->getRHS ()->getType ()) &&
62+ " Invalid assignment" );
63+
64+ // Emit the RHS. __block variables need the RHS evaluated first.
65+ value = Visit (e->getRHS ());
66+
67+ // Compute the address to store into.
68+ LValue lhs = cgf.emitLValue (e->getLHS ());
69+
70+ // Store the result value into the LHS lvalue.
71+ emitStoreOfComplex (cgf.getLoc (e->getExprLoc ()), value, lhs, /* isInit*/ false );
72+ return lhs;
73+ }
74+
75+ mlir::Value ComplexExprEmitter::emitCast (CastKind ck, Expr *op,
76+ QualType destTy) {
77+ switch (ck) {
78+ case CK_LValueToRValue:
79+ return Visit (op);
80+ default :
81+ cgf.cgm .errorNYI (" ComplexType Cast" );
82+ break ;
83+ }
84+ return {};
85+ }
86+
87+ mlir::Value ComplexExprEmitter::emitConstant (
88+ const CIRGenFunction::ConstantEmission &constant, Expr *e) {
89+ assert (constant && " not a constant" );
90+ if (constant.isReference ())
91+ return emitLoadOfLValue (constant.getReferenceLValue (cgf, e),
92+ e->getExprLoc ());
93+
94+ mlir::TypedAttr valueAttr = constant.getValue ();
95+ return builder.getConstant (cgf.getLoc (e->getSourceRange ()), valueAttr);
96+ }
97+
5198mlir::Value ComplexExprEmitter::emitLoadOfLValue (LValue lv,
5299 SourceLocation loc) {
53100 assert (lv.isSimple () && " non-simple complex l-value?" );
@@ -70,14 +117,44 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
70117 builder.createStore (loc, val, destAddr);
71118}
72119
120+ mlir::Value ComplexExprEmitter::VisitBinAssign (const BinaryOperator *e) {
121+ mlir::Value value;
122+ LValue lv = emitBinAssignLValue (e, value);
123+
124+ // The result of an assignment in C is the assigned r-value.
125+ if (!cgf.getLangOpts ().CPlusPlus )
126+ return value;
127+
128+ // If the lvalue is non-volatile, return the computed value of the
129+ // assignment.
130+ if (!lv.isVolatile ())
131+ return value;
132+
133+ return emitLoadOfLValue (lv, e->getExprLoc ());
134+ }
135+
73136mlir::Value ComplexExprEmitter::VisitCallExpr (const CallExpr *e) {
74137 if (e->getCallReturnType (cgf.getContext ())->isReferenceType ())
75138 return emitLoadOfLValue (e);
76139
77140 return cgf.emitCallExpr (e).getValue ();
78141}
79142
80- mlir::Value ComplexExprEmitter::VisitInitListExpr (InitListExpr *e) {
143+ mlir::Value ComplexExprEmitter::VisitDeclRefExpr (DeclRefExpr *e) {
144+ if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant (e))
145+ return emitConstant (constant, e);
146+ return emitLoadOfLValue (e);
147+ }
148+
149+ mlir::Value ComplexExprEmitter::VisitImplicitCastExpr (ImplicitCastExpr *e) {
150+ // Unlike for scalars, we don't have to worry about function->ptr demotion
151+ // here.
152+ if (e->changesVolatileQualification ())
153+ return emitLoadOfLValue (e);
154+ return emitCast (e->getCastKind (), e->getSubExpr (), e->getType ());
155+ }
156+
157+ mlir::Value ComplexExprEmitter::VisitInitListExpr (const InitListExpr *e) {
81158 mlir::Location loc = cgf.getLoc (e->getExprLoc ());
82159 if (e->getNumInits () == 2 ) {
83160 mlir::Value real = cgf.emitScalarExpr (e->getInit (0 ));
@@ -127,6 +204,17 @@ ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
127204 return builder.create <cir::ConstantOp>(loc, complexAttr);
128205}
129206
207+ LValue CIRGenFunction::emitComplexAssignmentLValue (const BinaryOperator *e) {
208+ assert (e->getOpcode () == BO_Assign && " Expected assign op" );
209+
210+ mlir::Value value; // ignored
211+ LValue lvalue = ComplexExprEmitter (*this ).emitBinAssignLValue (e, value);
212+ if (getLangOpts ().OpenMP )
213+ cgm.errorNYI (" emitComplexAssignmentLValue OpenMP" );
214+
215+ return lvalue;
216+ }
217+
130218mlir::Value CIRGenFunction::emitComplexExpr (const Expr *e) {
131219 assert (e && getComplexType (e->getType ()) &&
132220 " Invalid complex expression to emit" );
0 commit comments