@@ -104,6 +104,7 @@ namespace {
104
104
void CheckStaticCast ();
105
105
void CheckDynamicCast ();
106
106
void CheckCXXCStyleCast (bool FunctionalCast, bool ListInitialization);
107
+ bool CheckHLSLCStyleCast (CheckedConversionKind CCK);
107
108
void CheckCStyleCast ();
108
109
void CheckBuiltinBitCast ();
109
110
void CheckAddrspaceCast ();
@@ -2776,39 +2777,9 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
2776
2777
CheckedConversionKind CCK = FunctionalStyle
2777
2778
? CheckedConversionKind::FunctionalCast
2778
2779
: CheckedConversionKind::CStyleCast;
2779
-
2780
- QualType SrcTy = SrcExpr.get ()->getType ();
2781
- // This case should not trigger on regular vector cast, vector truncation
2782
- if (Self.getLangOpts ().HLSL &&
2783
- Self.HLSL ().CanPerformElementwiseCast (SrcExpr.get (), DestType)) {
2784
- if (SrcTy->isConstantArrayType ())
2785
- SrcExpr = Self.ImpCastExprToType (
2786
- SrcExpr.get (), Self.Context .getArrayParameterType (SrcTy),
2787
- CK_HLSLArrayRValue, VK_PRValue, nullptr , CCK);
2788
- Kind = CK_HLSLElementwiseCast;
2789
- return ;
2790
- }
2791
-
2792
- // This case should not trigger on regular vector splat
2793
- // If the relative order of this and the HLSLElementWise cast checks
2794
- // are changed, it might change which cast handles what in a few cases
2795
- if (Self.getLangOpts ().HLSL &&
2796
- Self.HLSL ().CanPerformAggregateSplatCast (SrcExpr.get (), DestType)) {
2797
- const VectorType *VT = SrcTy->getAs <VectorType>();
2798
- // change splat from vec1 case to splat from scalar
2799
- if (VT && VT->getNumElements () == 1 )
2800
- SrcExpr = Self.ImpCastExprToType (
2801
- SrcExpr.get (), VT->getElementType (), CK_HLSLVectorTruncation,
2802
- SrcExpr.get ()->getValueKind (), nullptr , CCK);
2803
- // Inserting a scalar cast here allows for a simplified codegen in
2804
- // the case the destTy is a vector
2805
- if (const VectorType *DVT = DestType->getAs <VectorType>())
2806
- SrcExpr = Self.ImpCastExprToType (
2807
- SrcExpr.get (), DVT->getElementType (),
2808
- Self.PrepareScalarCast (SrcExpr, DVT->getElementType ()),
2809
- SrcExpr.get ()->getValueKind (), nullptr , CCK);
2810
- Kind = CK_HLSLAggregateSplatCast;
2811
- return ;
2780
+ if (Self.getLangOpts ().HLSL ) {
2781
+ if (CheckHLSLCStyleCast (CCK))
2782
+ return ;
2812
2783
}
2813
2784
2814
2785
if (ValueKind == VK_PRValue && !DestType->isRecordType () &&
@@ -2927,6 +2898,56 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
2927
2898
}
2928
2899
}
2929
2900
2901
+ // CheckHLSLCStyleCast - Returns `true` ihe cast is handled or errored as an
2902
+ // HLSL-specific cast. Returns false if the cast should be checked as a CXX
2903
+ // C-Style cast.
2904
+ bool CastOperation::CheckHLSLCStyleCast (CheckedConversionKind CCK) {
2905
+ assert (Self.getLangOpts ().HLSL && " Must be HLSL!" );
2906
+ QualType SrcTy = SrcExpr.get ()->getType ();
2907
+ // HLSL has several unique forms of C-style casts which support aggregate to
2908
+ // aggregate casting.
2909
+ // This case should not trigger on regular vector cast, vector truncation
2910
+ if (Self.HLSL ().CanPerformElementwiseCast (SrcExpr.get (), DestType)) {
2911
+ if (SrcTy->isConstantArrayType ())
2912
+ SrcExpr = Self.ImpCastExprToType (
2913
+ SrcExpr.get (), Self.Context .getArrayParameterType (SrcTy),
2914
+ CK_HLSLArrayRValue, VK_PRValue, nullptr , CCK);
2915
+ Kind = CK_HLSLElementwiseCast;
2916
+ return true ;
2917
+ }
2918
+
2919
+ // This case should not trigger on regular vector splat
2920
+ // If the relative order of this and the HLSLElementWise cast checks
2921
+ // are changed, it might change which cast handles what in a few cases
2922
+ if (Self.HLSL ().CanPerformAggregateSplatCast (SrcExpr.get (), DestType)) {
2923
+ const VectorType *VT = SrcTy->getAs <VectorType>();
2924
+ // change splat from vec1 case to splat from scalar
2925
+ if (VT && VT->getNumElements () == 1 )
2926
+ SrcExpr = Self.ImpCastExprToType (
2927
+ SrcExpr.get (), VT->getElementType (), CK_HLSLVectorTruncation,
2928
+ SrcExpr.get ()->getValueKind (), nullptr , CCK);
2929
+ // Inserting a scalar cast here allows for a simplified codegen in
2930
+ // the case the destTy is a vector
2931
+ if (const VectorType *DVT = DestType->getAs <VectorType>())
2932
+ SrcExpr = Self.ImpCastExprToType (
2933
+ SrcExpr.get (), DVT->getElementType (),
2934
+ Self.PrepareScalarCast (SrcExpr, DVT->getElementType ()),
2935
+ SrcExpr.get ()->getValueKind (), nullptr , CCK);
2936
+ Kind = CK_HLSLAggregateSplatCast;
2937
+ return true ;
2938
+ }
2939
+
2940
+ // If the destination is an array, we've exhausted the valid HLSL casts, so we
2941
+ // should emit a dignostic and stop processing.
2942
+ if (DestType->isArrayType ()) {
2943
+ Self.Diag (OpRange.getBegin (), diag::err_bad_cxx_cast_generic)
2944
+ << 4 << SrcTy << DestType;
2945
+ SrcExpr = ExprError ();
2946
+ return true ;
2947
+ }
2948
+ return false ;
2949
+ }
2950
+
2930
2951
// / DiagnoseBadFunctionCast - Warn whenever a function call is cast to a
2931
2952
// / non-matching type. Such as enum function call to int, int call to
2932
2953
// / pointer; etc. Cast to 'void' is an exception.
0 commit comments