diff --git a/toolchain/driver/compile_subcommand.cpp b/toolchain/driver/compile_subcommand.cpp index 92d310badc860..8078225053818 100644 --- a/toolchain/driver/compile_subcommand.cpp +++ b/toolchain/driver/compile_subcommand.cpp @@ -282,7 +282,7 @@ to be specified in the compile command line. Excludes files with the given prefix from dumps. )""", }, - [&](auto& arg_b) { arg_b.Set(&exclude_dump_file_prefix); }); + [&](auto& arg_b) { arg_b.Append(&exclude_dump_file_prefixes); }); b.AddFlag( { .name = "debug-info", @@ -508,12 +508,13 @@ class MultiUnitCache { private: auto BuildIncludeInDumps() -> void { CARBON_CHECK(include_in_dumps_.empty()); - llvm::append_range(include_in_dumps_, - llvm::map_range(units_, [&](const auto& unit) { - return options_->exclude_dump_file_prefix.empty() || - !unit->input_filename().starts_with( - options_->exclude_dump_file_prefix); - })); + llvm::append_range( + include_in_dumps_, llvm::map_range(units_, [&](const auto& unit) { + return llvm::none_of( + options_->exclude_dump_file_prefixes, [&](auto prefix) { + return unit->input_filename().starts_with(prefix); + }); + })); } auto BuildTreeAndSubtreesGetters() -> void { diff --git a/toolchain/driver/compile_subcommand.h b/toolchain/driver/compile_subcommand.h index 2c5e993542fab..bf0e61502b5c9 100644 --- a/toolchain/driver/compile_subcommand.h +++ b/toolchain/driver/compile_subcommand.h @@ -66,7 +66,7 @@ struct CompileOptions { bool prelude_import = false; bool include_debug_info = true; - llvm::StringRef exclude_dump_file_prefix; + llvm::SmallVector exclude_dump_file_prefixes; }; // Implements the compile subcommand of the driver. diff --git a/toolchain/lower/testdata/operators/arithmetic.carbon b/toolchain/lower/testdata/operators/arithmetic.carbon index 709107c3094e1..67d943f66f074 100644 --- a/toolchain/lower/testdata/operators/arithmetic.carbon +++ b/toolchain/lower/testdata/operators/arithmetic.carbon @@ -2,6 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/full.carbon +// // AUTOUPDATE // TIP: To test this file alone, run: // TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/operators/arithmetic.carbon @@ -128,47 +130,47 @@ fn div_u16(a: u16, b: u16) -> u16 { return a / b; } // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} // CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) // CHECK:STDOUT: !3 = !DIFile(filename: "arithmetic.carbon", directory: "") -// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "add_i32", linkageName: "_Cadd_i32.Main", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "add_i32", linkageName: "_Cadd_i32.Main", scope: null, file: !3, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} -// CHECK:STDOUT: !7 = !DILocation(line: 14, column: 44, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 14, column: 37, scope: !4) -// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "add_u32", linkageName: "_Cadd_u32.Main", scope: null, file: !3, line: 15, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !10 = !DILocation(line: 15, column: 44, scope: !9) -// CHECK:STDOUT: !11 = !DILocation(line: 15, column: 37, scope: !9) -// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "div_i32", linkageName: "_Cdiv_i32.Main", scope: null, file: !3, line: 17, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !13 = !DILocation(line: 17, column: 44, scope: !12) -// CHECK:STDOUT: !14 = !DILocation(line: 17, column: 37, scope: !12) -// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "div_u32", linkageName: "_Cdiv_u32.Main", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !16 = !DILocation(line: 18, column: 44, scope: !15) -// CHECK:STDOUT: !17 = !DILocation(line: 18, column: 37, scope: !15) -// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "mod_i32", linkageName: "_Cmod_i32.Main", scope: null, file: !3, line: 20, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !19 = !DILocation(line: 20, column: 44, scope: !18) -// CHECK:STDOUT: !20 = !DILocation(line: 20, column: 37, scope: !18) -// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "mod_u32", linkageName: "_Cmod_u32.Main", scope: null, file: !3, line: 21, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !22 = !DILocation(line: 21, column: 44, scope: !21) -// CHECK:STDOUT: !23 = !DILocation(line: 21, column: 37, scope: !21) -// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "mul_i32", linkageName: "_Cmul_i32.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !25 = !DILocation(line: 23, column: 44, scope: !24) -// CHECK:STDOUT: !26 = !DILocation(line: 23, column: 37, scope: !24) -// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "mul_u32", linkageName: "_Cmul_u32.Main", scope: null, file: !3, line: 24, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !28 = !DILocation(line: 24, column: 44, scope: !27) -// CHECK:STDOUT: !29 = !DILocation(line: 24, column: 37, scope: !27) -// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "neg_i32", linkageName: "_Cneg_i32.Main", scope: null, file: !3, line: 26, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !31 = !DILocation(line: 26, column: 36, scope: !30) -// CHECK:STDOUT: !32 = !DILocation(line: 26, column: 29, scope: !30) -// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "neg_u32", linkageName: "_Cneg_u32.Main", scope: null, file: !3, line: 27, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !34 = !DILocation(line: 27, column: 36, scope: !33) -// CHECK:STDOUT: !35 = !DILocation(line: 27, column: 29, scope: !33) -// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "sub_i32", linkageName: "_Csub_i32.Main", scope: null, file: !3, line: 29, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !37 = !DILocation(line: 29, column: 44, scope: !36) -// CHECK:STDOUT: !38 = !DILocation(line: 29, column: 37, scope: !36) -// CHECK:STDOUT: !39 = distinct !DISubprogram(name: "sub_u32", linkageName: "_Csub_u32.Main", scope: null, file: !3, line: 30, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !40 = !DILocation(line: 30, column: 44, scope: !39) -// CHECK:STDOUT: !41 = !DILocation(line: 30, column: 37, scope: !39) -// CHECK:STDOUT: !42 = distinct !DISubprogram(name: "div_i16", linkageName: "_Cdiv_i16.Main", scope: null, file: !3, line: 34, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !43 = !DILocation(line: 34, column: 44, scope: !42) -// CHECK:STDOUT: !44 = !DILocation(line: 34, column: 37, scope: !42) -// CHECK:STDOUT: !45 = distinct !DISubprogram(name: "div_u16", linkageName: "_Cdiv_u16.Main", scope: null, file: !3, line: 35, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !46 = !DILocation(line: 35, column: 44, scope: !45) -// CHECK:STDOUT: !47 = !DILocation(line: 35, column: 37, scope: !45) +// CHECK:STDOUT: !7 = !DILocation(line: 16, column: 44, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 16, column: 37, scope: !4) +// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "add_u32", linkageName: "_Cadd_u32.Main", scope: null, file: !3, line: 17, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !10 = !DILocation(line: 17, column: 44, scope: !9) +// CHECK:STDOUT: !11 = !DILocation(line: 17, column: 37, scope: !9) +// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "div_i32", linkageName: "_Cdiv_i32.Main", scope: null, file: !3, line: 19, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !13 = !DILocation(line: 19, column: 44, scope: !12) +// CHECK:STDOUT: !14 = !DILocation(line: 19, column: 37, scope: !12) +// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "div_u32", linkageName: "_Cdiv_u32.Main", scope: null, file: !3, line: 20, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !16 = !DILocation(line: 20, column: 44, scope: !15) +// CHECK:STDOUT: !17 = !DILocation(line: 20, column: 37, scope: !15) +// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "mod_i32", linkageName: "_Cmod_i32.Main", scope: null, file: !3, line: 22, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !19 = !DILocation(line: 22, column: 44, scope: !18) +// CHECK:STDOUT: !20 = !DILocation(line: 22, column: 37, scope: !18) +// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "mod_u32", linkageName: "_Cmod_u32.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !22 = !DILocation(line: 23, column: 44, scope: !21) +// CHECK:STDOUT: !23 = !DILocation(line: 23, column: 37, scope: !21) +// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "mul_i32", linkageName: "_Cmul_i32.Main", scope: null, file: !3, line: 25, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !25 = !DILocation(line: 25, column: 44, scope: !24) +// CHECK:STDOUT: !26 = !DILocation(line: 25, column: 37, scope: !24) +// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "mul_u32", linkageName: "_Cmul_u32.Main", scope: null, file: !3, line: 26, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !28 = !DILocation(line: 26, column: 44, scope: !27) +// CHECK:STDOUT: !29 = !DILocation(line: 26, column: 37, scope: !27) +// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "neg_i32", linkageName: "_Cneg_i32.Main", scope: null, file: !3, line: 28, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !31 = !DILocation(line: 28, column: 36, scope: !30) +// CHECK:STDOUT: !32 = !DILocation(line: 28, column: 29, scope: !30) +// CHECK:STDOUT: !33 = distinct !DISubprogram(name: "neg_u32", linkageName: "_Cneg_u32.Main", scope: null, file: !3, line: 29, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !34 = !DILocation(line: 29, column: 36, scope: !33) +// CHECK:STDOUT: !35 = !DILocation(line: 29, column: 29, scope: !33) +// CHECK:STDOUT: !36 = distinct !DISubprogram(name: "sub_i32", linkageName: "_Csub_i32.Main", scope: null, file: !3, line: 31, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !37 = !DILocation(line: 31, column: 44, scope: !36) +// CHECK:STDOUT: !38 = !DILocation(line: 31, column: 37, scope: !36) +// CHECK:STDOUT: !39 = distinct !DISubprogram(name: "sub_u32", linkageName: "_Csub_u32.Main", scope: null, file: !3, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !40 = !DILocation(line: 32, column: 44, scope: !39) +// CHECK:STDOUT: !41 = !DILocation(line: 32, column: 37, scope: !39) +// CHECK:STDOUT: !42 = distinct !DISubprogram(name: "div_i16", linkageName: "_Cdiv_i16.Main", scope: null, file: !3, line: 36, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !43 = !DILocation(line: 36, column: 44, scope: !42) +// CHECK:STDOUT: !44 = !DILocation(line: 36, column: 37, scope: !42) +// CHECK:STDOUT: !45 = distinct !DISubprogram(name: "div_u16", linkageName: "_Cdiv_u16.Main", scope: null, file: !3, line: 37, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !46 = !DILocation(line: 37, column: 44, scope: !45) +// CHECK:STDOUT: !47 = !DILocation(line: 37, column: 37, scope: !45) diff --git a/toolchain/testing/file_test.cpp b/toolchain/testing/file_test.cpp index 5d58084cadf1c..5ec3b9579ea44 100644 --- a/toolchain/testing/file_test.cpp +++ b/toolchain/testing/file_test.cpp @@ -117,9 +117,36 @@ auto ToolchainFileTest::Run( } } + llvm::SmallVector filtered_test_args; + if (component_ == "check" || component_ == "lower") { + filtered_test_args.reserve(test_args.size()); + bool found_prelude_flag = false; + for (auto arg : test_args) { + bool driver_flag = arg == "--custom-core" || arg == "--no-prelude-import"; + // A flag specified by a test prelude to indicate the intention to include + // the full production prelude. + bool full_prelude = arg == "--expect-full-prelude"; + if (driver_flag || full_prelude) { + found_prelude_flag = true; + } + if (!full_prelude) { + filtered_test_args.push_back(arg); + } + } + if (!found_prelude_flag) { + // TODO: Enable this error when all check/ and lower/ tests include a + // prelude choice explicitly. + // return Error( + // "Include a prelude from //toolchain/testing/testdata/min_prelude " + // "to specify what should be imported into the test."); + } + } else { + filtered_test_args = test_args; + } + Driver driver(fs, &installation_, input_stream, &output_stream, &error_stream); - auto driver_result = driver.RunCommand(test_args); + auto driver_result = driver.RunCommand(filtered_test_args); // If any diagnostics have been produced, add a trailing newline to make the // last diagnostic match intermediate diagnostics (that have a newline // separator between them). This reduces churn when adding new diagnostics diff --git a/toolchain/testing/testdata/min_prelude/full.carbon b/toolchain/testing/testdata/min_prelude/full.carbon new file mode 100644 index 0000000000000..bea3c44fafec2 --- /dev/null +++ b/toolchain/testing/testdata/min_prelude/full.carbon @@ -0,0 +1,15 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// EXTRA-ARGS: --expect-full-prelude --exclude-dump-file-prefix=min_prelude/ + +// Including this file indicates explicitly to file_test that the test wants to +// include the full production prelude. Note that this is quite slow relative to +// a more minimal prelude (e.g. ~1s vs 10ms), and makes debugging tests quite +// noisy as the prelude compiles many things. + +// --- min_prelude/full.carbon + +// A no-op package. +package MinPreludeFull;