xref: /freebsd/contrib/llvm-project/clang/lib/Serialization/ModuleCache.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "clang/Serialization/ModuleCache.h"
10 
11 #include "clang/Serialization/InMemoryModuleCache.h"
12 #include "clang/Serialization/ModuleFile.h"
13 #include "llvm/Support/FileSystem.h"
14 #include "llvm/Support/LockFileManager.h"
15 #include "llvm/Support/Path.h"
16 
17 using namespace clang;
18 
19 namespace {
20 class CrossProcessModuleCache : public ModuleCache {
21   InMemoryModuleCache InMemory;
22 
23 public:
24   void prepareForGetLock(StringRef ModuleFilename) override {
25     // FIXME: Do this in LockFileManager and only if the directory doesn't
26     // exist.
27     StringRef Dir = llvm::sys::path::parent_path(ModuleFilename);
28     llvm::sys::fs::create_directories(Dir);
29   }
30 
31   std::unique_ptr<llvm::AdvisoryLock>
32   getLock(StringRef ModuleFilename) override {
33     return std::make_unique<llvm::LockFileManager>(ModuleFilename);
34   }
35 
36   std::time_t getModuleTimestamp(StringRef ModuleFilename) override {
37     llvm::sys::fs::file_status Status;
38     if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{})
39       return 0;
40     return llvm::sys::toTimeT(Status.getLastModificationTime());
41   }
42 
43   void updateModuleTimestamp(StringRef ModuleFilename) override {
44     // Overwrite the timestamp file contents so that file's mtime changes.
45     std::error_code EC;
46     llvm::raw_fd_ostream OS(
47         serialization::ModuleFile::getTimestampFilename(ModuleFilename), EC,
48         llvm::sys::fs::OF_TextWithCRLF);
49     if (EC)
50       return;
51     OS << "Timestamp file\n";
52     OS.close();
53     OS.clear_error(); // Avoid triggering a fatal error.
54   }
55 
56   InMemoryModuleCache &getInMemoryModuleCache() override { return InMemory; }
57   const InMemoryModuleCache &getInMemoryModuleCache() const override {
58     return InMemory;
59   }
60 };
61 } // namespace
62 
63 IntrusiveRefCntPtr<ModuleCache> clang::createCrossProcessModuleCache() {
64   return llvm::makeIntrusiveRefCnt<CrossProcessModuleCache>();
65 }
66