@@ -2959,6 +2959,8 @@ bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
2959
2959
template <class Emitter >
2960
2960
bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
2961
2961
const Expr *SubExpr = E->getSubExpr ();
2962
+ if (SubExpr->getType ()->isAnyComplexType ())
2963
+ return this ->VisitComplexUnaryOperator (E);
2962
2964
std::optional<PrimType> T = classify (SubExpr->getType ());
2963
2965
2964
2966
switch (E->getOpcode ()) {
@@ -3109,16 +3111,81 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
3109
3111
return false ;
3110
3112
return DiscardResult ? this ->emitPop (*T, E) : this ->emitComp (*T, E);
3111
3113
case UO_Real: // __real x
3112
- if (T)
3113
- return this ->delegate (SubExpr);
3114
- return this ->emitComplexReal (SubExpr);
3114
+ assert (T);
3115
+ return this ->delegate (SubExpr);
3115
3116
case UO_Imag: { // __imag x
3116
- if (T) {
3117
- if (!this ->discard (SubExpr))
3117
+ assert (T);
3118
+ if (!this ->discard (SubExpr))
3119
+ return false ;
3120
+ return this ->visitZeroInitializer (*T, SubExpr->getType (), SubExpr);
3121
+ }
3122
+ case UO_Extension:
3123
+ return this ->delegate (SubExpr);
3124
+ case UO_Coawait:
3125
+ assert (false && " Unhandled opcode" );
3126
+ }
3127
+
3128
+ return false ;
3129
+ }
3130
+
3131
+ template <class Emitter >
3132
+ bool ByteCodeExprGen<Emitter>::VisitComplexUnaryOperator(
3133
+ const UnaryOperator *E) {
3134
+ const Expr *SubExpr = E->getSubExpr ();
3135
+ assert (SubExpr->getType ()->isAnyComplexType ());
3136
+
3137
+ if (DiscardResult)
3138
+ return this ->discard (SubExpr);
3139
+
3140
+ std::optional<PrimType> ResT = classify (E);
3141
+
3142
+ // Prepare storage for result.
3143
+ if (!ResT && !Initializing) {
3144
+ std::optional<unsigned > LocalIndex =
3145
+ allocateLocal (SubExpr, /* IsExtended=*/ false );
3146
+ if (!LocalIndex)
3147
+ return false ;
3148
+ if (!this ->emitGetPtrLocal (*LocalIndex, E))
3149
+ return false ;
3150
+ }
3151
+
3152
+ // The offset of the temporary, if we created one.
3153
+ unsigned SubExprOffset = ~0u ;
3154
+ auto createTemp = [=, &SubExprOffset]() -> bool {
3155
+ SubExprOffset = this ->allocateLocalPrimitive (SubExpr, PT_Ptr, true , false );
3156
+ if (!this ->visit (SubExpr))
3157
+ return false ;
3158
+ return this ->emitSetLocal (PT_Ptr, SubExprOffset, E);
3159
+ };
3160
+
3161
+ PrimType ElemT = classifyComplexElementType (SubExpr->getType ());
3162
+ auto getElem = [=](unsigned Offset, unsigned Index) -> bool {
3163
+ if (!this ->emitGetLocal (PT_Ptr, Offset, E))
3164
+ return false ;
3165
+ return this ->emitArrayElemPop (ElemT, Index, E);
3166
+ };
3167
+
3168
+ switch (E->getOpcode ()) {
3169
+ case UO_Minus:
3170
+ if (!createTemp ())
3171
+ return false ;
3172
+ for (unsigned I = 0 ; I != 2 ; ++I) {
3173
+ if (!getElem (SubExprOffset, I))
3174
+ return false ;
3175
+ if (!this ->emitNeg (ElemT, E))
3176
+ return false ;
3177
+ if (!this ->emitInitElem (ElemT, I, E))
3118
3178
return false ;
3119
- return this ->visitZeroInitializer (*T, SubExpr->getType (), SubExpr);
3120
3179
}
3180
+ break ;
3181
+
3182
+ case UO_AddrOf:
3183
+ return this ->delegate (SubExpr);
3121
3184
3185
+ case UO_Real:
3186
+ return this ->emitComplexReal (SubExpr);
3187
+
3188
+ case UO_Imag:
3122
3189
if (!this ->visit (SubExpr))
3123
3190
return false ;
3124
3191
@@ -3131,14 +3198,12 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
3131
3198
// Since our _Complex implementation does not map to a primitive type,
3132
3199
// we sometimes have to do the lvalue-to-rvalue conversion here manually.
3133
3200
return this ->emitArrayElemPop (classifyPrim (E->getType ()), 1 , E);
3134
- }
3135
- case UO_Extension:
3136
- return this ->delegate (SubExpr);
3137
- case UO_Coawait:
3138
- assert (false && " Unhandled opcode" );
3201
+
3202
+ default :
3203
+ return this ->emitInvalid (E);
3139
3204
}
3140
3205
3141
- return false ;
3206
+ return true ;
3142
3207
}
3143
3208
3144
3209
template <class Emitter >
0 commit comments