@@ -238,8 +238,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
238238 case CK_DerivedToBaseMemberPointer: {
239239 assert (classifyPrim (CE->getType ()) == PT_MemberPtr);
240240 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>();
243243
244244 unsigned DerivedOffset =
245245 Ctx.collectBaseOffset (ToMP->getMostRecentCXXRecordDecl (),
@@ -254,8 +254,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
254254 case CK_BaseToDerivedMemberPointer: {
255255 assert (classifyPrim (CE) == PT_MemberPtr);
256256 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>();
259259
260260 unsigned DerivedOffset =
261261 Ctx.collectBaseOffset (FromMP->getMostRecentCXXRecordDecl (),
@@ -320,37 +320,36 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
320320 }
321321
322322 case CK_IntegralToFloating: {
323- std::optional<PrimType> FromT = classify (SubExpr->getType ());
324- if (!FromT)
325- return false ;
326-
327323 if (!this ->visit (SubExpr))
328324 return false ;
329-
330325 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);
333328 }
334329
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 ())
341333 return false ;
342-
334+ if (const auto *FL = dyn_cast<FloatingLiteral>(SubExpr))
335+ return this ->emitConstBool (FL->getValue ().isNonZero (), CE);
343336 if (!this ->visit (SubExpr))
344337 return false ;
338+ return this ->emitCastFloatingIntegralBool (getFPOptions (CE), CE);
339+ }
345340
341+ case CK_FloatingToIntegral: {
342+ if (!this ->visit (SubExpr))
343+ return false ;
344+ PrimType ToT = classifyPrim (CE);
346345 if (ToT == PT_IntAP)
347346 return this ->emitCastFloatingIntegralAP (Ctx.getBitWidth (CE->getType ()),
348347 getFPOptions (CE), CE);
349348 if (ToT == PT_IntAPS)
350349 return this ->emitCastFloatingIntegralAPS (Ctx.getBitWidth (CE->getType ()),
351350 getFPOptions (CE), CE);
352351
353- return this ->emitCastFloatingIntegral (* ToT, getFPOptions (CE), CE);
352+ return this ->emitCastFloatingIntegral (ToT, getFPOptions (CE), CE);
354353 }
355354
356355 case CK_NullToPointer:
@@ -395,9 +394,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
395394 case CK_ArrayToPointerDecay: {
396395 if (!this ->visit (SubExpr))
397396 return false ;
398- if (!this ->emitArrayDecay (CE))
399- return false ;
400- return true ;
397+ return this ->emitArrayDecay (CE);
401398 }
402399
403400 case CK_IntegralToPointer: {
@@ -480,47 +477,63 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
480477 return this ->emitBuiltinBitCast (CE);
481478
482479 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+
484493 case CK_BooleanToSignedIntegral:
485494 case CK_IntegralCast: {
486495 std::optional<PrimType> FromT = classify (SubExpr->getType ());
487496 std::optional<PrimType> ToT = classify (CE->getType ());
488-
489497 if (!FromT || !ToT)
490498 return false ;
491499
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+ }
494511
495512 // Possibly diagnose casts to enum types if the target type does not
496513 // have a fixed size.
497514 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 ()) {
500517 if (!this ->emitCheckEnumValue (*FromT, ET->getDecl (), CE))
501518 return false ;
502519 }
503520 }
504521
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 ;
524537 }
525538
526539 case CK_PointerToBoolean:
0 commit comments