Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions c2rust-transpile/src/c_ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,21 @@ impl TypedAstContext {
}
}

/// Sort the top-level declarations with macros coming last.
/// This is needed during conversion so that when recreating macros,
/// we can look up the [`Translation::expr_override_tys`],
/// which are set when the macro expansion expressions are converted.
pub fn sort_top_decls_for_converting(&mut self) {
self.c_decls_top.sort_unstable_by_key(|decl_id| {
let reverse_order = match self.c_decls.get(decl_id).unwrap().kind {
CDeclKind::MacroFunction { .. } => 0,
CDeclKind::MacroObject { .. } => 1,
_ => 2,
};
-reverse_order
});
}

/// Sort the top-level declarations by file and source location
/// so that we preserve the ordering of all declarations in each file.
/// This preserves the order when we emit the converted declarations.
Expand Down
22 changes: 21 additions & 1 deletion c2rust-transpile/src/translator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,15 @@ pub struct Translation<'c> {
potential_flexible_array_members: RefCell<IndexSet<CDeclId>>,
macro_expansions: RefCell<IndexMap<CDeclId, Option<MacroExpansion>>>,

/// For every call to [`Self::convert_expr`],
/// we record the `override_ty` that is used for that expression.
///
/// This is needed [`Self::recreate_const_macro_from_expansions`]
/// when we call [`Self::convert_expr`] for each of the macro expansions,
/// as unlike normal [`Self::convert_expr`]s, there is no surrounding context
/// higher in the call stack calculating the `override_ty`.
expr_override_tys: RefCell<HashMap<CExprId, CQualTypeId>>,

// Comment support
pub comment_context: CommentContext, // Incoming comments
pub comment_store: RefCell<CommentStore>, // Outgoing comments
Expand Down Expand Up @@ -689,6 +698,8 @@ pub fn translate(
}
}

t.ast_context.sort_top_decls_for_converting();

// Export top-level value declarations.
// We do this in a conversion pass and then an insertion pass
// so that the conversion order can differ from the order they're emitted in.
Expand Down Expand Up @@ -1215,6 +1226,7 @@ impl<'c> Translation<'c> {
function_context: RefCell::new(FuncContext::new()),
potential_flexible_array_members: RefCell::new(IndexSet::new()),
macro_expansions: RefCell::new(IndexMap::new()),
expr_override_tys: Default::default(),
comment_context,
comment_store: RefCell::new(CommentStore::new()),
spans: HashMap::new(),
Expand Down Expand Up @@ -2195,7 +2207,9 @@ impl<'c> Translation<'c> {
.kind
.get_type()
.ok_or_else(|| format_err!("Invalid expression type"))?;
let expr = self.convert_expr(ctx, id, None)?;
let override_ty = self.expr_override_tys.borrow().get(&id).copied();
let expr = self.convert_expr(ctx, id, override_ty)?;
let ty = override_ty.map(|ty| ty.ctype).unwrap_or(ty);

// Join ty and cur_ty to the smaller of the two types. If the
// types are not cast-compatible, abort the fold.
Expand Down Expand Up @@ -3283,6 +3297,12 @@ impl<'c> Translation<'c> {
expr_id: CExprId,
override_ty: Option<CQualTypeId>,
) -> TranslationResult<WithStmts<Box<Expr>>> {
if let Some(override_ty) = override_ty {
self.expr_override_tys
.borrow_mut()
.insert(expr_id, override_ty);
}

let Located {
loc: src_loc,
kind: expr_kind,
Expand Down
74 changes: 40 additions & 34 deletions c2rust-transpile/tests/snapshots/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ pub struct ntlmdata {
pub target_info_len: core::ffi::c_uint,
}
pub const true_0: core::ffi::c_int = 1 as core::ffi::c_int;
pub const UINTPTR_MAX: core::ffi::c_ulong = 18446744073709551615 as core::ffi::c_ulong;
pub const UINTPTR_MAX: uintptr_t = 18446744073709551615 as uintptr_t;
pub const LITERAL_INT: core::ffi::c_int = 0xffff as core::ffi::c_int;
pub const LITERAL_BOOL: core::ffi::c_int = true_0;
pub const LITERAL_FLOAT: core::ffi::c_double = 3.14f64;
pub const LITERAL_FLOAT: core::ffi::c_float = 3.14f32;
pub const LITERAL_CHAR: core::ffi::c_int = 'x' as i32;
pub const LITERAL_STR: [core::ffi::c_char; 6] =
unsafe { ::core::mem::transmute::<[u8; 6], [core::ffi::c_char; 6]>(*b"hello\0") };
Expand All @@ -50,7 +50,7 @@ pub const LITERAL_STRUCT: S = {
};
pub const NESTED_INT: core::ffi::c_int = LITERAL_INT;
pub const NESTED_BOOL: core::ffi::c_int = LITERAL_BOOL;
pub const NESTED_FLOAT: core::ffi::c_double = LITERAL_FLOAT;
pub const NESTED_FLOAT: core::ffi::c_float = LITERAL_FLOAT;
pub const NESTED_CHAR: core::ffi::c_int = LITERAL_CHAR;
pub const NESTED_STR: [core::ffi::c_char; 6] = LITERAL_STR;
pub const NESTED_STRUCT: S = LITERAL_STRUCT;
Expand All @@ -67,7 +67,7 @@ pub const CONVERSION_CAST: core::ffi::c_double = LITERAL_INT as core::ffi::c_dou
pub unsafe extern "C" fn local_muts() {
let mut literal_int: core::ffi::c_int = LITERAL_INT;
let mut literal_bool: bool = LITERAL_BOOL != 0;
let mut literal_float: core::ffi::c_float = LITERAL_FLOAT as core::ffi::c_float;
let mut literal_float: core::ffi::c_float = LITERAL_FLOAT;
let mut literal_char: core::ffi::c_char = LITERAL_CHAR as core::ffi::c_char;
let mut literal_str_ptr: *const core::ffi::c_char = LITERAL_STR.as_ptr();
let mut literal_str: [core::ffi::c_char; 6] = LITERAL_STR;
Expand All @@ -79,7 +79,7 @@ pub unsafe extern "C" fn local_muts() {
let mut literal_struct: S = LITERAL_STRUCT;
let mut nested_int: core::ffi::c_int = NESTED_INT;
let mut nested_bool: bool = NESTED_BOOL != 0;
let mut nested_float: core::ffi::c_float = NESTED_FLOAT as core::ffi::c_float;
let mut nested_float: core::ffi::c_float = NESTED_FLOAT;
let mut nested_char: core::ffi::c_char = NESTED_CHAR as core::ffi::c_char;
let mut nested_str_ptr: *const core::ffi::c_char = NESTED_STR.as_ptr();
let mut nested_str: [core::ffi::c_char; 6] = NESTED_STR;
Expand All @@ -90,23 +90,25 @@ pub unsafe extern "C" fn local_muts() {
];
let mut nested_struct: S = NESTED_STRUCT;
let mut int_arithmetic: core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as core::ffi::c_int;
let mut mixed_arithmetic: core::ffi::c_float =
(LITERAL_INT as core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double) as core::ffi::c_float;
let mut mixed_arithmetic: core::ffi::c_float = (LITERAL_INT as core::ffi::c_double
+ NESTED_FLOAT as core::ffi::c_double * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double)
as core::ffi::c_float;
let mut parens: core::ffi::c_int = PARENS;
let mut ptr_arithmetic: *const core::ffi::c_char = PTR_ARITHMETIC;
let mut widening_cast: core::ffi::c_ulonglong = WIDENING_CAST;
let mut narrowing_cast: core::ffi::c_char = LITERAL_INT as core::ffi::c_char;
let mut conversion_cast: core::ffi::c_double = CONVERSION_CAST;
let mut indexing: core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize];
let mut indexing: core::ffi::c_char =
NESTED_STR[LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as usize];
let mut str_concatenation_ptr: *const core::ffi::c_char =
b"hello hello world\0" as *const u8 as *const core::ffi::c_char;
let mut str_concatenation: [core::ffi::c_char; 18] =
::core::mem::transmute::<[u8; 18], [core::ffi::c_char; 18]>(*b"hello hello world\0");
let mut builtin: core::ffi::c_int = (LITERAL_INT as core::ffi::c_uint).leading_zeros() as i32;
let mut ref_indexing: *const core::ffi::c_char = &*NESTED_STR
.as_ptr()
.offset(LITERAL_FLOAT as core::ffi::c_int as isize)
.offset(LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as isize)
as *const core::ffi::c_char;
let mut ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
let mut ternary: core::ffi::c_int = if LITERAL_BOOL != 0 {
Expand All @@ -119,9 +121,9 @@ pub unsafe extern "C" fn local_muts() {
let mut builtin_0: core::ffi::c_int =
(LITERAL_INT as core::ffi::c_uint).leading_zeros() as i32;
let mut indexing_0: core::ffi::c_char =
NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize];
NESTED_STR[LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as usize];
let mut mixed: core::ffi::c_float = (LITERAL_INT as core::ffi::c_double
+ NESTED_FLOAT * LITERAL_CHAR as core::ffi::c_double
+ NESTED_FLOAT as core::ffi::c_double * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double)
as core::ffi::c_float;
let mut i: core::ffi::c_int = 0 as core::ffi::c_int;
Expand All @@ -136,7 +138,7 @@ pub unsafe extern "C" fn local_muts() {
pub unsafe extern "C" fn local_consts() {
let literal_int: core::ffi::c_int = LITERAL_INT;
let literal_bool: bool = LITERAL_BOOL != 0;
let literal_float: core::ffi::c_float = LITERAL_FLOAT as core::ffi::c_float;
let literal_float: core::ffi::c_float = LITERAL_FLOAT;
let literal_char: core::ffi::c_char = LITERAL_CHAR as core::ffi::c_char;
let literal_str_ptr: *const core::ffi::c_char = LITERAL_STR.as_ptr();
let literal_str: [core::ffi::c_char; 6] = LITERAL_STR;
Expand All @@ -148,7 +150,7 @@ pub unsafe extern "C" fn local_consts() {
let literal_struct: S = LITERAL_STRUCT;
let nested_int: core::ffi::c_int = NESTED_INT;
let nested_bool: bool = NESTED_BOOL != 0;
let nested_float: core::ffi::c_float = NESTED_FLOAT as core::ffi::c_float;
let nested_float: core::ffi::c_float = NESTED_FLOAT;
let nested_char: core::ffi::c_char = NESTED_CHAR as core::ffi::c_char;
let nested_str_ptr: *const core::ffi::c_char = NESTED_STR.as_ptr();
let nested_str: [core::ffi::c_char; 6] = NESTED_STR;
Expand All @@ -159,23 +161,25 @@ pub unsafe extern "C" fn local_consts() {
];
let nested_struct: S = NESTED_STRUCT;
let int_arithmetic: core::ffi::c_int = NESTED_INT + LITERAL_INT + 1 as core::ffi::c_int;
let mixed_arithmetic: core::ffi::c_float =
(LITERAL_INT as core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double) as core::ffi::c_float;
let mixed_arithmetic: core::ffi::c_float = (LITERAL_INT as core::ffi::c_double
+ NESTED_FLOAT as core::ffi::c_double * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double)
as core::ffi::c_float;
let parens: core::ffi::c_int = PARENS;
let ptr_arithmetic: *const core::ffi::c_char = PTR_ARITHMETIC;
let widening_cast: core::ffi::c_ulonglong = WIDENING_CAST;
let narrowing_cast: core::ffi::c_char = LITERAL_INT as core::ffi::c_char;
let conversion_cast: core::ffi::c_double = CONVERSION_CAST;
let indexing: core::ffi::c_char = NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize];
let indexing: core::ffi::c_char =
NESTED_STR[LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as usize];
let str_concatenation_ptr: *const core::ffi::c_char =
b"hello hello world\0" as *const u8 as *const core::ffi::c_char;
let str_concatenation: [core::ffi::c_char; 18] =
::core::mem::transmute::<[u8; 18], [core::ffi::c_char; 18]>(*b"hello hello world\0");
let builtin: core::ffi::c_int = (LITERAL_INT as core::ffi::c_uint).leading_zeros() as i32;
let ref_indexing: *const core::ffi::c_char = &*NESTED_STR
.as_ptr()
.offset(LITERAL_FLOAT as core::ffi::c_int as isize)
.offset(LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as isize)
as *const core::ffi::c_char;
let ref_struct: *const S = &mut LITERAL_STRUCT as *mut S;
let ternary: core::ffi::c_int = if LITERAL_BOOL != 0 {
Expand All @@ -188,9 +192,9 @@ pub unsafe extern "C" fn local_consts() {
let mut builtin_0: core::ffi::c_int =
(LITERAL_INT as core::ffi::c_uint).leading_zeros() as i32;
let mut indexing_0: core::ffi::c_char =
NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize];
NESTED_STR[LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as usize];
let mut mixed: core::ffi::c_float = (LITERAL_INT as core::ffi::c_double
+ NESTED_FLOAT * LITERAL_CHAR as core::ffi::c_double
+ NESTED_FLOAT as core::ffi::c_double * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double)
as core::ffi::c_float;
let mut i: core::ffi::c_int = 0 as core::ffi::c_int;
Expand All @@ -203,8 +207,7 @@ pub unsafe extern "C" fn local_consts() {
}
static mut global_static_const_literal_int: core::ffi::c_int = LITERAL_INT;
static mut global_static_const_literal_bool: bool = LITERAL_BOOL != 0;
static mut global_static_const_literal_float: core::ffi::c_float =
LITERAL_FLOAT as core::ffi::c_float;
static mut global_static_const_literal_float: core::ffi::c_float = LITERAL_FLOAT;
static mut global_static_const_literal_char: core::ffi::c_char = LITERAL_CHAR as core::ffi::c_char;
static mut global_static_const_literal_str_ptr: *const core::ffi::c_char = LITERAL_STR.as_ptr();
static mut global_static_const_literal_str: [core::ffi::c_char; 6] = LITERAL_STR;
Expand All @@ -216,8 +219,7 @@ static mut global_static_const_literal_array: [core::ffi::c_int; 3] = [
static mut global_static_const_literal_struct: S = LITERAL_STRUCT;
static mut global_static_const_nested_int: core::ffi::c_int = NESTED_INT;
static mut global_static_const_nested_bool: bool = NESTED_BOOL != 0;
static mut global_static_const_nested_float: core::ffi::c_float =
NESTED_FLOAT as core::ffi::c_float;
static mut global_static_const_nested_float: core::ffi::c_float = NESTED_FLOAT;
static mut global_static_const_nested_char: core::ffi::c_char = NESTED_CHAR as core::ffi::c_char;
static mut global_static_const_nested_str_ptr: *const core::ffi::c_char = NESTED_STR.as_ptr();
static mut global_static_const_nested_str: [core::ffi::c_char; 6] = NESTED_STR;
Expand All @@ -230,7 +232,8 @@ static mut global_static_const_nested_struct: S = NESTED_STRUCT;
static mut global_static_const_int_arithmetic: core::ffi::c_int =
NESTED_INT + LITERAL_INT + 1 as core::ffi::c_int;
static mut global_static_const_mixed_arithmetic: core::ffi::c_float =
(LITERAL_INT as core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as core::ffi::c_double
(LITERAL_INT as core::ffi::c_double
+ NESTED_FLOAT as core::ffi::c_double * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double) as core::ffi::c_float;
static mut global_static_const_parens: core::ffi::c_int = PARENS;
static mut global_static_const_ptr_arithmetic: *const core::ffi::c_char =
Expand All @@ -257,7 +260,7 @@ pub static mut global_const_literal_int: core::ffi::c_int = LITERAL_INT;
#[no_mangle]
pub static mut global_const_literal_bool: bool = LITERAL_BOOL != 0;
#[no_mangle]
pub static mut global_const_literal_float: core::ffi::c_float = LITERAL_FLOAT as core::ffi::c_float;
pub static mut global_const_literal_float: core::ffi::c_float = LITERAL_FLOAT;
#[no_mangle]
pub static mut global_const_literal_char: core::ffi::c_char = LITERAL_CHAR as core::ffi::c_char;
#[no_mangle]
Expand All @@ -277,7 +280,7 @@ pub static mut global_const_nested_int: core::ffi::c_int = NESTED_INT;
#[no_mangle]
pub static mut global_const_nested_bool: bool = NESTED_BOOL != 0;
#[no_mangle]
pub static mut global_const_nested_float: core::ffi::c_float = NESTED_FLOAT as core::ffi::c_float;
pub static mut global_const_nested_float: core::ffi::c_float = NESTED_FLOAT;
#[no_mangle]
pub static mut global_const_nested_char: core::ffi::c_char = NESTED_CHAR as core::ffi::c_char;
#[no_mangle]
Expand All @@ -297,7 +300,8 @@ pub static mut global_const_int_arithmetic: core::ffi::c_int =
NESTED_INT + LITERAL_INT + 1 as core::ffi::c_int;
#[no_mangle]
pub static mut global_const_mixed_arithmetic: core::ffi::c_float =
(LITERAL_INT as core::ffi::c_double + NESTED_FLOAT * LITERAL_CHAR as core::ffi::c_double
(LITERAL_INT as core::ffi::c_double
+ NESTED_FLOAT as core::ffi::c_double * LITERAL_CHAR as core::ffi::c_double
- true_0 as core::ffi::c_double) as core::ffi::c_float;
#[no_mangle]
pub static mut global_const_parens: core::ffi::c_int = PARENS;
Expand Down Expand Up @@ -413,7 +417,7 @@ pub unsafe extern "C" fn use_local_value() -> core::ffi::c_int {
}
#[no_mangle]
pub unsafe extern "C" fn use_portable_type(mut len: uintptr_t) -> bool {
return len <= (UINTPTR_MAX as uintptr_t).wrapping_div(2 as uintptr_t);
return len <= UINTPTR_MAX.wrapping_div(2 as uintptr_t);
}
#[no_mangle]
pub unsafe extern "C" fn ntlm_v2_blob_len(mut ntlm: *mut ntlmdata) -> core::ffi::c_uint {
Expand All @@ -431,10 +435,11 @@ pub unsafe extern "C" fn late_init_var() -> core::ffi::c_int {
}
unsafe extern "C" fn run_static_initializers() {
global_static_const_ptr_arithmetic = PTR_ARITHMETIC;
global_static_const_indexing = NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize];
global_static_const_indexing =
NESTED_STR[LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as usize];
global_static_const_ref_indexing = &*NESTED_STR
.as_ptr()
.offset(LITERAL_FLOAT as core::ffi::c_int as isize)
.offset(LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as isize)
as *const core::ffi::c_char;
global_static_const_ternary = if LITERAL_BOOL != 0 {
1 as core::ffi::c_int
Expand All @@ -443,10 +448,11 @@ unsafe extern "C" fn run_static_initializers() {
};
global_static_const_member = LITERAL_STRUCT.i;
global_const_ptr_arithmetic = PTR_ARITHMETIC;
global_const_indexing = NESTED_STR[LITERAL_FLOAT as core::ffi::c_int as usize];
global_const_indexing =
NESTED_STR[LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as usize];
global_const_ref_indexing = &*NESTED_STR
.as_ptr()
.offset(LITERAL_FLOAT as core::ffi::c_int as isize)
.offset(LITERAL_FLOAT as core::ffi::c_double as core::ffi::c_int as isize)
as *const core::ffi::c_char;
global_const_ternary = if LITERAL_BOOL != 0 {
1 as core::ffi::c_int
Expand Down
Loading