From f987504614dd0b477c0248fb9e78db199c9b1089 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 8 Jul 2025 17:47:21 -0700 Subject: [PATCH] Track the location of the Cpp import for use in Clang diagnostics. (#5783) When diagnosing a problem with C++ code imported from Carbon, include the location of the specific `import Cpp` statement that imported the C++ code as part of the backtrace, rather than providing a location in a generated file that doesn't exist on disk. Also fix handling in autoupdate of check lines that contain multiple file name and line number pairs to use the matched file name for remapping of locations rather than the first file name in the line. --- testing/file_test/autoupdate.cpp | 63 +++++++++++-------- testing/file_test/autoupdate.h | 25 ++++++-- .../multiple_file_refs_in_line.carbon | 24 +++++++ toolchain/check/import_cpp.cpp | 13 +++- .../testdata/interop/cpp/bad_import.carbon | 4 +- .../interop/cpp/cpp_diagnostics.carbon | 58 ++++++++--------- .../interop/cpp/file_not_found.carbon | 4 +- 7 files changed, 125 insertions(+), 66 deletions(-) create mode 100644 testing/file_test/testdata/multiple_file_refs_in_line.carbon diff --git a/testing/file_test/autoupdate.cpp b/testing/file_test/autoupdate.cpp index 26472537ba36..a5644aa1f81a 100644 --- a/testing/file_test/autoupdate.cpp +++ b/testing/file_test/autoupdate.cpp @@ -43,6 +43,7 @@ FileTestAutoupdater::FileAndLineNumber::FileAndLineNumber( line_number(ParseLineNumber(line_number)) {} auto FileTestAutoupdater::CheckLine::RemapLineNumbers( + const llvm::DenseMap& file_to_number_map, const llvm::DenseMap, int>& output_line_remap, const llvm::SmallVector& new_last_line_numbers) -> void { // Only need to do remappings when there's a line number replacement. @@ -60,9 +61,10 @@ auto FileTestAutoupdater::CheckLine::RemapLineNumbers( line_cursor.remove_prefix(line_offset); // Look for a line number to replace. There may be multiple, so we // repeatedly check. + absl::string_view matched_filename; absl::string_view matched_line_number; if (replacement_->has_file) { - RE2::PartialMatch(line_cursor, *replacement_->re, nullptr, + RE2::PartialMatch(line_cursor, *replacement_->re, &matched_filename, &matched_line_number); } else { RE2::PartialMatch(line_cursor, *replacement_->re, &matched_line_number); @@ -71,25 +73,31 @@ auto FileTestAutoupdater::CheckLine::RemapLineNumbers( return; } - // Update the cursor offset from the match. - line_offset = matched_line_number.begin() - line_.c_str(); + // Map the matched filename to its file number. + auto matched_file_number = file_number(); + if (replacement_->has_file) { + auto it = file_to_number_map.find(matched_filename); + if (it != file_to_number_map.end()) { + matched_file_number = it->second; + } + } // Calculate the new line number (possibly with new CHECK lines added, or // some removed). int old_line_number = ParseLineNumber(matched_line_number); int new_line_number = -1; if (auto remapped = - output_line_remap.find({file_number(), old_line_number}); + output_line_remap.find({matched_file_number, old_line_number}); remapped != output_line_remap.end()) { // Map old non-check lines to their new line numbers. new_line_number = remapped->second; } else { // We assume unmapped references point to the end-of-file. - new_line_number = new_last_line_numbers[file_number()]; + new_line_number = new_last_line_numbers[matched_file_number]; } std::string replacement; - if (output_file_number_ == file_number()) { + if (matched_file_number == output_file_number_) { int offset = new_line_number - output_line_number_; // Update the line offset in the CHECK line. const char* offset_prefix = offset < 0 ? "" : "+"; @@ -103,8 +111,11 @@ auto FileTestAutoupdater::CheckLine::RemapLineNumbers( replacement = llvm::formatv(replacement_->line_formatv.c_str(), new_line_number); } - line_.replace(matched_line_number.data() - line_.data(), - matched_line_number.size(), replacement); + auto line_number_offset = matched_line_number.data() - line_.data(); + line_.replace(line_number_offset, matched_line_number.size(), replacement); + + // Resume matching from the end of the replacement line number. + line_offset = line_number_offset + replacement.size(); } } @@ -144,12 +155,6 @@ auto FileTestAutoupdater::BuildCheckLines(llvm::StringRef output, return CheckLines({}); } - // Prepare to look for filenames in lines. - llvm::DenseMap file_to_number_map; - for (auto [number, name] : llvm::enumerate(filenames_)) { - file_to_number_map.insert({name, number}); - } - // %t substitution means we may see the temporary directory's path in output. std::filesystem::path tmpdir_path = GetTempDirectory(); llvm::StringRef tmpdir = tmpdir_path.native(); @@ -200,14 +205,14 @@ auto FileTestAutoupdater::BuildCheckLines(llvm::StringRef output, if (default_file_re_) { absl::string_view filename; if (RE2::PartialMatch(line, *default_file_re_, &filename)) { - auto it = file_to_number_map.find(filename); - CARBON_CHECK(it != file_to_number_map.end(), + auto it = file_to_number_map_.find(filename); + CARBON_CHECK(it != file_to_number_map_.end(), "default_file_re had unexpected match in '{0}' (`{1}`)", line, default_file_re_->pattern()); default_file_number = it->second; } } - auto file_and_line = GetFileAndLineNumber(file_to_number_map, + auto file_and_line = GetFileAndLineNumber(file_to_number_map_, default_file_number, check_line); check_lines.push_back(CheckLine(file_and_line, check_line)); } @@ -241,7 +246,8 @@ auto FileTestAutoupdater::AddTips() -> void { auto FileTestAutoupdater::ShouldAddCheckLine(const CheckLines& check_lines, bool to_file_end) const -> bool { - return !autoupdate_split_ && check_lines.cursor != check_lines.lines.end() && + return !autoupdate_split_file_ && + check_lines.cursor != check_lines.lines.end() && (check_lines.cursor->file_number() < output_file_number_ || (check_lines.cursor->file_number() == output_file_number_ && (to_file_end || check_lines.cursor->line_number() <= @@ -318,7 +324,7 @@ auto FileTestAutoupdater::Run(bool dry_run) -> bool { // lines after AUTOUPDATE. AddRemappedNonCheckLine(); AddTips(); - if (!autoupdate_split_) { + if (!autoupdate_split_file_) { AddCheckLines(stderr_, /*to_file_end=*/false); if (any_attached_stdout_lines_) { AddCheckLines(stdout_, /*to_file_end=*/false); @@ -331,8 +337,7 @@ auto FileTestAutoupdater::Run(bool dry_run) -> bool { if (output_file_number_ < non_check_line_->file_number()) { FinishFile(/*is_last_file=*/false); StartSplitFile(); - if (autoupdate_split_ && - output_file_number_ == static_cast(filenames_.size())) { + if (output_file_number_ == autoupdate_split_file_) { break; } continue; @@ -353,18 +358,22 @@ auto FileTestAutoupdater::Run(bool dry_run) -> bool { ++non_check_line_; } - // When autoupdate_split_ was true, this will result in all check lines (and - // only check lines) being added to the split by FinishFile. We don't use - // autoupdate_split_ past this point. - autoupdate_split_ = false; + // Clear out the autoupdate split, which would otherwise prevent check lines + // being written to the autoupdate file. When autoupdate_split_file_ was set, + // this will result in all check lines (and only check lines) being added to + // the split by FinishFile. We don't use autoupdate_split_file_ past this + // point. + autoupdate_split_file_ = std::nullopt; FinishFile(/*is_last_file=*/true); for (auto& check_line : stdout_.lines) { - check_line.RemapLineNumbers(output_line_remap_, new_last_line_numbers_); + check_line.RemapLineNumbers(file_to_number_map_, output_line_remap_, + new_last_line_numbers_); } for (auto& check_line : stderr_.lines) { - check_line.RemapLineNumbers(output_line_remap_, new_last_line_numbers_); + check_line.RemapLineNumbers(file_to_number_map_, output_line_remap_, + new_last_line_numbers_); } // Generate the autoupdated file. diff --git a/testing/file_test/autoupdate.h b/testing/file_test/autoupdate.h index 9da9ed920061..6dfd2bd41782 100644 --- a/testing/file_test/autoupdate.h +++ b/testing/file_test/autoupdate.h @@ -47,13 +47,14 @@ class FileTestAutoupdater { test_command_(std::move(test_command)), dump_command_(std::move(dump_command)), input_content_(input_content), - filenames_(filenames), autoupdate_line_number_(autoupdate_line_number), - autoupdate_split_(autoupdate_split), non_check_lines_(non_check_lines), default_file_re_(default_file_re), line_number_replacements_(line_number_replacements), do_extra_check_replacements_(std::move(do_extra_check_replacements)), + autoupdate_split_file_( + autoupdate_split ? std::optional(filenames.size()) : std::nullopt), + file_to_number_map_(BuildFileToNumberMap(filenames)), // BuildCheckLines should only be called after other member // initialization. stdout_(BuildCheckLines(actual_stdout, "STDOUT")), @@ -132,6 +133,7 @@ class FileTestAutoupdater { // When the location of all lines in a file are known, we can set the line // offset based on the target line. auto RemapLineNumbers( + const llvm::DenseMap& file_to_number_map, const llvm::DenseMap, int>& output_line_remap, const llvm::SmallVector& new_last_line_numbers) -> void; @@ -163,6 +165,16 @@ class FileTestAutoupdater { int default_file_number, const std::string& check_line) -> FileAndLineNumber; + // Builds a mapping from file name to file number. + auto BuildFileToNumberMap(const llvm::SmallVector& filenames) + -> llvm::DenseMap { + llvm::DenseMap file_to_number_map; + for (auto [number, name] : llvm::enumerate(filenames)) { + file_to_number_map.insert({name, number}); + } + return file_to_number_map; + } + // Builds CheckLine lists for autoupdate. auto BuildCheckLines(llvm::StringRef output, const char* label) -> CheckLines; @@ -197,17 +209,22 @@ class FileTestAutoupdater { std::string test_command_; std::string dump_command_; llvm::StringRef input_content_; - const llvm::SmallVector& filenames_; int autoupdate_line_number_; - bool autoupdate_split_; const llvm::SmallVector& non_check_lines_; const std::optional& default_file_re_; const llvm::SmallVector& line_number_replacements_; std::functionvoid> do_extra_check_replacements_; + // If we have an autoupdate split that still needs to be processed, the file + // number of the autoupdate split. Otherwise, this is nullopt. + std::optional autoupdate_split_file_; + // Generated TIP lines, from AddTips. llvm::SmallVector tips_; + // Mapping from file names to file numbers. + llvm::DenseMap file_to_number_map_; + // The constructed CheckLine list and cursor. CheckLines stdout_; CheckLines stderr_; diff --git a/testing/file_test/testdata/multiple_file_refs_in_line.carbon b/testing/file_test/testdata/multiple_file_refs_in_line.carbon new file mode 100644 index 000000000000..2e8d04ef1f53 --- /dev/null +++ b/testing/file_test/testdata/multiple_file_refs_in_line.carbon @@ -0,0 +1,24 @@ +// 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 + +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //testing/file_test:file_test_base_test --test_arg=--file_tests=testing/file_test/testdata/multiple_file_refs_in_line.carbon +// TIP: To dump output, run: +// TIP: bazel run //testing/file_test:file_test_base_test -- --dump_output --file_tests=testing/file_test/testdata/multiple_file_refs_in_line.carbon +// CHECK:STDOUT: 3 args: `default_args`, `a.carbon`, `b.carbon` + +// --- a.carbon +a.carbon:1: b.carbon:3: a.carbon:3: hello +// CHECK:STDOUT: a.carbon:[[@LINE-1]]: a.carbon:[[@LINE-1]]: b.carbon:3: a.carbon:[[@LINE+1]]: hello + +// --- b.carbon + + +a.carbon:1: b.carbon:3: a.carbon:3: hello +// CHECK:STDOUT: b.carbon:[[@LINE-1]]: a.carbon:1: b.carbon:[[@LINE-1]]: a.carbon:3: hello +a.carbon:1: b.carbon:5: a.carbon:3: hello +// CHECK:STDOUT: b.carbon:[[@LINE-1]]: a.carbon:1: b.carbon:[[@LINE-1]]: a.carbon:3: hello +a.carbon:1: b.carbon:7: a.carbon:3: hello +// CHECK:STDOUT: b.carbon:[[@LINE-1]]: a.carbon:1: b.carbon:[[@LINE-1]]: a.carbon:3: hello diff --git a/toolchain/check/import_cpp.cpp b/toolchain/check/import_cpp.cpp index 6ced5552543f..7b850fe89ba2 100644 --- a/toolchain/check/import_cpp.cpp +++ b/toolchain/check/import_cpp.cpp @@ -13,6 +13,7 @@ #include "clang/Frontend/TextDiagnostic.h" #include "clang/Sema/Lookup.h" #include "clang/Tooling/Tooling.h" +#include "common/ostream.h" #include "common/raw_string_ostream.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" @@ -44,6 +45,15 @@ static auto GenerateCppIncludesHeaderCode( std::string code; llvm::raw_string_ostream code_stream(code); for (const Parse::Tree::PackagingNames& import : imports) { + // Add a line marker directive pointing at the location of the `import Cpp` + // declaration in the Carbon source file. This will cause Clang's + // diagnostics machinery to track and report the location in Carbon code + // where the import was written. + auto token = context.parse_tree().node_token(import.node_id); + code_stream << "# " << context.tokens().GetLineNumber(token) << " \"" + << FormatEscaped(context.tokens().source().filename()) + << "\"\n"; + code_stream << "#include \"" << FormatEscaped( context.string_literal_values().Get(import.library_id)) @@ -108,6 +118,7 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer { // TODO: Consider allowing setting `DiagnosticOptions` or use // `ASTUnit::getDiagnostics().getLangOptions().getDiagnosticOptions()`. clang::DiagnosticOptions diagnostic_options; + diagnostic_options.ShowPresumedLoc = true; clang::TextDiagnostic text_diagnostic(diagnostics_stream, lang_options, diagnostic_options); text_diagnostic.emitDiagnostic( @@ -139,8 +150,6 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer { case clang::DiagnosticsEngine::Warning: case clang::DiagnosticsEngine::Error: case clang::DiagnosticsEngine::Fatal: { - // TODO: Parse the message to select the relevant C++ import and add - // that information to the location. CARBON_DIAGNOSTIC(CppInteropParseWarning, Warning, "{0}", std::string); CARBON_DIAGNOSTIC(CppInteropParseError, Error, "{0}", std::string); diff --git a/toolchain/check/testdata/interop/cpp/bad_import.carbon b/toolchain/check/testdata/interop/cpp/bad_import.carbon index c265ce0a3a39..54df4d287b37 100644 --- a/toolchain/check/testdata/interop/cpp/bad_import.carbon +++ b/toolchain/check/testdata/interop/cpp/bad_import.carbon @@ -35,8 +35,8 @@ import Cpp library ""; library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_import_cpp_library_file_with_quotes.carbon:[[@LINE+6]]:1: in import [InImport] -// CHECK:STDERR: fail_import_cpp_library_file_with_quotes.carbon.generated.cpp_imports.h:1: error: fail_import_cpp_library_file_with_quotes.carbon.generated.cpp_imports.h:1:10: fatal error: '\"foo.h\"' file not found -// CHECK:STDERR: 1 | #include "\"foo.h\"" +// CHECK:STDERR: fail_import_cpp_library_file_with_quotes.carbon:[[@LINE+5]]: error: fail_import_cpp_library_file_with_quotes.carbon:[[@LINE+5]]:10: fatal error: '\"foo.h\"' file not found +// CHECK:STDERR: 10 | #include "\"foo.h\"" // CHECK:STDERR: | ^~~~~~~~~~~ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: diff --git a/toolchain/check/testdata/interop/cpp/cpp_diagnostics.carbon b/toolchain/check/testdata/interop/cpp/cpp_diagnostics.carbon index 47b5f636400f..e7b985633a01 100644 --- a/toolchain/check/testdata/interop/cpp/cpp_diagnostics.carbon +++ b/toolchain/check/testdata/interop/cpp/cpp_diagnostics.carbon @@ -23,7 +23,7 @@ library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_import_cpp_file_with_one_error.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./one_error.h:2: error: In file included from fail_import_cpp_file_with_one_error.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_error.h:2: error: In file included from fail_import_cpp_file_with_one_error.carbon:[[@LINE+6]]: // CHECK:STDERR: ./one_error.h:2:2: error: "error1" // CHECK:STDERR: 2 | #error "error1" // CHECK:STDERR: | ^ @@ -45,14 +45,14 @@ import Cpp library "one_error.h"; library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_import_cpp_file_with_multiple_errors.carbon:[[@LINE+14]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors.h:2: error: In file included from fail_import_cpp_file_with_multiple_errors.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_errors.h:2: error: In file included from fail_import_cpp_file_with_multiple_errors.carbon:[[@LINE+13]]: // CHECK:STDERR: ./multiple_errors.h:2:2: error: "error1" // CHECK:STDERR: 2 | #error "error1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: // CHECK:STDERR: fail_import_cpp_file_with_multiple_errors.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors.h:3: error: In file included from fail_import_cpp_file_with_multiple_errors.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_errors.h:3: error: In file included from fail_import_cpp_file_with_multiple_errors.carbon:[[@LINE+6]]: // CHECK:STDERR: ./multiple_errors.h:3:2: error: "error2" // CHECK:STDERR: 3 | #error "error2" // CHECK:STDERR: | ^ @@ -74,7 +74,7 @@ library "[[@TEST_NAME]]"; //@dump-sem-ir-begin // CHECK:STDERR: import_cpp_file_with_one_warning.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./one_warning.h:2: warning: In file included from import_cpp_file_with_one_warning.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_warning.h:2: warning: In file included from import_cpp_file_with_one_warning.carbon:[[@LINE+6]]: // CHECK:STDERR: ./one_warning.h:2:2: warning: "warning1" // CHECK:STDERR: 2 | #warning "warning1" // CHECK:STDERR: | ^ @@ -99,21 +99,21 @@ library "[[@TEST_NAME]]"; //@dump-sem-ir-begin // CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon:[[@LINE+21]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_warnings.h:2: warning: In file included from import_cpp_file_with_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_warnings.h:2: warning: In file included from import_cpp_file_with_multiple_warnings.carbon:[[@LINE+20]]: // CHECK:STDERR: ./multiple_warnings.h:2:2: warning: "warning1" // CHECK:STDERR: 2 | #warning "warning1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon:[[@LINE+14]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_warnings.h:3: warning: In file included from import_cpp_file_with_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_warnings.h:3: warning: In file included from import_cpp_file_with_multiple_warnings.carbon:[[@LINE+13]]: // CHECK:STDERR: ./multiple_warnings.h:3:2: warning: "warning2" // CHECK:STDERR: 3 | #warning "warning2" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_warnings.h:4: warning: In file included from import_cpp_file_with_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_warnings.h:4: warning: In file included from import_cpp_file_with_multiple_warnings.carbon:[[@LINE+6]]: // CHECK:STDERR: ./multiple_warnings.h:4:2: warning: "warning3" // CHECK:STDERR: 4 | #warning "warning3" // CHECK:STDERR: | ^ @@ -136,14 +136,14 @@ import Cpp library "multiple_warnings.h"; library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_import_cpp_file_with_one_error_and_one_warning.carbon:[[@LINE+14]]:1: in import [InImport] -// CHECK:STDERR: ./one_error_and_one_warning.h:2: error: In file included from fail_import_cpp_file_with_one_error_and_one_warning.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_error_and_one_warning.h:2: error: In file included from fail_import_cpp_file_with_one_error_and_one_warning.carbon:[[@LINE+13]]: // CHECK:STDERR: ./one_error_and_one_warning.h:2:2: error: "error1" // CHECK:STDERR: 2 | #error "error1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: // CHECK:STDERR: fail_import_cpp_file_with_one_error_and_one_warning.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./one_error_and_one_warning.h:3: warning: In file included from fail_import_cpp_file_with_one_error_and_one_warning.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_error_and_one_warning.h:3: warning: In file included from fail_import_cpp_file_with_one_error_and_one_warning.carbon:[[@LINE+6]]: // CHECK:STDERR: ./one_error_and_one_warning.h:3:2: warning: "warning1" // CHECK:STDERR: 3 | #warning "warning1" // CHECK:STDERR: | ^ @@ -168,35 +168,35 @@ import Cpp library "one_error_and_one_warning.h"; library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+35]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2: error: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2: error: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+34]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2:2: error: "error1" // CHECK:STDERR: 2 | #error "error1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: // CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+28]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3: error: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3: error: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+27]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3:2: error: "error2" // CHECK:STDERR: 3 | #error "error2" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: // CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+21]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4: warning: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4: warning: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+20]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4:2: warning: "warning1" // CHECK:STDERR: 4 | #warning "warning1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+14]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5: warning: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5: warning: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+13]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5:2: warning: "warning2" // CHECK:STDERR: 5 | #warning "warning2" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6: warning: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6: warning: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+6]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6:2: warning: "warning3" // CHECK:STDERR: 6 | #warning "warning3" // CHECK:STDERR: | ^ @@ -214,28 +214,28 @@ library "[[@TEST_NAME]]"; //@dump-sem-ir-begin // CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+28]]:1: in import [InImport] -// CHECK:STDERR: ./one_warning.h:2: warning: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_warning.h:2: warning: In file included from import_multiple_cpp_files_with_warnings.carbon:[[@LINE+27]]: // CHECK:STDERR: ./one_warning.h:2:2: warning: "warning1" // CHECK:STDERR: 2 | #warning "warning1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+21]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_warnings.h:2: warning: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_warnings.h:2: warning: In file included from import_multiple_cpp_files_with_warnings.carbon:[[@LINE+21]]: // CHECK:STDERR: ./multiple_warnings.h:2:2: warning: "warning1" // CHECK:STDERR: 2 | #warning "warning1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+14]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_warnings.h:3: warning: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_warnings.h:3: warning: In file included from import_multiple_cpp_files_with_warnings.carbon:[[@LINE+14]]: // CHECK:STDERR: ./multiple_warnings.h:3:2: warning: "warning2" // CHECK:STDERR: 3 | #warning "warning2" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_warnings.h:4: warning: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_warnings.h:4: warning: In file included from import_multiple_cpp_files_with_warnings.carbon:[[@LINE+7]]: // CHECK:STDERR: ./multiple_warnings.h:4:2: warning: "warning3" // CHECK:STDERR: 4 | #warning "warning3" // CHECK:STDERR: | ^ @@ -254,49 +254,49 @@ import Cpp library "multiple_warnings.h"; library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+49]]:1: in import [InImport] -// CHECK:STDERR: ./one_error_and_one_warning.h:2: error: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_error_and_one_warning.h:2: error: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+48]]: // CHECK:STDERR: ./one_error_and_one_warning.h:2:2: error: "error1" // CHECK:STDERR: 2 | #error "error1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: // CHECK:STDERR: fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+42]]:1: in import [InImport] -// CHECK:STDERR: ./one_error_and_one_warning.h:3: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_error_and_one_warning.h:3: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+41]]: // CHECK:STDERR: ./one_error_and_one_warning.h:3:2: warning: "warning1" // CHECK:STDERR: 3 | #warning "warning1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+35]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2: error: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2: error: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+35]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2:2: error: "error1" // CHECK:STDERR: 2 | #error "error1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: // CHECK:STDERR: fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+28]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3: error: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3: error: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+28]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3:2: error: "error2" // CHECK:STDERR: 3 | #error "error2" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: // CHECK:STDERR: fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+21]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+21]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4:2: warning: "warning1" // CHECK:STDERR: 4 | #warning "warning1" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+14]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+14]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5:2: warning: "warning2" // CHECK:STDERR: 5 | #warning "warning2" // CHECK:STDERR: | ^ // CHECK:STDERR: [CppInteropParseWarning] // CHECK:STDERR: // CHECK:STDERR: fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+7]]:1: in import [InImport] -// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon.generated.cpp_imports.h:2: +// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6: warning: In file included from fail_import_multiple_cpp_files_with_errors_and_warnings.carbon:[[@LINE+7]]: // CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6:2: warning: "warning3" // CHECK:STDERR: 6 | #warning "warning3" // CHECK:STDERR: | ^ @@ -320,7 +320,7 @@ library "[[@TEST_NAME]]"; // TODO: The `In file included from` line should not be prefixed. See // https://github.com/carbon-language/carbon-lang/pull/5614#pullrequestreview-2900939411 // CHECK:STDERR: fail_todo_import_indirect_error.carbon:[[@LINE+8]]:1: in import [InImport] -// CHECK:STDERR: ./one_error.h:2: error: In file included from fail_todo_import_indirect_error.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_error.h:2: error: In file included from fail_todo_import_indirect_error.carbon:[[@LINE+7]]: // CHECK:STDERR: In file included from ./indirect_error.h:2: // CHECK:STDERR: ./one_error.h:2:2: error: "error1" // CHECK:STDERR: 2 | #error "error1" @@ -345,7 +345,7 @@ library "[[@TEST_NAME]]"; // https://github.com/carbon-language/carbon-lang/pull/5614#pullrequestreview-2900939411 //@dump-sem-ir-begin // CHECK:STDERR: todo_import_indirect_warning.carbon:[[@LINE+8]]:1: in import [InImport] -// CHECK:STDERR: ./one_warning.h:2: warning: In file included from todo_import_indirect_warning.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_warning.h:2: warning: In file included from todo_import_indirect_warning.carbon:[[@LINE+7]]: // CHECK:STDERR: In file included from ./indirect_warning.h:2: // CHECK:STDERR: ./one_warning.h:2:2: warning: "warning1" // CHECK:STDERR: 2 | #warning "warning1" @@ -365,7 +365,7 @@ library "[[@TEST_NAME]]"; // Trailing comment // TODO: Move this warning to be after the lexer trailing comment error. // CHECK:STDERR: fail_import_cpp_library_lexer_error.carbon:[[@LINE+11]]:1: in import [InImport] -// CHECK:STDERR: ./one_warning.h:2: warning: In file included from fail_import_cpp_library_lexer_error.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./one_warning.h:2: warning: In file included from fail_import_cpp_library_lexer_error.carbon:[[@LINE+10]]: // CHECK:STDERR: ./one_warning.h:2:2: warning: "warning1" // CHECK:STDERR: 2 | #warning "warning1" // CHECK:STDERR: | ^ @@ -390,7 +390,7 @@ double score = 0.1 library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_import_fix_it_hints.carbon:[[@LINE+8]]:1: in import [InImport] -// CHECK:STDERR: ./fix_it_hints.h:2: error: In file included from fail_import_fix_it_hints.carbon.generated.cpp_imports.h:1: +// CHECK:STDERR: ./fix_it_hints.h:2: error: In file included from fail_import_fix_it_hints.carbon:[[@LINE+7]]: // CHECK:STDERR: ./fix_it_hints.h:2:19: error: expected ';' after top level declarator // CHECK:STDERR: 2 | double score = 0.1 // CHECK:STDERR: | ^ diff --git a/toolchain/check/testdata/interop/cpp/file_not_found.carbon b/toolchain/check/testdata/interop/cpp/file_not_found.carbon index dbb573bc6a55..f4a301b323e3 100644 --- a/toolchain/check/testdata/interop/cpp/file_not_found.carbon +++ b/toolchain/check/testdata/interop/cpp/file_not_found.carbon @@ -15,8 +15,8 @@ library "[[@TEST_NAME]]"; // CHECK:STDERR: fail_cpp_file_not_found.carbon:[[@LINE+6]]:1: in import [InImport] -// CHECK:STDERR: fail_cpp_file_not_found.carbon.generated.cpp_imports.h:1: error: fail_cpp_file_not_found.carbon.generated.cpp_imports.h:1:10: fatal error: 'not_found.h' file not found -// CHECK:STDERR: 1 | #include "not_found.h" +// CHECK:STDERR: fail_cpp_file_not_found.carbon:[[@LINE+5]]: error: fail_cpp_file_not_found.carbon:[[@LINE+5]]:10: fatal error: 'not_found.h' file not found +// CHECK:STDERR: 10 | #include "not_found.h" // CHECK:STDERR: | ^~~~~~~~~~~~~ // CHECK:STDERR: [CppInteropParseError] // CHECK:STDERR: