[cfe-commits] r98598 - in /cfe/trunk: include/clang/Basic/DiagnosticCommonKinds.td include/clang/Basic/SourceManager.h lib/AST/ASTImporter.cpp lib/Basic/SourceManager.cpp lib/Frontend/CacheTokens.cpp lib/Frontend/PCHWriter.cpp lib/Lex/PPLexerChange.cpp

Douglas Gregor dgregor at apple.com
Mon Mar 15 17:35:39 PDT 2010


Author: dgregor
Date: Mon Mar 15 19:35:39 2010
New Revision: 98598

URL: http://llvm.org/viewvc/llvm-project?rev=98598&view=rev
Log:
Use SourceManager's Diagnostic object for all file-reading errors,
simplifying the SourceManager interfaces somewhat.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/Basic/SourceManager.cpp
    cfe/trunk/lib/Frontend/CacheTokens.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Lex/PPLexerChange.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=98598&r1=98597&r2=98598&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Mon Mar 15 19:35:39 2010
@@ -63,7 +63,12 @@
 def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
 def err_target_invalid_feature : Error<"invalid target feature '%0'">;
 
-// Anywhere we open a file
+// Source manager
 def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
-
+def err_file_size_changed : Error<
+  "size of file '%0' changed since it was first processed (from %1 to %2)">, 
+  DefaultFatal;
+def err_file_modified : Error<
+  "file '%0' modified since it was first processed">, DefaultFatal;
+  
 }

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=98598&r1=98597&r2=98598&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Mon Mar 15 19:35:39 2010
@@ -35,50 +35,6 @@
 class FileEntry;
 class LineTableInfo;
   
-/// \brief Class used as a return value by operations that return an
-/// \c llvm::MemoryBuffer.
-///
-/// Since not all source-manager routines that return buffers are guaranteed
-/// to succeed, 
-class BufferResult {
-  struct FailureData;
-  llvm::PointerUnion<const llvm::MemoryBuffer *, FailureData *> Data;
-  
-  // Cannot copy buffer result structures
-  BufferResult &operator=(const BufferResult &Other);
-  
-public:
-  BufferResult(const BufferResult &Other);
-  BufferResult(const llvm::MemoryBuffer *Buffer) : Data(Buffer) { }
-  BufferResult(const char *FileName, llvm::StringRef ErrorStr,
-               const llvm::MemoryBuffer *Buffer = 0);
-  ~BufferResult();
-  
-  // \brief Determine whether there was any failure when finding this buffer.
-  bool isInvalid() const;
-  
-  /// \brief Retrieve the memory buffer that this result refers to. If an
-  /// error occurs, emits a diagnostic via the given diagnostics object and
-  /// may return NULL.
-  const llvm::MemoryBuffer *getBuffer(Diagnostic &Diags) const;
-  
-  /// \brief Retrieve the memory buffer that this result refers to. If an error
-  /// occurs, provides the file name and a non-empty error string to indicate 
-  /// what failed, and may return NULL.
-  const llvm::MemoryBuffer *getBuffer(llvm::StringRef &FileName, 
-                                      std::string &Error) const;
-  
-  // FIXME: TEMPORARY! Allows a buffer result to be interpreted as a buffer,
-  // which is very unsafe (but is used throughout Clang). Note that this will
-  // spit a diagnostic to standard error before returning the buffer.
-  operator const llvm::MemoryBuffer *() const;
-  
-  // FIXME: TEMPORARY! Allows a buffer result to be interpreted like a smart
-  // pointer to a buffer, which is very unsafe. Note that this will emit a
-  // diagnostic to standard error before returning the buffer.
-  const llvm::MemoryBuffer * operator->() const { return *this; }
-};
-  
 /// SrcMgr - Public enums and private classes that are part of the
 /// SourceManager implementation.
 ///
@@ -115,8 +71,14 @@
     /// if SourceLineCache is non-null.
     unsigned NumLines;
 
-    /// getBuffer - Returns the memory buffer for the associated content. 
-    BufferResult getBuffer() const;
+    /// getBuffer - Returns the memory buffer for the associated content.
+    ///
+    /// \param Diag Object through which diagnostics will be emitted it the
+    /// buffer cannot be retrieved.
+    /// 
+    /// \param Invalid If non-NULL, will be set \c true if an error occurred.
+    const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag, 
+                                        bool *Invalid = 0) const;
 
     /// getSize - Returns the size of the content encapsulated by this
     ///  ContentCache. This can be the size of the source file or the size of an
@@ -455,7 +417,7 @@
                                         unsigned Offset = 0);
 
   /// \brief Retrieve the memory buffer associated with the given file.
-  BufferResult getMemoryBufferForFile(const FileEntry *File);
+  const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File);
 
   /// \brief Override the contents of the given source file by providing an
   /// already-allocated buffer.
@@ -476,8 +438,8 @@
   /// getBuffer - Return the buffer for the specified FileID. If there is an
   /// error opening this buffer the first time, this manufactures a temporary
   /// buffer and returns a non-empty error string.
-  BufferResult getBuffer(FileID FID) const{
-    return getSLocEntry(FID).getFile().getContentCache()->getBuffer();
+  const llvm::MemoryBuffer *getBuffer(FileID FID) const {
+    return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Diag);
   }
 
   /// getFileEntryForID - Returns the FileEntry record for the provided FileID.

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=98598&r1=98597&r2=98598&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Mar 15 19:35:39 2010
@@ -3089,7 +3089,7 @@
                              FromSLoc.getFile().getFileCharacteristic());
   } else {
     // FIXME: We want to re-use the existing MemoryBuffer!
-    const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
+    const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(getDiags());
     llvm::MemoryBuffer *ToBuf
       = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
                                              FromBuf->getBufferEnd(),

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=98598&r1=98597&r2=98598&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Mon Mar 15 19:35:39 2010
@@ -22,7 +22,6 @@
 #include <algorithm>
 #include <string>
 #include <cstring>
-#include <cstdio>
 
 using namespace clang;
 using namespace SrcMgr;
@@ -32,75 +31,6 @@
 // SourceManager Helper Classes
 //===----------------------------------------------------------------------===//
 
-struct BufferResult::FailureData {
-  const llvm::MemoryBuffer *Buffer;
-  const char *FileName;
-  std::string ErrorStr;  
-};
-
-BufferResult::BufferResult(const BufferResult &Other) {
-  if (const llvm::MemoryBuffer *Buffer
-                        = Other.Data.dyn_cast<const llvm::MemoryBuffer *>()) {
-    Data = Buffer;
-    return;
-  }
-  
-  Data = new FailureData(*Other.Data.get<FailureData *>());
-}
-
-BufferResult::BufferResult(const char *FileName, llvm::StringRef ErrorStr,
-                           const llvm::MemoryBuffer *Buffer) {
-  FailureData *FD = new FailureData;
-  FD->FileName = FileName;
-  FD->ErrorStr = ErrorStr;
-  FD->Buffer = Buffer;
-  Data = FD;
-}
-
-BufferResult::~BufferResult() {
-  if (FailureData *FD = Data.dyn_cast<FailureData *>())
-    delete FD;
-}
-
-bool BufferResult::isInvalid() const {
-  return Data.is<FailureData *>();
-}
-
-const llvm::MemoryBuffer *BufferResult::getBuffer(Diagnostic &Diags) const {
-  llvm::StringRef FileName;
-  std::string ErrorMsg;
-  const llvm::MemoryBuffer *Result = getBuffer(FileName, ErrorMsg);
-  if (!ErrorMsg.empty()) {
-    Diags.Report(diag::err_cannot_open_file)
-      << FileName << ErrorMsg;
-  }
-  return Result;
-}
-
-const llvm::MemoryBuffer *BufferResult::getBuffer(llvm::StringRef &FileName, 
-                                                  std::string &Error) const {
-  if (const llvm::MemoryBuffer *Buffer
-                                  = Data.dyn_cast<const llvm::MemoryBuffer *>())
-    return Buffer;
- 
-  FailureData *Fail = Data.get<FailureData *>();
-  FileName = Fail->FileName;
-  Error = Fail->ErrorStr;
-  return Fail->Buffer;
-}
-
-BufferResult::operator const llvm::MemoryBuffer *() const {
-  llvm::StringRef FileName;
-  std::string ErrorMsg;
-  const llvm::MemoryBuffer *Result = getBuffer(FileName, ErrorMsg);
-  if (!ErrorMsg.empty()) {
-    fprintf(stderr, "error: cannot open file '%s': %s\n",
-            FileName.str().c_str(), ErrorMsg.c_str());
-  }
-  
-  return Result;
-}
-
 ContentCache::~ContentCache() {
   delete Buffer;
 }
@@ -128,7 +58,11 @@
   Buffer = B;
 }
 
-BufferResult ContentCache::getBuffer() const {
+const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
+                                                  bool *Invalid) const {
+  if (Invalid)
+    *Invalid = false;
+      
   // Lazily create the Buffer for ContentCaches that wrap files.
   if (!Buffer && Entry) {
     std::string ErrorStr;
@@ -152,17 +86,23 @@
       char *Ptr = const_cast<char*>(Buffer->getBufferStart());
       for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
         Ptr[i] = FillStr[i % FillStr.size()];
-      return BufferResult(Entry->getName(), ErrorStr, Buffer);
+      Diag.Report(diag::err_cannot_open_file)
+        << Entry->getName() << ErrorStr;
+      if (Invalid)
+        *Invalid = true;
     } else {
       // Check that the file's size and modification time is the same as 
       // in the file entry (which may have come from a stat cache).
-      // FIXME: Make these strings localizable.
       if (FileInfo.st_size != Entry->getSize()) {
-        ErrorStr = "file has changed size since it was originally read";
-        return BufferResult(Entry->getName(), ErrorStr, Buffer);
+        Diag.Report(diag::err_file_size_changed)
+          << Entry->getName() << (unsigned)Entry->getSize() 
+          << (unsigned)FileInfo.st_size;
+        if (Invalid)
+          *Invalid = true;
       } else if (FileInfo.st_mtime != Entry->getModificationTime()) {
-        ErrorStr = "file has been modified since it was originally read";
-        return BufferResult(Entry->getName(), ErrorStr, Buffer);
+        Diag.Report(diag::err_file_modified) << Entry->getName();
+        if (Invalid)
+          *Invalid = true;
       }
     }
   }
@@ -516,10 +456,11 @@
   return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
 }
 
-BufferResult SourceManager::getMemoryBufferForFile(const FileEntry *File) {
+const llvm::MemoryBuffer *
+SourceManager::getMemoryBufferForFile(const FileEntry *File) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
   assert(IR && "getOrCreateContentCache() cannot return NULL");
-  return IR->getBuffer();
+  return IR->getBuffer(Diag);
 }
 
 bool SourceManager::overrideFileContents(const FileEntry *SourceFile,
@@ -537,7 +478,7 @@
   if (Invalid)
     *Invalid = false;
   
-  const llvm::MemoryBuffer *Buf = getBuffer(FID).getBuffer(Diag);
+  const llvm::MemoryBuffer *Buf = getBuffer(FID);
   if (!Buf) {
     if (*Invalid)
       *Invalid = true;
@@ -767,7 +708,7 @@
 
   // Note that calling 'getBuffer()' may lazily page in a source file.
   return getSLocEntry(LocInfo.first).getFile().getContentCache()
-              ->getBuffer()->getBufferStart() + LocInfo.second;
+              ->getBuffer(Diag)->getBufferStart() + LocInfo.second;
 }
 
 
@@ -796,11 +737,13 @@
 
 
 
-static DISABLE_INLINE void ComputeLineNumbers(ContentCache* FI,
+static DISABLE_INLINE void ComputeLineNumbers(Diagnostic &Diag,
+                                              ContentCache* FI,
                                               llvm::BumpPtrAllocator &Alloc);
-static void ComputeLineNumbers(ContentCache* FI, llvm::BumpPtrAllocator &Alloc){
+static void ComputeLineNumbers(Diagnostic &Diag, ContentCache* FI, 
+                               llvm::BumpPtrAllocator &Alloc){
   // Note that calling 'getBuffer()' may lazily page in the file.
-  const MemoryBuffer *Buffer = FI->getBuffer();
+  const MemoryBuffer *Buffer = FI->getBuffer(Diag);
 
   // Find the file offsets of all of the *physical* source lines.  This does
   // not look at trigraphs, escaped newlines, or anything else tricky.
@@ -857,7 +800,7 @@
   // If this is the first use of line information for this buffer, compute the
   /// SourceLineCache for it on demand.
   if (Content->SourceLineCache == 0)
-    ComputeLineNumbers(Content, ContentCacheAlloc);
+    ComputeLineNumbers(Diag, Content, ContentCacheAlloc);
 
   // Okay, we know we have a line number table.  Do a binary search to find the
   // line number that this character position lands on.
@@ -1015,7 +958,7 @@
   // before the MemBuffer as this will avoid unnecessarily paging in the
   // MemBuffer.
   const char *Filename =
-    C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
+    C->Entry ? C->Entry->getName() : C->getBuffer(Diag)->getBufferIdentifier();
   unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second);
   unsigned ColNo  = getColumnNumber(LocInfo.first, LocInfo.second);
   SourceLocation IncludeLoc = FI.getIncludeLoc();
@@ -1072,7 +1015,7 @@
   // If this is the first use of line information for this buffer, compute the
   /// SourceLineCache for it on demand.
   if (Content->SourceLineCache == 0)
-    ComputeLineNumbers(Content, ContentCacheAlloc);
+    ComputeLineNumbers(Diag, Content, ContentCacheAlloc);
 
   // Find the first file ID that corresponds to the given file.
   FileID FirstFID;
@@ -1101,15 +1044,15 @@
     return SourceLocation();
 
   if (Line > Content->NumLines) {
-    unsigned Size = Content->getBuffer()->getBufferSize();
+    unsigned Size = Content->getBuffer(Diag)->getBufferSize();
     if (Size > 0)
       --Size;
     return getLocForStartOfFile(FirstFID).getFileLocWithOffset(Size);
   }
 
   unsigned FilePos = Content->SourceLineCache[Line - 1];
-  const char *Buf = Content->getBuffer()->getBufferStart() + FilePos;
-  unsigned BufLength = Content->getBuffer()->getBufferEnd() - Buf;
+  const char *Buf = Content->getBuffer(Diag)->getBufferStart() + FilePos;
+  unsigned BufLength = Content->getBuffer(Diag)->getBufferEnd() - Buf;
   unsigned i = 0;
 
   // Check that the given column is valid.

Modified: cfe/trunk/lib/Frontend/CacheTokens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CacheTokens.cpp?rev=98598&r1=98597&r2=98598&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CacheTokens.cpp (original)
+++ cfe/trunk/lib/Frontend/CacheTokens.cpp Mon Mar 15 19:35:39 2010
@@ -474,7 +474,7 @@
     if (!P.isAbsolute())
       continue;
 
-    const llvm::MemoryBuffer *B = C.getBuffer();
+    const llvm::MemoryBuffer *B = C.getBuffer(PP.getDiagnostics());
     if (!B) continue;
 
     FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=98598&r1=98597&r2=98598&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Mar 15 19:35:39 2010
@@ -1089,7 +1089,8 @@
         // We add one to the size so that we capture the trailing NULL
         // that is required by llvm::MemoryBuffer::getMemBuffer (on
         // the reader side).
-        const llvm::MemoryBuffer *Buffer = Content->getBuffer();
+        const llvm::MemoryBuffer *Buffer
+          = Content->getBuffer(PP.getDiagnostics());
         const char *Name = Buffer->getBufferIdentifier();
         Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
                                   llvm::StringRef(Name, strlen(Name) + 1));

Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=98598&r1=98597&r2=98598&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)
+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Mon Mar 15 19:35:39 2010
@@ -80,8 +80,7 @@
   }
   
   // Get the MemoryBuffer for this FID, if it fails, we fail.
-  const llvm::MemoryBuffer *InputFile
-    = getSourceManager().getBuffer(FID).getBuffer(getDiagnostics());
+  const llvm::MemoryBuffer *InputFile = getSourceManager().getBuffer(FID);
   if (!InputFile)
     return true;
   





More information about the cfe-commits mailing list