https://github.com/devajithvs updated https://github.com/llvm/llvm-project/pull/182044
>From 200de7ba5e19ad8de2d42f3c0d2d4b1fe7653f21 Mon Sep 17 00:00:00 2001 From: Devajith Valaparambil Sreeramaswamy <[email protected]> Date: Thu, 19 Feb 2026 10:17:33 +0100 Subject: [PATCH] [clang-repl] Create virtual files for `input_line_N` buffers Instead of using memory buffers without file backing, this patch registers `input_line_N` buffers as virtual files. This patch enables us to use input line numbers when verifying tests in `clang-repl`. --- .../lib/Frontend/VerifyDiagnosticConsumer.cpp | 24 +++++++++++++++---- clang/lib/Interpreter/IncrementalParser.cpp | 13 ++++++++-- clang/test/Interpreter/verify-diagnostics.cpp | 16 +++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 clang/test/Interpreter/verify-diagnostics.cpp diff --git a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index e263e10bb065a..5b24de73b29d5 100644 --- a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -516,6 +516,15 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, bool MatchAnyLine = false; if (!PH.Next("@")) { ExpectedLoc = Pos; + + // If an implicit directive is found in an incremental input buffer, allow + // it to match any other incremental input buffer + if (PP->isIncrementalProcessingEnabled()) { + StringRef CurrentBufferName = + SM.getBufferOrFake(SM.getFileID(Pos)).getBufferIdentifier(); + if (CurrentBufferName.starts_with("input_line_")) + MatchAnyFileAndLine = true; + } } else { PH.Advance(); unsigned Line = 0; @@ -552,10 +561,17 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, MatchAnyLine = true; ExpectedLoc = SourceLocation(); } else { - // Lookup file via Preprocessor, like a #include. - OptionalFileEntryRef File = - PP->LookupFile(Pos, Filename, false, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr); + OptionalFileEntryRef File; + if (PP->isIncrementalProcessingEnabled() && + Filename.starts_with("input_line_")) { + // Check if it came from the prompt + File = SM.getFileManager().getOptionalFileRef(Filename); + } else { + // Lookup file via Preprocessor, like a #include. + File = + PP->LookupFile(Pos, Filename, false, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr); + } if (!File) { Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin), diag::err_verify_missing_file) diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index bf08911e23533..2d5c1fecda2f5 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -129,8 +129,17 @@ IncrementalParser::Parse(llvm::StringRef input) { SourceLocation NewLoc = SM.getLocForStartOfFile(SM.getMainFileID()); // Create FileID for the current buffer. - FileID FID = SM.createFileID(std::move(MB), SrcMgr::C_User, /*LoadedID=*/0, - /*LoadedOffset=*/0, NewLoc); + FileID FID; + // Create FileEntry and FileID for the current buffer. + FileEntryRef FE = SM.getFileManager().getVirtualFileRef( + SourceName.str(), InputSize, 0 /* mod time*/); + SM.overrideFileContents(FE, std::move(MB)); + + // Ensure HeaderFileInfo exists before lookup to prevent assertion + HeaderSearch &HS = PP.getHeaderSearchInfo(); + HS.getFileInfo(FE); + + FID = SM.createFileID(FE, NewLoc, SrcMgr::C_User); // NewLoc only used for diags. if (PP.EnterSourceFile(FID, /*DirLookup=*/nullptr, NewLoc)) diff --git a/clang/test/Interpreter/verify-diagnostics.cpp b/clang/test/Interpreter/verify-diagnostics.cpp new file mode 100644 index 0000000000000..7187a77379846 --- /dev/null +++ b/clang/test/Interpreter/verify-diagnostics.cpp @@ -0,0 +1,16 @@ +// REQUIRES: host-supports-jit +// RUN: cat %s | clang-repl -Xcc -Xclang -Xcc -verify + +auto x = unknown_val; +// expected-error@input_line_4:1 {{use of undeclared identifier 'unknown_val'}} + +int get_int() { return 42; } +char* ptr = get_int(); +// expected-error@input_line_8:1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'int'}} + +// Verify without input_line_* +int y = ; +// expected-error {{expected expression}} + +const char* a = "test"; // expected-note {{previous definition is here}} +const char* a = ""; // expected-error {{redefinition of 'a'}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
