@@ -50,12 +50,32 @@ pub mod util;
50
50
fn main ( ) {
51
51
env_logger:: init ( ) ;
52
52
53
- let config = parse_config ( env:: args ( ) . collect ( ) ) ;
53
+ let mut config = parse_config ( env:: args ( ) . collect ( ) ) ;
54
54
55
55
if config. valgrind_path . is_none ( ) && config. force_valgrind {
56
56
panic ! ( "Can't find Valgrind to run Valgrind tests" ) ;
57
57
}
58
58
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
+
59
79
log_config ( & config) ;
60
80
run_tests ( & config) ;
61
81
}
@@ -108,6 +128,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
108
128
"force-valgrind" ,
109
129
"fail if Valgrind tests cannot be run under Valgrind" ,
110
130
)
131
+ . optflag (
132
+ "" ,
133
+ "force-clang-based-tests" ,
134
+ "fail if Clang-based run-make tests can't be run for some reason" ,
135
+ )
111
136
. optopt (
112
137
"" ,
113
138
"llvm-filecheck" ,
@@ -189,6 +214,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
189
214
"VERSION STRING" ,
190
215
)
191
216
. 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
+ )
192
223
. optopt (
193
224
"" ,
194
225
"android-cross-path" ,
@@ -298,6 +329,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
298
329
docck_python : matches. opt_str ( "docck-python" ) . unwrap ( ) ,
299
330
valgrind_path : matches. opt_str ( "valgrind-path" ) ,
300
331
force_valgrind : matches. opt_present ( "force-valgrind" ) ,
332
+ force_clang_based_tests : matches. opt_present ( "force-clang-based-tests" ) ,
301
333
llvm_filecheck : matches. opt_str ( "llvm-filecheck" ) . map ( |s| PathBuf :: from ( & s) ) ,
302
334
src_base,
303
335
build_base : opt_path ( matches, "build-base" ) ,
@@ -323,6 +355,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
323
355
lldb_native_rust,
324
356
llvm_version : matches. opt_str ( "llvm-version" ) ,
325
357
system_llvm : matches. opt_present ( "system-llvm" ) ,
358
+ clang_version : matches. opt_str ( "clang-version" ) ,
326
359
android_cross_path : android_cross_path,
327
360
adb_path : opt_str2 ( matches. opt_str ( "adb-path" ) ) ,
328
361
adb_test_dir : opt_str2 ( matches. opt_str ( "adb-test-dir" ) ) ,
@@ -1031,3 +1064,54 @@ fn test_extract_gdb_version() {
1031
1064
7012050 : "GNU gdb (GDB) 7.12.50.20161027-git" ,
1032
1065
}
1033
1066
}
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