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