This PR sets up an `AtomicLineLogger` (added by https://github.com/llvm/llvm-project/pull/205395) to log the sequence of dependency scanning events. The logging is triggered by a new `LogPath` option in `DependencyScanningServiceOptions`. This PR adds an option `-log-path=` to `clang-scan-deps` to trigger the log. We are logging 16 events during dependency scanning. | Event | Logged In | When | |-------|-----------|------| | `starting scanning command: <args>` | `DependencyScanningWorker.cpp` | Start of each TU scan | | `finished scanning command: <args>` | `DependencyScanningWorker.cpp` | End of each TU scan | | `init_compiler_instance_with_context: <args>` | `DependencyScanningTool.cpp` | CompilerInstanceWithContext created for by-name scanning | | `start scan_by_name: <module name>` | `DependencyScanningTool.cpp` | Start of a by-name module query | | `finish scan_by_name: <module name>` | `DependencyScanningTool.cpp` | End of a by-name module query | | `module_compile_thread: parent=<TID> pcm_compile: <pcm path>` | `CompilerInstance::compileModule` | A new thread is created to compile a pcm | | `timestamp_read: <pcm path>` | `InProcessModuleCache::getModuleTimestamp` | Validation timestamp read | | `timestamp_write: <pcm path>` | `InProcessModuleCache::updateModuleTimestamp` | Validation timestamp update | | `pcm_write: <pcm path>` | `InProcessModuleCache::write` | PCM write to disk attempted | | `pcm_read_disk: <pcm path>` | `InProcessModuleCache::read` | PCM read from disk attempted | | `pcm_read_cached: <pcm path>` | `InMemoryModuleCache::lookupPCM` | PCM looked up in in-memory cache | | `pcm_add: <pcm path>` | `InMemoryModuleCache::addPCM` | PCM added to cache (not validated) | | `pcm_add_built: <pcm path>` | `InMemoryModuleCache::addBuiltPCM` | PCM added to cache (final) | | `pcm_finalized: <pcm path>` | `InMemoryModuleCache::finalizePCM` | PCM marked as validated/final | | `pcm_dropped: <pcm path>` | `InMemoryModuleCache::tryToDropPCM` | PCM dropped (validation failed) | | `pcm_not_dropped: <pcm path>` | `InMemoryModuleCache::tryToDropPCM` | PCM not dropped (validation failed, but already final) | In addition to checking the logger's functionality, `clang/test/ClangScanDeps/logging-simple.c` checks against the change committed by https://github.com/llvm/llvm-project/pull/177062. Without https://github.com/llvm/llvm-project/pull/177062, `clang/test/ClangScanDeps/logging-simple.c` fails. This implementation adds a single instance of `AtomicLineLogger` to the `DependencyScanningService`. Most of the plumbing goes into the `ModuleCache` and its derived classes. Assisted-by: claude-opus-4.6 rdar://39907408
76 lines
2.3 KiB
C++
76 lines
2.3 KiB
C++
#include "clang/DependencyScanning/InProcessModuleCache.h"
|
|
|
|
#include "clang/Basic/AtomicLineLogger.h"
|
|
#include "llvm/Support/FileSystem.h"
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
#include "llvm/Testing/Support/Error.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace clang;
|
|
using namespace clang::dependencies;
|
|
|
|
TEST(InProcessModuleCache, ReadWriteInvalidation) {
|
|
ModuleCacheEntries Entries;
|
|
AtomicLineLogger Logger;
|
|
std::shared_ptr<ModuleCache> ModCache =
|
|
makeInProcessModuleCache(Entries, Logger);
|
|
|
|
int FD;
|
|
llvm::SmallString<256> Path;
|
|
ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("M", "pcm", FD, Path));
|
|
|
|
{
|
|
llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
|
|
OS << "original\n";
|
|
}
|
|
|
|
off_t Size;
|
|
time_t ModTime;
|
|
std::unique_ptr<llvm::MemoryBuffer> Buf;
|
|
ASSERT_THAT_ERROR(ModCache->read(Path, Size, ModTime).moveInto(Buf),
|
|
llvm::Succeeded());
|
|
EXPECT_EQ(Buf->getBuffer(), "original\n");
|
|
|
|
auto NewBuf = llvm::MemoryBuffer::getMemBufferCopy("modified\n", Path);
|
|
ASSERT_EQ(ModCache->write(Path, *NewBuf, Size, ModTime), std::error_code{});
|
|
|
|
// Writing a new buffer should not invalidate the previously-read buffer.
|
|
EXPECT_EQ(Buf->getBuffer(), "original\n");
|
|
}
|
|
|
|
TEST(InProcessModuleCache, ReadReadInvalidation) {
|
|
ModuleCacheEntries Entries;
|
|
AtomicLineLogger Logger;
|
|
std::shared_ptr<ModuleCache> ModCache =
|
|
makeInProcessModuleCache(Entries, Logger);
|
|
|
|
int FD;
|
|
llvm::SmallString<256> Path;
|
|
ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("M", "pcm", FD, Path));
|
|
|
|
{
|
|
llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
|
|
OS << "original\n";
|
|
}
|
|
|
|
off_t Size1;
|
|
time_t ModTime1;
|
|
std::unique_ptr<llvm::MemoryBuffer> Buf1;
|
|
ASSERT_THAT_ERROR(ModCache->read(Path, Size1, ModTime1).moveInto(Buf1),
|
|
llvm::Succeeded());
|
|
EXPECT_EQ(Buf1->getBuffer(), "original\n");
|
|
|
|
off_t Size2;
|
|
time_t ModTime2;
|
|
std::unique_ptr<llvm::MemoryBuffer> Buf2;
|
|
ASSERT_THAT_ERROR(ModCache->read(Path, Size2, ModTime2).moveInto(Buf2),
|
|
llvm::Succeeded());
|
|
EXPECT_EQ(Buf2->getBuffer(), "original\n");
|
|
|
|
// Subsequent reads should not invalidate previous reads.
|
|
EXPECT_EQ(Buf1->getBuffer(), "original\n");
|
|
// All read buffers should point to the same memory.
|
|
EXPECT_EQ(Buf1->getBuffer().begin(), Buf2->getBuffer().begin());
|
|
EXPECT_EQ(Buf1->getBuffer().end(), Buf2->getBuffer().end());
|
|
}
|