diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2020-12-10 15:27:51 -0800 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2020-12-23 15:18:50 -0800 |
commit | 3ee43adfb20d5dc56b7043b314bd22f457c55483 (patch) | |
tree | 53f588c5df51e1ed87cbb3ae42a7ef55b758701a /clang/lib/Basic/FileManager.cpp | |
parent | 245218bb355599771ba43a0fe1449d1670f2666c (diff) | |
download | llvm-3ee43adfb20d5dc56b7043b314bd22f457c55483.zip llvm-3ee43adfb20d5dc56b7043b314bd22f457c55483.tar.gz llvm-3ee43adfb20d5dc56b7043b314bd22f457c55483.tar.bz2 |
Basic: Add native support for stdin to SourceManager and FileManager
Add support for stdin to SourceManager and FileManager. Adds
FileManager::getSTDIN, which adds a FileEntryRef for `<stdin>` and reads
the MemoryBuffer, which is stored as `FileEntry::Content`.
Eventually the other buffers in `ContentCache` will sink to here as well
-- we probably usually want to load/save a MemoryBuffer eagerly -- but
it's happening early for stdin to get rid of
CompilerInstance::InitializeSourceManager's final call to
`SourceManager::overrideFileContents`.
clang/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.export/p1.cpp
relies on building a module from stdin; supporting that requires setting
ContentCache::BufferOverridden.
Differential Revision: https://reviews.llvm.org/D93148
Diffstat (limited to 'clang/lib/Basic/FileManager.cpp')
-rw-r--r-- | clang/lib/Basic/FileManager.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index f3afe6d..6e9d5d7 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -338,6 +338,25 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { return ReturnedRef; } +llvm::Expected<FileEntryRef> FileManager::getSTDIN() { + // Only read stdin once. + if (STDIN) + return *STDIN; + + std::unique_ptr<llvm::MemoryBuffer> Content; + if (auto ContentOrError = llvm::MemoryBuffer::getSTDIN()) + Content = std::move(*ContentOrError); + else + return llvm::errorCodeToError(ContentOrError.getError()); + + STDIN = getVirtualFileRef(Content->getBufferIdentifier(), + Content->getBufferSize(), 0); + FileEntry &FE = const_cast<FileEntry &>(STDIN->getFileEntry()); + FE.Content = std::move(Content); + FE.IsNamedPipe = true; + return *STDIN; +} + const FileEntry *FileManager::getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime) { return &getVirtualFileRef(Filename, Size, ModificationTime).getFileEntry(); @@ -486,6 +505,10 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, bool RequiresNullTerminator) { + // If the content is living on the file entry, return a reference to it. + if (Entry->Content) + return llvm::MemoryBuffer::getMemBuffer(Entry->Content->getMemBufferRef()); + uint64_t FileSize = Entry->getSize(); // If there's a high enough chance that the file have changed since we // got its size, force a stat before opening it. |