@@ -1307,34 +1307,24 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
1307
1307
}
1308
1308
InConstantContext = D.hasConstantInitialization ();
1309
1309
1310
+ const Expr * E = D.getInit ();
1311
+ assert (E && " No initializer to emit" );
1312
+
1310
1313
QualType destType = D.getType ();
1311
1314
1315
+ if (!destType->isReferenceType ()) {
1316
+ QualType nonMemoryDestType = getNonMemoryType (CGM, destType);
1317
+ if (auto C = ConstExprEmitter (*this ).Visit (const_cast <Expr *>(E),
1318
+ nonMemoryDestType))
1319
+ return emitForMemory (C, destType);
1320
+ }
1321
+
1312
1322
// Try to emit the initializer. Note that this can allow some things that
1313
1323
// are not allowed by tryEmitPrivateForMemory alone.
1314
- if (auto value = D.evaluateValue ()) {
1324
+ if (auto value = D.evaluateValue ())
1315
1325
return tryEmitPrivateForMemory (*value, destType);
1316
- }
1317
-
1318
- // FIXME: Implement C++11 [basic.start.init]p2: if the initializer of a
1319
- // reference is a constant expression, and the reference binds to a temporary,
1320
- // then constant initialization is performed. ConstExprEmitter will
1321
- // incorrectly emit a prvalue constant in this case, and the calling code
1322
- // interprets that as the (pointer) value of the reference, rather than the
1323
- // desired value of the referee.
1324
- if (destType->isReferenceType ())
1325
- return {};
1326
-
1327
- // Evaluation failed and not a reference type: ensure initializer exists.
1328
- const Expr *E = D.getInit ();
1329
- assert (E && " No initializer to emit" );
1330
1326
1331
- // Initializer exists: emit it "manually" through visitors.
1332
- auto nonMemoryDestType = getNonMemoryType (CGM, destType);
1333
- auto C =
1334
- ConstExprEmitter (*this ).Visit (const_cast <Expr *>(E), nonMemoryDestType);
1335
-
1336
- // Return either the initializer attribute or a null attribute on failure.
1337
- return (C ? emitForMemory (C, destType) : nullptr );
1327
+ return nullptr ;
1338
1328
}
1339
1329
1340
1330
mlir::Attribute ConstantEmitter::tryEmitAbstract (const Expr *E,
@@ -1405,30 +1395,34 @@ mlir::Attribute ConstantEmitter::emitForMemory(CIRGenModule &CGM,
1405
1395
return C;
1406
1396
}
1407
1397
1408
- mlir::TypedAttr ConstantEmitter::tryEmitPrivate (const Expr *E, QualType T) {
1409
- assert (!T->isVoidType () && " can't emit a void constant" );
1410
- Expr::EvalResult Result;
1411
- bool Success;
1398
+ mlir::TypedAttr ConstantEmitter::tryEmitPrivate (const Expr *E,
1399
+ QualType destType) {
1400
+ assert (!destType->isVoidType () && " can't emit a void constant" );
1412
1401
1413
- // TODO: Implement the missing functionalities below.
1414
- assert (!T->isReferenceType () && " NYI" );
1402
+ if (auto C = ConstExprEmitter (*this ).Visit (const_cast <Expr *>(E), destType)) {
1403
+ if (auto TypedC = C.dyn_cast_or_null <mlir::TypedAttr>())
1404
+ return TypedC;
1405
+ llvm_unreachable (" this should always be typed" );
1406
+ }
1415
1407
1416
- // NOTE: Not all constant expressions can be emited by the ConstExprEmitter.
1417
- // So we have to fold/evaluate the expression in some cases.
1418
- //
1419
- // Try folding constant expression into an RValue.
1420
- Success = E->EvaluateAsRValue (Result, CGM.getASTContext (), InConstantContext);
1408
+ Expr::EvalResult Result;
1421
1409
1422
- mlir::Attribute C;
1423
- if (Success && !Result.HasSideEffects )
1424
- C = tryEmitPrivate (Result.Val , T);
1410
+ bool Success;
1411
+
1412
+ if (destType->isReferenceType ())
1413
+ Success = E->EvaluateAsLValue (Result, CGM.getASTContext ());
1425
1414
else
1426
- C = ConstExprEmitter (*this ).Visit (const_cast <Expr *>(E), T);
1415
+ Success =
1416
+ E->EvaluateAsRValue (Result, CGM.getASTContext (), InConstantContext);
1427
1417
1428
- auto typedC = llvm::dyn_cast<mlir::TypedAttr>(C);
1429
- if (!typedC)
1418
+ if (Success && !Result.hasSideEffects ()) {
1419
+ auto C = tryEmitPrivate (Result.Val , destType);
1420
+ if (auto TypedC = C.dyn_cast_or_null <mlir::TypedAttr>())
1421
+ return TypedC;
1430
1422
llvm_unreachable (" this should always be typed" );
1431
- return typedC;
1423
+ }
1424
+
1425
+ return nullptr ;
1432
1426
}
1433
1427
1434
1428
mlir::Attribute ConstantEmitter::tryEmitPrivate (const APValue &Value,
0 commit comments