@@ -19,6 +19,13 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
19
19
// Utilities
20
20
// ===--------------------------------------------------------------------===//
21
21
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
+
22
29
// / Given an expression with complex type that represents a value l-value,
23
30
// / this method emits the address of the l-value, then loads and returns the
24
31
// / result.
@@ -27,18 +34,18 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
27
34
}
28
35
29
36
mlir::Value emitLoadOfLValue (LValue lv, SourceLocation loc);
30
-
31
37
// / Store the specified real/imag parts into the
32
38
// / specified value pointer.
33
39
void emitStoreOfComplex (mlir::Location loc, mlir::Value val, LValue lv,
34
40
bool isInit);
35
41
42
+ mlir::Value VisitBinAssign (const BinaryOperator *e);
36
43
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);
39
47
mlir::Value VisitImaginaryLiteral (const ImaginaryLiteral *il);
40
48
};
41
-
42
49
} // namespace
43
50
44
51
static const ComplexType *getComplexType (QualType type) {
@@ -48,6 +55,46 @@ static const ComplexType *getComplexType(QualType type) {
48
55
return cast<ComplexType>(cast<AtomicType>(type)->getValueType ());
49
56
}
50
57
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
+
51
98
mlir::Value ComplexExprEmitter::emitLoadOfLValue (LValue lv,
52
99
SourceLocation loc) {
53
100
assert (lv.isSimple () && " non-simple complex l-value?" );
@@ -70,14 +117,44 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
70
117
builder.createStore (loc, val, destAddr);
71
118
}
72
119
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
+
73
136
mlir::Value ComplexExprEmitter::VisitCallExpr (const CallExpr *e) {
74
137
if (e->getCallReturnType (cgf.getContext ())->isReferenceType ())
75
138
return emitLoadOfLValue (e);
76
139
77
140
return cgf.emitCallExpr (e).getValue ();
78
141
}
79
142
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) {
81
158
mlir::Location loc = cgf.getLoc (e->getExprLoc ());
82
159
if (e->getNumInits () == 2 ) {
83
160
mlir::Value real = cgf.emitScalarExpr (e->getInit (0 ));
@@ -127,6 +204,17 @@ ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
127
204
return builder.create <cir::ConstantOp>(loc, complexAttr);
128
205
}
129
206
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
+
130
218
mlir::Value CIRGenFunction::emitComplexExpr (const Expr *e) {
131
219
assert (e && getComplexType (e->getType ()) &&
132
220
" Invalid complex expression to emit" );
0 commit comments