@@ -50,12 +50,32 @@ pub mod util;
5050fn main ( ) {
5151 env_logger:: init ( ) ;
5252
53- let config = parse_config ( env:: args ( ) . collect ( ) ) ;
53+ let mut config = parse_config ( env:: args ( ) . collect ( ) ) ;
5454
5555 if config. valgrind_path . is_none ( ) && config. force_valgrind {
5656 panic ! ( "Can't find Valgrind to run Valgrind tests" ) ;
5757 }
5858
59+ // Some run-make tests need a version of Clang available that matches
60+ // rustc's LLVM version. Since this isn't always the case, these tests are
61+ // opt-in.
62+ let clang_based_tests_possible = check_clang_based_tests_possible ( & config) ;
63+ match ( clang_based_tests_possible, config. force_clang_based_tests ) {
64+ ( Ok ( _) , true ) |
65+ ( Err ( _) , false ) => {
66+ // Nothing to do
67+ }
68+ ( Ok ( _) , false ) => {
69+ // If a valid clang version is available, run the tests even if
70+ // they are not forced.
71+ config. force_clang_based_tests = true ;
72+ }
73+ ( Err ( msg) , true ) => {
74+ // Tests are forced but we don't have a valid version of Clang.
75+ panic ! ( "{}" , msg)
76+ }
77+ }
78+
5979 log_config ( & config) ;
6080 run_tests ( & config) ;
6181}
@@ -108,6 +128,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
108128 "force-valgrind" ,
109129 "fail if Valgrind tests cannot be run under Valgrind" ,
110130 )
131+ . optflag (
132+ "" ,
133+ "force-clang-based-tests" ,
134+ "fail if Clang-based run-make tests can't be run for some reason" ,
135+ )
111136 . optopt (
112137 "" ,
113138 "llvm-filecheck" ,
@@ -189,6 +214,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
189214 "VERSION STRING" ,
190215 )
191216 . optflag ( "" , "system-llvm" , "is LLVM the system LLVM" )
217+ . optopt (
218+ "" ,
219+ "clang-version" ,
220+ "the version of Clang available to run-make tests" ,
221+ "VERSION STRING" ,
222+ )
192223 . optopt (
193224 "" ,
194225 "android-cross-path" ,
@@ -298,6 +329,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
298329 docck_python : matches. opt_str ( "docck-python" ) . unwrap ( ) ,
299330 valgrind_path : matches. opt_str ( "valgrind-path" ) ,
300331 force_valgrind : matches. opt_present ( "force-valgrind" ) ,
332+ force_clang_based_tests : matches. opt_present ( "force-clang-based-tests" ) ,
301333 llvm_filecheck : matches. opt_str ( "llvm-filecheck" ) . map ( |s| PathBuf :: from ( & s) ) ,
302334 src_base,
303335 build_base : opt_path ( matches, "build-base" ) ,
@@ -323,6 +355,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
323355 lldb_native_rust,
324356 llvm_version : matches. opt_str ( "llvm-version" ) ,
325357 system_llvm : matches. opt_present ( "system-llvm" ) ,
358+ clang_version : matches. opt_str ( "clang-version" ) ,
326359 android_cross_path : android_cross_path,
327360 adb_path : opt_str2 ( matches. opt_str ( "adb-path" ) ) ,
328361 adb_test_dir : opt_str2 ( matches. opt_str ( "adb-test-dir" ) ) ,
@@ -1031,3 +1064,54 @@ fn test_extract_gdb_version() {
10311064 7012050 : "GNU gdb (GDB) 7.12.50.20161027-git" ,
10321065 }
10331066}
1067+
1068+
1069+ fn check_clang_based_tests_possible ( config : & Config ) -> Result < ( ) , String > {
1070+
1071+ let llvm_version = if let Some ( llvm_version) = config. llvm_version . as_ref ( ) {
1072+ llvm_version
1073+ } else {
1074+ return Err ( format ! ( "Running `compiletest` with `--force-clang-based-tests` \
1075+ requires `--llvm-version` to be specified.") ) ;
1076+ } ;
1077+
1078+ let clang_major_version = if let Some ( ref version_string) = config. clang_version {
1079+ major_version_from_clang_version_string ( version_string) ?
1080+ } else {
1081+ return Err ( format ! ( "Clang is required for running tests \
1082+ (because of --force-clang-based-tests) \
1083+ but it does not seem to be available.") ) ;
1084+ } ;
1085+
1086+ let rustc_llvm_major_version = major_version_from_llvm_version_string ( & llvm_version) ?;
1087+
1088+ return if clang_major_version != rustc_llvm_major_version {
1089+ Err ( format ! ( "`--force-clang-based-tests` needs the major version of Clang \
1090+ and rustc's LLVM to be the same. Clang version is: {}, \
1091+ Rustc LLVM is: {}",
1092+ config. clang_version. clone( ) . unwrap( ) ,
1093+ llvm_version) )
1094+ } else {
1095+ Ok ( ( ) )
1096+ } ;
1097+
1098+ fn major_version_from_clang_version_string ( clang_version : & str ) -> Result < & str , String > {
1099+ let re = regex:: Regex :: new ( r"clang version (\d)\.\d" ) . unwrap ( ) ;
1100+ if let Some ( captures) = re. captures ( clang_version) {
1101+ Ok ( captures. get ( 1 ) . unwrap ( ) . as_str ( ) )
1102+ } else {
1103+ Err ( format ! ( "Failed to parse major version from Clang version \
1104+ string '{}'.", clang_version) )
1105+ }
1106+ }
1107+
1108+ fn major_version_from_llvm_version_string ( llvm_version : & str ) -> Result < & str , String > {
1109+ let re = regex:: Regex :: new ( r"(\d)\.\d" ) . unwrap ( ) ;
1110+ if let Some ( captures) = re. captures ( llvm_version) {
1111+ Ok ( captures. get ( 1 ) . unwrap ( ) . as_str ( ) )
1112+ } else {
1113+ Err ( format ! ( "Failed to parse major version from LLVM version \
1114+ string '{}'.", llvm_version) )
1115+ }
1116+ }
1117+ }
0 commit comments