mirror-llvm-project/clang/unittests/DependencyScanning/InProcessModuleCacheTest.cpp
Qiongsi Wu a730dda7d5
[clang][DependencyScanning] Logging Dependency Scanning Events (#195896)
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
2026-07-16 10:41:22 -07:00

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());
}