xref: /freebsd/contrib/llvm-project/clang/lib/Serialization/ModuleCache.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
1700637cbSDimitry Andric //===----------------------------------------------------------------------===//
2700637cbSDimitry Andric //
3700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6700637cbSDimitry Andric //
7700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8700637cbSDimitry Andric 
9700637cbSDimitry Andric #include "clang/Serialization/ModuleCache.h"
10700637cbSDimitry Andric 
11700637cbSDimitry Andric #include "clang/Serialization/InMemoryModuleCache.h"
12700637cbSDimitry Andric #include "clang/Serialization/ModuleFile.h"
13700637cbSDimitry Andric #include "llvm/Support/FileSystem.h"
14700637cbSDimitry Andric #include "llvm/Support/LockFileManager.h"
15700637cbSDimitry Andric #include "llvm/Support/Path.h"
16700637cbSDimitry Andric 
17700637cbSDimitry Andric using namespace clang;
18700637cbSDimitry Andric 
19700637cbSDimitry Andric namespace {
20700637cbSDimitry Andric class CrossProcessModuleCache : public ModuleCache {
21700637cbSDimitry Andric   InMemoryModuleCache InMemory;
22700637cbSDimitry Andric 
23700637cbSDimitry Andric public:
prepareForGetLock(StringRef ModuleFilename)24700637cbSDimitry Andric   void prepareForGetLock(StringRef ModuleFilename) override {
25700637cbSDimitry Andric     // FIXME: Do this in LockFileManager and only if the directory doesn't
26700637cbSDimitry Andric     // exist.
27700637cbSDimitry Andric     StringRef Dir = llvm::sys::path::parent_path(ModuleFilename);
28700637cbSDimitry Andric     llvm::sys::fs::create_directories(Dir);
29700637cbSDimitry Andric   }
30700637cbSDimitry Andric 
31700637cbSDimitry Andric   std::unique_ptr<llvm::AdvisoryLock>
getLock(StringRef ModuleFilename)32700637cbSDimitry Andric   getLock(StringRef ModuleFilename) override {
33700637cbSDimitry Andric     return std::make_unique<llvm::LockFileManager>(ModuleFilename);
34700637cbSDimitry Andric   }
35700637cbSDimitry Andric 
getModuleTimestamp(StringRef ModuleFilename)36700637cbSDimitry Andric   std::time_t getModuleTimestamp(StringRef ModuleFilename) override {
37*e64bea71SDimitry Andric     std::string TimestampFilename =
38*e64bea71SDimitry Andric         serialization::ModuleFile::getTimestampFilename(ModuleFilename);
39700637cbSDimitry Andric     llvm::sys::fs::file_status Status;
40*e64bea71SDimitry Andric     if (llvm::sys::fs::status(TimestampFilename, Status) != std::error_code{})
41700637cbSDimitry Andric       return 0;
42700637cbSDimitry Andric     return llvm::sys::toTimeT(Status.getLastModificationTime());
43700637cbSDimitry Andric   }
44700637cbSDimitry Andric 
updateModuleTimestamp(StringRef ModuleFilename)45700637cbSDimitry Andric   void updateModuleTimestamp(StringRef ModuleFilename) override {
46700637cbSDimitry Andric     // Overwrite the timestamp file contents so that file's mtime changes.
47700637cbSDimitry Andric     std::error_code EC;
48700637cbSDimitry Andric     llvm::raw_fd_ostream OS(
49700637cbSDimitry Andric         serialization::ModuleFile::getTimestampFilename(ModuleFilename), EC,
50700637cbSDimitry Andric         llvm::sys::fs::OF_TextWithCRLF);
51700637cbSDimitry Andric     if (EC)
52700637cbSDimitry Andric       return;
53700637cbSDimitry Andric     OS << "Timestamp file\n";
54700637cbSDimitry Andric     OS.close();
55700637cbSDimitry Andric     OS.clear_error(); // Avoid triggering a fatal error.
56700637cbSDimitry Andric   }
57700637cbSDimitry Andric 
getInMemoryModuleCache()58700637cbSDimitry Andric   InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
getInMemoryModuleCache() const59700637cbSDimitry Andric   const InMemoryModuleCache &getInMemoryModuleCache() const override {
60700637cbSDimitry Andric     return InMemory;
61700637cbSDimitry Andric   }
62700637cbSDimitry Andric };
63700637cbSDimitry Andric } // namespace
64700637cbSDimitry Andric 
createCrossProcessModuleCache()65700637cbSDimitry Andric IntrusiveRefCntPtr<ModuleCache> clang::createCrossProcessModuleCache() {
66700637cbSDimitry Andric   return llvm::makeIntrusiveRefCnt<CrossProcessModuleCache>();
67700637cbSDimitry Andric }
68