[cfe-commits] r39425 - in /cfe/cfe/trunk: Basic/SourceBuffer.cpp Basic/SourceManager.cpp include/clang/Basic/SourceBuffer.h

clattner at cs.uiuc.edu clattner at cs.uiuc.edu
Wed Jul 11 09:44:13 PDT 2007


Author: clattner
Date: Wed Jul 11 11:44:13 2007
New Revision: 39425

URL: http://llvm.org/viewvc/llvm-project?rev=39425&view=rev
Log:
Refactor the SourceBuffer code so that it is safe to move to the LLVM
support library, where it can be used by other LLVM clients.  There are
some ugly fixme's in the short-term.

Modified:
    cfe/cfe/trunk/Basic/SourceBuffer.cpp
    cfe/cfe/trunk/Basic/SourceManager.cpp
    cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h

Modified: cfe/cfe/trunk/Basic/SourceBuffer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Basic/SourceBuffer.cpp?rev=39425&r1=39424&r2=39425&view=diff

==============================================================================
--- cfe/cfe/trunk/Basic/SourceBuffer.cpp (original)
+++ cfe/cfe/trunk/Basic/SourceBuffer.cpp Wed Jul 11 11:44:13 2007
@@ -17,12 +17,7 @@
 #include "llvm/System/Process.h"
 #include <cstdio>
 #include <cstring>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/uio.h>
 #include <cerrno>
-#include <sys/fcntl.h>
-
 using namespace llvm;
 using namespace clang;
 
@@ -83,8 +78,8 @@
   return new SourceBufferMem(StartPtr, EndPtr, BufferName);
 }
 
-/// getNewUninitMemBuffer - Allocate a new SourceBuffer of the specified size that
-/// is completely initialized to zeros.  Note that the caller should
+/// getNewUninitMemBuffer - Allocate a new SourceBuffer of the specified size
+/// that is completely initialized to zeros.  Note that the caller should
 /// initialize the memory allocated by this method.  The memory is owned by
 /// the SourceBuffer object.
 SourceBuffer *SourceBuffer::getNewUninitMemBuffer(unsigned Size,
@@ -160,13 +155,70 @@
 }
 
 //===----------------------------------------------------------------------===//
-// SourceBufferReadFile implementation.
+// SourceBuffer::getFile implementation.
 //===----------------------------------------------------------------------===//
 
+SourceBuffer *SourceBuffer::getFile(const char *FilenameStart, unsigned FnSize,
+                                    int64_t FileSize) {
+  sys::PathWithStatus P(FilenameStart, FnSize);
+#if 1
+  return new SourceBufferMMapFile(P);
+#else  
+  
+  // If the user didn't specify a filesize, do a stat to find it.
+  if (FileSize == -1) {
+    const sys::FileStatus *FS = P.getFileStatus();
+    if (FS == 0) return 0;  // Error stat'ing file.
+   
+    FileSize = FS->fileSize;
+  }
+  
+  // If the file is larger than some threshold, use mmap, otherwise use 'read'.
+  if (FileSize >= 4096*4)
+    return new SourceBufferMMapFile(P);
+  
+  SourceBuffer *SB = getNewUninitMemBuffer(FileSize, FilenameStart);
+  char *BufPtr = const_cast<char*>(SB->getBufferStart());
+  
+  int FD = ::open(FilenameStart, O_RDONLY);
+  if (FD == -1) {
+    delete SB;
+    return 0;
+  }
+  
+  unsigned BytesLeft = FileSize;
+  while (BytesLeft) {
+    ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
+    if (NumRead != -1) {
+      BytesLeft -= NumRead;
+      BufPtr += NumRead;
+    } else if (errno == EINTR) {
+      // try again
+    } else {
+      // error reading.
+      close(FD);
+      delete SB;
+      return 0;
+    }
+  }
+  close(FD);
+  
+  return SB;
+#endif
+}
+
+#if 0
 SourceBuffer *SourceBuffer::getFile(const FileEntry *FileEnt) {
+#if 0
+  // FIXME: 
+  return getFile(FileEnt->getName(), strlen(FileEnt->getName()),
+                 FileEnt->getSize());
+#endif
+  
   // If the file is larger than some threshold, use 'read', otherwise use mmap.
   if (FileEnt->getSize() >= 4096*4)
-    return new SourceBufferMMapFile(sys::Path(FileEnt->getName()));
+    return new SourceBufferMMapFile(sys::Path(FileEnt->getName(),
+                                              strlen(FileEnt->getName())));
 
   SourceBuffer *SB = getNewUninitMemBuffer(FileEnt->getSize(),
                                            FileEnt->getName());
@@ -197,9 +249,10 @@
     
   return SB;
 }
+#endif
 
 //===----------------------------------------------------------------------===//
-// SourceBufferSTDIN implementation.
+// SourceBuffer::getSTDIN implementation.
 //===----------------------------------------------------------------------===//
 
 namespace {

Modified: cfe/cfe/trunk/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Basic/SourceManager.cpp?rev=39425&r1=39424&r2=39425&view=diff

==============================================================================
--- cfe/cfe/trunk/Basic/SourceManager.cpp (original)
+++ cfe/cfe/trunk/Basic/SourceManager.cpp Wed Jul 11 11:44:13 2007
@@ -35,6 +35,58 @@
   }
 }
 
+
+// FIXME: REMOVE THESE
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/fcntl.h>
+#include <cerrno>
+
+static const SourceBuffer *ReadFileFast(const FileEntry *FileEnt) {
+#if 0
+  // FIXME: Reintroduce this and zap this function once the common llvm stuff
+  // is fast for the small case.
+  return SourceBuffer::getFile(FileEnt->getName(), strlen(FileEnt->getName()),
+                               FileEnt->getSize());
+#endif
+  
+  // If the file is larger than some threshold, use 'read', otherwise use mmap.
+  if (FileEnt->getSize() >= 4096*4)
+    return SourceBuffer::getFile(FileEnt->getName(), strlen(FileEnt->getName()),
+                                 FileEnt->getSize());
+  
+  SourceBuffer *SB = SourceBuffer::getNewUninitMemBuffer(FileEnt->getSize(),
+                                                         FileEnt->getName());
+  char *BufPtr = const_cast<char*>(SB->getBufferStart());
+  
+  int FD = ::open(FileEnt->getName(), O_RDONLY);
+  if (FD == -1) {
+    delete SB;
+    return 0;
+  }
+  
+  unsigned BytesLeft = FileEnt->getSize();
+  while (BytesLeft) {
+    ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
+    if (NumRead != -1) {
+      BytesLeft -= NumRead;
+      BufPtr += NumRead;
+    } else if (errno == EINTR) {
+      // try again
+    } else {
+      // error reading.
+      close(FD);
+      delete SB;
+      return 0;
+    }
+  }
+  close(FD);
+  
+  return SB;
+}
+
+
 /// getFileInfo - Create or return a cached FileInfo for the specified file.
 ///
 const InfoRec *
@@ -47,7 +99,7 @@
     return &*I;
   
   // Nope, get information.
-  const SourceBuffer *File = clang::SourceBuffer::getFile(FileEnt);
+  const SourceBuffer *File = ReadFileFast(FileEnt);
   if (File == 0)
     return 0;
 

Modified: cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h?rev=39425&r1=39424&r2=39425&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h (original)
+++ cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h Wed Jul 11 11:44:13 2007
@@ -14,15 +14,15 @@
 #ifndef LLVM_CLANG_SOURCEBUFFER_H
 #define LLVM_CLANG_SOURCEBUFFER_H
 
+#include "llvm/Support/DataTypes.h"
+
 namespace llvm {
-namespace sys { class Path; }
 namespace clang {
-  class FileEntry;
 
-/// SourceFile - This interface provides simple read-only access to the raw bits
-/// in a source file in a memory efficient way.  In addition to basic access to
-/// the characters in the file, this interface guarantees you can read one
-/// character past the end of the file, and that this character will read as
+/// SourceBuffer - This interface provides simple read-only access to the raw
+/// bits in a source file in a memory efficient way.  In addition to basic
+/// access to the characters in the file, this interface guarantees you can read
+/// one character past the end of the file, and that this character will read as
 /// '\0'.
 class SourceBuffer {
   const char *BufferStart; // Start of the buffer.
@@ -47,10 +47,13 @@
   virtual const char *getBufferIdentifier() const {
     return "Unknown buffer";
   }
-    
+
   /// getFile - Open the specified file as a SourceBuffer, returning a new
-  /// SourceBuffer if successful, otherwise returning null.
-  static SourceBuffer *getFile(const FileEntry *FileEnt);
+  /// SourceBuffer if successful, otherwise returning null.  If FileSize is
+  /// specified, this means that the client knows that the file exists and that
+  /// it has the specified size.
+  static SourceBuffer *getFile(const char *FilenameStart, unsigned FnSize,
+                               int64_t FileSize = -1);
 
   /// getMemBuffer - Open the specified memory range as a SourceBuffer.  Note
   /// that EndPtr[0] must be a null byte and be accessible!





More information about the cfe-commits mailing list