@@ -2985,7 +2985,7 @@ impl<'c> Translation<'c> {
29852985 /// and in many cases should override it.
29862986 pub fn convert_expr (
29872987 & self ,
2988- mut ctx : ExprContext ,
2988+ ctx : ExprContext ,
29892989 expr_id : CExprId ,
29902990 override_ty : Option < CQualTypeId > ,
29912991 ) -> TranslationResult < WithStmts < Box < Expr > > > {
@@ -3268,102 +3268,15 @@ impl<'c> Translation<'c> {
32683268 Literal ( ty, ref kind) => self . convert_literal ( ctx, override_ty. unwrap_or ( ty) , kind) ,
32693269
32703270 ImplicitCast ( ty, expr, kind, opt_field_id, _)
3271- | ExplicitCast ( ty, expr, kind, opt_field_id, _) => {
3272- let is_explicit = matches ! ( expr_kind, CExprKind :: ExplicitCast ( ..) ) ;
3273- // A reference must be decayed if a bitcast is required. Const casts in
3274- // LLVM 8 are now NoOp casts, so we need to include it as well.
3275- match kind {
3276- CastKind :: IntegralToBoolean
3277- | CastKind :: FloatingToBoolean
3278- | CastKind :: PointerToBoolean => {
3279- return self . convert_condition ( ctx, true , expr) ;
3280- }
3281- CastKind :: BitCast | CastKind :: PointerToIntegral | CastKind :: NoOp => {
3282- ctx. decay_ref = DecayRef :: Yes
3283- }
3284- CastKind :: ArrayToPointerDecay
3285- | CastKind :: FunctionToPointerDecay
3286- | CastKind :: BuiltinFnToFnPtr => {
3287- ctx. needs_address = true ;
3288- }
3289- _ => { }
3290- }
3291-
3292- let expr_kind = & self . ast_context . index_unwrap_parens ( expr) . kind ;
3293- let target_ty = override_ty. unwrap_or ( ty) ;
3294-
3295- // In general, if we are casting the result of an expression, then the inner
3296- // expression should be translated to whatever type it normally would.
3297- // But for literals, if we don't absolutely have to cast, we would rather the
3298- // literal is translated according to the type we're expecting, and then we can
3299- // skip the cast entirely.
3300- if !is_explicit {
3301- let mut literal_expr_kind = expr_kind;
3302- let mut is_negated = false ;
3303-
3304- if let & CExprKind :: Unary ( _, CUnOp :: Negate , subexpr_id, _) = literal_expr_kind {
3305- literal_expr_kind = & self . ast_context . index_unwrap_parens ( subexpr_id) . kind ;
3306- is_negated = true ;
3307- }
3308-
3309- if let CExprKind :: Literal ( _, lit) = literal_expr_kind {
3310- if self . literal_matches_ty ( lit, target_ty, is_negated) {
3311- return self . convert_expr ( ctx, expr, Some ( target_ty) ) ;
3312- }
3313- }
3314- }
3315-
3316- let mut val = self . convert_expr ( ctx, expr, None ) ?;
3317-
3318- if is_explicit {
3319- let stmts = self . compute_variable_array_sizes ( ctx, ty. ctype ) ?;
3320- val = val. prepend_stmts ( stmts) ;
3321- }
3322-
3323- // Shuffle Vector "function" builtins will add a cast to the output of the
3324- // builtin call which is unnecessary for translation purposes
3325- if self . casting_simd_builtin_call ( expr, is_explicit, kind) {
3326- return Ok ( val) ;
3327- }
3328-
3329- let source_ty = if let Some ( func_decl) = self
3330- . ast_context
3331- . fn_declref_decl ( expr)
3332- . filter ( |_| is_explicit)
3333- {
3334- // If we're casting a function, look for its declared ty to use as a more
3335- // precise source type. The AST node's type will not preserve typedef arg types
3336- // but the function's declaration will.
3337- let kind_with_declared_args =
3338- self . ast_context . fn_decl_ty_with_declared_args ( func_decl) ;
3339- let func_ty = self
3340- . ast_context
3341- . type_for_kind ( & kind_with_declared_args)
3342- . unwrap_or_else ( || panic ! ( "no type for kind {kind_with_declared_args:?}" ) ) ;
3343- let func_ptr_ty = self
3344- . ast_context
3345- . type_for_kind ( & CTypeKind :: Pointer ( CQualTypeId :: new ( func_ty) ) )
3346- . unwrap_or_else ( || panic ! ( "no type for kind {kind_with_declared_args:?}" ) ) ;
3347-
3348- CQualTypeId :: new ( func_ptr_ty)
3349- } else {
3350- self . ast_context
3351- . index_unwrap_parens ( expr)
3352- . kind
3353- . get_qual_type ( )
3354- . ok_or_else ( || format_err ! ( "bad source type" ) ) ?
3355- } ;
3356-
3357- self . convert_cast (
3358- ctx,
3359- source_ty,
3360- target_ty,
3361- val,
3362- Some ( expr) ,
3363- Some ( kind) ,
3364- opt_field_id,
3365- )
3366- }
3271+ | ExplicitCast ( ty, expr, kind, opt_field_id, _) => self . convert_cast (
3272+ ctx,
3273+ override_ty,
3274+ ty,
3275+ expr,
3276+ kind,
3277+ opt_field_id,
3278+ matches ! ( expr_kind, CExprKind :: ExplicitCast ( ..) ) ,
3279+ ) ,
33673280
33683281 Unary ( type_id, op, arg, _lrvalue) => {
33693282 self . convert_unary_operator ( ctx, op, override_ty. unwrap_or ( type_id) , arg)
@@ -3653,6 +3566,120 @@ impl<'c> Translation<'c> {
36533566 }
36543567
36553568 pub fn convert_cast (
3569+ & self ,
3570+ mut ctx : ExprContext ,
3571+ override_ty : Option < CQualTypeId > ,
3572+ ty : CQualTypeId ,
3573+ expr : CExprId ,
3574+ kind : CastKind ,
3575+ opt_field_id : Option < CDeclId > ,
3576+ is_explicit : bool ,
3577+ ) -> TranslationResult < WithStmts < Box < Expr > > > {
3578+ // A reference must be decayed if a bitcast is required. Const casts in
3579+ // LLVM 8 are now NoOp casts, so we need to include it as well.
3580+ match kind {
3581+ CastKind :: IntegralToBoolean
3582+ | CastKind :: FloatingToBoolean
3583+ | CastKind :: PointerToBoolean => {
3584+ return self . convert_condition ( ctx, true , expr) ;
3585+ }
3586+ CastKind :: BitCast | CastKind :: PointerToIntegral | CastKind :: NoOp => {
3587+ ctx. decay_ref = DecayRef :: Yes
3588+ }
3589+ CastKind :: ArrayToPointerDecay
3590+ | CastKind :: FunctionToPointerDecay
3591+ | CastKind :: BuiltinFnToFnPtr => {
3592+ ctx. needs_address = true ;
3593+ }
3594+ _ => { }
3595+ }
3596+
3597+ let expr_kind = & self . ast_context . index_unwrap_parens ( expr) . kind ;
3598+ let target_ty = override_ty. unwrap_or ( ty) ;
3599+
3600+ // In general, if we are casting the result of an expression, then the inner
3601+ // expression should be translated to whatever type it normally would.
3602+ // But for literals, if we don't absolutely have to cast, we would rather the
3603+ // literal is translated according to the type we're expecting, and then we can
3604+ // skip the cast entirely.
3605+ if !is_explicit {
3606+ let mut literal_expr_kind = expr_kind;
3607+ let mut is_negated = false ;
3608+
3609+ if let & CExprKind :: Unary ( _, CUnOp :: Negate , subexpr_id, _) = literal_expr_kind {
3610+ literal_expr_kind = & self . ast_context . index_unwrap_parens ( subexpr_id) . kind ;
3611+ is_negated = true ;
3612+ }
3613+
3614+ if let CExprKind :: Literal ( _, lit) = literal_expr_kind {
3615+ if self . literal_matches_ty ( lit, target_ty, is_negated) {
3616+ return self . convert_expr ( ctx, expr, Some ( target_ty) ) ;
3617+ }
3618+ }
3619+ }
3620+
3621+ let mut val = self . convert_expr ( ctx, expr, None ) ?;
3622+
3623+ if is_explicit {
3624+ let stmts = self . compute_variable_array_sizes ( ctx, ty. ctype ) ?;
3625+ val = val. prepend_stmts ( stmts) ;
3626+ }
3627+
3628+ // Shuffle Vector "function" builtins will add a cast to the output of the
3629+ // builtin call which is unnecessary for translation purposes
3630+ if self . casting_simd_builtin_call ( expr, is_explicit, kind) {
3631+ return Ok ( val) ;
3632+ }
3633+
3634+ let source_ty = if let Some ( func_decl) = self
3635+ . ast_context
3636+ . fn_declref_decl ( expr)
3637+ . filter ( |_| is_explicit)
3638+ {
3639+ // If we're casting a function, look for its declared ty to use as a more
3640+ // precise source type. The AST node's type will not preserve typedef arg types
3641+ // but the function's declaration will.
3642+ let kind_with_declared_args = self . ast_context . fn_decl_ty_with_declared_args ( func_decl) ;
3643+ let func_ty = self
3644+ . ast_context
3645+ . type_for_kind ( & kind_with_declared_args)
3646+ . unwrap_or_else ( || panic ! ( "no type for kind {kind_with_declared_args:?}" ) ) ;
3647+ let func_ptr_ty = self
3648+ . ast_context
3649+ . type_for_kind ( & CTypeKind :: Pointer ( CQualTypeId :: new ( func_ty) ) )
3650+ . unwrap_or_else ( || panic ! ( "no type for kind {kind_with_declared_args:?}" ) ) ;
3651+
3652+ CQualTypeId :: new ( func_ptr_ty)
3653+ } else {
3654+ self . ast_context
3655+ . index_unwrap_parens ( expr)
3656+ . kind
3657+ . get_qual_type ( )
3658+ . ok_or_else ( || format_err ! ( "bad source type" ) ) ?
3659+ } ;
3660+
3661+ self . make_cast_full (
3662+ ctx,
3663+ source_ty,
3664+ target_ty,
3665+ val,
3666+ Some ( expr) ,
3667+ Some ( kind) ,
3668+ opt_field_id,
3669+ )
3670+ }
3671+
3672+ pub fn make_cast (
3673+ & self ,
3674+ ctx : ExprContext ,
3675+ source_type_id : CQualTypeId ,
3676+ target_type_id : CQualTypeId ,
3677+ val : WithStmts < Box < Expr > > ,
3678+ ) -> TranslationResult < WithStmts < Box < Expr > > > {
3679+ self . make_cast_full ( ctx, source_type_id, target_type_id, val, None , None , None )
3680+ }
3681+
3682+ pub fn make_cast_full (
36563683 & self ,
36573684 ctx : ExprContext ,
36583685 source_cty : CQualTypeId ,
0 commit comments