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 AndricIntrusiveRefCntPtr<ModuleCache> clang::createCrossProcessModuleCache() { 66700637cbSDimitry Andric return llvm::makeIntrusiveRefCnt<CrossProcessModuleCache>(); 67700637cbSDimitry Andric } 68