@@ -4294,6 +4294,20 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4294
4294
return From;
4295
4295
}
4296
4296
4297
+ // adjustVectorType - Compute the intermediate cast type casting elements of the
4298
+ // from type to the elements of the to type without resizing the vector.
4299
+ static QualType adjustVectorType (ASTContext &Context, QualType FromTy,
4300
+ QualType ToType, QualType *ElTy = nullptr ) {
4301
+ auto *ToVec = ToType->castAs <VectorType>();
4302
+ QualType ElType = ToVec->getElementType ();
4303
+ if (ElTy)
4304
+ *ElTy = ElType;
4305
+ if (!FromTy->isVectorType ())
4306
+ return ElType;
4307
+ auto *FromVec = FromTy->castAs <VectorType>();
4308
+ return Context.getExtVectorType (ElType, FromVec->getNumElements ());
4309
+ }
4310
+
4297
4311
ExprResult
4298
4312
Sema::PerformImplicitConversion (Expr *From, QualType ToType,
4299
4313
const StandardConversionSequence& SCS,
@@ -4443,27 +4457,36 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4443
4457
break ;
4444
4458
4445
4459
case ICK_Integral_Promotion:
4446
- case ICK_Integral_Conversion:
4447
- if (ToType->isBooleanType ()) {
4460
+ case ICK_Integral_Conversion: {
4461
+ QualType ElTy = ToType;
4462
+ QualType StepTy = ToType;
4463
+ if (ToType->isVectorType ())
4464
+ StepTy = adjustVectorType (Context, FromType, ToType, &ElTy);
4465
+ if (ElTy->isBooleanType ()) {
4448
4466
assert (FromType->castAs <EnumType>()->getDecl ()->isFixed () &&
4449
4467
SCS.Second == ICK_Integral_Promotion &&
4450
4468
" only enums with fixed underlying type can promote to bool" );
4451
- From = ImpCastExprToType (From, ToType , CK_IntegralToBoolean, VK_PRValue,
4469
+ From = ImpCastExprToType (From, StepTy , CK_IntegralToBoolean, VK_PRValue,
4452
4470
/* BasePath=*/ nullptr , CCK)
4453
4471
.get ();
4454
4472
} else {
4455
- From = ImpCastExprToType (From, ToType , CK_IntegralCast, VK_PRValue,
4473
+ From = ImpCastExprToType (From, StepTy , CK_IntegralCast, VK_PRValue,
4456
4474
/* BasePath=*/ nullptr , CCK)
4457
4475
.get ();
4458
4476
}
4459
4477
break ;
4478
+ }
4460
4479
4461
4480
case ICK_Floating_Promotion:
4462
- case ICK_Floating_Conversion:
4463
- From = ImpCastExprToType (From, ToType, CK_FloatingCast, VK_PRValue,
4481
+ case ICK_Floating_Conversion: {
4482
+ QualType StepTy = ToType;
4483
+ if (ToType->isVectorType ())
4484
+ StepTy = adjustVectorType (Context, FromType, ToType);
4485
+ From = ImpCastExprToType (From, StepTy, CK_FloatingCast, VK_PRValue,
4464
4486
/* BasePath=*/ nullptr , CCK)
4465
4487
.get ();
4466
4488
break ;
4489
+ }
4467
4490
4468
4491
case ICK_Complex_Promotion:
4469
4492
case ICK_Complex_Conversion: {
@@ -4486,16 +4509,21 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4486
4509
break ;
4487
4510
}
4488
4511
4489
- case ICK_Floating_Integral:
4490
- if (ToType->isRealFloatingType ())
4491
- From = ImpCastExprToType (From, ToType, CK_IntegralToFloating, VK_PRValue,
4512
+ case ICK_Floating_Integral: {
4513
+ QualType ElTy = ToType;
4514
+ QualType StepTy = ToType;
4515
+ if (ToType->isVectorType ())
4516
+ StepTy = adjustVectorType (Context, FromType, ToType, &ElTy);
4517
+ if (ElTy->isRealFloatingType ())
4518
+ From = ImpCastExprToType (From, StepTy, CK_IntegralToFloating, VK_PRValue,
4492
4519
/* BasePath=*/ nullptr , CCK)
4493
4520
.get ();
4494
4521
else
4495
- From = ImpCastExprToType (From, ToType , CK_FloatingToIntegral, VK_PRValue,
4522
+ From = ImpCastExprToType (From, StepTy , CK_FloatingToIntegral, VK_PRValue,
4496
4523
/* BasePath=*/ nullptr , CCK)
4497
4524
.get ();
4498
4525
break ;
4526
+ }
4499
4527
4500
4528
case ICK_Fixed_Point_Conversion:
4501
4529
assert ((FromType->isFixedPointType () || ToType->isFixedPointType ()) &&
@@ -4617,18 +4645,26 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4617
4645
break ;
4618
4646
}
4619
4647
4620
- case ICK_Boolean_Conversion:
4648
+ case ICK_Boolean_Conversion: {
4621
4649
// Perform half-to-boolean conversion via float.
4622
4650
if (From->getType ()->isHalfType ()) {
4623
4651
From = ImpCastExprToType (From, Context.FloatTy , CK_FloatingCast).get ();
4624
4652
FromType = Context.FloatTy ;
4625
4653
}
4654
+ QualType ElTy = FromType;
4655
+ QualType StepTy = ToType;
4656
+ if (FromType->isVectorType ()) {
4657
+ if (getLangOpts ().HLSL )
4658
+ StepTy = adjustVectorType (Context, FromType, ToType);
4659
+ ElTy = FromType->castAs <VectorType>()->getElementType ();
4660
+ }
4626
4661
4627
- From = ImpCastExprToType (From, Context. BoolTy ,
4628
- ScalarTypeToBooleanCastKind (FromType), VK_PRValue,
4662
+ From = ImpCastExprToType (From, StepTy, ScalarTypeToBooleanCastKind (ElTy) ,
4663
+ VK_PRValue,
4629
4664
/* BasePath=*/ nullptr , CCK)
4630
4665
.get ();
4631
4666
break ;
4667
+ }
4632
4668
4633
4669
case ICK_Derived_To_Base: {
4634
4670
CXXCastPath BasePath;
@@ -4754,22 +4790,6 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4754
4790
CK_ZeroToOCLOpaqueType,
4755
4791
From->getValueKind ()).get ();
4756
4792
break ;
4757
- case ICK_HLSL_Vector_Truncation: {
4758
- // Note: HLSL built-in vectors are ExtVectors. Since this truncates a vector
4759
- // to a smaller vector, this can only operate on arguments where the source
4760
- // and destination types are ExtVectors.
4761
- assert (From->getType ()->isExtVectorType () && ToType->isExtVectorType () &&
4762
- " HLSL vector truncation should only apply to ExtVectors" );
4763
- auto *FromVec = From->getType ()->castAs <VectorType>();
4764
- auto *ToVec = ToType->castAs <VectorType>();
4765
- QualType ElType = FromVec->getElementType ();
4766
- QualType TruncTy =
4767
- Context.getExtVectorType (ElType, ToVec->getNumElements ());
4768
- From = ImpCastExprToType (From, TruncTy, CK_HLSLVectorTruncation,
4769
- From->getValueKind ())
4770
- .get ();
4771
- break ;
4772
- }
4773
4793
4774
4794
case ICK_Lvalue_To_Rvalue:
4775
4795
case ICK_Array_To_Pointer:
@@ -4780,73 +4800,45 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
4780
4800
case ICK_C_Only_Conversion:
4781
4801
case ICK_Incompatible_Pointer_Conversion:
4782
4802
case ICK_HLSL_Array_RValue:
4803
+ case ICK_HLSL_Vector_Truncation:
4804
+ case ICK_HLSL_Vector_Splat:
4783
4805
llvm_unreachable (" Improper second standard conversion" );
4784
4806
}
4785
4807
4786
- if (SCS.Element != ICK_Identity) {
4808
+ if (SCS.Dimension != ICK_Identity) {
4787
4809
// If SCS.Element is not ICK_Identity the To and From types must be HLSL
4788
4810
// vectors or matrices.
4789
4811
4790
4812
// TODO: Support HLSL matrices.
4791
4813
assert ((!From->getType ()->isMatrixType () && !ToType->isMatrixType ()) &&
4792
- " Element conversion for matrix types is not implemented yet." );
4793
- assert (From->getType ()->isVectorType () && ToType->isVectorType () &&
4794
- " Element conversion is only supported for vector types." );
4795
- assert (From->getType ()->getAs <VectorType>()->getNumElements () ==
4796
- ToType->getAs <VectorType>()->getNumElements () &&
4797
- " Element conversion is only supported for vectors with the same "
4798
- " element counts." );
4799
- QualType FromElTy = From->getType ()->getAs <VectorType>()->getElementType ();
4800
- unsigned NumElts = ToType->getAs <VectorType>()->getNumElements ();
4801
- switch (SCS.Element ) {
4802
- case ICK_Boolean_Conversion:
4803
- // Perform half-to-boolean conversion via float.
4804
- if (FromElTy->isHalfType ()) {
4805
- QualType FPExtType = Context.getExtVectorType (FromElTy, NumElts);
4806
- From = ImpCastExprToType (From, FPExtType, CK_FloatingCast).get ();
4807
- FromType = FPExtType;
4808
- }
4809
-
4810
- From =
4811
- ImpCastExprToType (From, ToType, ScalarTypeToBooleanCastKind (FromElTy),
4812
- VK_PRValue,
4813
- /* BasePath=*/ nullptr , CCK)
4814
- .get ();
4815
- break ;
4816
- case ICK_Integral_Promotion:
4817
- case ICK_Integral_Conversion:
4818
- if (ToType->isBooleanType ()) {
4819
- assert (FromType->castAs <EnumType>()->getDecl ()->isFixed () &&
4820
- SCS.Second == ICK_Integral_Promotion &&
4821
- " only enums with fixed underlying type can promote to bool" );
4822
- From = ImpCastExprToType (From, ToType, CK_IntegralToBoolean, VK_PRValue,
4823
- /* BasePath=*/ nullptr , CCK)
4824
- .get ();
4825
- } else {
4826
- From = ImpCastExprToType (From, ToType, CK_IntegralCast, VK_PRValue,
4827
- /* BasePath=*/ nullptr , CCK)
4828
- .get ();
4829
- }
4830
- break ;
4831
-
4832
- case ICK_Floating_Promotion:
4833
- case ICK_Floating_Conversion:
4834
- From = ImpCastExprToType (From, ToType, CK_FloatingCast, VK_PRValue,
4814
+ " Dimension conversion for matrix types is not implemented yet." );
4815
+ assert (ToType->isVectorType () &&
4816
+ " Dimension conversion is only supported for vector types." );
4817
+ switch (SCS.Dimension ) {
4818
+ case ICK_HLSL_Vector_Splat: {
4819
+ // Vector splat from any arithmetic type to a vector.
4820
+ Expr *Elem = prepareVectorSplat (ToType, From).get ();
4821
+ From = ImpCastExprToType (Elem, ToType, CK_VectorSplat, VK_PRValue,
4835
4822
/* BasePath=*/ nullptr , CCK)
4836
4823
.get ();
4837
4824
break ;
4838
- case ICK_Floating_Integral:
4839
- if (ToType->hasFloatingRepresentation ())
4840
- From =
4841
- ImpCastExprToType (From, ToType, CK_IntegralToFloating, VK_PRValue,
4842
- /* BasePath=*/ nullptr , CCK)
4843
- .get ();
4844
- else
4845
- From =
4846
- ImpCastExprToType (From, ToType, CK_FloatingToIntegral, VK_PRValue,
4847
- /* BasePath=*/ nullptr , CCK)
4848
- .get ();
4825
+ }
4826
+ case ICK_HLSL_Vector_Truncation: {
4827
+ // Note: HLSL built-in vectors are ExtVectors. Since this truncates a
4828
+ // vector to a smaller vector, this can only operate on arguments where
4829
+ // the source and destination types are ExtVectors.
4830
+ assert (From->getType ()->isExtVectorType () && ToType->isExtVectorType () &&
4831
+ " HLSL vector truncation should only apply to ExtVectors" );
4832
+ auto *FromVec = From->getType ()->castAs <VectorType>();
4833
+ auto *ToVec = ToType->castAs <VectorType>();
4834
+ QualType ElType = FromVec->getElementType ();
4835
+ QualType TruncTy =
4836
+ Context.getExtVectorType (ElType, ToVec->getNumElements ());
4837
+ From = ImpCastExprToType (From, TruncTy, CK_HLSLVectorTruncation,
4838
+ From->getValueKind ())
4839
+ .get ();
4849
4840
break ;
4841
+ }
4850
4842
case ICK_Identity:
4851
4843
default :
4852
4844
llvm_unreachable (" Improper element standard conversion" );
0 commit comments