11use std:: fs;
2- use std:: io:: Write ;
2+ use std:: io:: { self , Write } ;
3+ use std:: path:: PathBuf ;
34use std:: process:: { Command , Stdio } ;
45
56use rustc_codegen_ssa:: back:: write:: { CodegenContext , ModuleConfig } ;
@@ -8,11 +9,33 @@ use rustc_errors::{DiagCtxtHandle, FatalError};
89use rustc_session:: config:: OutputType ;
910use tracing:: error;
1011
12+ fn write_module ( c_out : & PathBuf , module : & ModuleCodegen < String > ) -> io:: Result < ( ) > {
13+ let mut c_out_file = fs:: File :: create ( c_out) ?;
14+ writeln ! ( c_out_file, "// file: {}.c" , module. name) ?;
15+ write ! ( c_out_file, "{}" , module. module_llvm) ?;
16+ Ok ( ( ) )
17+ }
18+ fn compiled_module (
19+ success : bool ,
20+ module : ModuleCodegen < String > ,
21+ cgcx : & CodegenContext < crate :: CCodegen > ,
22+ ) -> CompiledModule {
23+ module. into_compiled_module (
24+ success,
25+ false ,
26+ false ,
27+ false ,
28+ false ,
29+ & cgcx. output_filenames ,
30+ cgcx. invocation_temp . as_deref ( ) ,
31+ )
32+ }
33+
1134pub ( crate ) fn codegen (
1235 cgcx : & CodegenContext < crate :: CCodegen > ,
1336 module : ModuleCodegen < String > ,
1437 _config : & ModuleConfig ,
15- ) -> Result < CompiledModule , FatalError > {
38+ ) -> CompiledModule {
1639 let dcx = cgcx. create_dcx ( ) ;
1740 let dcx = dcx. handle ( ) ;
1841 let obj_out = cgcx. output_filenames . temp_path_for_cgu (
@@ -23,44 +46,41 @@ pub(crate) fn codegen(
2346 let c_out = obj_out. with_extension ( "c" ) ;
2447
2548 // output c source code
26- let c_out_file = fs:: File :: create ( & c_out) . map_err ( |_| FatalError ) ?;
27- writeln ! ( & c_out_file, "// file: {}.c" , module. name) . map_err ( |_| FatalError ) ?;
28- write ! ( & c_out_file, "{}" , module. module_llvm) . map_err ( |_| FatalError ) ?;
49+ if let Err ( c_out_err) = write_module ( & c_out, & module) {
50+ dcx. emit_err ( crate :: errors:: CFileWriteError { err : c_out_err } ) ;
51+ return compiled_module ( false , module, cgcx) ;
52+ }
2953
3054 // invoke cc to compile
3155 // FIXME: configure cc
3256 // FIXME: handle long command line (windows)
3357 // FIXME: flush_linked_file (windows)
3458 let mut cmd = Command :: new ( "clang" ) ;
3559 cmd. arg ( & c_out) . arg ( "-o" ) . arg ( & obj_out) . arg ( "-c" ) ;
36- let output = match cmd
60+ let success = match cmd
3761 . stdout ( Stdio :: piped ( ) )
3862 . stderr ( Stdio :: piped ( ) )
3963 . spawn ( )
4064 . and_then ( |child| child. wait_with_output ( ) )
4165 {
42- Ok ( output) => output,
66+ Ok ( output) if !output. status . success ( ) => {
67+ error ! ( "compiler stderr:\n {}" , String :: from_utf8_lossy( & output. stderr) ) ;
68+ error ! ( "compiler stdout:\n {}" , String :: from_utf8_lossy( & output. stdout) ) ;
69+ dcx. emit_err ( crate :: errors:: CCompilerError {
70+ cc_stderr : String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ,
71+ cc_stdout : String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) ,
72+ } ) ;
73+ false
74+ }
75+ Ok ( _) => true ,
4376 Err ( e) => {
4477 error ! ( "failed to spawn C compiler: {}" , e) ;
45- return Err ( FatalError ) ;
78+ dcx. emit_err ( crate :: errors:: CCompilerSpawnError { err : e } ) ;
79+ false
4680 }
4781 } ;
4882
49- if !output. status . success ( ) {
50- error ! ( "compiler stderr:\n {}" , String :: from_utf8_lossy( & output. stderr) ) ;
51- error ! ( "compiler stdout:\n {}" , String :: from_utf8_lossy( & output. stdout) ) ;
52- return Err ( FatalError ) ;
53- }
54-
55- Ok ( module. into_compiled_module (
56- true ,
57- false ,
58- false ,
59- false ,
60- false ,
61- & cgcx. output_filenames ,
62- cgcx. invocation_temp . as_deref ( ) ,
63- ) )
83+ compiled_module ( success, module, cgcx)
6484}
6585
6686pub ( crate ) fn link (
0 commit comments