Skip to content

Commit 57fc61a

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 48caa16 commit 57fc61a

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
@@ -688,26 +688,37 @@ pub fn translate(
688688
}
689689
}
690690

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

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

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

0 commit comments

Comments
 (0)