@@ -4294,6 +4294,20 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
42944294 return From;
42954295}
42964296
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+
42974311ExprResult
42984312Sema::PerformImplicitConversion (Expr *From, QualType ToType,
42994313 const StandardConversionSequence& SCS,
@@ -4443,27 +4457,36 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
44434457 break ;
44444458
44454459 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 ()) {
44484466 assert (FromType->castAs <EnumType>()->getDecl ()->isFixed () &&
44494467 SCS.Second == ICK_Integral_Promotion &&
44504468 " 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,
44524470 /* BasePath=*/ nullptr , CCK)
44534471 .get ();
44544472 } else {
4455- From = ImpCastExprToType (From, ToType , CK_IntegralCast, VK_PRValue,
4473+ From = ImpCastExprToType (From, StepTy , CK_IntegralCast, VK_PRValue,
44564474 /* BasePath=*/ nullptr , CCK)
44574475 .get ();
44584476 }
44594477 break ;
4478+ }
44604479
44614480 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,
44644486 /* BasePath=*/ nullptr , CCK)
44654487 .get ();
44664488 break ;
4489+ }
44674490
44684491 case ICK_Complex_Promotion:
44694492 case ICK_Complex_Conversion: {
@@ -4486,16 +4509,21 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
44864509 break ;
44874510 }
44884511
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,
44924519 /* BasePath=*/ nullptr , CCK)
44934520 .get ();
44944521 else
4495- From = ImpCastExprToType (From, ToType , CK_FloatingToIntegral, VK_PRValue,
4522+ From = ImpCastExprToType (From, StepTy , CK_FloatingToIntegral, VK_PRValue,
44964523 /* BasePath=*/ nullptr , CCK)
44974524 .get ();
44984525 break ;
4526+ }
44994527
45004528 case ICK_Fixed_Point_Conversion:
45014529 assert ((FromType->isFixedPointType () || ToType->isFixedPointType ()) &&
@@ -4617,18 +4645,26 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
46174645 break ;
46184646 }
46194647
4620- case ICK_Boolean_Conversion:
4648+ case ICK_Boolean_Conversion: {
46214649 // Perform half-to-boolean conversion via float.
46224650 if (From->getType ()->isHalfType ()) {
46234651 From = ImpCastExprToType (From, Context.FloatTy , CK_FloatingCast).get ();
46244652 FromType = Context.FloatTy ;
46254653 }
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+ }
46264661
4627- From = ImpCastExprToType (From, Context. BoolTy ,
4628- ScalarTypeToBooleanCastKind (FromType), VK_PRValue,
4662+ From = ImpCastExprToType (From, StepTy, ScalarTypeToBooleanCastKind (ElTy) ,
4663+ VK_PRValue,
46294664 /* BasePath=*/ nullptr , CCK)
46304665 .get ();
46314666 break ;
4667+ }
46324668
46334669 case ICK_Derived_To_Base: {
46344670 CXXCastPath BasePath;
@@ -4754,22 +4790,6 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
47544790 CK_ZeroToOCLOpaqueType,
47554791 From->getValueKind ()).get ();
47564792 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- }
47734793
47744794 case ICK_Lvalue_To_Rvalue:
47754795 case ICK_Array_To_Pointer:
@@ -4780,73 +4800,45 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
47804800 case ICK_C_Only_Conversion:
47814801 case ICK_Incompatible_Pointer_Conversion:
47824802 case ICK_HLSL_Array_RValue:
4803+ case ICK_HLSL_Vector_Truncation:
4804+ case ICK_HLSL_Vector_Splat:
47834805 llvm_unreachable (" Improper second standard conversion" );
47844806 }
47854807
4786- if (SCS.Element != ICK_Identity) {
4808+ if (SCS.Dimension != ICK_Identity) {
47874809 // If SCS.Element is not ICK_Identity the To and From types must be HLSL
47884810 // vectors or matrices.
47894811
47904812 // TODO: Support HLSL matrices.
47914813 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,
48354822 /* BasePath=*/ nullptr , CCK)
48364823 .get ();
48374824 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 ();
48494840 break ;
4841+ }
48504842 case ICK_Identity:
48514843 default :
48524844 llvm_unreachable (" Improper element standard conversion" );
0 commit comments