浏览代码

SourceManager intialization tweaks.

- Open files before calling stat on them.
- Go through FileManager for getting the buffer of named pipes. It has the
  necessary plumbing to deal with "volatile" files.
- Print the cause when stdin reading fails. The only case I can imagine where
  this happens is when stdin is wired to a device file, so no test case.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188178 91177308-0d34-0410-b5e6-96231b3b80d8
Benjamin Kramer 12 年之前
父节点
当前提交
a3bf897544
共有 2 个文件被更改,包括 15 次插入14 次删除
  1. 1 1
      include/clang/Basic/DiagnosticFrontendKinds.td
  2. 14 13
      lib/Frontend/CompilerInstance.cpp

+ 1 - 1
include/clang/Basic/DiagnosticFrontendKinds.td

@@ -11,7 +11,7 @@ let Component = "Frontend" in {
 
 
 def err_fe_error_opening : Error<"error opening '%0': %1">;
 def err_fe_error_opening : Error<"error opening '%0': %1">;
 def err_fe_error_reading : Error<"error reading '%0'">;
 def err_fe_error_reading : Error<"error reading '%0'">;
-def err_fe_error_reading_stdin : Error<"error reading stdin">;
+def err_fe_error_reading_stdin : Error<"error reading stdin: %0">;
 def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
 def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
 
 
 // Error generated by the backend.
 // Error generated by the backend.

+ 14 - 13
lib/Frontend/CompilerInstance.cpp

@@ -618,7 +618,7 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
 
 
   // Figure out where to get and map in the main file.
   // Figure out where to get and map in the main file.
   if (InputFile != "-") {
   if (InputFile != "-") {
-    const FileEntry *File = FileMgr.getFile(InputFile);
+    const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true);
     if (!File) {
     if (!File) {
       Diags.Report(diag::err_fe_error_reading) << InputFile;
       Diags.Report(diag::err_fe_error_reading) << InputFile;
       return false;
       return false;
@@ -626,26 +626,27 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
 
 
     // The natural SourceManager infrastructure can't currently handle named
     // The natural SourceManager infrastructure can't currently handle named
     // pipes, but we would at least like to accept them for the main
     // 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.
+    // file. Detect them here, read them with the volatile flag so FileMgr will
+    // pick up the correct size, and simply override their contents as we do for
+    // STDIN.
     if (File->isNamedPipe()) {
     if (File->isNamedPipe()) {
-      OwningPtr<llvm::MemoryBuffer> MB;
-      if (llvm::error_code ec = llvm::MemoryBuffer::getFile(InputFile, MB)) {
-        Diags.Report(diag::err_cannot_open_file) << InputFile << ec.message();
+      std::string ErrorStr;
+      if (llvm::MemoryBuffer *MB =
+              FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)) {
+        // Create a new virtual file that will have the correct size.
+        File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0);
+        SourceMgr.overrideFileContents(File, MB);
+      } else {
+        Diags.Report(diag::err_cannot_open_file) << InputFile << ErrorStr;
         return false;
         return false;
       }
       }
-
-      // Create a new virtual file that will have the correct size.
-      File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0);
-      SourceMgr.overrideFileContents(File, MB.take());
     }
     }
 
 
     SourceMgr.createMainFileID(File, Kind);
     SourceMgr.createMainFileID(File, Kind);
   } else {
   } else {
     OwningPtr<llvm::MemoryBuffer> SB;
     OwningPtr<llvm::MemoryBuffer> SB;
-    if (llvm::MemoryBuffer::getSTDIN(SB)) {
-      // FIXME: Give ec.message() in this diag.
-      Diags.Report(diag::err_fe_error_reading_stdin);
+    if (llvm::error_code ec = llvm::MemoryBuffer::getSTDIN(SB)) {
+      Diags.Report(diag::err_fe_error_reading_stdin) << ec.message();
       return false;
       return false;
     }
     }
     const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
     const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),