Skip to content

Commit 49338c5

Browse files
committed
transpile: separate top-level decl conversion and insertion (into emitted code)
This sets things up to iterate through different orders for each.
1 parent e685e76 commit 49338c5

File tree

1 file changed

+58
-34
lines changed
  • c2rust-transpile/src/translator

1 file changed

+58
-34
lines changed

c2rust-transpile/src/translator/mod.rs

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -687,26 +687,37 @@ pub fn translate(
687687
}
688688
}
689689

690-
// Export top-level value declarations
691-
for top_id in &t.ast_context.c_decls_top {
692-
use CDeclKind::*;
693-
let needs_export = match t.ast_context[*top_id].kind {
694-
Function { is_implicit, .. } => !is_implicit,
695-
Variable { .. } => true,
696-
MacroObject { .. } => true, // Depends on `tcfg.translate_const_macros`, but handled in `fn convert_const_macro_expansion`.
697-
MacroFunction { .. } => true, // Depends on `tcfg.translate_fn_macros`, but handled in `fn convert_fn_macro_invocation`.
698-
_ => false,
699-
};
700-
if needs_export {
701-
let decl = t.ast_context.get_decl(top_id).unwrap();
690+
// Export top-level value declarations.
691+
// We do this in a conversion pass and then an insertion pass
692+
// so that the conversion order can differ from the order they're emitted in.
693+
let mut converted_decls = t
694+
.ast_context
695+
.c_decls_top
696+
.iter()
697+
.filter_map(|&top_id| {
698+
use CDeclKind::*;
699+
let needs_export = match t.ast_context[top_id].kind {
700+
Function { is_implicit, .. } => !is_implicit,
701+
Variable { .. } => true,
702+
MacroObject { .. } => true, // Depends on `tcfg.translate_const_macros`, but handled in `fn convert_const_macro_expansion`.
703+
MacroFunction { .. } => true, // Depends on `tcfg.translate_fn_macros`, but handled in `fn convert_fn_macro_invocation`.
704+
_ => false,
705+
};
706+
if !needs_export {
707+
return None;
708+
}
709+
710+
let decl = t.ast_context.get_decl(&top_id).unwrap();
702711
let decl_file_id = t.ast_context.file_id(decl);
703712

704713
if t.tcfg.reorganize_definitions
705714
&& decl_file_id.map_or(false, |id| id != t.main_file)
706715
{
707716
t.cur_file.set(decl_file_id);
708717
}
709-
match t.convert_decl(ctx, *top_id) {
718+
719+
// TODO use `.inspect_err` once stabilized in Rust 1.76.
720+
let converted = match t.convert_decl(ctx, top_id) {
710721
Err(e) => {
711722
let decl_identifier = decl.kind.get_name().map_or_else(
712723
|| {
@@ -718,32 +729,45 @@ pub fn translate(
718729
);
719730
let msg = format!("Failed to translate {}: {}", decl_identifier, e);
720731
translate_failure(t.tcfg, &msg);
732+
Err(e)
721733
}
722-
Ok(converted_decl) => {
723-
use ConvertedDecl::*;
724-
match converted_decl {
725-
Item(item) => {
726-
t.insert_item(item, decl);
727-
}
728-
ForeignItem(item) => {
729-
t.insert_foreign_item(*item, decl);
730-
}
731-
Items(items) => {
732-
for item in items {
733-
t.insert_item(item, decl);
734-
}
735-
}
736-
NoItem => {}
737-
}
738-
}
734+
Ok(converted) => Ok(converted),
739735
}
736+
.ok()?;
737+
740738
t.cur_file.take();
741739

742-
if t.tcfg.reorganize_definitions
743-
&& decl_file_id.map_or(false, |id| id != t.main_file)
744-
{
745-
t.generate_submodule_imports(*top_id, decl_file_id);
740+
Some((top_id, converted))
741+
})
742+
.collect::<HashMap<_, _>>();
743+
744+
for top_id in &t.ast_context.c_decls_top {
745+
let decl = t.ast_context.get_decl(top_id).unwrap();
746+
let decl_file_id = t.ast_context.file_id(decl);
747+
// TODO use `let else` when it stabilizes.
748+
let converted_decl = match converted_decls.remove(top_id) {
749+
Some(converted) => converted,
750+
None => continue,
751+
};
752+
753+
use ConvertedDecl::*;
754+
match converted_decl {
755+
Item(item) => {
756+
t.insert_item(item, decl);
746757
}
758+
ForeignItem(item) => {
759+
t.insert_foreign_item(*item, decl);
760+
}
761+
Items(items) => {
762+
for item in items {
763+
t.insert_item(item, decl);
764+
}
765+
}
766+
NoItem => {}
767+
};
768+
769+
if t.tcfg.reorganize_definitions && decl_file_id.map_or(false, |id| id != t.main_file) {
770+
t.generate_submodule_imports(*top_id, decl_file_id);
747771
}
748772
}
749773

0 commit comments

Comments
 (0)