@@ -495,10 +495,6 @@ pub fn translate(
495495 } ;
496496
497497 {
498- // Sort the top-level declarations by file and source location so that we
499- // preserve the ordering of all declarations in each file.
500- t. ast_context . sort_top_decls ( ) ;
501-
502498 t. locate_comments ( ) ;
503499
504500 // Headers often pull in declarations that are unused;
@@ -688,26 +684,37 @@ pub fn translate(
688684 }
689685 }
690686
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 ( ) ;
687+ // Export top-level value declarations.
688+ // We do this in a conversion pass and then an insertion pass
689+ // so that the conversion order can differ from the order they're emitted in.
690+ let mut converted_decls = t
691+ . ast_context
692+ . c_decls_top
693+ . iter ( )
694+ . filter_map ( |& top_id| {
695+ use CDeclKind :: * ;
696+ let needs_export = match t. ast_context [ top_id] . kind {
697+ Function { is_implicit, .. } => !is_implicit,
698+ Variable { .. } => true ,
699+ MacroObject { .. } => true , // Depends on `tcfg.translate_const_macros`, but handled in `fn convert_const_macro_expansion`.
700+ MacroFunction { .. } => true , // Depends on `tcfg.translate_fn_macros`, but handled in `fn convert_fn_macro_invocation`.
701+ _ => false ,
702+ } ;
703+ if !needs_export {
704+ return None ;
705+ }
706+
707+ let decl = t. ast_context . get_decl ( & top_id) . unwrap ( ) ;
703708 let decl_file_id = t. ast_context . file_id ( decl) ;
704709
705710 if t. tcfg . reorganize_definitions
706711 && decl_file_id. map_or ( false , |id| id != t. main_file )
707712 {
708713 t. cur_file . set ( decl_file_id) ;
709714 }
710- match t. convert_decl ( ctx, * top_id) {
715+
716+ // TODO use `.inspect_err` once stabilized in Rust 1.76.
717+ let converted = match t. convert_decl ( ctx, top_id) {
711718 Err ( e) => {
712719 let decl_identifier = decl. kind . get_name ( ) . map_or_else (
713720 || {
@@ -719,32 +726,47 @@ pub fn translate(
719726 ) ;
720727 let msg = format ! ( "Failed to translate {}: {}" , decl_identifier, e) ;
721728 translate_failure ( t. tcfg , & msg) ;
729+ Err ( e)
722730 }
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- }
731+ Ok ( converted) => Ok ( converted) ,
740732 }
733+ . ok ( ) ?;
734+
741735 t. cur_file . take ( ) ;
742736
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) ;
737+ Some ( ( top_id, converted) )
738+ } )
739+ . collect :: < HashMap < _ , _ > > ( ) ;
740+
741+ t. ast_context . sort_top_decls_for_emitting ( ) ;
742+
743+ for top_id in & t. ast_context . c_decls_top {
744+ let decl = t. ast_context . get_decl ( top_id) . unwrap ( ) ;
745+ let decl_file_id = t. ast_context . file_id ( decl) ;
746+ // TODO use `let else` when it stabilizes.
747+ let converted_decl = match converted_decls. remove ( top_id) {
748+ Some ( converted) => converted,
749+ None => continue ,
750+ } ;
751+
752+ use ConvertedDecl :: * ;
753+ match converted_decl {
754+ Item ( item) => {
755+ t. insert_item ( item, decl) ;
747756 }
757+ ForeignItem ( item) => {
758+ t. insert_foreign_item ( * item, decl) ;
759+ }
760+ Items ( items) => {
761+ for item in items {
762+ t. insert_item ( item, decl) ;
763+ }
764+ }
765+ NoItem => { }
766+ } ;
767+
768+ if t. tcfg . reorganize_definitions && decl_file_id. map_or ( false , |id| id != t. main_file ) {
769+ t. generate_submodule_imports ( * top_id, decl_file_id) ;
748770 }
749771 }
750772
0 commit comments