@@ -238,8 +238,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
238
238
case CK_DerivedToBaseMemberPointer: {
239
239
assert (classifyPrim (CE->getType ()) == PT_MemberPtr);
240
240
assert (classifyPrim (SubExpr->getType ()) == PT_MemberPtr);
241
- const auto *FromMP = SubExpr->getType ()->getAs <MemberPointerType>();
242
- const auto *ToMP = CE->getType ()->getAs <MemberPointerType>();
241
+ const auto *FromMP = SubExpr->getType ()->castAs <MemberPointerType>();
242
+ const auto *ToMP = CE->getType ()->castAs <MemberPointerType>();
243
243
244
244
unsigned DerivedOffset =
245
245
Ctx.collectBaseOffset (ToMP->getMostRecentCXXRecordDecl (),
@@ -254,8 +254,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
254
254
case CK_BaseToDerivedMemberPointer: {
255
255
assert (classifyPrim (CE) == PT_MemberPtr);
256
256
assert (classifyPrim (SubExpr) == PT_MemberPtr);
257
- const auto *FromMP = SubExpr->getType ()->getAs <MemberPointerType>();
258
- const auto *ToMP = CE->getType ()->getAs <MemberPointerType>();
257
+ const auto *FromMP = SubExpr->getType ()->castAs <MemberPointerType>();
258
+ const auto *ToMP = CE->getType ()->castAs <MemberPointerType>();
259
259
260
260
unsigned DerivedOffset =
261
261
Ctx.collectBaseOffset (FromMP->getMostRecentCXXRecordDecl (),
@@ -320,37 +320,38 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
320
320
}
321
321
322
322
case CK_IntegralToFloating: {
323
- std::optional<PrimType> FromT = classify (SubExpr->getType ());
324
- if (!FromT)
323
+ if (!CE->getType ()->isRealFloatingType ())
325
324
return false ;
326
-
327
325
if (!this ->visit (SubExpr))
328
326
return false ;
329
-
330
327
const auto *TargetSemantics = &Ctx.getFloatSemantics (CE->getType ());
331
- return this ->emitCastIntegralFloating (*FromT, TargetSemantics,
332
- getFPOptions (CE), CE);
328
+ return this ->emitCastIntegralFloating (
329
+ classifyPrim (SubExpr), TargetSemantics, getFPOptions (CE), CE);
333
330
}
334
331
335
- case CK_FloatingToBoolean:
336
- case CK_FloatingToIntegral: {
337
-
338
- std::optional<PrimType> ToT = classify (CE->getType ());
339
-
340
- if (!ToT)
332
+ case CK_FloatingToBoolean: {
333
+ if (!SubExpr->getType ()->isRealFloatingType () ||
334
+ !CE->getType ()->isBooleanType ())
341
335
return false ;
342
-
336
+ if (const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
337
+ return this ->emitConstBool (FL->getValue ().isNonZero (), CE);
343
338
if (!this ->visit (SubExpr))
344
339
return false ;
340
+ return this ->emitCastFloatingIntegralBool (getFPOptions (CE), CE);
341
+ }
345
342
343
+ case CK_FloatingToIntegral: {
344
+ if (!this ->visit (SubExpr))
345
+ return false ;
346
+ PrimType ToT = classifyPrim (CE);
346
347
if (ToT == PT_IntAP)
347
348
return this ->emitCastFloatingIntegralAP (Ctx.getBitWidth (CE->getType ()),
348
349
getFPOptions (CE), CE);
349
350
if (ToT == PT_IntAPS)
350
351
return this ->emitCastFloatingIntegralAPS (Ctx.getBitWidth (CE->getType ()),
351
352
getFPOptions (CE), CE);
352
353
353
- return this ->emitCastFloatingIntegral (* ToT, getFPOptions (CE), CE);
354
+ return this ->emitCastFloatingIntegral (ToT, getFPOptions (CE), CE);
354
355
}
355
356
356
357
case CK_NullToPointer:
@@ -395,9 +396,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
395
396
case CK_ArrayToPointerDecay: {
396
397
if (!this ->visit (SubExpr))
397
398
return false ;
398
- if (!this ->emitArrayDecay (CE))
399
- return false ;
400
- return true ;
399
+ return this ->emitArrayDecay (CE);
401
400
}
402
401
403
402
case CK_IntegralToPointer: {
@@ -480,47 +479,63 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
480
479
return this ->emitBuiltinBitCast (CE);
481
480
482
481
case CK_IntegralToBoolean:
483
- case CK_FixedPointToBoolean:
482
+ case CK_FixedPointToBoolean: {
483
+ // HLSL uses this to cast to one-element vectors.
484
+ std::optional<PrimType> FromT = classify (SubExpr->getType ());
485
+ if (!FromT)
486
+ return false ;
487
+
488
+ if (const auto *IL = dyn_cast<IntegerLiteral>(SubExpr))
489
+ return this ->emitConst (IL->getValue (), CE);
490
+ if (!this ->visit (SubExpr))
491
+ return false ;
492
+ return this ->emitCast (*FromT, classifyPrim (CE), CE);
493
+ }
494
+
484
495
case CK_BooleanToSignedIntegral:
485
496
case CK_IntegralCast: {
486
497
std::optional<PrimType> FromT = classify (SubExpr->getType ());
487
498
std::optional<PrimType> ToT = classify (CE->getType ());
488
-
489
499
if (!FromT || !ToT)
490
500
return false ;
491
501
492
- if (!this ->visit (SubExpr))
493
- return false ;
502
+ // Try to emit a casted known constant value directly.
503
+ if (const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
504
+ if (ToT != PT_IntAP && ToT != PT_IntAPS && FromT != PT_IntAP &&
505
+ FromT != PT_IntAPS && !CE->getType ()->isEnumeralType ())
506
+ return this ->emitConst (IL->getValue (), CE);
507
+ if (!this ->emitConst (IL->getValue (), SubExpr))
508
+ return false ;
509
+ } else {
510
+ if (!this ->visit (SubExpr))
511
+ return false ;
512
+ }
494
513
495
514
// Possibly diagnose casts to enum types if the target type does not
496
515
// have a fixed size.
497
516
if (Ctx.getLangOpts ().CPlusPlus && CE->getType ()->isEnumeralType ()) {
498
- if (const auto *ET = CE->getType ().getCanonicalType ()->getAs <EnumType>();
499
- ET && !ET->getDecl ()->isFixed ()) {
517
+ if (const auto *ET = CE->getType ().getCanonicalType ()->castAs <EnumType>();
518
+ !ET->getDecl ()->isFixed ()) {
500
519
if (!this ->emitCheckEnumValue (*FromT, ET->getDecl (), CE))
501
520
return false ;
502
521
}
503
522
}
504
523
505
- auto maybeNegate = [&]() -> bool {
506
- if (CE->getCastKind () == CK_BooleanToSignedIntegral)
507
- return this ->emitNeg (*ToT, CE);
508
- return true ;
509
- };
510
-
511
- if (ToT == PT_IntAP)
512
- return this ->emitCastAP (*FromT, Ctx.getBitWidth (CE->getType ()), CE) &&
513
- maybeNegate ();
514
- if (ToT == PT_IntAPS)
515
- return this ->emitCastAPS (*FromT, Ctx.getBitWidth (CE->getType ()), CE) &&
516
- maybeNegate ();
517
-
518
- if (FromT == ToT)
519
- return true ;
520
- if (!this ->emitCast (*FromT, *ToT, CE))
521
- return false ;
522
-
523
- return maybeNegate ();
524
+ if (ToT == PT_IntAP) {
525
+ if (!this ->emitCastAP (*FromT, Ctx.getBitWidth (CE->getType ()), CE))
526
+ return false ;
527
+ } else if (ToT == PT_IntAPS) {
528
+ if (!this ->emitCastAPS (*FromT, Ctx.getBitWidth (CE->getType ()), CE))
529
+ return false ;
530
+ } else {
531
+ if (FromT == ToT)
532
+ return true ;
533
+ if (!this ->emitCast (*FromT, *ToT, CE))
534
+ return false ;
535
+ }
536
+ if (CE->getCastKind () == CK_BooleanToSignedIntegral)
537
+ return this ->emitNeg (*ToT, CE);
538
+ return true ;
524
539
}
525
540
526
541
case CK_PointerToBoolean:
0 commit comments