[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