aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Basic/FileManager.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2020-12-10 15:27:51 -0800
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2020-12-23 15:18:50 -0800
commit3ee43adfb20d5dc56b7043b314bd22f457c55483 (patch)
tree53f588c5df51e1ed87cbb3ae42a7ef55b758701a /clang/lib/Basic/FileManager.cpp
parent245218bb355599771ba43a0fe1449d1670f2666c (diff)
downloadllvm-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.cpp23
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.