diff options
Diffstat (limited to 'clang/lib/Basic/SourceManager.cpp')
-rw-r--r-- | clang/lib/Basic/SourceManager.cpp | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 61f4e866524..a2540bc18af 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -370,7 +370,8 @@ LineTableInfo &SourceManager::getLineTable() { SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr) : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), - NumBinaryProbes(0), FakeBufferForRecovery(0) { + NumBinaryProbes(0), FakeBufferForRecovery(0), + FakeContentCacheForRecovery(0) { clearIDTables(); Diag.setSourceManager(this); } @@ -396,6 +397,7 @@ SourceManager::~SourceManager() { } delete FakeBufferForRecovery; + delete FakeContentCacheForRecovery; for (llvm::DenseMap<FileID, MacroArgsMap *>::iterator I = MacroArgsCacheMap.begin(),E = MacroArgsCacheMap.end(); I!=E; ++I) { @@ -469,6 +471,25 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { return Entry; } +const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index, + bool *Invalid) const { + assert(!SLocEntryLoaded[Index]); + if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) { + if (Invalid) + *Invalid = true; + // If the file of the SLocEntry changed we could still have loaded it. + if (!SLocEntryLoaded[Index]) { + // Try to recover; create a SLocEntry so the rest of clang can handle it. + LoadedSLocEntryTable[Index] = SLocEntry::get(0, + FileInfo::get(SourceLocation(), + getFakeContentCacheForRecovery(), + SrcMgr::C_User)); + } + } + + return LoadedSLocEntryTable[Index]; +} + std::pair<int, unsigned> SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize) { @@ -491,6 +512,18 @@ const llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const { return FakeBufferForRecovery; } +/// \brief As part of recovering from missing or changed content, produce a +/// fake content cache. +const SrcMgr::ContentCache * +SourceManager::getFakeContentCacheForRecovery() const { + if (!FakeContentCacheForRecovery) { + FakeContentCacheForRecovery = new ContentCache(); + FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(), + /*DoNotFree=*/true); + } + return FakeContentCacheForRecovery; +} + //===----------------------------------------------------------------------===// // Methods to create new FileID's and macro expansions. //===----------------------------------------------------------------------===// |