18bef5cd4SDuncan P. N. Exon Smith //===- InMemoryModuleCache.cpp - Cache for loaded memory buffers ----------===//
28bef5cd4SDuncan P. N. Exon Smith //
38bef5cd4SDuncan P. N. Exon Smith // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48bef5cd4SDuncan P. N. Exon Smith // See https://llvm.org/LICENSE.txt for license information.
58bef5cd4SDuncan P. N. Exon Smith // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68bef5cd4SDuncan P. N. Exon Smith //
78bef5cd4SDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
88bef5cd4SDuncan P. N. Exon Smith 
98bef5cd4SDuncan P. N. Exon Smith #include "clang/Serialization/InMemoryModuleCache.h"
108bef5cd4SDuncan P. N. Exon Smith #include "llvm/Support/MemoryBuffer.h"
118bef5cd4SDuncan P. N. Exon Smith 
128bef5cd4SDuncan P. N. Exon Smith using namespace clang;
138bef5cd4SDuncan P. N. Exon Smith 
14*0a2be46cSDuncan P. N. Exon Smith InMemoryModuleCache::State
15*0a2be46cSDuncan P. N. Exon Smith InMemoryModuleCache::getPCMState(llvm::StringRef Filename) const {
16*0a2be46cSDuncan P. N. Exon Smith   auto I = PCMs.find(Filename);
17*0a2be46cSDuncan P. N. Exon Smith   if (I == PCMs.end())
18*0a2be46cSDuncan P. N. Exon Smith     return Unknown;
19*0a2be46cSDuncan P. N. Exon Smith   if (I->second.IsFinal)
20*0a2be46cSDuncan P. N. Exon Smith     return Final;
21*0a2be46cSDuncan P. N. Exon Smith   return I->second.Buffer ? Tentative : ToBuild;
22*0a2be46cSDuncan P. N. Exon Smith }
23*0a2be46cSDuncan P. N. Exon Smith 
248bef5cd4SDuncan P. N. Exon Smith llvm::MemoryBuffer &
25*0a2be46cSDuncan P. N. Exon Smith InMemoryModuleCache::addPCM(llvm::StringRef Filename,
268bef5cd4SDuncan P. N. Exon Smith                             std::unique_ptr<llvm::MemoryBuffer> Buffer) {
27*0a2be46cSDuncan P. N. Exon Smith   auto Insertion = PCMs.insert(std::make_pair(Filename, std::move(Buffer)));
28*0a2be46cSDuncan P. N. Exon Smith   assert(Insertion.second && "Already has a PCM");
298bef5cd4SDuncan P. N. Exon Smith   return *Insertion.first->second.Buffer;
308bef5cd4SDuncan P. N. Exon Smith }
318bef5cd4SDuncan P. N. Exon Smith 
32*0a2be46cSDuncan P. N. Exon Smith llvm::MemoryBuffer &
33*0a2be46cSDuncan P. N. Exon Smith InMemoryModuleCache::addBuiltPCM(llvm::StringRef Filename,
34*0a2be46cSDuncan P. N. Exon Smith                                  std::unique_ptr<llvm::MemoryBuffer> Buffer) {
35*0a2be46cSDuncan P. N. Exon Smith   auto &PCM = PCMs[Filename];
36*0a2be46cSDuncan P. N. Exon Smith   assert(!PCM.IsFinal && "Trying to override finalized PCM?");
37*0a2be46cSDuncan P. N. Exon Smith   assert(!PCM.Buffer && "Trying to override tentative PCM?");
38*0a2be46cSDuncan P. N. Exon Smith   PCM.Buffer = std::move(Buffer);
39*0a2be46cSDuncan P. N. Exon Smith   PCM.IsFinal = true;
40*0a2be46cSDuncan P. N. Exon Smith   return *PCM.Buffer;
41*0a2be46cSDuncan P. N. Exon Smith }
42*0a2be46cSDuncan P. N. Exon Smith 
438bef5cd4SDuncan P. N. Exon Smith llvm::MemoryBuffer *
44*0a2be46cSDuncan P. N. Exon Smith InMemoryModuleCache::lookupPCM(llvm::StringRef Filename) const {
458bef5cd4SDuncan P. N. Exon Smith   auto I = PCMs.find(Filename);
468bef5cd4SDuncan P. N. Exon Smith   if (I == PCMs.end())
478bef5cd4SDuncan P. N. Exon Smith     return nullptr;
488bef5cd4SDuncan P. N. Exon Smith   return I->second.Buffer.get();
498bef5cd4SDuncan P. N. Exon Smith }
508bef5cd4SDuncan P. N. Exon Smith 
51*0a2be46cSDuncan P. N. Exon Smith bool InMemoryModuleCache::isPCMFinal(llvm::StringRef Filename) const {
52*0a2be46cSDuncan P. N. Exon Smith   return getPCMState(Filename) == Final;
538bef5cd4SDuncan P. N. Exon Smith }
548bef5cd4SDuncan P. N. Exon Smith 
55*0a2be46cSDuncan P. N. Exon Smith bool InMemoryModuleCache::shouldBuildPCM(llvm::StringRef Filename) const {
56*0a2be46cSDuncan P. N. Exon Smith   return getPCMState(Filename) == ToBuild;
57*0a2be46cSDuncan P. N. Exon Smith }
58*0a2be46cSDuncan P. N. Exon Smith 
59*0a2be46cSDuncan P. N. Exon Smith bool InMemoryModuleCache::tryToDropPCM(llvm::StringRef Filename) {
608bef5cd4SDuncan P. N. Exon Smith   auto I = PCMs.find(Filename);
61*0a2be46cSDuncan P. N. Exon Smith   assert(I != PCMs.end() && "PCM to remove is unknown...");
62*0a2be46cSDuncan P. N. Exon Smith 
63*0a2be46cSDuncan P. N. Exon Smith   auto &PCM = I->second;
64*0a2be46cSDuncan P. N. Exon Smith   assert(PCM.Buffer && "PCM to remove is scheduled to be built...");
65*0a2be46cSDuncan P. N. Exon Smith 
66*0a2be46cSDuncan P. N. Exon Smith   if (PCM.IsFinal)
678bef5cd4SDuncan P. N. Exon Smith     return true;
688bef5cd4SDuncan P. N. Exon Smith 
69*0a2be46cSDuncan P. N. Exon Smith   PCM.Buffer.reset();
708bef5cd4SDuncan P. N. Exon Smith   return false;
718bef5cd4SDuncan P. N. Exon Smith }
728bef5cd4SDuncan P. N. Exon Smith 
73*0a2be46cSDuncan P. N. Exon Smith void InMemoryModuleCache::finalizePCM(llvm::StringRef Filename) {
74*0a2be46cSDuncan P. N. Exon Smith   auto I = PCMs.find(Filename);
75*0a2be46cSDuncan P. N. Exon Smith   assert(I != PCMs.end() && "PCM to finalize is unknown...");
76*0a2be46cSDuncan P. N. Exon Smith 
77*0a2be46cSDuncan P. N. Exon Smith   auto &PCM = I->second;
78*0a2be46cSDuncan P. N. Exon Smith   assert(PCM.Buffer && "Trying to finalize a dropped PCM...");
79*0a2be46cSDuncan P. N. Exon Smith   PCM.IsFinal = true;
808bef5cd4SDuncan P. N. Exon Smith }
81