diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index b00f2b7827..b2f578da7b 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -103,6 +103,10 @@ public: bool operator<(const FileEntry &RHS) const { return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode); } + + /// \brief Check whether the file is a named pipe (and thus can't be opened by + /// the native FileManager methods). + bool isNamedPipe() const; }; /// \brief Implements support for file system lookup, file system caching, diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp index c6b894c7e2..6a0fbf80b9 100644 --- a/lib/Basic/FileManager.cpp +++ b/lib/Basic/FileManager.cpp @@ -57,6 +57,10 @@ FileEntry::~FileEntry() { if (FD != -1) ::close(FD); } +bool FileEntry::isNamedPipe() const { + return FileMode & S_IFIFO; +} + //===----------------------------------------------------------------------===// // Windows. //===----------------------------------------------------------------------===// diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index c6c5fb5fe2..b85832208b 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -610,6 +610,19 @@ bool CompilerInstance::InitializeSourceManager(StringRef InputFile, return false; } SourceMgr.createMainFileID(File, Kind); + + // The natural SourceManager infrastructure can't currently handle named + // pipes, but we would at least like to accept them for the main + // file. Detect them here, read them with the more generic MemoryBuffer + // function, and simply override their contents as we do for STDIN. + if (File->isNamedPipe()) { + OwningPtr MB; + if (llvm::error_code ec = llvm::MemoryBuffer::getFile(InputFile, MB)) { + Diags.Report(diag::err_cannot_open_file) << InputFile << ec.message(); + return false; + } + SourceMgr.overrideFileContents(File, MB.take()); + } } else { OwningPtr SB; if (llvm::MemoryBuffer::getSTDIN(SB)) {