]> granicus.if.org Git - clang/commitdiff
push some source location information down through the compiler,
authorChris Lattner <sabre@nondot.org>
Tue, 20 Apr 2010 20:35:58 +0000 (20:35 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 20 Apr 2010 20:35:58 +0000 (20:35 +0000)
into ContentCache::getBuffer.  This allows it to produce
diagnostics on the broken #include line instead of without a
location.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101939 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/clang/Basic/SourceManager.h
include/clang/Lex/Preprocessor.h
lib/AST/ASTImporter.cpp
lib/Basic/SourceManager.cpp
lib/Frontend/CacheTokens.cpp
lib/Frontend/FrontendActions.cpp
lib/Frontend/PCHWriter.cpp
lib/Frontend/PrintPreprocessedOutput.cpp
lib/Frontend/RewriteMacros.cpp
lib/Lex/PPDirectives.cpp
lib/Lex/PPLexerChange.cpp
lib/Lex/Preprocessor.cpp
lib/Sema/ParseAST.cpp
test/Lexer/utf-16.c

index d1239694fc16b39fef5950ba7f43afeb5c6371ff..930fb52873eb4889b9976c0d8b35e150e4cab455 100644 (file)
@@ -78,8 +78,13 @@ namespace SrcMgr {
     /// \param Diag Object through which diagnostics will be emitted it the
     /// buffer cannot be retrieved.
     /// 
+    /// \param Loc If specified, is the location that invalid file diagnostics
+    ///     will be emitted at.
+    ///
     /// \param Invalid If non-NULL, will be set \c true if an error occurred.
-    const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag, 
+    const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag,
+                                        const SourceManager &SM,
+                                        SourceLocation Loc = SourceLocation(),
                                         bool *Invalid = 0) const;
 
     /// getSize - Returns the size of the content encapsulated by this
@@ -447,11 +452,17 @@ public:
   /// 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, bool *Invalid = 0) const {
-    return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Diag,
-                                                                    Invalid);
+  const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+                                      bool *Invalid = 0) const {
+    return getSLocEntry(FID).getFile().getContentCache()
+       ->getBuffer(Diag, *this, Loc, Invalid);
   }
 
+  const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
+    return getSLocEntry(FID).getFile().getContentCache()
+       ->getBuffer(Diag, *this, SourceLocation(), Invalid);
+  }
+  
   /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
   const FileEntry *getFileEntryForID(FileID FID) const {
     return getSLocEntry(FID).getFile().getContentCache()->Entry;
index 312a760e01d380b9b3840f4a60fc6c3564b7c130..20d9fc50e49fdf55b57a191d98bca4d657c7af8a 100644 (file)
@@ -366,17 +366,17 @@ public:
   
   /// EnterMainSourceFile - Enter the specified FileID as the main source file,
   /// which implicitly adds the builtin defines etc.
-  bool EnterMainSourceFile();
+  void EnterMainSourceFile();
 
   /// EndSourceFile - Inform the preprocessor callbacks that processing is
   /// complete.
   void EndSourceFile();
 
   /// EnterSourceFile - Add a source file to the top of the include stack and
-  /// start lexing tokens from it instead of the current buffer.  Return true
-  /// and fill in ErrorStr with the error information on failure.
-  bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
-                       std::string &ErrorStr);
+  /// start lexing tokens from it instead of the current buffer.  Emit an error
+  /// and don't enter the file on error.
+  void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+                       SourceLocation Loc);
 
   /// EnterMacro - Add a Macro to the top of the include stack and start lexing
   /// tokens from it instead of the current buffer.  Args specifies the
index 5651121402e7f5d984213396c4fa64aace47dc17..d3268030c91b3697467473cbd10b6f98a2f0d024 100644 (file)
@@ -3090,7 +3090,7 @@ FileID ASTImporter::Import(FileID FromID) {
                              FromSLoc.getFile().getFileCharacteristic());
   } else {
     // FIXME: We want to re-use the existing MemoryBuffer!
-    const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(getDiags());
+    const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(getDiags(), FromSM);
     llvm::MemoryBuffer *ToBuf
       = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
                                              FromBuf->getBufferIdentifier());
index c76624139a08c4e20fd2d6876920eec18f9a1d49..355b87a9dd7af229776fe14492cbec03573dbefb 100644 (file)
@@ -60,12 +60,17 @@ void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B) {
 }
 
 const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
+                                                  const SourceManager &sm,
+                                                  SourceLocation Loc,
                                                   bool *Invalid) const {
   if (Invalid)
     *Invalid = false;
       
   // Lazily create the Buffer for ContentCaches that wrap files.
   if (!Buffer.getPointer() && Entry) {
+    // FIXME:
+    SourceManager &SM = const_cast<SourceManager &>(sm);
+    
     std::string ErrorStr;
     struct stat FileInfo;
     Buffer.setPointer(MemoryBuffer::getFile(Entry->getName(), &ErrorStr,
@@ -94,7 +99,7 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
         Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 
                                   Entry->getName(), ErrorStr);
       else 
-        Diag.Report(diag::err_cannot_open_file)
+        Diag.Report(FullSourceLoc(Loc, SM), diag::err_cannot_open_file)
           << Entry->getName() << ErrorStr;
 
       Buffer.setInt(true);
@@ -114,7 +119,8 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
         Diag.SetDelayedDiagnostic(diag::err_file_modified,
                                   Entry->getName());
       else
-        Diag.Report(diag::err_file_modified) << Entry->getName();
+        Diag.Report(FullSourceLoc(Loc, SM), diag::err_file_modified)
+          << Entry->getName();
 
       Buffer.setInt(true);
 #endif
@@ -150,7 +156,8 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
         BOM = "BOCU-1";
       
       if (BOM) {
-        Diag.Report(diag::err_unsupported_bom) << BOM << Entry->getName();
+        Diag.Report(FullSourceLoc(Loc, SM), diag::err_unsupported_bom)
+          << BOM << Entry->getName();
         Buffer.setInt(1);
       }
     }
@@ -513,7 +520,7 @@ SourceManager::getMemoryBufferForFile(const FileEntry *File,
                                       bool *Invalid) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
   assert(IR && "getOrCreateContentCache() cannot return NULL");
-  return IR->getBuffer(Diag, Invalid);
+  return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
 }
 
 bool SourceManager::overrideFileContents(const FileEntry *SourceFile,
@@ -760,8 +767,8 @@ const char *SourceManager::getCharacterData(SourceLocation SL,
   // Note that calling 'getBuffer()' may lazily page in a source file.
   bool CharDataInvalid = false;
   const llvm::MemoryBuffer *Buffer
-    = getSLocEntry(LocInfo.first).getFile().getContentCache()->getBuffer(Diag, 
-                                                              &CharDataInvalid);
+    = getSLocEntry(LocInfo.first).getFile().getContentCache()
+    ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid);
   if (Invalid)
     *Invalid = CharDataInvalid;
   return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
@@ -800,14 +807,16 @@ unsigned SourceManager::getInstantiationColumnNumber(SourceLocation Loc,
   return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
 }
 
-static DISABLE_INLINE void ComputeLineNumbers(Diagnostic &Diag,
-                                              ContentCache* FI,
-                                              llvm::BumpPtrAllocator &Alloc,
-                                              bool &Invalid);
-static void ComputeLineNumbers(Diagnostic &Diag, ContentCache* FI, 
-                               llvm::BumpPtrAllocator &Alloc, bool &Invalid) {
+static DISABLE_INLINE void
+ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI,
+                   llvm::BumpPtrAllocator &Alloc,
+                   const SourceManager &SM, bool &Invalid);
+static void ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI, 
+                               llvm::BumpPtrAllocator &Alloc,
+                               const SourceManager &SM, bool &Invalid) {
   // Note that calling 'getBuffer()' may lazily page in the file.
-  const MemoryBuffer *Buffer = FI->getBuffer(Diag, &Invalid);
+  const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(),
+                                             &Invalid);
   if (Invalid)
     return;
 
@@ -868,7 +877,7 @@ unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos,
   /// SourceLineCache for it on demand.
   if (Content->SourceLineCache == 0) {
     bool MyInvalid = false;
-    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, MyInvalid);
+    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
     if (Invalid)
       *Invalid = MyInvalid;
     if (MyInvalid)
@@ -1034,8 +1043,11 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
   // To get the source name, first consult the FileEntry (if one exists)
   // before the MemBuffer as this will avoid unnecessarily paging in the
   // MemBuffer.
-  const char *Filename =
-    C->Entry ? C->Entry->getName() : C->getBuffer(Diag)->getBufferIdentifier();
+  const char *Filename;
+  if (C->Entry)
+    Filename = C->Entry->getName();
+  else
+    Filename = C->getBuffer(Diag, *this)->getBufferIdentifier();
   unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second);
   unsigned ColNo  = getColumnNumber(LocInfo.first, LocInfo.second);
   SourceLocation IncludeLoc = FI.getIncludeLoc();
@@ -1093,7 +1105,7 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
   /// SourceLineCache for it on demand.
   if (Content->SourceLineCache == 0) {
     bool MyInvalid = false;
-    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, MyInvalid);
+    ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
     if (MyInvalid)
       return SourceLocation();
   }
@@ -1125,15 +1137,15 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
     return SourceLocation();
 
   if (Line > Content->NumLines) {
-    unsigned Size = Content->getBuffer(Diag)->getBufferSize();
+    unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize();
     if (Size > 0)
       --Size;
     return getLocForStartOfFile(FirstFID).getFileLocWithOffset(Size);
   }
 
   unsigned FilePos = Content->SourceLineCache[Line - 1];
-  const char *Buf = Content->getBuffer(Diag)->getBufferStart() + FilePos;
-  unsigned BufLength = Content->getBuffer(Diag)->getBufferEnd() - Buf;
+  const char *Buf = Content->getBuffer(Diag, *this)->getBufferStart() + FilePos;
+  unsigned BufLength = Content->getBuffer(Diag, *this)->getBufferEnd() - Buf;
   unsigned i = 0;
 
   // Check that the given column is valid.
index d069e8f42f26cfe016b14014f26178c3d0dcf0df..a5fcebe99411667760c26342e61cf641a727056d 100644 (file)
@@ -475,7 +475,7 @@ void PTHWriter::GeneratePTH(const std::string &MainFile) {
     if (!P.isAbsolute())
       continue;
 
-    const llvm::MemoryBuffer *B = C.getBuffer(PP.getDiagnostics());
+    const llvm::MemoryBuffer *B = C.getBuffer(PP.getDiagnostics(), SM);
     if (!B) continue;
 
     FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
@@ -550,8 +550,7 @@ void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) {
   // Lex through the entire file.  This will populate SourceManager with
   // all of the header information.
   Token Tok;
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
   do { PP.Lex(Tok); } while (Tok.isNot(tok::eof));
 
   // Generate the PTH file.
index ce3e841b904a658430ef9b5b8cdac63ec60cb248..e2b2fd7deb3184b515cfd427946b2c5782908f74 100644 (file)
@@ -236,8 +236,7 @@ void DumpTokensAction::ExecuteAction() {
   Preprocessor &PP = getCompilerInstance().getPreprocessor();
   // Start preprocessing the specified input file.
   Token Tok;
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
   do {
     PP.Lex(Tok);
     PP.DumpToken(Tok, true);
@@ -265,8 +264,7 @@ void ParseOnlyAction::ExecuteAction() {
   llvm::OwningPtr<Action> PA(new MinimalAction(PP));
 
   Parser P(PP, *PA);
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
   P.ParseTranslationUnit();
 }
 
@@ -275,8 +273,7 @@ void PreprocessOnlyAction::ExecuteAction() {
 
   Token Tok;
   // Start parsing the specified input file.
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
   do {
     PP.Lex(Tok);
   } while (Tok.isNot(tok::eof));
@@ -291,8 +288,7 @@ void PrintParseAction::ExecuteAction() {
   llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS));
 
   Parser P(PP, *PA);
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
   P.ParseTranslationUnit();
 }
 
index a6faf9ba999145cb0fa638623a311c14711dee98..ee20122de7226e91de4059224399605a648c59fc 100644 (file)
@@ -1,4 +1,4 @@
-//===--- PCHWriter.h - Precompiled Headers Writer ---------------*- C++ -*-===//
+//===--- PCHWriter.cpp - Precompiled Headers Writer -----------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -1104,7 +1104,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
         // that is required by llvm::MemoryBuffer::getMemBuffer (on
         // the reader side).
         const llvm::MemoryBuffer *Buffer
-          = Content->getBuffer(PP.getDiagnostics());
+          = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
         const char *Name = Buffer->getBufferIdentifier();
         Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
                                   llvm::StringRef(Name, strlen(Name) + 1));
index 17edd12a675818402c201011024ec988671174f0..b6c18b77316cc6b74be5186800816796b55bd0de 100644 (file)
@@ -456,8 +456,7 @@ static int MacroIDCompare(const void* a, const void* b) {
 static void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
   // -dM mode just scans and ignores all tokens in the files, then dumps out
   // the macro table at the end.
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
 
   Token Tok;
   do PP.Lex(Tok);
@@ -502,8 +501,7 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
   PP.addPPCallbacks(Callbacks);
 
   // After we have configured the preprocessor, enter the main file.
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
 
   // Consume all of the tokens that come from the predefines buffer.  Those
   // should not be emitted into the output and are guaranteed to be at the
index 4ffb2978db7a334203b192f0ebe2a9442312e244..954e8e23cac79728c1a0805767df235e774d75b3 100644 (file)
@@ -101,8 +101,7 @@ void clang::RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream *OS) {
 
 
   // Get the first preprocessing token.
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
   Token PPTok;
   PP.Lex(PPTok);
 
index eb8664585f3fd4ede153be194e211beb9a722e5c..417724b7778704d21655e7f7de15617969831fde 100644 (file)
@@ -1098,9 +1098,8 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
   // Ask HeaderInfo if we should enter this #include file.  If not, #including
   // this file will have no effect.
   if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) {
-    if (Callbacks) {
+    if (Callbacks)
       Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
-    }
     return;
   }
 
@@ -1113,10 +1112,7 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
   }
 
   // Finally, if all is good, enter the new file!
-  std::string ErrorStr;
-  if (EnterSourceFile(FID, CurDir, ErrorStr))
-    Diag(FilenameTok, diag::err_pp_error_opening_file)
-      << std::string(SourceMgr.getFileEntryForID(FID)->getName()) << ErrorStr;
+  EnterSourceFile(FID, CurDir, FilenameTok.getLocation());
 }
 
 /// HandleIncludeNextDirective - Implements #include_next.
index 335d3db627dd398fbcb97aef39120b7b807c1efe..4a404059926305146915b18f96730c975eb60384 100644 (file)
@@ -64,8 +64,8 @@ PreprocessorLexer *Preprocessor::getCurrentFileLexer() const {
 
 /// EnterSourceFile - Add a source file to the top of the include stack and
 /// start lexing tokens from it instead of the current buffer.
-bool Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
-                                   std::string &ErrorStr) {
+void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
+                                   SourceLocation Loc) {
   assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!");
   ++NumEnteredSourceFiles;
 
@@ -75,19 +75,23 @@ bool Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
   if (PTH) {
     if (PTHLexer *PL = PTH->CreateLexer(FID)) {
       EnterSourceFileWithPTH(PL, CurDir);
-      return false;
+      return;
     }
   }
   
   // Get the MemoryBuffer for this FID, if it fails, we fail.
   bool Invalid = false;
-  const llvm::MemoryBuffer *InputFile = getSourceManager().getBuffer(FID,
-                                                                     &Invalid);
-  if (Invalid)
-    return true;
+  const llvm::MemoryBuffer *InputFile = 
+    getSourceManager().getBuffer(FID, Loc, &Invalid);
+  if (Invalid) {
+    SourceLocation FileStart = SourceMgr.getLocForStartOfFile(FID);
+    Diag(Loc, diag::err_pp_error_opening_file)
+      << std::string(SourceMgr.getBufferName(FileStart)) << "";
+    return;
+  }
   
   EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir);
-  return false;
+  return;
 }
 
 /// EnterSourceFileWithLexer - Add a source file to the top of the include stack
index 4598383c1c93554824770d3984c98aa8eec59587..ce6d9ab5c0539ca2384525a4e2ba4ebd81978c05 100644 (file)
@@ -490,7 +490,7 @@ SourceLocation Preprocessor::getLocForEndOfToken(SourceLocation Loc,
 
 /// EnterMainSourceFile - Enter the specified FileID as the main source file,
 /// which implicitly adds the builtin defines etc.
-bool Preprocessor::EnterMainSourceFile() {
+void Preprocessor::EnterMainSourceFile() {
   // We do not allow the preprocessor to reenter the main file.  Doing so will
   // cause FileID's to accumulate information from both runs (e.g. #line
   // information) and predefined macros aren't guaranteed to be set properly.
@@ -498,9 +498,7 @@ bool Preprocessor::EnterMainSourceFile() {
   FileID MainFileID = SourceMgr.getMainFileID();
 
   // Enter the main file source buffer.
-  std::string ErrorStr;
-  if (EnterSourceFile(MainFileID, 0, ErrorStr))
-    return true;
+  EnterSourceFile(MainFileID, 0, SourceLocation());
 
   // Tell the header info that the main file was entered.  If the file is later
   // #imported, it won't be re-entered.
@@ -515,7 +513,7 @@ bool Preprocessor::EnterMainSourceFile() {
   assert(!FID.isInvalid() && "Could not create FileID for predefines?");
 
   // Start parsing the predefines.
-  return EnterSourceFile(FID, 0, ErrorStr);
+  EnterSourceFile(FID, 0, SourceLocation());
 }
 
 void Preprocessor::EndSourceFile() {
index f620927a8dd6b8a90b85e58adad7fc946a146d87..bb0bd9e1cb5e1136af52625c11a9d2179891e7a4 100644 (file)
@@ -64,8 +64,7 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
 
   Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
   Parser P(PP, S);
-  if (PP.EnterMainSourceFile())
-    return;
+  PP.EnterMainSourceFile();
 
   // Initialize the parser.
   P.Initialize();
index 7c14e3932be074e1403485ff9b46cf56b64a7327..2b313e49fd2deb477f06bbc4629bbb9f87fe9ec2 100644 (file)
@@ -1,4 +1,6 @@
-// RUN: not %clang -xc %s.txt -fsyntax-only 2>&1 | grep 'UTF-16 (LE) byte order mark detected'
+// RUN: not %clang %s -fsyntax-only -verify
 // rdar://7876588
 
-// This test verifies that clang gives a decent error for UTF-16 source files.
\ No newline at end of file
+// This test verifies that clang gives a decent error for UTF-16 source files.
+
+#include "utf-16.c.txt" // expected-error {{UTF-16 (LE) byte order mark detected}}