[cfe-commits] r98585 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/Basic/DiagnosticCommonKinds.td include/clang/Basic/SourceManager.h lib/AST/ASTContext.cpp lib/Basic/SourceManager.cpp lib/Frontend/RewriteObjC.cpp lib/Frontend/TextDiagnosticPrinter.cpp lib/Lex/Lexer.cpp lib/Lex/PPLexerChange.cpp lib/Lex/TokenLexer.cpp lib/Rewrite/HTMLRewrite.cpp lib/Rewrite/Rewriter.cpp lib/Sema/SemaChecking.cpp tools/CIndex/CIndex.cpp

Douglas Gregor dgregor at apple.com
Mon Mar 15 15:54:52 PDT 2010


Author: dgregor
Date: Mon Mar 15 17:54:52 2010
New Revision: 98585

URL: http://llvm.org/viewvc/llvm-project?rev=98585&view=rev
Log:
Introduce a new BufferResult class to act as the return type of
SourceManager's getBuffer() (and similar) operations. This abstract
can be used to force callers to cope with errors in getBuffer(), such
as missing files and changed files. Fix a bunch of callers to use the
new interface.

Add some very basic checks for file consistency (file size,
modification time) into ContentCache::getBuffer(), although these
checks don't help much until we've updated the main callers (e.g.,
SourceManager::getSpelling()).


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Basic/SourceManager.cpp
    cfe/trunk/lib/Frontend/RewriteObjC.cpp
    cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Lex/PPLexerChange.cpp
    cfe/trunk/lib/Lex/TokenLexer.cpp
    cfe/trunk/lib/Rewrite/HTMLRewrite.cpp
    cfe/trunk/lib/Rewrite/Rewriter.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/tools/CIndex/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Mar 15 17:54:52 2010
@@ -40,6 +40,7 @@
   class ASTRecordLayout;
   class BlockExpr;
   class CharUnits;
+  class Diagnostic;
   class Expr;
   class ExternalASTSource;
   class IdentifierTable;
@@ -356,7 +357,7 @@
   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
 
 
-  const char *getCommentForDecl(const Decl *D);
+  const char *getCommentForDecl(const Decl *D, Diagnostic &Diags);
 
   // Builtin Types.
   CanQualType VoidTy;

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Mon Mar 15 17:54:52 2010
@@ -63,4 +63,7 @@
 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
+def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
+
 }

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Mon Mar 15 17:54:52 2010
@@ -17,21 +17,68 @@
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/System/DataTypes.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/DenseMap.h"
 #include <vector>
 #include <cassert>
 
 namespace llvm {
 class MemoryBuffer;
+class StringRef;
 }
 
 namespace clang {
 
+class Diagnostic;
 class SourceManager;
 class FileManager;
 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.
 ///
@@ -68,10 +115,8 @@
     /// if SourceLineCache is non-null.
     unsigned NumLines;
 
-    /// getBuffer - Returns the memory buffer for the associated content.  If
-    /// there is an error opening this buffer the first time, this manufactures
-    /// a temporary buffer and returns a non-empty error string.
-    const llvm::MemoryBuffer *getBuffer(std::string *ErrorStr = 0) const;
+    /// getBuffer - Returns the memory buffer for the associated content. 
+    BufferResult getBuffer() 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
@@ -407,7 +452,7 @@
                                         unsigned Offset = 0);
 
   /// \brief Retrieve the memory buffer associated with the given file.
-  const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File);
+  BufferResult getMemoryBufferForFile(const FileEntry *File);
 
   /// \brief Override the contents of the given source file by providing an
   /// already-allocated buffer.
@@ -428,8 +473,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.
-  const llvm::MemoryBuffer *getBuffer(FileID FID, std::string *Error = 0) const{
-    return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Error);
+  BufferResult getBuffer(FileID FID) const{
+    return getSLocEntry(FID).getFile().getContentCache()->getBuffer();
   }
 
   /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
@@ -439,8 +484,21 @@
 
   /// getBufferData - Return a pointer to the start and end of the source buffer
   /// data for the specified FileID.
-  std::pair<const char*, const char*> getBufferData(FileID FID) const;
+  ///
+  /// If an error occurs while reading in the file, provides the file name 
+  /// and a non-empty error string and returns a pair of NULL pointers.
+  std::pair<const char*, const char*> getBufferData(FileID FID,
+                                                    llvm::StringRef &FileName,
+                                                    std::string &Error) const;
 
+  /// getBufferData - Return a pointer to the start and end of the source buffer
+  /// data for the specified FileID.
+  /// 
+  /// If an error occurs while reading in the file, emits a diagnostic to the
+  /// given \c Diagnostic object and returns a pair of NULL pointers.
+  std::pair<const char*, const char*> getBufferData(FileID FID, 
+                                                    Diagnostic &Diags) const;
+  
 
   //===--------------------------------------------------------------------===//
   // SourceLocation manipulation methods.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Mar 15 17:54:52 2010
@@ -423,10 +423,14 @@
 /// (which requires a < after the Doxygen-comment delimiter). Otherwise,
 /// we only return true when we find a non-member comment.
 static bool
-isDoxygenComment(SourceManager &SourceMgr, SourceRange Comment,
-                 bool Member = false) {
+isDoxygenComment(SourceManager &SourceMgr, Diagnostic &Diags,
+                 SourceRange Comment, bool Member = false) {
   const char *BufferStart
-    = SourceMgr.getBufferData(SourceMgr.getFileID(Comment.getBegin())).first;
+    = SourceMgr.getBufferData(SourceMgr.getFileID(Comment.getBegin()), 
+                              Diags).first;
+  if (!BufferStart)
+    return false;
+  
   const char *Start = BufferStart + SourceMgr.getFileOffset(Comment.getBegin());
   const char* End = BufferStart + SourceMgr.getFileOffset(Comment.getEnd());
 
@@ -444,7 +448,7 @@
 
 /// \brief Retrieve the comment associated with the given declaration, if
 /// it has one.
-const char *ASTContext::getCommentForDecl(const Decl *D) {
+const char *ASTContext::getCommentForDecl(const Decl *D, Diagnostic &Diags) {
   if (!D)
     return 0;
 
@@ -489,12 +493,14 @@
   std::pair<FileID, unsigned> DeclStartDecomp
     = SourceMgr.getDecomposedLoc(DeclStartLoc);
   const char *FileBufferStart
-    = SourceMgr.getBufferData(DeclStartDecomp.first).first;
-
+    = SourceMgr.getBufferData(DeclStartDecomp.first, Diags).first;
+  if (!FileBufferStart)
+    return 0;
+  
   // First check whether we have a comment for a member.
   if (LastComment != Comments.end() &&
       !isa<TagDecl>(D) && !isa<NamespaceDecl>(D) &&
-      isDoxygenComment(SourceMgr, *LastComment, true)) {
+      isDoxygenComment(SourceMgr, Diags, *LastComment, true)) {
     std::pair<FileID, unsigned> LastCommentEndDecomp
       = SourceMgr.getDecomposedLoc(LastComment->getEnd());
     if (DeclStartDecomp.first == LastCommentEndDecomp.first &&
@@ -526,7 +532,7 @@
     return 0;
 
   // Check that we actually have a Doxygen comment.
-  if (!isDoxygenComment(SourceMgr, *LastComment))
+  if (!isDoxygenComment(SourceMgr, Diags, *LastComment))
     return 0;
 
   // Compute the starting line for the declaration and for the end of the
@@ -561,7 +567,7 @@
     }
 
     // If this comment is not a Doxygen comment, we're done.
-    if (!isDoxygenComment(SourceMgr, *FirstComment)) {
+    if (!isDoxygenComment(SourceMgr, Diags, *FirstComment)) {
       ++FirstComment;
       break;
     }

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Mon Mar 15 17:54:52 2010
@@ -13,12 +13,15 @@
 
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManagerInternals.h"
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
 #include <algorithm>
+#include <string>
+
 using namespace clang;
 using namespace SrcMgr;
 using llvm::MemoryBuffer;
@@ -27,6 +30,75 @@
 // 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;
 }
@@ -54,10 +126,13 @@
   Buffer = B;
 }
 
-const llvm::MemoryBuffer *ContentCache::getBuffer(std::string *ErrorStr) const {
+BufferResult ContentCache::getBuffer() const {
   // Lazily create the Buffer for ContentCaches that wrap files.
   if (!Buffer && Entry) {
-    Buffer = MemoryBuffer::getFile(Entry->getName(), ErrorStr,Entry->getSize());
+    std::string ErrorStr;
+    struct stat FileInfo;
+    Buffer = MemoryBuffer::getFile(Entry->getName(), &ErrorStr,
+                                   Entry->getSize(), &FileInfo);
 
     // If we were unable to open the file, then we are in an inconsistent
     // situation where the content cache referenced a file which no longer
@@ -75,8 +150,21 @@
       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);
+    } 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);
+      } else if (FileInfo.st_mtime != Entry->getModificationTime()) {
+        ErrorStr = "file has been modified since it was originally read";
+        return BufferResult(Entry->getName(), ErrorStr, Buffer);
+      }
     }
   }
+  
   return Buffer;
 }
 
@@ -426,12 +514,9 @@
   return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
 }
 
-const llvm::MemoryBuffer *
-SourceManager::getMemoryBufferForFile(const FileEntry *File) {
+BufferResult SourceManager::getMemoryBufferForFile(const FileEntry *File) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
-  if (IR == 0)
-    return 0;
-
+  assert(IR && "getOrCreateContentCache() cannot return NULL");
   return IR->getBuffer();
 }
 
@@ -445,14 +530,22 @@
   return false;
 }
 
-/// getBufferData - Return a pointer to the start and end of the source buffer
-/// data for the specified FileID.
 std::pair<const char*, const char*>
-SourceManager::getBufferData(FileID FID) const {
-  const llvm::MemoryBuffer *Buf = getBuffer(FID);
+SourceManager::getBufferData(FileID FID, llvm::StringRef &FileName,
+                             std::string &Error) const {
+  const llvm::MemoryBuffer *Buf = getBuffer(FID).getBuffer(FileName, Error);
+  if (!Error.empty())
+    return std::make_pair((const char *)0, (const char *)0);
   return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
 }
 
+std::pair<const char*, const char*>
+SourceManager::getBufferData(FileID FID, Diagnostic &Diags) const {
+  const llvm::MemoryBuffer *Buf = getBuffer(FID).getBuffer(Diags);
+  if (!Buf)
+    return std::make_pair((const char *)0, (const char *)0);
+  return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
+}
 
 //===----------------------------------------------------------------------===//
 // SourceLocation manipulation methods.

Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Mon Mar 15 17:54:52 2010
@@ -706,7 +706,11 @@
 
 void RewriteObjC::RewriteInclude() {
   SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
-  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
+  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID, 
+                                                                  Diags);
+  if (!MainBuf.first)
+    return;
+  
   const char *MainBufStart = MainBuf.first;
   const char *MainBufEnd = MainBuf.second;
   size_t ImportLen = strlen("import");
@@ -731,7 +735,11 @@
 }
 
 void RewriteObjC::RewriteTabs() {
-  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
+  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID,
+                                                                  Diags);
+  if (!MainBuf.first)
+    return;
+  
   const char *MainBufStart = MainBuf.first;
   const char *MainBufEnd = MainBuf.second;
 
@@ -973,7 +981,10 @@
 }
 
 void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
-  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
+  std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID,
+                                                                  Diags);
+  if (!MainBuf.first)
+    return;
 
   SourceLocation LocStart = PDecl->getLocStart();
 

Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Mon Mar 15 17:54:52 2010
@@ -330,9 +330,15 @@
   unsigned FileOffset = LocInfo.second;
 
   // Get information about the buffer it points into.
-  std::pair<const char*, const char*> BufferInfo = SM.getBufferData(FID);
+  llvm::StringRef ErrorFileName;
+  std::string ErrorStr;
+  std::pair<const char*, const char*> BufferInfo = SM.getBufferData(FID, 
+                                                                  ErrorFileName,
+                                                                    ErrorStr);
   const char *BufStart = BufferInfo.first;
-
+  if (!BufStart)
+    return;
+  
   unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
   unsigned CaretEndColNo
     = ColNo + Lexer::MeasureTokenLength(Loc, SM, *LangOpts);

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Mon Mar 15 17:54:52 2010
@@ -229,7 +229,14 @@
   // the token this macro expanded to.
   Loc = SM.getInstantiationLoc(Loc);
   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
-  std::pair<const char *,const char *> Buffer = SM.getBufferData(LocInfo.first);
+  llvm::StringRef FileName;
+  std::string ErrorStr;
+  std::pair<const char *,const char *> Buffer = SM.getBufferData(LocInfo.first,
+                                                                 FileName,
+                                                                 ErrorStr);
+  if (!Buffer.first)
+    return 0;
+  
   const char *StrData = Buffer.first+LocInfo.second;
 
   if (isWhitespace(StrData[0]))

Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)
+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Mon Mar 15 17:54:52 2010
@@ -80,9 +80,9 @@
   }
   
   // Get the MemoryBuffer for this FID, if it fails, we fail.
-  const llvm::MemoryBuffer *InputFile =
-    getSourceManager().getBuffer(FID, &ErrorStr);
-  if (!ErrorStr.empty())
+  const llvm::MemoryBuffer *InputFile
+    = getSourceManager().getBuffer(FID).getBuffer(getDiagnostics());
+  if (!InputFile)
     return true;
   
   EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir);

Modified: cfe/trunk/lib/Lex/TokenLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Mon Mar 15 17:54:52 2010
@@ -439,7 +439,10 @@
       SourceManager &SourceMgr = PP.getSourceManager();
       FileID LocFileID = SourceMgr.getFileID(ResultTokLoc);
 
-      const char *ScratchBufStart = SourceMgr.getBufferData(LocFileID).first;
+      const char *ScratchBufStart
+        = SourceMgr.getBufferData(LocFileID, PP.getDiagnostics()).first;
+      if (!ScratchBufStart)
+        return false;
 
       // Make a lexer to lex this string from.  Lex just this one token.
       // Make a lexer object so that we lex and expand the paste result.

Modified: cfe/trunk/lib/Rewrite/HTMLRewrite.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/HTMLRewrite.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/HTMLRewrite.cpp (original)
+++ cfe/trunk/lib/Rewrite/HTMLRewrite.cpp Mon Mar 15 17:54:52 2010
@@ -43,8 +43,18 @@
   // Include the whole end token in the range.
   EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr(), R.getLangOpts());
 
+  llvm::StringRef FileName;
+  std::string ErrorStr;
+  const char *BufferStart = SM.getBufferData(FID, FileName, ErrorStr).first;
+  if (!BufferStart) {
+    // FIXME: Add a diagnostic object somewhere?
+    fprintf(stderr, "error: cannot open file '%s': %s\n", 
+            FileName.str().c_str(), ErrorStr.c_str());
+    return;
+  }
+  
   HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
-                 SM.getBufferData(FID).first, StartTag, EndTag);
+                 BufferStart, StartTag, EndTag);
 }
 
 /// HighlightRange - This is the same as the above method, but takes

Modified: cfe/trunk/lib/Rewrite/Rewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/Rewriter.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/Rewriter.cpp (original)
+++ cfe/trunk/lib/Rewrite/Rewriter.cpp Mon Mar 15 17:54:52 2010
@@ -165,7 +165,17 @@
     return I->second;
   I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
 
-  std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FID);
+  llvm::StringRef FileName;
+  std::string ErrorStr;
+  
+  std::pair<const char*, const char*> MB
+    = SourceMgr->getBufferData(FID, FileName, ErrorStr);
+  if (!MB.first) {
+    // FIXME: Add a diagnostic object somewhere?
+    fprintf(stderr, "error: cannot open file '%s': %s\n", 
+            FileName.str().c_str(), ErrorStr.c_str());
+  }
+  
   I->second.Initialize(MB.first, MB.second);
 
   return I->second;

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Mar 15 17:54:52 2010
@@ -60,7 +60,10 @@
     std::pair<FileID, unsigned> LocInfo =
       SourceMgr.getDecomposedLoc(StrTokSpellingLoc);
     std::pair<const char *,const char *> Buffer =
-      SourceMgr.getBufferData(LocInfo.first);
+      SourceMgr.getBufferData(LocInfo.first, Diags);
+    if (!Buffer.first)
+      return StrTokSpellingLoc;
+      
     const char *StrData = Buffer.first+LocInfo.second;
 
     // Create a langops struct and enable trigraphs.  This is sufficient for

Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=98585&r1=98584&r2=98585&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Mon Mar 15 17:54:52 2010
@@ -2043,7 +2043,10 @@
   std::pair<FileID, unsigned> LocInfo
     = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
   std::pair<const char *,const char *> Buffer
-    = CXXUnit->getSourceManager().getBufferData(LocInfo.first);
+    = CXXUnit->getSourceManager().getBufferData(LocInfo.first,
+                                  CXXUnit->getPreprocessor().getDiagnostics());
+  if (!Buffer.first)
+    return createCXString("");
 
   return createCXString(llvm::StringRef(Buffer.first+LocInfo.second,
                                         CXTok.int_data[2]));
@@ -2096,7 +2099,11 @@
 
   // Create a lexer
   std::pair<const char *,const char *> Buffer
-    = SourceMgr.getBufferData(BeginLocInfo.first);
+    = SourceMgr.getBufferData(BeginLocInfo.first, 
+                              CXXUnit->getPreprocessor().getDiagnostics());
+  if (!Buffer.first)
+    return;
+  
   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
             CXXUnit->getASTContext().getLangOptions(),
             Buffer.first, Buffer.first + BeginLocInfo.second, Buffer.second);
@@ -2125,12 +2132,16 @@
       CXTok.int_data[0] = CXToken_Literal;
       CXTok.ptr_data = (void *)Tok.getLiteralData();
     } else if (Tok.is(tok::identifier)) {
-      // Lookup the identifier to determine whether we have a
+      // Lookup the identifier to determine whether we have a keyword.
       std::pair<FileID, unsigned> LocInfo
         = SourceMgr.getDecomposedLoc(Tok.getLocation());
-      const char *StartPos
-        = CXXUnit->getSourceManager().getBufferData(LocInfo.first).first +
-          LocInfo.second;
+      std::pair<const char *, const char *> Buf
+        = CXXUnit->getSourceManager().getBufferData(LocInfo.first,
+                                  CXXUnit->getPreprocessor().getDiagnostics());
+      if (!Buf.first)
+        return;
+      
+      const char *StartPos= Buf.first + LocInfo.second;
       IdentifierInfo *II
         = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos);
       CXTok.int_data[0] = II->getTokenID() == tok::identifier?





More information about the cfe-commits mailing list