[cfe-commits] r68963 - in /cfe/trunk: include/clang/Basic/SourceManager.h include/clang/Basic/SourceManagerInternals.h include/clang/Frontend/PCHBitCodes.h lib/Basic/SourceManager.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp test/PCH/line-directive.c test/PCH/line-directive.h test/PCH/variables.c

Douglas Gregor dgregor at apple.com
Mon Apr 13 09:31:15 PDT 2009


Author: dgregor
Date: Mon Apr 13 11:31:14 2009
New Revision: 68963

URL: http://llvm.org/viewvc/llvm-project?rev=68963&view=rev
Log:
Include the SourceManager's line table in the PCH file. We can now
properly cope with #line directives in PCH files.


Added:
    cfe/trunk/test/PCH/line-directive.c   (with props)
    cfe/trunk/test/PCH/line-directive.h   (with props)
Modified:
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/include/clang/Basic/SourceManagerInternals.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/lib/Basic/SourceManager.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/test/PCH/variables.c

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

==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Mon Apr 13 11:31:14 2009
@@ -589,7 +589,13 @@
   void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
                    bool IsFileEntry, bool IsFileExit, 
                    bool IsSystemHeader, bool IsExternCHeader);
-  
+
+  /// \brief Determine if the source manager has a line table.
+  bool hasLineTable() const { return LineTable != 0; }
+
+  /// \brief Retrieve the stored line table.
+  LineTableInfo &getLineTable();
+
   //===--------------------------------------------------------------------===//
   // Other miscellaneous methods.
   //===--------------------------------------------------------------------===//
@@ -624,6 +630,11 @@
 
   unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
 
+  const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
+    assert(FID.ID < SLocEntryTable.size() && "Invalid id");
+    return SLocEntryTable[FID.ID];
+  }
+
 private:
   friend class SrcMgr::ContentCache; // Used for deserialization.
   
@@ -654,11 +665,6 @@
   ///  memory buffer.
   const SrcMgr::ContentCache* 
   createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
-
-  const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
-    assert(FID.ID < SLocEntryTable.size() && "Invalid id");
-    return SLocEntryTable[FID.ID];
-  }
   
   FileID getFileIDSlow(unsigned SLocOffset) const;
 

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

==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManagerInternals.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManagerInternals.h Mon Apr 13 11:31:14 2009
@@ -102,7 +102,8 @@
     assert(ID < FilenamesByID.size() && "Invalid FilenameID");
     return FilenamesByID[ID]->getKeyData();
   }
-  
+  unsigned getNumFilenames() const { return FilenamesByID.size(); }
+
   void AddLineNote(unsigned FID, unsigned Offset,
                    unsigned LineNo, int FilenameID);
   void AddLineNote(unsigned FID, unsigned Offset,
@@ -113,6 +114,15 @@
   /// FindNearestLineEntry - Find the line entry nearest to FID that is before
   /// it.  If there is no line entry before Offset in FID, return null.
   const LineEntry *FindNearestLineEntry(unsigned FID, unsigned Offset);
+
+  // Low-level access
+  typedef std::map<unsigned, std::vector<LineEntry> >::iterator iterator;
+  iterator begin() { return LineEntries.begin(); }
+  iterator end() { return LineEntries.end(); }
+
+  /// \brief Add a new line entry that has already been encoded into
+  /// the internal representation of the line table.
+  void AddEntry(unsigned FID, const std::vector<LineEntry> &Entries);
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=68963&r1=68962&r2=68963&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Mon Apr 13 11:31:14 2009
@@ -147,7 +147,10 @@
       SM_SLOC_BUFFER_BLOB = 3,
       /// \brief Describes a source location entry (SLocEntry) for a
       /// macro instantiation.
-      SM_SLOC_INSTANTIATION_ENTRY = 4
+      SM_SLOC_INSTANTIATION_ENTRY = 4,
+      /// \brief Describes the SourceManager's line table, with
+      /// information about #line directives.
+      SM_LINE_TABLE = 5
     };
     
     /// \brief Record types used within a preprocessor block.

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

==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Mon Apr 13 11:31:14 2009
@@ -157,6 +157,12 @@
   return &*--I;
 }
 
+/// \brief Add a new line entry that has already been encoded into
+/// the internal representation of the line table.
+void LineTableInfo::AddEntry(unsigned FID, 
+                             const std::vector<LineEntry> &Entries) {
+  LineEntries[FID] = Entries;
+}
 
 /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
 /// 
@@ -224,6 +230,11 @@
                          EntryExit, FileKind);
 }
 
+LineTableInfo &SourceManager::getLineTable() {
+  if (LineTable == 0)
+    LineTable = new LineTableInfo();
+  return *LineTable;
+}
 
 //===----------------------------------------------------------------------===//
 // Private 'Create' methods.

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=68963&r1=68962&r2=68963&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Mon Apr 13 11:31:14 2009
@@ -18,6 +18,7 @@
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceManagerInternals.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Bitcode/BitstreamReader.h"
@@ -191,6 +192,50 @@
   return true;
 }
 
+/// \brief Read the line table in the source manager block.
+/// \returns true if ther was an error.
+static bool ParseLineTable(SourceManager &SourceMgr, 
+                           llvm::SmallVectorImpl<uint64_t> &Record) {
+  unsigned Idx = 0;
+  LineTableInfo &LineTable = SourceMgr.getLineTable();
+
+  // Parse the file names
+  for (unsigned I = 0, N = Record[Idx++]; I != N; ++I) {
+    // Extract the file name
+    unsigned FilenameLen = Record[Idx++];
+    std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
+    Idx += FilenameLen;
+    unsigned ID = LineTable.getLineTableFilenameID(Filename.c_str(), 
+                                                   Filename.size());
+    if (ID != I)
+      return Error("Filename ID mismatch in PCH line table");
+  }
+
+  // Parse the line entries
+  std::vector<LineEntry> Entries;
+  while (Idx < Record.size()) {
+    unsigned FID = Record[Idx++];
+
+    // Extract the line entries
+    unsigned NumEntries = Record[Idx++];
+    Entries.clear();
+    Entries.reserve(NumEntries);
+    for (unsigned I = 0; I != NumEntries; ++I) {
+      unsigned FileOffset = Record[Idx++];
+      unsigned LineNo = Record[Idx++];
+      int FilenameID = Record[Idx++];
+      SrcMgr::CharacteristicKind FileKind 
+        = (SrcMgr::CharacteristicKind)Record[Idx++];
+      unsigned IncludeOffset = Record[Idx++];
+      Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
+                                       FileKind, IncludeOffset));
+    }
+    LineTable.AddEntry(FID, Entries);
+  }
+
+  return false;
+}
+
 /// \brief Read the source manager block
 PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
   using namespace SrcMgr;
@@ -242,9 +287,12 @@
       const FileEntry *File 
         = PP.getFileManager().getFile(BlobStart, BlobStart + BlobLen);
       // FIXME: Error recovery if file cannot be found.
-      SourceMgr.createFileID(File,
-                             SourceLocation::getFromRawEncoding(Record[1]),
-                             (CharacteristicKind)Record[2]);
+      FileID ID = SourceMgr.createFileID(File,
+                                SourceLocation::getFromRawEncoding(Record[1]),
+                                         (CharacteristicKind)Record[2]);
+      if (Record[3])
+        const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(ID).getFile())
+          .setHasLineDirectives();
       break;
     }
 
@@ -278,6 +326,10 @@
       break;
     }
 
+    case pch::SM_LINE_TABLE: {
+      if (ParseLineTable(SourceMgr, Record))
+        return Failure;
+    }
     }
   }
 }

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=68963&r1=68962&r2=68963&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Apr 13 11:31:14 2009
@@ -21,6 +21,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceManagerInternals.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
 #include "llvm/Support/Compiler.h"
@@ -503,8 +504,7 @@
       const SrcMgr::FileInfo &File = SLoc->getFile();
       Record.push_back(File.getIncludeLoc().getRawEncoding());
       Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
-      Record.push_back(File.hasLineDirectives()); // FIXME: encode the
-                                                  // line directives?
+      Record.push_back(File.hasLineDirectives());
 
       const SrcMgr::ContentCache *Content = File.getContentCache();
       if (Content->Entry) {
@@ -550,6 +550,42 @@
     Record.clear();
   }
 
+  // Write the line table.
+  if (SourceMgr.hasLineTable()) {
+    LineTableInfo &LineTable = SourceMgr.getLineTable();
+
+    // Emit the file names
+    Record.push_back(LineTable.getNumFilenames());
+    for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
+      // Emit the file name
+      const char *Filename = LineTable.getFilename(I);
+      unsigned FilenameLen = Filename? strlen(Filename) : 0;
+      Record.push_back(FilenameLen);
+      if (FilenameLen)
+        Record.insert(Record.end(), Filename, Filename + FilenameLen);
+    }
+    
+    // Emit the line entries
+    for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
+         L != LEnd; ++L) {
+      // Emit the file ID
+      Record.push_back(L->first);
+      
+      // Emit the line entries
+      Record.push_back(L->second.size());
+      for (std::vector<LineEntry>::iterator LE = L->second.begin(), 
+                                         LEEnd = L->second.end();
+           LE != LEEnd; ++LE) {
+        Record.push_back(LE->FileOffset);
+        Record.push_back(LE->LineNo);
+        Record.push_back(LE->FilenameID);
+        Record.push_back((unsigned)LE->FileKind);
+        Record.push_back(LE->IncludeOffset);
+      }
+      S.EmitRecord(pch::SM_LINE_TABLE, Record);
+    }
+  }
+
   S.ExitBlock();
 }
 

Added: cfe/trunk/test/PCH/line-directive.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/line-directive.c?rev=68963&view=auto

==============================================================================
--- cfe/trunk/test/PCH/line-directive.c (added)
+++ cfe/trunk/test/PCH/line-directive.c Mon Apr 13 11:31:14 2009
@@ -0,0 +1,25 @@
+// Test this without pch.
+// RUN: clang-cc -triple=i686-apple-darwin9 -include %S/line-directive.h -fsyntax-only %s 2>&1|grep "25:5"
+
+// Test with pch.
+// RUN: clang-cc -emit-pch -triple=i686-apple-darwin9 -o %t %S/line-directive.h &&
+// RUN: clang-cc -triple=i686-apple-darwin9 -include-pch %t -fsyntax-only %s 2>&1|grep "25:5"  
+
+double x; // expected-error{{redefinition of 'x' with a different type}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// expected-note{{previous definition is here}}

Propchange: cfe/trunk/test/PCH/line-directive.c

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/PCH/line-directive.c

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/PCH/line-directive.c

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/PCH/line-directive.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/line-directive.h?rev=68963&view=auto

==============================================================================
--- cfe/trunk/test/PCH/line-directive.h (added)
+++ cfe/trunk/test/PCH/line-directive.h Mon Apr 13 11:31:14 2009
@@ -0,0 +1,2 @@
+#line 25 "line-directive.c"
+int x;

Propchange: cfe/trunk/test/PCH/line-directive.h

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/PCH/line-directive.h

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/PCH/line-directive.h

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/test/PCH/variables.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/variables.c?rev=68963&r1=68962&r2=68963&view=diff

==============================================================================
--- cfe/trunk/test/PCH/variables.c (original)
+++ cfe/trunk/test/PCH/variables.c Mon Apr 13 11:31:14 2009
@@ -1,5 +1,5 @@
 // Test this without pch.
-// RUN: clang-cc -triple=i686-apple-darwin9 -include %S/variables.h -fsyntax-only -verify %s &&
+// RUN: clang-cc -triple=i686-apple-darwin9 -include %S/variables.h -fsyntax-only -verify %s
 
 // Test with pch.
 // RUN: clang-cc -emit-pch -triple=i686-apple-darwin9 -o %t %S/variables.h &&





More information about the cfe-commits mailing list