11//@ needs-force-clang-based-tests
2- // This test checks that the clang defines for each target allign with the core ffi types defined in
3- // mod.rs. Therefore each rust target is queried and the clang defines for each target are read and
4- // compared to the core sizes to verify all types and sizes allign at buildtime.
5- //
6- // If this test fails because Rust adds a target that Clang does not support, this target should be
7- // added to SKIPPED_TARGETS.
2+
3+ //! This test checks that the clang defines for each target allign with the core ffi types
4+ //! defined in `library/core/src/ffi/primitives.rs'.
5+ //! Therefore each rust target is queried and the clang defines for each target
6+ //! are read and compared to the core sizes to verify all types and sizes allign at buildtime.
7+ //!
8+ //! If this test fails because Rust adds a target that Clang does not support, this target should be
9+ //! added to `SKIPPED_TARGETS`.
810
911use run_make_support:: { clang, regex, rfs, rustc, serde_json} ;
1012use serde_json:: Value ;
1113
1214// It is not possible to run the Rust test-suite on these targets.
1315const SKIPPED_TARGETS : & [ & str ] = & [
16+ // Clang doesn't have built-in support for the Xtensa architecture
1417 "xtensa-esp32-espidf" ,
1518 "xtensa-esp32-none-elf" ,
1619 "xtensa-esp32s2-espidf" ,
1720 "xtensa-esp32s2-none-elf" ,
1821 "xtensa-esp32s3-espidf" ,
1922 "xtensa-esp32s3-none-elf" ,
23+ // Clang doesn't include built-in support for the C-SKY architecture
2024 "csky-unknown-linux-gnuabiv2" ,
2125 "csky-unknown-linux-gnuabiv2hf" ,
26+ // GPU target with different memory model/type system - C type sizes don't map cleanly
27+ "amdgcn-amd-amdhsa" ,
2228] ;
2329
2430const MAPPED_TARGETS : & [ ( & str , & str ) ] = & [
@@ -56,8 +62,9 @@ fn main() {
5662 . unwrap_or ( llvm_target) ;
5763
5864 // Run Clang's preprocessor for the relevant target, printing default macro definitions.
59- let clang_output =
60- clang ( ) . args ( & [ "-E" , "-dM" , "-x" , "c" , "/dev/null" , "-target" , & target_to_use] ) . run ( ) ;
65+ let clang_output = clang ( )
66+ . args ( & [ "-nogpulib" , "-E" , "-dM" , "-x" , "c" , "/dev/null" , "-target" , & target_to_use] )
67+ . run ( ) ;
6168
6269 let defines = String :: from_utf8 ( clang_output. stdout ( ) ) . expect ( "Invalid UTF-8" ) ;
6370
@@ -74,6 +81,56 @@ fn main() {
7481 {minicore_content}
7582 /* end minicore content */
7683
84+ /// Vendored from the 'cfg_if' crate
85+ macro_rules! cfg_if {{
86+ // match if/else chains with a final `else`
87+ (
88+ $(
89+ if #[cfg( $i_meta:meta )] {{ $( $i_tokens:tt )* }}
90+ ) else+
91+ else {{ $( $e_tokens:tt )* }}
92+ ) => {{
93+ cfg_if! {{
94+ @__items () ;
95+ $(
96+ (( $i_meta ) ( $( $i_tokens )* )) ,
97+ )+
98+ (() ( $( $e_tokens )* )) ,
99+ }}
100+ }};
101+ // Internal and recursive macro to emit all the items
102+ //
103+ // Collects all the previous cfgs in a list at the beginning, so they can be
104+ // negated. After the semicolon is all the remaining items.
105+ (@__items ( $( $_:meta , )* ) ; ) => {{}};
106+ (
107+ @__items ( $( $no:meta , )* ) ;
108+ (( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
109+ $( $rest:tt , )*
110+ ) => {{
111+ // Emit all items within one block, applying an appropriate #[cfg]. The
112+ // #[cfg] will require all `$yes` matchers specified and must also negate
113+ // all previous matchers.
114+ #[cfg(all(
115+ $( $yes , )?
116+ not(any( $( $no ),* ))
117+ ))]
118+ cfg_if! {{ @__identity $( $tokens )* }}
119+ // Recurse to emit all other items in `$rest`, and when we do so add all
120+ // our `$yes` matchers to the list of `$no` matchers as future emissions
121+ // will have to negate everything we just matched as well.
122+ cfg_if! {{
123+ @__items ( $( $no , )* $( $yes , )? ) ;
124+ $( $rest , )*
125+ }}
126+ }};
127+ // Internal macro to make __apply work out right for different match types,
128+ // because of how macros match/expand stuff.
129+ (@__identity $( $tokens:tt )* ) => {{
130+ $( $tokens )*
131+ }};
132+ }}
133+
77134 #[path = "processed_mod.rs"]
78135 mod ffi;
79136 #[path = "tests.rs"]
@@ -127,9 +184,6 @@ fn main() {
127184 panic ! ( "Failed for target {}" , target) ;
128185 }
129186 }
130-
131- // Cleanup
132- rfs:: remove_file ( "processed_mod.rs" ) ;
133187}
134188
135189// Helper to parse size from clang defines
@@ -157,7 +211,7 @@ fn char_is_signed(defines: &str) -> bool {
157211
158212/// Parse core/ffi/mod.rs to retrieve only necessary macros and type defines
159213fn preprocess_core_ffi ( ) {
160- let mod_path = run_make_support:: source_root ( ) . join ( "library/core/src/ffi/mod .rs" ) ;
214+ let mod_path = run_make_support:: source_root ( ) . join ( "library/core/src/ffi/primitives .rs" ) ;
161215 let mut content = rfs:: read_to_string ( & mod_path) ;
162216
163217 //remove stability features #![unstable]
@@ -168,26 +222,10 @@ fn preprocess_core_ffi() {
168222 re = regex:: Regex :: new ( r"#\[doc[^]]*?\]" ) . unwrap ( ) ;
169223 content = re. replace_all ( & content, "" ) . to_string ( ) ;
170224
171- //remove lang feature #[lang...]
172- re = regex:: Regex :: new ( r"#\[lang[^]]*?\]" ) . unwrap ( ) ;
173- content = re. replace_all ( & content, "" ) . to_string ( ) ;
174-
175225 //remove non inline modules
176226 re = regex:: Regex :: new ( r".*mod.*;" ) . unwrap ( ) ;
177227 content = re. replace_all ( & content, "" ) . to_string ( ) ;
178228
179- //remove use
180- re = regex:: Regex :: new ( r".*use.*;" ) . unwrap ( ) ;
181- content = re. replace_all ( & content, "" ) . to_string ( ) ;
182-
183- //remove fn fmt {...}
184- re = regex:: Regex :: new ( r"(?s)fn fmt.*?\{.*?\}" ) . unwrap ( ) ;
185- content = re. replace_all ( & content, "" ) . to_string ( ) ;
186-
187- //rmv impl fmt {...}
188- re = regex:: Regex :: new ( r"(?s)impl fmt::Debug for.*?\{.*?\}" ) . unwrap ( ) ;
189- content = re. replace_all ( & content, "" ) . to_string ( ) ;
190-
191229 let file_name = "processed_mod.rs" ;
192230
193231 rfs:: write ( & file_name, content) ;
0 commit comments