diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/SourceManager.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Basic/SourceManager.cpp | 203 |
1 files changed, 58 insertions, 145 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp index 12b0305e707c..58b95289eaf2 100644 --- a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp @@ -96,7 +96,7 @@ void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree) { } const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, - const SourceManager &SM, + FileManager &FM, SourceLocation Loc, bool *Invalid) const { // Lazily create the Buffer for ContentCaches that wrap files. If we already @@ -134,9 +134,7 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, return Buffer.getPointer(); } - bool isVolatile = SM.userFilesAreVolatile() && !IsSystemFile; - auto BufferOrError = - SM.getFileManager().getBufferForFile(ContentsEntry, isVolatile); + auto BufferOrError = FM.getBufferForFile(ContentsEntry, IsFileVolatile); // If we were unable to open the file, then we are in an inconsistent // situation where the content cache referenced a file which no longer @@ -389,7 +387,7 @@ void SourceManager::initializeForReplay(const SourceManager &Old) { Clone->OrigEntry = Cache->OrigEntry; Clone->ContentsEntry = Cache->ContentsEntry; Clone->BufferOverridden = Cache->BufferOverridden; - Clone->IsSystemFile = Cache->IsSystemFile; + Clone->IsFileVolatile = Cache->IsFileVolatile; Clone->IsTransient = Cache->IsTransient; Clone->replaceBuffer(Cache->getRawBuffer(), /*DoNotFree*/true); return Clone; @@ -438,7 +436,7 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt, new (Entry) ContentCache(FileEnt); } - Entry->IsSystemFile = isSystemFile; + Entry->IsFileVolatile = UserFilesAreVolatile && !isSystemFile; Entry->IsTransient = FilesAreTransient; return Entry; @@ -466,10 +464,9 @@ const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index, // 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)); + LoadedSLocEntryTable[Index] = SLocEntry::get( + 0, FileInfo::get(SourceLocation(), getFakeContentCacheForRecovery(), + SrcMgr::C_User, "")); } } @@ -505,7 +502,7 @@ llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const { const SrcMgr::ContentCache * SourceManager::getFakeContentCacheForRecovery() const { if (!FakeContentCacheForRecovery) { - FakeContentCacheForRecovery = llvm::make_unique<SrcMgr::ContentCache>(); + FakeContentCacheForRecovery = std::make_unique<SrcMgr::ContentCache>(); FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(), /*DoNotFree=*/true); } @@ -556,7 +553,7 @@ FileID SourceManager::getNextFileID(FileID FID) const { /// createFileID - Create a new FileID for the specified ContentCache and /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. -FileID SourceManager::createFileID(const ContentCache *File, +FileID SourceManager::createFileID(const ContentCache *File, StringRef Filename, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID, unsigned LoadedOffset) { @@ -565,14 +562,14 @@ FileID SourceManager::createFileID(const ContentCache *File, unsigned Index = unsigned(-LoadedID) - 2; assert(Index < LoadedSLocEntryTable.size() && "FileID out of range"); assert(!SLocEntryLoaded[Index] && "FileID already loaded"); - LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, - FileInfo::get(IncludePos, File, FileCharacter)); + LoadedSLocEntryTable[Index] = SLocEntry::get( + LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename)); SLocEntryLoaded[Index] = true; return FileID::get(LoadedID); } - LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, - FileInfo::get(IncludePos, File, - FileCharacter))); + LocalSLocEntryTable.push_back( + SLocEntry::get(NextLocalOffset, + FileInfo::get(IncludePos, File, FileCharacter, Filename))); unsigned FileSize = File->getSize(); assert(NextLocalOffset + FileSize + 1 > NextLocalOffset && NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset && @@ -646,7 +643,7 @@ const llvm::MemoryBuffer * SourceManager::getMemoryBufferForFile(const FileEntry *File, bool *Invalid) { const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); assert(IR && "getOrCreateContentCache() cannot return NULL"); - return IR->getBuffer(Diag, *this, SourceLocation(), Invalid); + return IR->getBuffer(Diag, getFileManager(), SourceLocation(), Invalid); } void SourceManager::overrideFileContents(const FileEntry *SourceFile, @@ -672,17 +669,19 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile, getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile; } -void SourceManager::disableFileContentsOverride(const FileEntry *File) { - if (!isFileOverridden(File)) - return; +const FileEntry * +SourceManager::bypassFileContentsOverride(const FileEntry &File) { + assert(isFileOverridden(&File)); + llvm::Optional<FileEntryRef> BypassFile = + FileMgr.getBypassFile(FileEntryRef(File.getName(), File)); - const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); - const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(nullptr); - const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry; + // If the file can't be found in the FS, give up. + if (!BypassFile) + return nullptr; - assert(OverriddenFilesInfo); - OverriddenFilesInfo->OverriddenFiles.erase(File); - OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File); + const FileEntry *FE = &BypassFile->getFileEntry(); + (void)getOrCreateContentCache(FE); + return FE; } void SourceManager::setFileIsTransient(const FileEntry *File) { @@ -700,7 +699,7 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { } const llvm::MemoryBuffer *Buf = SLoc.getFile().getContentCache()->getBuffer( - Diag, *this, SourceLocation(), &MyInvalid); + Diag, getFileManager(), SourceLocation(), &MyInvalid); if (Invalid) *Invalid = MyInvalid; @@ -1131,7 +1130,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL, } const llvm::MemoryBuffer *Buffer = Entry.getFile().getContentCache()->getBuffer( - Diag, *this, SourceLocation(), &CharDataInvalid); + Diag, getFileManager(), SourceLocation(), &CharDataInvalid); if (Invalid) *Invalid = CharDataInvalid; return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second); @@ -1228,7 +1227,7 @@ static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, const SourceManager &SM, bool &Invalid) { // Note that calling 'getBuffer()' may lazily page in the file. const MemoryBuffer *Buffer = - FI->getBuffer(Diag, SM, SourceLocation(), &Invalid); + FI->getBuffer(Diag, SM.getFileManager(), SourceLocation(), &Invalid); if (Invalid) return; @@ -1459,7 +1458,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, if (C->OrigEntry) Filename = C->OrigEntry->getName(); else - Filename = C->getBuffer(Diag, *this)->getBufferIdentifier(); + Filename = C->getBuffer(Diag, getFileManager())->getBufferIdentifier(); unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second, &Invalid); if (Invalid) @@ -1558,22 +1557,6 @@ unsigned SourceManager::getFileIDSize(FileID FID) const { // Other miscellaneous methods. //===----------------------------------------------------------------------===// -/// Retrieve the inode for the given file entry, if possible. -/// -/// This routine involves a system call, and therefore should only be used -/// in non-performance-critical code. -static Optional<llvm::sys::fs::UniqueID> -getActualFileUID(const FileEntry *File) { - if (!File) - return None; - - llvm::sys::fs::UniqueID ID; - if (llvm::sys::fs::getUniqueID(File->getName(), ID)) - return None; - - return ID; -} - /// Get the source location for the given file:line:col triplet. /// /// If the source file is included multiple times, the source location will @@ -1595,13 +1578,8 @@ SourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile, FileID SourceManager::translateFile(const FileEntry *SourceFile) const { assert(SourceFile && "Null source file!"); - // Find the first file ID that corresponds to the given file. - FileID FirstFID; - // First, check the main file ID, since it is common to look for a // location in the main file. - Optional<llvm::sys::fs::UniqueID> SourceFileUID; - Optional<StringRef> SourceFileName; if (MainFileID.isValid()) { bool Invalid = false; const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid); @@ -1609,100 +1587,35 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { return FileID(); if (MainSLoc.isFile()) { - const ContentCache *MainContentCache - = MainSLoc.getFile().getContentCache(); - if (!MainContentCache || !MainContentCache->OrigEntry) { - // Can't do anything - } else if (MainContentCache->OrigEntry == SourceFile) { - FirstFID = MainFileID; - } else { - // Fall back: check whether we have the same base name and inode - // as the main file. - const FileEntry *MainFile = MainContentCache->OrigEntry; - SourceFileName = llvm::sys::path::filename(SourceFile->getName()); - if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) { - SourceFileUID = getActualFileUID(SourceFile); - if (SourceFileUID) { - if (Optional<llvm::sys::fs::UniqueID> MainFileUID = - getActualFileUID(MainFile)) { - if (*SourceFileUID == *MainFileUID) { - FirstFID = MainFileID; - SourceFile = MainFile; - } - } - } - } - } + const ContentCache *MainContentCache = + MainSLoc.getFile().getContentCache(); + if (MainContentCache && MainContentCache->OrigEntry == SourceFile) + return MainFileID; } } - if (FirstFID.isInvalid()) { - // The location we're looking for isn't in the main file; look - // through all of the local source locations. - for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { - bool Invalid = false; - const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); - if (Invalid) - return FileID(); + // The location we're looking for isn't in the main file; look + // through all of the local source locations. + for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { + bool Invalid = false; + const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); + if (Invalid) + return FileID(); - if (SLoc.isFile() && - SLoc.getFile().getContentCache() && - SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { - FirstFID = FileID::get(I); - break; - } - } - // If that still didn't help, try the modules. - if (FirstFID.isInvalid()) { - for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) { - const SLocEntry &SLoc = getLoadedSLocEntry(I); - if (SLoc.isFile() && - SLoc.getFile().getContentCache() && - SLoc.getFile().getContentCache()->OrigEntry == SourceFile) { - FirstFID = FileID::get(-int(I) - 2); - break; - } - } - } + if (SLoc.isFile() && SLoc.getFile().getContentCache() && + SLoc.getFile().getContentCache()->OrigEntry == SourceFile) + return FileID::get(I); } - // If we haven't found what we want yet, try again, but this time stat() - // each of the files in case the files have changed since we originally - // parsed the file. - if (FirstFID.isInvalid() && - (SourceFileName || - (SourceFileName = llvm::sys::path::filename(SourceFile->getName()))) && - (SourceFileUID || (SourceFileUID = getActualFileUID(SourceFile)))) { - bool Invalid = false; - for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { - FileID IFileID; - IFileID.ID = I; - const SLocEntry &SLoc = getSLocEntry(IFileID, &Invalid); - if (Invalid) - return FileID(); - - if (SLoc.isFile()) { - const ContentCache *FileContentCache - = SLoc.getFile().getContentCache(); - const FileEntry *Entry = FileContentCache ? FileContentCache->OrigEntry - : nullptr; - if (Entry && - *SourceFileName == llvm::sys::path::filename(Entry->getName())) { - if (Optional<llvm::sys::fs::UniqueID> EntryUID = - getActualFileUID(Entry)) { - if (*SourceFileUID == *EntryUID) { - FirstFID = FileID::get(I); - SourceFile = Entry; - break; - } - } - } - } - } + // If that still didn't help, try the modules. + for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) { + const SLocEntry &SLoc = getLoadedSLocEntry(I); + if (SLoc.isFile() && SLoc.getFile().getContentCache() && + SLoc.getFile().getContentCache()->OrigEntry == SourceFile) + return FileID::get(-int(I) - 2); } - (void) SourceFile; - return FirstFID; + return FileID(); } /// Get the source location in \arg FID for the given line:col. @@ -1745,13 +1658,13 @@ SourceLocation SourceManager::translateLineCol(FileID FID, } if (Line > Content->NumLines) { - unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize(); + unsigned Size = Content->getBuffer(Diag, getFileManager())->getBufferSize(); if (Size > 0) --Size; return FileLoc.getLocWithOffset(Size); } - const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this); + const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, getFileManager()); unsigned FilePos = Content->SourceLineCache[Line - 1]; const char *Buf = Buffer->getBufferStart() + FilePos; unsigned BufLength = Buffer->getBufferSize() - FilePos; @@ -1927,7 +1840,7 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID]; if (!MacroArgsCache) { - MacroArgsCache = llvm::make_unique<MacroArgsMap>(); + MacroArgsCache = std::make_unique<MacroArgsMap>(); computeMacroArgsCache(*MacroArgsCache, FID); } @@ -2256,14 +2169,14 @@ SourceManagerForFile::SourceManagerForFile(StringRef FileName, // This is passed to `SM` as reference, so the pointer has to be referenced // in `Environment` so that `FileMgr` can out-live this function scope. FileMgr = - llvm::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem); + std::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem); // This is passed to `SM` as reference, so the pointer has to be referenced // by `Environment` due to the same reason above. - Diagnostics = llvm::make_unique<DiagnosticsEngine>( + Diagnostics = std::make_unique<DiagnosticsEngine>( IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), new DiagnosticOptions); - SourceMgr = llvm::make_unique<SourceManager>(*Diagnostics, *FileMgr); - FileID ID = SourceMgr->createFileID(FileMgr->getFile(FileName), + SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr); + FileID ID = SourceMgr->createFileID(*FileMgr->getFile(FileName), SourceLocation(), clang::SrcMgr::C_User); assert(ID.isValid()); SourceMgr->setMainFileID(ID); |