|
|
@@ -33,6 +33,64 @@ class FileTestAutoupdater {
|
|
|
std::string line_formatv;
|
|
|
};
|
|
|
|
|
|
+ // The file and line number that a CHECK line refers to, and the
|
|
|
+ // replacement from which they were determined, if any.
|
|
|
+ struct FileAndLineNumber {
|
|
|
+ explicit FileAndLineNumber(int file_number) : file_number(file_number) {}
|
|
|
+
|
|
|
+ explicit FileAndLineNumber(const LineNumberReplacement* replacement,
|
|
|
+ int file_number, absl::string_view line_number);
|
|
|
+
|
|
|
+ const LineNumberReplacement* replacement = nullptr;
|
|
|
+ int file_number;
|
|
|
+ int line_number = -1;
|
|
|
+ };
|
|
|
+
|
|
|
+ // A CHECK line which is integrated into autoupdate output.
|
|
|
+ //
|
|
|
+ // `final` because we use pointer arithmetic on this type.
|
|
|
+ class CheckLine final : public FileTestLineBase {
|
|
|
+ public:
|
|
|
+ explicit CheckLine(FileAndLineNumber file_and_line_number, std::string line)
|
|
|
+ : FileTestLineBase(file_and_line_number.file_number,
|
|
|
+ file_and_line_number.line_number),
|
|
|
+ replacement_(file_and_line_number.replacement),
|
|
|
+ line_(std::move(line)) {}
|
|
|
+
|
|
|
+ auto Print(llvm::raw_ostream& out) const -> void override {
|
|
|
+ out << indent_ << line_;
|
|
|
+ }
|
|
|
+
|
|
|
+ // When the location of the CHECK in output is known, we can set the indent
|
|
|
+ // and its line.
|
|
|
+ auto SetOutputLine(llvm::StringRef indent, int output_file_number,
|
|
|
+ int output_line_number) -> void {
|
|
|
+ indent_ = indent;
|
|
|
+ output_file_number_ = output_file_number;
|
|
|
+ output_line_number_ = output_line_number;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 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<llvm::StringRef, int>& file_to_number_map,
|
|
|
+ const llvm::DenseMap<std::pair<int, int>, int>& output_line_remap,
|
|
|
+ const llvm::SmallVector<int>& new_last_line_numbers) -> void;
|
|
|
+
|
|
|
+ auto line() const -> llvm::StringRef { return line_; }
|
|
|
+
|
|
|
+ auto is_blank() const -> bool override { return false; }
|
|
|
+
|
|
|
+ private:
|
|
|
+ const LineNumberReplacement* replacement_;
|
|
|
+ std::string line_;
|
|
|
+ llvm::StringRef indent_;
|
|
|
+ int output_file_number_ = -1;
|
|
|
+ int output_line_number_ = -1;
|
|
|
+ };
|
|
|
+
|
|
|
+ using CheckLineArray = llvm::SmallVector<FileTestAutoupdater::CheckLine>;
|
|
|
+
|
|
|
explicit FileTestAutoupdater(
|
|
|
const std::filesystem::path& file_test_path, std::string test_command,
|
|
|
std::string dump_command, llvm::StringRef input_content,
|
|
|
@@ -42,7 +100,8 @@ class FileTestAutoupdater {
|
|
|
llvm::StringRef actual_stdout, llvm::StringRef actual_stderr,
|
|
|
const std::optional<RE2>& default_file_re,
|
|
|
const llvm::SmallVector<LineNumberReplacement>& line_number_replacements,
|
|
|
- std::function<auto(std::string&)->void> do_extra_check_replacements)
|
|
|
+ std::function<auto(std::string&)->void> do_extra_check_replacements,
|
|
|
+ std::function<auto(CheckLineArray&, bool)->void> finalize_check_lines)
|
|
|
: file_test_path_(file_test_path),
|
|
|
test_command_(std::move(test_command)),
|
|
|
dump_command_(std::move(dump_command)),
|
|
|
@@ -52,13 +111,14 @@ class FileTestAutoupdater {
|
|
|
default_file_re_(default_file_re),
|
|
|
line_number_replacements_(line_number_replacements),
|
|
|
do_extra_check_replacements_(std::move(do_extra_check_replacements)),
|
|
|
+ finalize_check_lines_(std::move(finalize_check_lines)),
|
|
|
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")),
|
|
|
- stderr_(BuildCheckLines(actual_stderr, "STDERR")),
|
|
|
+ stdout_(BuildCheckLines(actual_stdout, /*is_stderr=*/false)),
|
|
|
+ stderr_(BuildCheckLines(actual_stderr, /*is_stderr=*/true)),
|
|
|
any_attached_stdout_lines_(llvm::any_of(
|
|
|
stdout_.lines,
|
|
|
[&](const CheckLine& line) { return line.line_number() != -1; })),
|
|
|
@@ -78,19 +138,6 @@ class FileTestAutoupdater {
|
|
|
auto Run(bool dry_run) -> bool;
|
|
|
|
|
|
private:
|
|
|
- // The file and line number that a CHECK line refers to, and the
|
|
|
- // replacement from which they were determined, if any.
|
|
|
- struct FileAndLineNumber {
|
|
|
- explicit FileAndLineNumber(int file_number) : file_number(file_number) {}
|
|
|
-
|
|
|
- explicit FileAndLineNumber(const LineNumberReplacement* replacement,
|
|
|
- int file_number, absl::string_view line_number);
|
|
|
-
|
|
|
- const LineNumberReplacement* replacement = nullptr;
|
|
|
- int file_number;
|
|
|
- int line_number = -1;
|
|
|
- };
|
|
|
-
|
|
|
// A TIP line added by autoupdate. Not associated with any line in output.
|
|
|
class TipLine : public FileTestLineBase {
|
|
|
public:
|
|
|
@@ -105,55 +152,13 @@ class FileTestAutoupdater {
|
|
|
std::string line_;
|
|
|
};
|
|
|
|
|
|
- // A CHECK line which is integrated into autoupdate output.
|
|
|
- //
|
|
|
- // `final` because we use pointer arithmetic on this type.
|
|
|
- class CheckLine final : public FileTestLineBase {
|
|
|
- public:
|
|
|
- // RE2 is passed by a pointer because it doesn't support std::optional.
|
|
|
- explicit CheckLine(FileAndLineNumber file_and_line_number, std::string line)
|
|
|
- : FileTestLineBase(file_and_line_number.file_number,
|
|
|
- file_and_line_number.line_number),
|
|
|
- replacement_(file_and_line_number.replacement),
|
|
|
- line_(std::move(line)) {}
|
|
|
-
|
|
|
- auto Print(llvm::raw_ostream& out) const -> void override {
|
|
|
- out << indent_ << line_;
|
|
|
- }
|
|
|
-
|
|
|
- // When the location of the CHECK in output is known, we can set the indent
|
|
|
- // and its line.
|
|
|
- auto SetOutputLine(llvm::StringRef indent, int output_file_number,
|
|
|
- int output_line_number) -> void {
|
|
|
- indent_ = indent;
|
|
|
- output_file_number_ = output_file_number;
|
|
|
- output_line_number_ = output_line_number;
|
|
|
- }
|
|
|
-
|
|
|
- // 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<llvm::StringRef, int>& file_to_number_map,
|
|
|
- const llvm::DenseMap<std::pair<int, int>, int>& output_line_remap,
|
|
|
- const llvm::SmallVector<int>& new_last_line_numbers) -> void;
|
|
|
-
|
|
|
- auto is_blank() const -> bool override { return false; }
|
|
|
-
|
|
|
- private:
|
|
|
- const LineNumberReplacement* replacement_;
|
|
|
- std::string line_;
|
|
|
- llvm::StringRef indent_;
|
|
|
- int output_file_number_ = -1;
|
|
|
- int output_line_number_ = -1;
|
|
|
- };
|
|
|
-
|
|
|
// Clusters information for stdout and stderr.
|
|
|
struct CheckLines {
|
|
|
- explicit CheckLines(llvm::SmallVector<CheckLine> lines)
|
|
|
+ explicit CheckLines(CheckLineArray lines)
|
|
|
: lines(std::move(lines)), cursor(this->lines.begin()) {}
|
|
|
|
|
|
// The full list of check lines.
|
|
|
- llvm::SmallVector<CheckLine> lines;
|
|
|
+ CheckLineArray lines;
|
|
|
// An iterator into check_lines.
|
|
|
CheckLine* cursor;
|
|
|
};
|
|
|
@@ -176,7 +181,7 @@ class FileTestAutoupdater {
|
|
|
}
|
|
|
|
|
|
// Builds CheckLine lists for autoupdate.
|
|
|
- auto BuildCheckLines(llvm::StringRef output, const char* label) -> CheckLines;
|
|
|
+ auto BuildCheckLines(llvm::StringRef output, bool is_stderr) -> CheckLines;
|
|
|
|
|
|
// Adds a non-check line to the new_lines and output_line_remap. The caller
|
|
|
// still needs to advance the cursor when ready.
|
|
|
@@ -214,6 +219,7 @@ class FileTestAutoupdater {
|
|
|
const std::optional<RE2>& default_file_re_;
|
|
|
const llvm::SmallVector<LineNumberReplacement>& line_number_replacements_;
|
|
|
std::function<auto(std::string&)->void> do_extra_check_replacements_;
|
|
|
+ std::function<auto(CheckLineArray&, bool)->void> finalize_check_lines_;
|
|
|
|
|
|
// If we have an autoupdate split that still needs to be processed, the file
|
|
|
// number of the autoupdate split. Otherwise, this is nullopt.
|