aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-01-17 06:22:33 +0000
committerChris Lattner <sabre@nondot.org>2009-01-17 06:22:33 +0000
commit2b2453a7d8fe732561795431f39ceb2b2a832d84 (patch)
treead3d68197002f997b30e6617e41e290eff963b03 /lib
parent05816591ec488a933dfecc9ff9f3cbf3c32767c2 (diff)
this massive patch introduces a simple new abstraction: it makes
"FileID" a concept that is now enforced by the compiler's type checker instead of yet-another-random-unsigned floating around. This is an important distinction from the "FileID" currently tracked by SourceLocation. *That* FileID may refer to the start of a file or to a chunk within it. The new FileID *only* refers to the file (and its #include stack and eventually #line data), it cannot refer to a chunk. FileID is a completely opaque datatype to all clients, only SourceManager is allowed to poke and prod it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62407 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Basic/SourceLocation.cpp2
-rw-r--r--lib/Basic/SourceManager.cpp61
-rw-r--r--lib/Driver/HTMLDiagnostics.cpp92
-rw-r--r--lib/Driver/PlistDiagnostics.cpp29
-rw-r--r--lib/Lex/Lexer.cpp24
-rw-r--r--lib/Lex/PPDirectives.cpp12
-rw-r--r--lib/Lex/PPLexerChange.cpp15
-rw-r--r--lib/Lex/PTHLexer.cpp63
-rw-r--r--lib/Lex/Pragma.cpp10
-rw-r--r--lib/Lex/Preprocessor.cpp21
-rw-r--r--lib/Lex/PreprocessorLexer.cpp14
-rw-r--r--lib/Lex/ScratchBuffer.cpp6
-rw-r--r--lib/Lex/TokenLexer.cpp3
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp50
-rw-r--r--lib/Rewrite/Rewriter.cpp44
-rw-r--r--lib/Rewrite/TokenRewriter.cpp6
16 files changed, 225 insertions, 227 deletions
diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
index 2b7584efda..84fac86a6d 100644
--- a/lib/Basic/SourceLocation.cpp
+++ b/lib/Basic/SourceLocation.cpp
@@ -105,7 +105,7 @@ const char *FullSourceLoc::getCharacterData() const {
const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const {
assert(isValid());
- return SrcMgr->getBuffer(getFileID());
+ return SrcMgr->getBuffer(*this);
}
void FullSourceLoc::dump() const {
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 1240262007..b6c4ffab4d 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -111,7 +111,7 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
/// createFileID - Create a new fileID for the specified ContentCache and
/// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.
-unsigned SourceManager::createFileID(const ContentCache *File,
+FileID SourceManager::createFileID(const ContentCache *File,
SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter) {
// If FileEnt is really large (e.g. it's a large .i file), we may not be able
@@ -123,7 +123,7 @@ unsigned SourceManager::createFileID(const ContentCache *File,
FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter));
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
"Ran out of file ID's!");
- return FileIDs.size();
+ return FileID::Create(FileIDs.size());
}
// Create one FileID for each chunk of the file.
@@ -140,7 +140,7 @@ unsigned SourceManager::createFileID(const ContentCache *File,
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
"Ran out of file ID's!");
- return Result;
+ return FileID::Create(Result);
}
/// getInstantiationLoc - Return a new SourceLocation that encodes the fact
@@ -181,13 +181,20 @@ SourceLocation SourceManager::getInstantiationLoc(SourceLocation SpellingLoc,
}
/// getBufferData - Return a pointer to the start and end of the character
-/// data for the specified FileID.
+/// data for the specified location.
std::pair<const char*, const char*>
-SourceManager::getBufferData(unsigned FileID) const {
- const llvm::MemoryBuffer *Buf = getBuffer(FileID);
+SourceManager::getBufferData(SourceLocation Loc) const {
+ const llvm::MemoryBuffer *Buf = getBuffer(Loc);
return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
}
+std::pair<const char*, const char*>
+SourceManager::getBufferData(FileID FID) const {
+ const llvm::MemoryBuffer *Buf = getBuffer(FID);
+ return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
+}
+
+
/// getCharacterData - Return a pointer to the start of the specified location
/// in the appropriate MemoryBuffer.
@@ -196,9 +203,11 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const {
// heavily used by -E mode.
SL = getSpellingLoc(SL);
+ std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(SL);
+
// Note that calling 'getBuffer()' may lazily page in a source file.
- return getContentCache(SL.getFileID())->getBuffer()->getBufferStart() +
- getFullFilePos(SL);
+ return getContentCache(LocInfo.first)->getBuffer()->getBufferStart() +
+ LocInfo.second;
}
@@ -206,12 +215,12 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const {
/// this is significantly cheaper to compute than the line number. This returns
/// zero if the column number isn't known.
unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
- unsigned FileID = Loc.getFileID();
- if (FileID == 0) return 0;
+ if (Loc.getFileID() == 0) return 0;
+
+ std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(Loc);
+ unsigned FilePos = LocInfo.second;
- unsigned FilePos = getFullFilePos(Loc);
- const MemoryBuffer *Buffer = getBuffer(FileID);
- const char *Buf = Buffer->getBufferStart();
+ const char *Buf = getBuffer(LocInfo.first)->getBufferStart();
unsigned LineStart = FilePos;
while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
@@ -223,12 +232,11 @@ unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
/// the SourceLocation specifies. This can be modified with #line directives,
/// etc.
const char *SourceManager::getSourceName(SourceLocation Loc) const {
- unsigned FileID = Loc.getFileID();
- if (FileID == 0) return "";
+ if (Loc.getFileID() == 0) return "";
// 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 SrcMgr::ContentCache* C = getContentCache(FileID);
+ const SrcMgr::ContentCache *C = getContentCacheForLoc(Loc);
return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
}
@@ -282,15 +290,16 @@ static void ComputeLineNumbers(ContentCache* FI) {
/// line offsets for the MemoryBuffer, so this is not cheap: use only when
/// about to emit a diagnostic.
unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
- unsigned FileID = Loc.getFileID();
- if (FileID == 0) return 0;
+ if (Loc.getFileID() == 0) return 0;
- ContentCache* Content;
+ ContentCache *Content;
+
+ std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(Loc);
- if (LastLineNoFileIDQuery == FileID)
+ if (LastLineNoFileIDQuery == LocInfo.first)
Content = LastLineNoContentCache;
else
- Content = const_cast<ContentCache*>(getContentCache(FileID));
+ Content = const_cast<ContentCache*>(getContentCache(LocInfo.first));
// If this is the first use of line information for this buffer, compute the
/// SourceLineCache for it on demand.
@@ -303,12 +312,12 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
unsigned *SourceLineCacheStart = SourceLineCache;
unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
- unsigned QueriedFilePos = getFullFilePos(Loc)+1;
+ unsigned QueriedFilePos = LocInfo.second+1;
// If the previous query was to the same file, we know both the file pos from
// that query and the line number returned. This allows us to narrow the
// search space from the entire file to something near the match.
- if (LastLineNoFileIDQuery == FileID) {
+ if (LastLineNoFileIDQuery == LocInfo.first) {
if (QueriedFilePos >= LastLineNoFilePos) {
SourceLineCache = SourceLineCache+LastLineNoResult-1;
@@ -362,7 +371,7 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
= std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
unsigned LineNo = Pos-SourceLineCacheStart;
- LastLineNoFileIDQuery = FileID;
+ LastLineNoFileIDQuery = LocInfo.first;
LastLineNoContentCache = Content;
LastLineNoFilePos = QueriedFilePos;
LastLineNoResult = LineNo;
@@ -492,7 +501,7 @@ MacroIDInfo MacroIDInfo::ReadVal(llvm::Deserializer& D) {
void SourceManager::Emit(llvm::Serializer& S) const {
S.EnterBlock();
S.EmitPtr(this);
- S.EmitInt(MainFileID);
+ S.EmitInt(MainFileID.getOpaqueValue());
// Emit: FileInfos. Just emit the file name.
S.EnterBlock();
@@ -527,7 +536,7 @@ SourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){
D.RegisterPtr(M);
// Read: the FileID of the main source file of the translation unit.
- M->MainFileID = D.ReadInt();
+ M->MainFileID = FileID::Create(D.ReadInt());
std::vector<char> Buf;
diff --git a/lib/Driver/HTMLDiagnostics.cpp b/lib/Driver/HTMLDiagnostics.cpp
index f335396ec4..81cedba557 100644
--- a/lib/Driver/HTMLDiagnostics.cpp
+++ b/lib/Driver/HTMLDiagnostics.cpp
@@ -49,10 +49,10 @@ public:
virtual void HandlePathDiagnostic(const PathDiagnostic* D);
- void HandlePiece(Rewriter& R, unsigned BugFileID,
+ void HandlePiece(Rewriter& R, FileID BugFileID,
const PathDiagnosticPiece& P, unsigned num, unsigned max);
- void HighlightRange(Rewriter& R, unsigned BugFileID, SourceRange Range);
+ void HighlightRange(Rewriter& R, FileID BugFileID, SourceRange Range);
void ReportDiag(const PathDiagnostic& D);
};
@@ -125,17 +125,15 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
return;
SourceManager &SMgr = D.begin()->getLocation().getManager();
- unsigned FileID = 0;
- bool FileIDInitialized = false;
+ FileID FID;
// Verify that the entire path is from the same FileID.
for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
FullSourceLoc L = I->getLocation().getInstantiationLoc();
- if (!FileIDInitialized) {
- FileID = SMgr.getCanonicalFileID(L);
- FileIDInitialized = true;
- } else if (SMgr.getCanonicalFileID(L) != FileID)
+ if (FID.isInvalid()) {
+ FID = SMgr.getCanonicalFileID(L);
+ } else if (SMgr.getCanonicalFileID(L) != FID)
return; // FIXME: Emit a warning?
// Check the source ranges.
@@ -147,7 +145,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
if (!L.isFileID())
return; // FIXME: Emit a warning?
- if (SMgr.getCanonicalFileID(L) != FileID)
+ if (SMgr.getCanonicalFileID(L) != FID)
return; // FIXME: Emit a warning?
L = SMgr.getInstantiationLoc(RI->getEnd());
@@ -155,12 +153,12 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
if (!L.isFileID())
return; // FIXME: Emit a warning?
- if (SMgr.getCanonicalFileID(L) != FileID)
+ if (SMgr.getCanonicalFileID(L) != FID)
return; // FIXME: Emit a warning?
}
}
- if (!FileIDInitialized)
+ if (FID.isInvalid())
return; // FIXME: Emit a warning?
// Create a new rewriter to generate HTML.
@@ -174,31 +172,31 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
I!=E; ++I, --n) {
- HandlePiece(R, FileID, *I, n, max);
+ HandlePiece(R, FID, *I, n, max);
}
// Add line numbers, header, footer, etc.
- // unsigned FileID = R.getSourceMgr().getMainFileID();
- html::EscapeText(R, FileID);
- html::AddLineNumbers(R, FileID);
+ // unsigned FID = R.getSourceMgr().getMainFileID();
+ html::EscapeText(R, FID);
+ html::AddLineNumbers(R, FID);
// If we have a preprocessor, relex the file and syntax highlight.
// We might not have a preprocessor if we come from a deserialized AST file,
// for example.
- if (PP) html::SyntaxHighlight(R, FileID, *PP);
+ if (PP) html::SyntaxHighlight(R, FID, *PP);
// FIXME: We eventually want to use PPF to create a fresh Preprocessor,
// once we have worked out the bugs.
//
- // if (PPF) html::HighlightMacros(R, FileID, *PPF);
+ // if (PPF) html::HighlightMacros(R, FID, *PPF);
//
- if (PP) html::HighlightMacros(R, FileID, *PP);
+ if (PP) html::HighlightMacros(R, FID, *PP);
// Get the full directory name of the analyzed file.
- const FileEntry* Entry = SMgr.getFileEntryForID(FileID);
+ const FileEntry* Entry = SMgr.getFileEntryForID(FID);
// This is a cludge; basically we want to append either the full
// working directory if we have no directory information. This is
@@ -241,7 +239,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n"
"<h3>Annotated Source Code</h3>\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+ R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
}
// Embed meta-data tags.
@@ -252,7 +250,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
std::string s;
llvm::raw_string_ostream os(s);
os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+ R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
}
const std::string& BugCategory = D.getCategory();
@@ -261,14 +259,14 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
std::string s;
llvm::raw_string_ostream os(s);
os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+ R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
}
{
std::string s;
llvm::raw_string_ostream os(s);
os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+ R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
}
{
@@ -276,22 +274,22 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
llvm::raw_string_ostream os(s);
os << "\n<!-- BUGLINE "
<< D.back()->getLocation().getInstantiationLineNumber() << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+ R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
}
{
std::string s;
llvm::raw_string_ostream os(s);
os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str());
+ R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
}
// Add CSS, header, and footer.
- html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName());
+ html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
// Get the rewrite buffer.
- const RewriteBuffer *Buf = R.getRewriteBufferFor(FileID);
+ const RewriteBuffer *Buf = R.getRewriteBufferFor(FID);
if (!Buf) {
llvm::cerr << "warning: no diagnostics generated for main file.\n";
@@ -325,28 +323,26 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
os << *I;
}
-void HTMLDiagnostics::HandlePiece(Rewriter& R, unsigned BugFileID,
+void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
const PathDiagnosticPiece& P,
unsigned num, unsigned max) {
// For now, just draw a box above the line in question, and emit the
// warning.
-
FullSourceLoc Pos = P.getLocation();
if (!Pos.isValid())
return;
- SourceManager& SM = R.getSourceMgr();
+ SourceManager &SM = R.getSourceMgr();
FullSourceLoc LPos = Pos.getInstantiationLoc();
- unsigned FileID = SM.getCanonicalFileID(LPos);
-
- assert (&LPos.getManager() == &SM && "SourceManagers are different!");
+ FileID FID = SM.getCanonicalFileID(LPos);
+ assert(&LPos.getManager() == &SM && "SourceManagers are different!");
if (SM.getCanonicalFileID(LPos) != BugFileID)
return;
- const llvm::MemoryBuffer *Buf = SM.getBuffer(FileID);
+ const llvm::MemoryBuffer *Buf = SM.getBuffer(FID);
const char* FileStart = Buf->getBufferStart();
// Compute the column number. Rewind from the current position to the start
@@ -436,30 +432,30 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, unsigned BugFileID,
os << html::EscapeText(Msg) << "</div></td></tr>";
// Insert the new html.
- unsigned DisplayPos = 0;
-
+ unsigned DisplayPos;
switch (P.getDisplayHint()) {
- case PathDiagnosticPiece::Above:
- DisplayPos = LineStart - FileStart;
- break;
- case PathDiagnosticPiece::Below:
- DisplayPos = LineEnd - FileStart;
- break;
- default:
- assert (false && "Unhandled hint.");
+ default: assert(0 && "Unhandled hint.");
+ case PathDiagnosticPiece::Above:
+ DisplayPos = LineStart - FileStart;
+ break;
+ case PathDiagnosticPiece::Below:
+ DisplayPos = LineEnd - FileStart;
+ break;
}
-
- R.InsertStrBefore(SourceLocation::getFileLoc(FileID, DisplayPos), os.str());
+
+ SourceLocation Loc =
+ SM.getLocForStartOfFile(FID).getFileLocWithOffset(DisplayPos);
+ R.InsertStrBefore(Loc, os.str());
}
// Now highlight the ranges.
for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
I != E; ++I)
- HighlightRange(R, FileID, *I);
+ HighlightRange(R, FID, *I);
}
-void HTMLDiagnostics::HighlightRange(Rewriter& R, unsigned BugFileID,
+void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
SourceRange Range) {
SourceManager& SM = R.getSourceMgr();
diff --git a/lib/Driver/PlistDiagnostics.cpp b/lib/Driver/PlistDiagnostics.cpp
index 14280288cd..0b2ca52f11 100644
--- a/lib/Driver/PlistDiagnostics.cpp
+++ b/lib/Driver/PlistDiagnostics.cpp
@@ -20,9 +20,9 @@
#include "llvm/System/Path.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-
using namespace clang;
-typedef llvm::DenseMap<unsigned,unsigned> FIDMap;
+
+typedef llvm::DenseMap<FileID, unsigned> FIDMap;
namespace clang {
class Preprocessor;
@@ -51,27 +51,28 @@ clang::CreatePlistDiagnosticClient(const std::string& s,
return new PlistDiagnostics(s);
}
-static void AddFID(FIDMap& FIDs,
- llvm::SmallVectorImpl<unsigned>& V,
+static void AddFID(FIDMap &FIDs,
+ llvm::SmallVectorImpl<FileID> &V,
SourceManager& SM, SourceLocation L) {
- unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
- FIDMap::iterator I = FIDs.find(fid);
+ FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
+ FIDMap::iterator I = FIDs.find(FID);
if (I != FIDs.end()) return;
- FIDs[fid] = V.size();
- V.push_back(fid);
+ FIDs[FID] = V.size();
+ V.push_back(FID);
}
static unsigned GetFID(const FIDMap& FIDs,
SourceManager& SM, SourceLocation L) {
- unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
- FIDMap::const_iterator I = FIDs.find(fid);
- assert (I != FIDs.end());
+ FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
+ FIDMap::const_iterator I = FIDs.find(FID);
+ assert(I != FIDs.end());
return I->second;
}
static llvm::raw_ostream& Indent(llvm::raw_ostream& o, const unsigned indent) {
- for (unsigned i = 0; i < indent; ++i) o << ' ';
+ for (unsigned i = 0; i < indent; ++i)
+ o << ' ';
return o;
}
@@ -171,7 +172,7 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
// Build up a set of FIDs that we use by scanning the locations and
// ranges of the diagnostics.
FIDMap FM;
- llvm::SmallVector<unsigned, 10> Fids;
+ llvm::SmallVector<FileID, 10> Fids;
for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I) {
AddFID(FM, Fids, SM, I->getLocation());
@@ -214,7 +215,7 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
" <key>files</key>\n"
" <array>\n";
- for (llvm::SmallVectorImpl<unsigned>::iterator I=Fids.begin(), E=Fids.end();
+ for (llvm::SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
I!=E; ++I)
o << " <string>" << SM.getFileEntryForID(*I)->getName() << "</string>\n";
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 5a14c1356a..d63c8cc37b 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -62,14 +62,18 @@ tok::ObjCKeywordKind Token::getObjCKeywordID() const {
/// with the specified preprocessor managing the lexing process. This lexer
/// assumes that the associated file buffer and Preprocessor objects will
/// outlive it, so it doesn't take ownership of either of them.
-Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp,
+Lexer::Lexer(SourceLocation fileloc, Preprocessor &PP,
const char *BufStart, const char *BufEnd)
- : PreprocessorLexer(&pp, fileloc), FileLoc(fileloc),
- Features(pp.getLangOptions()) {
+// FIXME: This is really horrible and only needed for _Pragma lexers, split this
+// out of the main lexer path!
+ : PreprocessorLexer(&PP,
+ PP.getSourceManager().getCanonicalFileID(
+ PP.getSourceManager().getSpellingLoc(fileloc))),
+ FileLoc(fileloc),
+ Features(PP.getLangOptions()) {
- SourceManager &SourceMgr = PP->getSourceManager();
- unsigned InputFileID = SourceMgr.getSpellingLoc(FileLoc).getFileID();
- const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(InputFileID);
+ SourceManager &SourceMgr = PP.getSourceManager();
+ const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(getFileID());
Is_PragmaLexer = false;
InitCharacterInfo();
@@ -103,7 +107,7 @@ Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp,
// Default to keeping comments if the preprocessor wants them.
ExtendedTokenMode = 0;
- SetCommentRetentionState(PP->getCommentRetentionState());
+ SetCommentRetentionState(PP.getCommentRetentionState());
}
/// Lexer constructor - Create a new raw lexer object. This object is only
@@ -187,9 +191,7 @@ unsigned Lexer::MeasureTokenLength(SourceLocation Loc,
// all obviously single-char tokens. This could use
// Lexer::isObviouslySimpleCharacter for example to handle identifiers or
// something.
-
-
- const char *BufEnd = SM.getBufferData(Loc.getFileID()).second;
+ const char *BufEnd = SM.getBufferData(Loc).second;
// Create a langops struct and enable trigraphs. This is sufficient for
// measuring tokens.
@@ -303,6 +305,8 @@ SourceLocation Lexer::getSourceLocation(const char *Loc) const {
if (FileLoc.isFileID())
return SourceLocation::getFileLoc(FileLoc.getFileID(), CharNo);
+ // Otherwise, this is the _Pragma lexer case, which pretends that all of the
+ // tokens are lexed from where the _Pragma was defined.
assert(PP && "This doesn't work on raw lexers");
return GetMappedTokenLoc(*PP, FileLoc, CharNo);
}
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 0566ec54b0..f7551a2532 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -394,8 +394,8 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart,
// info about where the current file is.
const FileEntry *CurFileEnt = 0;
if (!FromDir) {
- unsigned FileID = getCurrentFileLexer()->getFileID();
- CurFileEnt = SourceMgr.getFileEntryForID(FileID);
+ FileID FID = getCurrentFileLexer()->getFileID();
+ CurFileEnt = SourceMgr.getFileEntryForID(FID);
}
// Do a standard file entry lookup.
@@ -786,16 +786,16 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
SourceMgr.getFileCharacteristic(getCurrentFileLexer()->getFileID()));
// Look up the file, create a File ID for it.
- unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
- FileCharacter);
- if (FileID == 0) {
+ FileID FID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
+ FileCharacter);
+ if (FID.isInvalid()) {
Diag(FilenameTok, diag::err_pp_file_not_found)
<< std::string(FilenameStart, FilenameEnd);
return;
}
// Finally, if all is good, enter the new file!
- EnterSourceFile(FileID, CurDir);
+ EnterSourceFile(FID, CurDir);
}
/// HandleIncludeNextDirective - Implements #include_next.
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 0ecca3a8cc..cc8ccc4c10 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -66,8 +66,7 @@ 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. Return true
/// on failure.
-void Preprocessor::EnterSourceFile(unsigned FileID,
- const DirectoryLookup *CurDir) {
+void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir) {
assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!");
++NumEnteredSourceFiles;
@@ -75,8 +74,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
MaxIncludeStackDepth = IncludeMacroStack.size();
if (PTH) {
- PTHLexer* PL =
- PTH->CreateLexer(FileID, getSourceManager().getFileEntryForID(FileID));
+ PTHLexer *PL = PTH->CreateLexer(FID, SourceMgr.getFileEntryForID(FID));
if (PL) {
EnterSourceFileWithPTH(PL, CurDir);
@@ -84,7 +82,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
}
}
- Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this);
+ Lexer *TheLexer = new Lexer(SourceMgr.getLocForStartOfFile(FID), *this);
EnterSourceFileWithLexer(TheLexer, CurDir);
}
@@ -125,10 +123,9 @@ void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL,
// Notify the client, if desired, that we are in a new source file.
if (Callbacks) {
- unsigned FileID = CurPPLexer->getFileID();
- SrcMgr::CharacteristicKind FileType =
- SourceMgr.getFileCharacteristic(CurPPLexer->getFileID());
- Callbacks->FileChanged(SourceLocation::getFileLoc(FileID, 0),
+ FileID FID = CurPPLexer->getFileID();
+ SrcMgr::CharacteristicKind FileType = SourceMgr.getFileCharacteristic(FID);
+ Callbacks->FileChanged(SourceMgr.getLocForStartOfFile(FID),
PPCallbacks::EnterFile, FileType);
}
}
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index 6401b9ac8f..b2870f46fd 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -23,7 +23,6 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/OwningPtr.h"
-
using namespace clang;
#define DISK_TOKEN_SIZE (1+1+3+4+2)
@@ -48,15 +47,14 @@ static inline uint32_t Read32(const char*& data) {
// PTHLexer methods.
//===----------------------------------------------------------------------===//
-PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D,
- const char* ppcond,
- PTHSpellingSearch& mySpellingSrch,
- PTHManager& PM)
- : PreprocessorLexer(&pp, fileloc), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
+PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const char *D,
+ const char *ppcond,
+ PTHSpellingSearch &mySpellingSrch, PTHManager &PM)
+ : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
PPCond(ppcond), CurPPCondPtr(ppcond), MySpellingSrch(mySpellingSrch),
- PTHMgr(PM)
-{
- FileID = fileloc.getFileID();
+ PTHMgr(PM) {
+
+ FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID);
}
void PTHLexer::Lex(Token& Tok) {
@@ -96,7 +94,7 @@ LexNextToken:
Tok.setFlag(flags);
assert(!LexingRawMode);
Tok.setIdentifierInfo(perID ? PTHMgr.GetIdentifierInfo(perID-1) : 0);
- Tok.setLocation(SourceLocation::getFileLoc(FileID, FileOffset));
+ Tok.setLocation(FileStartLoc.getFileLocWithOffset(FileOffset));
Tok.setLength(Len);
//===--------------------------------------==//
@@ -295,23 +293,27 @@ SourceLocation PTHLexer::getSourceLocation() {
| (((uint32_t) ((uint8_t) p[1])) << 8)
| (((uint32_t) ((uint8_t) p[2])) << 16)
| (((uint32_t) ((uint8_t) p[3])) << 24);
- return SourceLocation::getFileLoc(FileID, offset);
+ return FileStartLoc.getFileLocWithOffset(offset);
}
//===----------------------------------------------------------------------===//
// getSpelling() - Use cached data in PTH files for getSpelling().
//===----------------------------------------------------------------------===//
-unsigned PTHManager::getSpelling(unsigned FileID, unsigned fpos,
- const char *& Buffer) {
-
- llvm::DenseMap<unsigned,PTHSpellingSearch*>::iterator I =
- SpellingMap.find(FileID);
+unsigned PTHManager::getSpelling(FileID FID, unsigned FPos,
+ const char *&Buffer) {
+ llvm::DenseMap<FileID, PTHSpellingSearch*>::iterator I =SpellingMap.find(FID);
if (I == SpellingMap.end())
return 0;
- return I->second->getSpellingBinarySearch(fpos, Buffer);
+ return I->second->getSpellingBinarySearch(FPos, Buffer);
+}
+
+unsigned PTHManager::getSpelling(SourceLocation Loc, const char *&Buffer) {
+ std::pair<FileID, unsigned> LocInfo =
+ PP->getSourceManager().getDecomposedFileLoc(Loc);
+ return getSpelling(LocInfo.first, LocInfo.second, Buffer);
}
unsigned PTHManager::getSpellingAtPTHOffset(unsigned PTHOffset,
@@ -420,14 +422,17 @@ unsigned PTHSpellingSearch::getSpellingBinarySearch(unsigned fpos,
return 0;
}
-unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) {
- SourceManager& SM = PP->getSourceManager();
- sloc = SM.getSpellingLoc(sloc);
- unsigned fid = SM.getCanonicalFileID(sloc);
- unsigned fpos = SM.getFullFilePos(sloc);
+unsigned PTHLexer::getSpelling(SourceLocation Loc, const char *&Buffer) {
+ SourceManager &SM = PP->getSourceManager();
+ Loc = SM.getSpellingLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedFileLoc(Loc);
+
+ FileID FID = LocInfo.first;
+ unsigned FPos = LocInfo.second;
- return (fid == FileID ) ? MySpellingSrch.getSpellingLinearSearch(fpos, Buffer)
- : PTHMgr.getSpelling(fid, fpos, Buffer);
+ if (FID == getFileID())
+ return MySpellingSrch.getSpellingLinearSearch(FPos, Buffer);
+ return PTHMgr.getSpelling(FID, FPos, Buffer);
}
//===----------------------------------------------------------------------===//
@@ -662,15 +667,14 @@ IdentifierInfo* PTHManager::get(const char *NameStart, const char *NameEnd) {
}
-PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
-
+PTHLexer* PTHManager::CreateLexer(FileID FID, const FileEntry* FE) {
if (!FE)
return 0;
// Lookup the FileEntry object in our file lookup data structure. It will
// return a variant that indicates whether or not there is an offset within
// the PTH file that contains cached tokens.
- PTHFileLookup::Val FileData = ((PTHFileLookup*) FileLookup)->Lookup(FE);
+ PTHFileLookup::Val FileData = ((PTHFileLookup*)FileLookup)->Lookup(FE);
if (!FileData.isValid()) // No tokens available.
return 0;
@@ -694,9 +698,8 @@ PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
// Create the SpellingSearch object for this FileID.
PTHSpellingSearch* ss = new PTHSpellingSearch(*this, len, spellingTable);
- SpellingMap[FileID] = ss;
+ SpellingMap[FID] = ss;
assert(PP && "No preprocessor set yet!");
- return new PTHLexer(*PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
- *ss, *this);
+ return new PTHLexer(*PP, FID, data, ppcond, *ss, *this);
}
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 667e4361a8..860301650b 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -191,10 +191,8 @@ void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
}
// Get the current file lexer we're looking at. Ignore _Pragma 'files' etc.
- unsigned FileID = getCurrentFileLexer()->getFileID();
-
// Mark the file as a once-only file now.
- HeaderInfo.MarkFileIncludeOnce(SourceMgr.getFileEntryForID(FileID));
+ HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
}
void Preprocessor::HandlePragmaMark() {
@@ -256,8 +254,7 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
PreprocessorLexer *TheLexer = getCurrentFileLexer();