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
This commit is contained in:
Chris Lattner 2009-01-17 06:22:33 +00:00
Родитель 05816591ec
Коммит 2b2453a7d8
34 изменённых файлов: 403 добавлений и 337 удалений

Просмотреть файл

@ -903,10 +903,10 @@ public:
return; return;
SourceManager& SourceMgr = TU.getContext().getSourceManager(); SourceManager& SourceMgr = TU.getContext().getSourceManager();
unsigned ID = SourceMgr.getMainFileID(); FileID ID = SourceMgr.getMainFileID();
assert (ID && "MainFileID not set!"); assert(!ID.isInvalid() && "MainFileID not set!");
const FileEntry* FE = SourceMgr.getFileEntryForID(ID); const FileEntry* FE = SourceMgr.getFileEntryForID(ID);
assert (FE && "No FileEntry for main file."); assert(FE && "No FileEntry for main file.");
// FIXME: This is not portable to Windows. // FIXME: This is not portable to Windows.
// FIXME: This logic should probably be moved elsewhere later. // FIXME: This logic should probably be moved elsewhere later.

Просмотреть файл

@ -485,8 +485,8 @@ void PTHWriter::GeneratePTH() {
const llvm::MemoryBuffer *B = C.getBuffer(); const llvm::MemoryBuffer *B = C.getBuffer();
if (!B) continue; if (!B) continue;
unsigned FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User); FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
Lexer L(SourceLocation::getFileLoc(FID, 0), LOpts, Lexer L(SM.getLocForStartOfFile(FID), LOpts,
B->getBufferStart(), B->getBufferEnd(), B); B->getBufferStart(), B->getBufferEnd(), B);
PM[FE] = LexTokens(L); PM[FE] = LexTokens(L);
} }

Просмотреть файл

@ -117,12 +117,12 @@ static void FindExpectedDiags(Preprocessor &PP,
DiagList &ExpectedNotes) { DiagList &ExpectedNotes) {
// Create a raw lexer to pull all the comments out of the main file. We don't // Create a raw lexer to pull all the comments out of the main file. We don't
// want to look in #include'd headers for expected-error strings. // want to look in #include'd headers for expected-error strings.
unsigned FileID = PP.getSourceManager().getMainFileID(); FileID FID = PP.getSourceManager().getMainFileID();
std::pair<const char*,const char*> File = std::pair<const char*,const char*> File =
PP.getSourceManager().getBufferData(FileID); PP.getSourceManager().getBufferData(FID);
// Create a lexer to lex all the tokens of the main file in raw mode. // Create a lexer to lex all the tokens of the main file in raw mode.
Lexer RawLex(SourceLocation::getFileLoc(FileID, 0), Lexer RawLex(PP.getSourceManager().getLocForStartOfFile(FID),
PP.getLangOptions(), File.first, File.second); PP.getLangOptions(), File.first, File.second);
// Return comments as tokens, this is how we find expected diagnostics. // Return comments as tokens, this is how we find expected diagnostics.

Просмотреть файл

@ -60,19 +60,19 @@ HTMLPrinter::~HTMLPrinter() {
return; return;
// Format the file. // Format the file.
unsigned FileID = R.getSourceMgr().getMainFileID(); FileID FID = R.getSourceMgr().getMainFileID();
const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FileID); const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
html::AddLineNumbers(R, FileID); html::AddLineNumbers(R, FID);
html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName()); html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
// If we have a preprocessor, relex the file and syntax highlight. // 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, // We might not have a preprocessor if we come from a deserialized AST file,
// for example. // for example.
if (PP) html::SyntaxHighlight(R, FileID, *PP); if (PP) html::SyntaxHighlight(R, FID, *PP);
if (PPF) html::HighlightMacros(R, FileID, *PP); if (PPF) html::HighlightMacros(R, FID, *PP);
html::EscapeText(R, FileID, false, true); html::EscapeText(R, FID, false, true);
// Open the output. // Open the output.
FILE *OutputFILE; FILE *OutputFILE;
@ -87,7 +87,7 @@ HTMLPrinter::~HTMLPrinter() {
} }
// Emit the HTML. // Emit the HTML.
const RewriteBuffer &RewriteBuf = R.getEditBuffer(FileID); const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
char *Buffer = (char*)malloc(RewriteBuf.size()); char *Buffer = (char*)malloc(RewriteBuf.size());
std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer); std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
fwrite(Buffer, 1, RewriteBuf.size(), OutputFILE); fwrite(Buffer, 1, RewriteBuf.size(), OutputFILE);

Просмотреть файл

@ -37,7 +37,7 @@ class RewriteBlocks : public ASTConsumer {
ASTContext *Context; ASTContext *Context;
SourceManager *SM; SourceManager *SM;
unsigned MainFileID; FileID MainFileID;
const char *MainFileStart, *MainFileEnd; const char *MainFileStart, *MainFileEnd;
// Block expressions. // Block expressions.
@ -223,7 +223,7 @@ void RewriteBlocks::Initialize(ASTContext &context) {
Preamble += "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n"; Preamble += "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n";
Preamble += "#endif\n"; Preamble += "#endif\n";
InsertText(SourceLocation::getFileLoc(MainFileID, 0), InsertText(SM->getLocForStartOfFile(MainFileID),
Preamble.c_str(), Preamble.size()); Preamble.c_str(), Preamble.size());
} }

Просмотреть файл

@ -65,7 +65,7 @@ static void LexRawTokensFromMainFile(Preprocessor &PP,
// Create a lexer to lex all the tokens of the main file in raw mode. Even // Create a lexer to lex all the tokens of the main file in raw mode. Even
// though it is in raw mode, it will not return comments. // though it is in raw mode, it will not return comments.
Lexer RawLex(SourceLocation::getFileLoc(SM.getMainFileID(), 0), Lexer RawLex(SM.getLocForStartOfFile(SM.getMainFileID()),
PP.getLangOptions(), File.first, File.second); PP.getLangOptions(), File.first, File.second);
// Switch on comment lexing because we really do want them. // Switch on comment lexing because we really do want them.

Просмотреть файл

@ -47,7 +47,7 @@ namespace {
ASTContext *Context; ASTContext *Context;
SourceManager *SM; SourceManager *SM;
TranslationUnitDecl *TUDecl; TranslationUnitDecl *TUDecl;
unsigned MainFileID; FileID MainFileID;
const char *MainFileStart, *MainFileEnd; const char *MainFileStart, *MainFileEnd;
SourceLocation LastIncLoc; SourceLocation LastIncLoc;
@ -597,7 +597,7 @@ void RewriteObjC::HandleTopLevelDecl(Decl *D) {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void RewriteObjC::RewriteInclude() { void RewriteObjC::RewriteInclude() {
SourceLocation LocStart = SourceLocation::getFileLoc(MainFileID, 0); 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);
const char *MainBufStart = MainBuf.first; const char *MainBufStart = MainBuf.first;
const char *MainBufEnd = MainBuf.second; const char *MainBufEnd = MainBuf.second;
@ -645,8 +645,8 @@ void RewriteObjC::RewriteTabs() {
unsigned Spaces = 8-(VCol & 7); unsigned Spaces = 8-(VCol & 7);
// Get the location of the tab. // Get the location of the tab.
SourceLocation TabLoc = SourceLocation TabLoc = SM->getLocForStartOfFile(MainFileID);
SourceLocation::getFileLoc(MainFileID, BufPtr-MainBufStart); TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart);
// Rewrite the single tab character into a sequence of spaces. // Rewrite the single tab character into a sequence of spaces.
ReplaceText(TabLoc, 1, " ", Spaces); ReplaceText(TabLoc, 1, " ", Spaces);
@ -4501,7 +4501,7 @@ void RewriteObjC::HandleTranslationUnit(TranslationUnit& TU) {
RewriteInclude(); RewriteInclude();
InsertText(SourceLocation::getFileLoc(MainFileID, 0), InsertText(SM->getLocForStartOfFile(MainFileID),
Preamble.c_str(), Preamble.size(), false); Preamble.c_str(), Preamble.size(), false);
if (ClassImplementation.size() || CategoryImplementation.size()) if (ClassImplementation.size() || CategoryImplementation.size())

Просмотреть файл

@ -919,14 +919,14 @@ static bool InitializePreprocessor(Preprocessor &PP,
if (InFile != "-") { if (InFile != "-") {
const FileEntry *File = FileMgr.getFile(InFile); const FileEntry *File = FileMgr.getFile(InFile);
if (File) SourceMgr.createMainFileID(File, SourceLocation()); if (File) SourceMgr.createMainFileID(File, SourceLocation());
if (SourceMgr.getMainFileID() == 0) { if (SourceMgr.getMainFileID().isInvalid()) {
fprintf(stderr, "Error reading '%s'!\n",InFile.c_str()); fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
return true; return true;
} }
} else { } else {
llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN(); llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
if (SB) SourceMgr.createMainFileIDForMemBuffer(SB); if (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
if (SourceMgr.getMainFileID() == 0) { if (SourceMgr.getMainFileID().isInvalid()) {
fprintf(stderr, "Error reading standard input! Empty?\n"); fprintf(stderr, "Error reading standard input! Empty?\n");
return true; return true;
} }
@ -1335,7 +1335,7 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
std::pair<const char*,const char*> File = std::pair<const char*,const char*> File =
SM.getBufferData(SM.getMainFileID()); SM.getBufferData(SM.getMainFileID());
// Start lexing the specified input file. // Start lexing the specified input file.
Lexer RawLex(SourceLocation::getFileLoc(SM.getMainFileID(), 0), Lexer RawLex(SM.getLocForStartOfFile(SM.getMainFileID()),
PP.getLangOptions(), File.first, File.second); PP.getLangOptions(), File.first, File.second);
RawLex.SetKeepWhitespaceMode(true); RawLex.SetKeepWhitespaceMode(true);

Просмотреть файл

@ -18,13 +18,46 @@
#include "llvm/Bitcode/SerializationFwd.h" #include "llvm/Bitcode/SerializationFwd.h"
namespace llvm { namespace llvm {
class MemoryBuffer; class MemoryBuffer;
template <typename T> struct DenseMapInfo;
} }
namespace clang { namespace clang {
class SourceManager; class SourceManager;
class FileEntry; class FileEntry;
/// FileID - This is an opaque identifier used by SourceManager which refers to
/// a source file (MemoryBuffer) along with its #include path and #line data.
///
class FileID {
/// ID - Opaque identifier, 0 is "invalid".
unsigned ID;
public:
FileID() : ID(0) {}
bool isInvalid() const { return ID == 0; }
bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
bool operator>(const FileID &RHS) const { return RHS < *this; }
bool operator>=(const FileID &RHS) const { return RHS <= *this; }
static FileID getSentinel() { return Create(~0U); }
unsigned getHashValue() const { return ID; }
private:
friend class SourceManager;
static FileID Create(unsigned V) {
FileID F;
F.ID = V;
return F;
}
unsigned getOpaqueValue() const { return ID; }
};
/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes /// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
/// a full include stack, line and column number information for a position in /// a full include stack, line and column number information for a position in
@ -269,4 +302,29 @@ public:
} // end namespace clang } // end namespace clang
namespace llvm {
/// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
/// DenseSets.
template <>
struct DenseMapInfo<clang::FileID> {
static inline clang::FileID getEmptyKey() {
return clang::FileID();
}
static inline clang::FileID getTombstoneKey() {
return clang::FileID::getSentinel();
}
static unsigned getHashValue(clang::FileID S) {
return S.getHashValue();
}
static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
return LHS == RHS;
}
static bool isPod() { return true; }
};
} // end namespace llvm
#endif #endif

Просмотреть файл

@ -256,47 +256,47 @@ class SourceManager {
/// LastLineNo - These ivars serve as a cache used in the getLineNumber /// LastLineNo - These ivars serve as a cache used in the getLineNumber
/// method which is used to speedup getLineNumber calls to nearby locations. /// method which is used to speedup getLineNumber calls to nearby locations.
mutable unsigned LastLineNoFileIDQuery; mutable FileID LastLineNoFileIDQuery;
mutable SrcMgr::ContentCache *LastLineNoContentCache; mutable SrcMgr::ContentCache *LastLineNoContentCache;
mutable unsigned LastLineNoFilePos; mutable unsigned LastLineNoFilePos;
mutable unsigned LastLineNoResult; mutable unsigned LastLineNoResult;
/// MainFileID - The file ID for the main source file of the translation unit. /// MainFileID - The file ID for the main source file of the translation unit.
unsigned MainFileID; FileID MainFileID;
// SourceManager doesn't support copy construction. // SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&); explicit SourceManager(const SourceManager&);
void operator=(const SourceManager&); void operator=(const SourceManager&);
public: public:
SourceManager() : LastLineNoFileIDQuery(~0U), MainFileID(0) {} SourceManager() {}
~SourceManager() {} ~SourceManager() {}
void clearIDTables() { void clearIDTables() {
MainFileID = 0; MainFileID = FileID();
FileIDs.clear(); FileIDs.clear();
MacroIDs.clear(); MacroIDs.clear();
LastLineNoFileIDQuery = ~0U; LastLineNoFileIDQuery = FileID();
LastLineNoContentCache = 0; LastLineNoContentCache = 0;
} }
/// getMainFileID - Returns the FileID of the main source file. /// getMainFileID - Returns the FileID of the main source file.
unsigned getMainFileID() const { return MainFileID; } FileID getMainFileID() const { return MainFileID; }
/// createFileID - Create a new FileID that represents the specified file /// createFileID - Create a new FileID that represents the specified file
/// being #included from the specified IncludePosition. This returns 0 on /// being #included from the specified IncludePosition. This returns 0 on
/// error and translates NULL into standard input. /// error and translates NULL into standard input.
unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter) { SrcMgr::CharacteristicKind FileCharacter) {
const SrcMgr::ContentCache *IR = getContentCache(SourceFile); const SrcMgr::ContentCache *IR = getContentCache(SourceFile);
if (IR == 0) return 0; // Error opening file? if (IR == 0) return FileID(); // Error opening file?
return createFileID(IR, IncludePos, FileCharacter); return createFileID(IR, IncludePos, FileCharacter);
} }
/// createMainFileID - Create the FileID for the main source file. /// createMainFileID - Create the FileID for the main source file.
unsigned createMainFileID(const FileEntry *SourceFile, FileID createMainFileID(const FileEntry *SourceFile,
SourceLocation IncludePos) { SourceLocation IncludePos) {
assert (MainFileID == 0 && "MainFileID already set!"); assert(MainFileID.isInvalid() && "MainFileID already set!");
MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User); MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
return MainFileID; return MainFileID;
} }
@ -304,7 +304,7 @@ public:
/// createFileIDForMemBuffer - Create a new FileID that represents the /// createFileIDForMemBuffer - Create a new FileID that represents the
/// specified memory buffer. This does no caching of the buffer and takes /// specified memory buffer. This does no caching of the buffer and takes
/// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once. /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
return createFileID(createMemBufferContentCache(Buffer), SourceLocation(), return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
SrcMgr::C_User); SrcMgr::C_User);
} }
@ -312,12 +312,19 @@ public:
/// createMainFileIDForMembuffer - Create the FileID for a memory buffer /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
/// that will represent the FileID for the main source. One example /// that will represent the FileID for the main source. One example
/// of when this would be used is when the main source is read from STDIN. /// of when this would be used is when the main source is read from STDIN.
unsigned createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
assert (MainFileID == 0 && "MainFileID already set!"); assert(MainFileID.isInvalid() && "MainFileID already set!");
MainFileID = createFileIDForMemBuffer(Buffer); MainFileID = createFileIDForMemBuffer(Buffer);
return MainFileID; return MainFileID;
} }
/// getLocForStartOfFile - Return the source location corresponding to the
/// first byte of the specified file.
SourceLocation getLocForStartOfFile(FileID FID) const {
return SourceLocation::getFileLoc(FID.ID, 0);
}
/// getInstantiationLoc - Return a new SourceLocation that encodes the fact /// getInstantiationLoc - Return a new SourceLocation that encodes the fact
/// that a token at Loc should actually be referenced from InstantiationLoc. /// that a token at Loc should actually be referenced from InstantiationLoc.
SourceLocation getInstantiationLoc(SourceLocation Loc, SourceLocation getInstantiationLoc(SourceLocation Loc,
@ -325,13 +332,19 @@ public:
/// getBuffer - Return the buffer for the specified FileID. /// getBuffer - Return the buffer for the specified FileID.
/// ///
const llvm::MemoryBuffer *getBuffer(unsigned FileID) const { const llvm::MemoryBuffer *getBuffer(FileID FID) const {
return getContentCache(FileID)->getBuffer(); return getContentCache(FID)->getBuffer();
} }
const llvm::MemoryBuffer *getBuffer(SourceLocation Loc) const {
return getContentCacheForLoc(Loc)->getBuffer();
}
/// getBufferData - Return a pointer to the start and end of the character /// getBufferData - Return a pointer to the start and end of the character
/// data for the specified FileID. /// data for the specified FileID.
std::pair<const char*, const char*> getBufferData(unsigned FileID) const; std::pair<const char*, const char*> getBufferData(SourceLocation Loc) const;
std::pair<const char*, const char*> getBufferData(FileID FID) const;
/// getIncludeLoc - Return the location of the #include for the specified /// getIncludeLoc - Return the location of the #include for the specified
/// SourceLocation. If this is a macro expansion, this transparently figures /// SourceLocation. If this is a macro expansion, this transparently figures
@ -414,8 +427,8 @@ public:
} }
/// getFileEntryForID - Returns the FileEntry record for the provided FileID. /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
const FileEntry* getFileEntryForID(unsigned id) const { const FileEntry *getFileEntryForID(FileID FID) const {
return getContentCache(id)->Entry; return getContentCache(FID)->Entry;
} }
/// getCanonicalFileID - Return the canonical FileID for a SourceLocation. /// getCanonicalFileID - Return the canonical FileID for a SourceLocation.
@ -423,14 +436,14 @@ public:
/// into multiple chunks. This method returns the unique FileID without /// into multiple chunks. This method returns the unique FileID without
/// chunk information for a given SourceLocation. Use this method when /// chunk information for a given SourceLocation. Use this method when
/// you want to compare FileIDs across SourceLocations. /// you want to compare FileIDs across SourceLocations.
unsigned getCanonicalFileID(SourceLocation SpellingLoc) const { FileID getCanonicalFileID(SourceLocation SpellingLoc) const {
return getDecomposedFileLoc(SpellingLoc).first; return getDecomposedFileLoc(SpellingLoc).first;
} }
/// getDecomposedFileLoc - Decompose the specified file location into a raw /// getDecomposedFileLoc - Decompose the specified file location into a raw
/// FileID + Offset pair. The first element is the FileID, the second is the /// FileID + Offset pair. The first element is the FileID, the second is the
/// offset from the start of the buffer of the location. /// offset from the start of the buffer of the location.
std::pair<unsigned, unsigned> getDecomposedFileLoc(SourceLocation Loc) const { std::pair<FileID, unsigned> getDecomposedFileLoc(SourceLocation Loc) const {
assert(Loc.isFileID() && "Isn't a File SourceLocation"); assert(Loc.isFileID() && "Isn't a File SourceLocation");
// TODO: Add a flag "is first chunk" to SLOC. // TODO: Add a flag "is first chunk" to SLOC.
@ -444,7 +457,7 @@ public:
assert(Loc.getFileID() >= ChunkNo && "Unexpected offset"); assert(Loc.getFileID() >= ChunkNo && "Unexpected offset");
return std::make_pair(Loc.getFileID()-ChunkNo, Offset); return std::make_pair(FileID::Create(Loc.getFileID()-ChunkNo), Offset);
} }
/// getFullFilePos - This (efficient) method returns the offset from the start /// getFullFilePos - This (efficient) method returns the offset from the start
@ -474,8 +487,8 @@ public:
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const { SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const {
return getFIDInfo(getSpellingLoc(Loc).getFileID())->getFileCharacteristic(); return getFIDInfo(getSpellingLoc(Loc).getFileID())->getFileCharacteristic();
} }
SrcMgr::CharacteristicKind getFileCharacteristic(unsigned FileID) const { SrcMgr::CharacteristicKind getFileCharacteristic(FileID FID) const {
return getFIDInfo(FileID)->getFileCharacteristic(); return getFIDInfo(FID)->getFileCharacteristic();
} }
// Iterators over FileInfos. // Iterators over FileInfos.
@ -500,26 +513,29 @@ private:
/// createFileID - Create a new fileID for the specified ContentCache and /// createFileID - Create a new fileID for the specified ContentCache and
/// include position. This works regardless of whether the ContentCache /// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source. /// corresponds to a file or some other input source.
unsigned createFileID(const SrcMgr::ContentCache* File, FileID createFileID(const SrcMgr::ContentCache* File,
SourceLocation IncludePos, SourceLocation IncludePos,
SrcMgr::CharacteristicKind DirCharacter); SrcMgr::CharacteristicKind DirCharacter);
/// getContentCache - Create or return a cached ContentCache for the specified /// getContentCache - Create or return a cached ContentCache for the specified
/// file. This returns null on failure. /// file. This returns null on failure.
const SrcMgr::ContentCache* getContentCache(const FileEntry* SourceFile); const SrcMgr::ContentCache* getContentCache(const FileEntry *SourceFile);
/// createMemBufferContentCache - Create a new ContentCache for the specified /// createMemBufferContentCache - Create a new ContentCache for the specified
/// memory buffer. /// memory buffer.
const SrcMgr::ContentCache* const SrcMgr::ContentCache*
createMemBufferContentCache(const llvm::MemoryBuffer* Buf); createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
const SrcMgr::FileIDInfo* getFIDInfo(unsigned FileID) const { const SrcMgr::FileIDInfo *getFIDInfo(unsigned FID) const {
assert(FileID-1 < FileIDs.size() && "Invalid FileID!"); assert(FID-1 < FileIDs.size() && "Invalid FileID!");
return &FileIDs[FileID-1]; return &FileIDs[FID-1];
}
const SrcMgr::FileIDInfo *getFIDInfo(FileID FID) const {
return getFIDInfo(FID.ID);
} }
const SrcMgr::ContentCache *getContentCache(unsigned FileID) const { const SrcMgr::ContentCache *getContentCache(FileID FID) const {
return getContentCache(getFIDInfo(FileID)); return getContentCache(getFIDInfo(FID.ID));
} }
/// Return the ContentCache structure for the specified FileID. /// Return the ContentCache structure for the specified FileID.

Просмотреть файл

@ -23,9 +23,7 @@ class PTHManager;
class PTHSpellingSearch; class PTHSpellingSearch;
class PTHLexer : public PreprocessorLexer { class PTHLexer : public PreprocessorLexer {
private: SourceLocation FileStartLoc;
/// FileID - The SourceManager FileID for the original source file.
unsigned FileID;
/// TokBuf - Buffer from PTH file containing raw token data. /// TokBuf - Buffer from PTH file containing raw token data.
const char* TokBuf; const char* TokBuf;
@ -66,10 +64,8 @@ protected:
friend class PTHManager; friend class PTHManager;
/// Create a PTHLexer for the specified token stream. /// Create a PTHLexer for the specified token stream.
PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D, PTHLexer(Preprocessor& pp, FileID FID, const char *D, const char* ppcond,
const char* ppcond, PTHSpellingSearch& mySpellingSrch, PTHManager &PM);
PTHSpellingSearch& mySpellingSrch,
PTHManager& PM);
public: public:
~PTHLexer() {} ~PTHLexer() {}

Просмотреть файл

@ -62,7 +62,7 @@ class PTHManager : public IdentifierInfoLookup {
const llvm::MemoryBuffer* Buf; const llvm::MemoryBuffer* Buf;
/// A map from FileIDs to SpellingSearch objects. /// A map from FileIDs to SpellingSearch objects.
llvm::DenseMap<unsigned,PTHSpellingSearch*> SpellingMap; llvm::DenseMap<FileID, PTHSpellingSearch*> SpellingMap;
/// Alloc - Allocator used for IdentifierInfo objects. /// Alloc - Allocator used for IdentifierInfo objects.
llvm::BumpPtrAllocator Alloc; llvm::BumpPtrAllocator Alloc;
@ -117,20 +117,22 @@ public:
/// Unlike the version in IdentifierTable, this returns a pointer instead /// Unlike the version in IdentifierTable, this returns a pointer instead
/// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// of a reference. If the pointer is NULL then the IdentifierInfo cannot
/// be found. /// be found.
IdentifierInfo* get(const char *NameStart, const char *NameEnd); IdentifierInfo *get(const char *NameStart, const char *NameEnd);
/// Create - This method creates PTHManager objects. The 'file' argument /// Create - This method creates PTHManager objects. The 'file' argument
/// is the name of the PTH file. This method returns NULL upon failure. /// is the name of the PTH file. This method returns NULL upon failure.
static PTHManager* Create(const std::string& file); static PTHManager *Create(const std::string& file);
void setPreprocessor(Preprocessor* pp) { PP = pp; } void setPreprocessor(Preprocessor *pp) { PP = pp; }
/// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the
/// specified file. This method returns NULL if no cached tokens exist. /// specified file. This method returns NULL if no cached tokens exist.
/// It is the responsibility of the caller to 'delete' the returned object. /// It is the responsibility of the caller to 'delete' the returned object.
PTHLexer* CreateLexer(unsigned FileID, const FileEntry* FE); PTHLexer *CreateLexer(FileID FID, const FileEntry *FE);
unsigned getSpelling(unsigned FileID, unsigned fpos, const char *& Buffer); unsigned getSpelling(SourceLocation Loc, const char *&Buffer);
private:
unsigned getSpelling(FileID FID, unsigned fpos, const char *& Buffer);
}; };
} // end namespace clang } // end namespace clang

Просмотреть файл

@ -284,7 +284,7 @@ public:
/// EnterSourceFile - Add a source file to the top of the include stack and /// EnterSourceFile - Add a source file to the top of the include stack and
/// start lexing tokens from it instead of the current buffer. If isMainFile /// start lexing tokens from it instead of the current buffer. If isMainFile
/// is true, this is the main file for the translation unit. /// is true, this is the main file for the translation unit.
void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir); void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir);
/// EnterMacro - Add a Macro to the top of the include stack and start lexing /// 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 /// tokens from it instead of the current buffer. Args specifies the
@ -456,10 +456,8 @@ public:
char getSpelledCharacterAt(SourceLocation SL) const { char getSpelledCharacterAt(SourceLocation SL) const {
if (PTH) { if (PTH) {
SL = SourceMgr.getSpellingLoc(SL); SL = SourceMgr.getSpellingLoc(SL);
unsigned FID = SourceMgr.getCanonicalFileID(SL);
unsigned FPos = SourceMgr.getFullFilePos(SL);
const char *Data; const char *Data;
if (PTH->getSpelling(FID, FPos, Data)) if (PTH->getSpelling(SL, Data))
return *Data; return *Data;
} }

Просмотреть файл

@ -27,8 +27,8 @@ class PreprocessorLexer {
protected: protected:
Preprocessor *PP; // Preprocessor object controlling lexing. Preprocessor *PP; // Preprocessor object controlling lexing.
/// The SourceManager fileID corresponding to the file being lexed. /// The SourceManager FileID corresponding to the file being lexed.
const unsigned FileID; const FileID FID;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor. // Context-specific lexing flags set by the preprocessor.
@ -67,15 +67,17 @@ protected:
void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT
friend class Preprocessor; friend class Preprocessor;
PreprocessorLexer(Preprocessor* pp, SourceLocation L); PreprocessorLexer(Preprocessor *pp, FileID fid)
: PP(pp), FID(fid), ParsingPreprocessorDirective(false),
ParsingFilename(false), LexingRawMode(false) {}
PreprocessorLexer() PreprocessorLexer()
: PP(0), FileID(0), : PP(0),
ParsingPreprocessorDirective(false), ParsingPreprocessorDirective(false),
ParsingFilename(false), ParsingFilename(false),
LexingRawMode(false) {} LexingRawMode(false) {}
virtual ~PreprocessorLexer(); virtual ~PreprocessorLexer() {}
virtual void IndirectLex(Token& Result) = 0; virtual void IndirectLex(Token& Result) = 0;
@ -143,11 +145,15 @@ public:
/// getPP - Return the preprocessor object for this lexer. /// getPP - Return the preprocessor object for this lexer.
Preprocessor *getPP() const { return PP; } Preprocessor *getPP() const { return PP; }
unsigned getFileID() const { FileID getFileID() const {
assert(PP && assert(PP &&
"PreprocessorLexer::getFileID() should only be used with a Preprocessor"); "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
return FileID; return FID;
} }
/// getFileEntry - Return the FileEntry corresponding to this FileID. Like
/// getFileID(), this only works for lexers with attached preprocessors.
const FileEntry *getFileEntry() const;
}; };
} // end namespace clang } // end namespace clang

Просмотреть файл

@ -14,9 +14,10 @@
#ifndef LLVM_CLANG_SCRATCHBUFFER_H #ifndef LLVM_CLANG_SCRATCHBUFFER_H
#define LLVM_CLANG_SCRATCHBUFFER_H #define LLVM_CLANG_SCRATCHBUFFER_H
#include "clang/Basic/SourceLocation.h"
namespace clang { namespace clang {
class SourceManager; class SourceManager;
class SourceLocation;
/// ScratchBuffer - This class exposes a simple interface for the dynamic /// ScratchBuffer - This class exposes a simple interface for the dynamic
/// construction of tokens. This is used for builtin macros (e.g. __LINE__) as /// construction of tokens. This is used for builtin macros (e.g. __LINE__) as
@ -24,7 +25,7 @@ namespace clang {
class ScratchBuffer { class ScratchBuffer {
SourceManager &SourceMgr; SourceManager &SourceMgr;
char *CurBuffer; char *CurBuffer;
unsigned FileID; SourceLocation BufferStartLoc;
unsigned BytesUsed; unsigned BytesUsed;
public: public:
ScratchBuffer(SourceManager &SM); ScratchBuffer(SourceManager &SM);

Просмотреть файл

@ -51,7 +51,7 @@ namespace html {
/// EscapeText - HTMLize a specified file so that special characters are /// EscapeText - HTMLize a specified file so that special characters are
/// are translated so that they are not interpreted as HTML tags. /// are translated so that they are not interpreted as HTML tags.
void EscapeText(Rewriter& R, unsigned FileID, void EscapeText(Rewriter& R, FileID FID,
bool EscapeSpaces = false, bool ReplacesTabs = true); bool EscapeSpaces = false, bool ReplacesTabs = true);
/// EscapeText - HTMLized the provided string so that special characters /// EscapeText - HTMLized the provided string so that special characters
@ -61,29 +61,21 @@ namespace html {
std::string EscapeText(const std::string& s, std::string EscapeText(const std::string& s,
bool EscapeSpaces = false, bool ReplaceTabs = true); bool EscapeSpaces = false, bool ReplaceTabs = true);
void AddLineNumbers(Rewriter& R, unsigned FileID); void AddLineNumbers(Rewriter& R, FileID FID);
void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID, void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
const char *title = NULL); const char *title = NULL);
/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
/// information about keywords, comments, etc. /// information about keywords, comments, etc.
void SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP); void SyntaxHighlight(Rewriter &R, FileID FID, Preprocessor &PP);
/// HighlightMacros - This uses the macro table state from the end of the /// HighlightMacros - This uses the macro table state from the end of the
/// file, to reexpand macros and insert (into the HTML) information about the /// file, to reexpand macros and insert (into the HTML) information about the
/// macro expansions. This won't be perfectly perfect, but it will be /// macro expansions. This won't be perfectly perfect, but it will be
/// reasonably close. /// reasonably close.
void HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor &PP); void HighlightMacros(Rewriter &R, FileID FID, Preprocessor &PP);
void HighlightMacros(Rewriter &R, FileID FID, PreprocessorFactory &PPF);
void HighlightMacros(Rewriter &R, unsigned FileID, PreprocessorFactory &PPF);
} // end html namespace } // end html namespace
} // end clang namespace } // end clang namespace

Просмотреть файл

@ -118,7 +118,7 @@ private: // Methods only usable by Rewriter.
class Rewriter { class Rewriter {
SourceManager *SourceMgr; SourceManager *SourceMgr;
std::map<unsigned, RewriteBuffer> RewriteBuffers; std::map<FileID, RewriteBuffer> RewriteBuffers;
public: public:
explicit Rewriter(SourceManager &SM) : SourceMgr(&SM) {} explicit Rewriter(SourceManager &SM) : SourceMgr(&SM) {}
explicit Rewriter() : SourceMgr(0) {} explicit Rewriter() : SourceMgr(0) {}
@ -205,9 +205,9 @@ public:
/// getRewriteBufferFor - Return the rewrite buffer for the specified FileID. /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
/// If no modification has been made to it, return null. /// If no modification has been made to it, return null.
const RewriteBuffer *getRewriteBufferFor(unsigned FileID) const { const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
std::map<unsigned, RewriteBuffer>::const_iterator I = std::map<FileID, RewriteBuffer>::const_iterator I =
RewriteBuffers.find(FileID); RewriteBuffers.find(FID);
return I == RewriteBuffers.end() ? 0 : &I->second; return I == RewriteBuffers.end() ? 0 : &I->second;
} }
@ -215,11 +215,10 @@ public:
/// buffer, and allows you to write on it directly. This is useful if you /// buffer, and allows you to write on it directly. This is useful if you
/// want efficient low-level access to apis for scribbling on one specific /// want efficient low-level access to apis for scribbling on one specific
/// FileID's buffer. /// FileID's buffer.
RewriteBuffer &getEditBuffer(unsigned FileID); RewriteBuffer &getEditBuffer(FileID FID);
private: private:
unsigned getLocationOffsetAndFileID(SourceLocation Loc, unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
unsigned &FileID) const;
}; };
} // end namespace clang } // end namespace clang

Просмотреть файл

@ -48,7 +48,7 @@ namespace clang {
public: public:
/// TokenRewriter - This creates a TokenRewriter for the file with the /// TokenRewriter - This creates a TokenRewriter for the file with the
/// specified FileID. /// specified FileID.
TokenRewriter(unsigned FileID, SourceManager &SM, const LangOptions &LO); TokenRewriter(FileID FID, SourceManager &SM, const LangOptions &LO);
~TokenRewriter(); ~TokenRewriter();
typedef std::list<Token>::const_iterator token_iterator; typedef std::list<Token>::const_iterator token_iterator;

Просмотреть файл

@ -105,7 +105,7 @@ const char *FullSourceLoc::getCharacterData() const {
const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const { const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const {
assert(isValid()); assert(isValid());
return SrcMgr->getBuffer(getFileID()); return SrcMgr->getBuffer(*this);
} }
void FullSourceLoc::dump() const { void FullSourceLoc::dump() const {

Просмотреть файл

@ -111,7 +111,7 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
/// createFileID - Create a new fileID for the specified ContentCache and /// createFileID - Create a new fileID for the specified ContentCache and
/// include position. This works regardless of whether the ContentCache /// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source. /// corresponds to a file or some other input source.
unsigned SourceManager::createFileID(const ContentCache *File, FileID SourceManager::createFileID(const ContentCache *File,
SourceLocation IncludePos, SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter) { SrcMgr::CharacteristicKind FileCharacter) {
// If FileEnt is really large (e.g. it's a large .i file), we may not be able // 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)); FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter));
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) && assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
"Ran out of file ID's!"); "Ran out of file ID's!");
return FileIDs.size(); return FileID::Create(FileIDs.size());
} }
// Create one FileID for each chunk of the file. // 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) && assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
"Ran out of file ID's!"); "Ran out of file ID's!");
return Result; return FileID::Create(Result);
} }
/// getInstantiationLoc - Return a new SourceLocation that encodes the fact /// 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 /// 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*> std::pair<const char*, const char*>
SourceManager::getBufferData(unsigned FileID) const { SourceManager::getBufferData(SourceLocation Loc) const {
const llvm::MemoryBuffer *Buf = getBuffer(FileID); const llvm::MemoryBuffer *Buf = getBuffer(Loc);
return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd()); 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 /// getCharacterData - Return a pointer to the start of the specified location
/// in the appropriate MemoryBuffer. /// in the appropriate MemoryBuffer.
@ -196,9 +203,11 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const {
// heavily used by -E mode. // heavily used by -E mode.
SL = getSpellingLoc(SL); SL = getSpellingLoc(SL);
std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(SL);
// Note that calling 'getBuffer()' may lazily page in a source file. // Note that calling 'getBuffer()' may lazily page in a source file.
return getContentCache(SL.getFileID())->getBuffer()->getBufferStart() + return getContentCache(LocInfo.first)->getBuffer()->getBufferStart() +
getFullFilePos(SL); 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 /// this is significantly cheaper to compute than the line number. This returns
/// zero if the column number isn't known. /// zero if the column number isn't known.
unsigned SourceManager::getColumnNumber(SourceLocation Loc) const { unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
unsigned FileID = Loc.getFileID(); if (Loc.getFileID() == 0) return 0;
if (FileID == 0) return 0;
unsigned FilePos = getFullFilePos(Loc); std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(Loc);
const MemoryBuffer *Buffer = getBuffer(FileID); unsigned FilePos = LocInfo.second;
const char *Buf = Buffer->getBufferStart();
const char *Buf = getBuffer(LocInfo.first)->getBufferStart();
unsigned LineStart = FilePos; unsigned LineStart = FilePos;
while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r') 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, /// the SourceLocation specifies. This can be modified with #line directives,
/// etc. /// etc.
const char *SourceManager::getSourceName(SourceLocation Loc) const { const char *SourceManager::getSourceName(SourceLocation Loc) const {
unsigned FileID = Loc.getFileID(); if (Loc.getFileID() == 0) return "";
if (FileID == 0) return "";
// To get the source name, first consult the FileEntry (if one exists) before // To get the source name, first consult the FileEntry (if one exists) before
// the MemBuffer as this will avoid unnecessarily paging in the MemBuffer. // 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(); 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 /// line offsets for the MemoryBuffer, so this is not cheap: use only when
/// about to emit a diagnostic. /// about to emit a diagnostic.
unsigned SourceManager::getLineNumber(SourceLocation Loc) const { unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
unsigned FileID = Loc.getFileID(); if (Loc.getFileID() == 0) return 0;
if (FileID == 0) return 0;
ContentCache* Content; ContentCache *Content;
if (LastLineNoFileIDQuery == FileID) std::pair<FileID, unsigned> LocInfo = getDecomposedFileLoc(Loc);
if (LastLineNoFileIDQuery == LocInfo.first)
Content = LastLineNoContentCache; Content = LastLineNoContentCache;
else 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 // If this is the first use of line information for this buffer, compute the
/// SourceLineCache for it on demand. /// SourceLineCache for it on demand.
@ -303,12 +312,12 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
unsigned *SourceLineCacheStart = SourceLineCache; unsigned *SourceLineCacheStart = SourceLineCache;
unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines; 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 // 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 // that query and the line number returned. This allows us to narrow the
// search space from the entire file to something near the match. // search space from the entire file to something near the match.
if (LastLineNoFileIDQuery == FileID) { if (LastLineNoFileIDQuery == LocInfo.first) {
if (QueriedFilePos >= LastLineNoFilePos) { if (QueriedFilePos >= LastLineNoFilePos) {
SourceLineCache = SourceLineCache+LastLineNoResult-1; SourceLineCache = SourceLineCache+LastLineNoResult-1;
@ -362,7 +371,7 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const {
= std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos); = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
unsigned LineNo = Pos-SourceLineCacheStart; unsigned LineNo = Pos-SourceLineCacheStart;
LastLineNoFileIDQuery = FileID; LastLineNoFileIDQuery = LocInfo.first;
LastLineNoContentCache = Content; LastLineNoContentCache = Content;
LastLineNoFilePos = QueriedFilePos; LastLineNoFilePos = QueriedFilePos;
LastLineNoResult = LineNo; LastLineNoResult = LineNo;
@ -492,7 +501,7 @@ MacroIDInfo MacroIDInfo::ReadVal(llvm::Deserializer& D) {
void SourceManager::Emit(llvm::Serializer& S) const { void SourceManager::Emit(llvm::Serializer& S) const {
S.EnterBlock(); S.EnterBlock();
S.EmitPtr(this); S.EmitPtr(this);
S.EmitInt(MainFileID); S.EmitInt(MainFileID.getOpaqueValue());
// Emit: FileInfos. Just emit the file name. // Emit: FileInfos. Just emit the file name.
S.EnterBlock(); S.EnterBlock();
@ -527,7 +536,7 @@ SourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){
D.RegisterPtr(M); D.RegisterPtr(M);
// Read: the FileID of the main source file of the translation unit. // 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; std::vector<char> Buf;

Просмотреть файл

@ -49,10 +49,10 @@ public:
virtual void HandlePathDiagnostic(const PathDiagnostic* D); 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); 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); void ReportDiag(const PathDiagnostic& D);
}; };
@ -125,17 +125,15 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
return; return;
SourceManager &SMgr = D.begin()->getLocation().getManager(); SourceManager &SMgr = D.begin()->getLocation().getManager();
unsigned FileID = 0; FileID FID;
bool FileIDInitialized = false;
// Verify that the entire path is from the same FileID. // Verify that the entire path is from the same FileID.
for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) { for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
FullSourceLoc L = I->getLocation().getInstantiationLoc(); FullSourceLoc L = I->getLocation().getInstantiationLoc();
if (!FileIDInitialized) { if (FID.isInvalid()) {
FileID = SMgr.getCanonicalFileID(L); FID = SMgr.getCanonicalFileID(L);
FileIDInitialized = true; } else if (SMgr.getCanonicalFileID(L) != FID)
} else if (SMgr.getCanonicalFileID(L) != FileID)
return; // FIXME: Emit a warning? return; // FIXME: Emit a warning?
// Check the source ranges. // Check the source ranges.
@ -147,7 +145,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
if (!L.isFileID()) if (!L.isFileID())
return; // FIXME: Emit a warning? return; // FIXME: Emit a warning?
if (SMgr.getCanonicalFileID(L) != FileID) if (SMgr.getCanonicalFileID(L) != FID)
return; // FIXME: Emit a warning? return; // FIXME: Emit a warning?
L = SMgr.getInstantiationLoc(RI->getEnd()); L = SMgr.getInstantiationLoc(RI->getEnd());
@ -155,12 +153,12 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
if (!L.isFileID()) if (!L.isFileID())
return; // FIXME: Emit a warning? return; // FIXME: Emit a warning?
if (SMgr.getCanonicalFileID(L) != FileID) if (SMgr.getCanonicalFileID(L) != FID)
return; // FIXME: Emit a warning? return; // FIXME: Emit a warning?
} }
} }
if (!FileIDInitialized) if (FID.isInvalid())
return; // FIXME: Emit a warning? return; // FIXME: Emit a warning?
// Create a new rewriter to generate HTML. // 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(); for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
I!=E; ++I, --n) { I!=E; ++I, --n) {
HandlePiece(R, FileID, *I, n, max); HandlePiece(R, FID, *I, n, max);
} }
// Add line numbers, header, footer, etc. // Add line numbers, header, footer, etc.
// unsigned FileID = R.getSourceMgr().getMainFileID(); // unsigned FID = R.getSourceMgr().getMainFileID();
html::EscapeText(R, FileID); html::EscapeText(R, FID);
html::AddLineNumbers(R, FileID); html::AddLineNumbers(R, FID);
// If we have a preprocessor, relex the file and syntax highlight. // 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, // We might not have a preprocessor if we come from a deserialized AST file,
// for example. // 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, // FIXME: We eventually want to use PPF to create a fresh Preprocessor,
// once we have worked out the bugs. // 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. // 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 // This is a cludge; basically we want to append either the full
// working directory if we have no directory information. This is // 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" os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n"
"<h3>Annotated Source Code</h3>\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. // Embed meta-data tags.
@ -252,7 +250,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
std::string s; std::string s;
llvm::raw_string_ostream os(s); llvm::raw_string_ostream os(s);
os << "\n<!-- BUGDESC " << BugDesc << " -->\n"; 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(); const std::string& BugCategory = D.getCategory();
@ -261,14 +259,14 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
std::string s; std::string s;
llvm::raw_string_ostream os(s); llvm::raw_string_ostream os(s);
os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n"; os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
} }
{ {
std::string s; std::string s;
llvm::raw_string_ostream os(s); llvm::raw_string_ostream os(s);
os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n"; 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); llvm::raw_string_ostream os(s);
os << "\n<!-- BUGLINE " os << "\n<!-- BUGLINE "
<< D.back()->getLocation().getInstantiationLineNumber() << " -->\n"; << D.back()->getLocation().getInstantiationLineNumber() << " -->\n";
R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
} }
{ {
std::string s; std::string s;
llvm::raw_string_ostream os(s); llvm::raw_string_ostream os(s);
os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n"; 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. // Add CSS, header, and footer.
html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName()); html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
// Get the rewrite buffer. // Get the rewrite buffer.
const RewriteBuffer *Buf = R.getRewriteBufferFor(FileID); const RewriteBuffer *Buf = R.getRewriteBufferFor(FID);
if (!Buf) { if (!Buf) {
llvm::cerr << "warning: no diagnostics generated for main file.\n"; llvm::cerr << "warning: no diagnostics generated for main file.\n";
@ -325,28 +323,26 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
os << *I; os << *I;
} }
void HTMLDiagnostics::HandlePiece(Rewriter& R, unsigned BugFileID, void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
const PathDiagnosticPiece& P, const PathDiagnosticPiece& P,
unsigned num, unsigned max) { unsigned num, unsigned max) {
// For now, just draw a box above the line in question, and emit the // For now, just draw a box above the line in question, and emit the
// warning. // warning.
FullSourceLoc Pos = P.getLocation(); FullSourceLoc Pos = P.getLocation();
if (!Pos.isValid()) if (!Pos.isValid())
return; return;
SourceManager& SM = R.getSourceMgr(); SourceManager &SM = R.getSourceMgr();
FullSourceLoc LPos = Pos.getInstantiationLoc(); FullSourceLoc LPos = Pos.getInstantiationLoc();
unsigned FileID = SM.getCanonicalFileID(LPos); FileID FID = SM.getCanonicalFileID(LPos);
assert(&LPos.getManager() == &SM && "SourceManagers are different!");
assert (&LPos.getManager() == &SM && "SourceManagers are different!");
if (SM.getCanonicalFileID(LPos) != BugFileID) if (SM.getCanonicalFileID(LPos) != BugFileID)
return; return;
const llvm::MemoryBuffer *Buf = SM.getBuffer(FileID); const llvm::MemoryBuffer *Buf = SM.getBuffer(FID);
const char* FileStart = Buf->getBufferStart(); const char* FileStart = Buf->getBufferStart();
// Compute the column number. Rewind from the current position to the start // 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>"; os << html::EscapeText(Msg) << "</div></td></tr>";
// Insert the new html. // Insert the new html.
unsigned DisplayPos = 0; unsigned DisplayPos;
switch (P.getDisplayHint()) { switch (P.getDisplayHint()) {
case PathDiagnosticPiece::Above: default: assert(0 && "Unhandled hint.");
DisplayPos = LineStart - FileStart; case PathDiagnosticPiece::Above:
break; DisplayPos = LineStart - FileStart;
case PathDiagnosticPiece::Below: break;
DisplayPos = LineEnd - FileStart; case PathDiagnosticPiece::Below:
break; DisplayPos = LineEnd - FileStart;
default: break;
assert (false && "Unhandled hint.");
} }
R.InsertStrBefore(SourceLocation::getFileLoc(FileID, DisplayPos), os.str()); SourceLocation Loc =
SM.getLocForStartOfFile(FID).getFileLocWithOffset(DisplayPos);
R.InsertStrBefore(Loc, os.str());
} }
// Now highlight the ranges. // Now highlight the ranges.
for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end(); for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
I != E; ++I) 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) { SourceRange Range) {
SourceManager& SM = R.getSourceMgr(); SourceManager& SM = R.getSourceMgr();

Просмотреть файл

@ -20,9 +20,9 @@
#include "llvm/System/Path.h" #include "llvm/System/Path.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
using namespace clang; using namespace clang;
typedef llvm::DenseMap<unsigned,unsigned> FIDMap;
typedef llvm::DenseMap<FileID, unsigned> FIDMap;
namespace clang { namespace clang {
class Preprocessor; class Preprocessor;
@ -51,27 +51,28 @@ clang::CreatePlistDiagnosticClient(const std::string& s,
return new PlistDiagnostics(s); return new PlistDiagnostics(s);
} }
static void AddFID(FIDMap& FIDs, static void AddFID(FIDMap &FIDs,
llvm::SmallVectorImpl<unsigned>& V, llvm::SmallVectorImpl<FileID> &V,
SourceManager& SM, SourceLocation L) { SourceManager& SM, SourceLocation L) {
unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L)); FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
FIDMap::iterator I = FIDs.find(fid); FIDMap::iterator I = FIDs.find(FID);
if (I != FIDs.end()) return; if (I != FIDs.end()) return;
FIDs[fid] = V.size(); FIDs[FID] = V.size();
V.push_back(fid); V.push_back(FID);
} }
static unsigned GetFID(const FIDMap& FIDs, static unsigned GetFID(const FIDMap& FIDs,
SourceManager& SM, SourceLocation L) { SourceManager& SM, SourceLocation L) {
unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L)); FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L));
FIDMap::const_iterator I = FIDs.find(fid); FIDMap::const_iterator I = FIDs.find(FID);
assert (I != FIDs.end()); assert(I != FIDs.end());
return I->second; return I->second;
} }
static llvm::raw_ostream& Indent(llvm::raw_ostream& o, const unsigned indent) { 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; 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 // Build up a set of FIDs that we use by scanning the locations and
// ranges of the diagnostics. // ranges of the diagnostics.
FIDMap FM; 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) { for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I) {
AddFID(FM, Fids, SM, I->getLocation()); AddFID(FM, Fids, SM, I->getLocation());
@ -214,7 +215,7 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
" <key>files</key>\n" " <key>files</key>\n"
" <array>\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) I!=E; ++I)
o << " <string>" << SM.getFileEntryForID(*I)->getName() << "</string>\n"; o << " <string>" << SM.getFileEntryForID(*I)->getName() << "</string>\n";

Просмотреть файл

@ -62,14 +62,18 @@ tok::ObjCKeywordKind Token::getObjCKeywordID() const {
/// with the specified preprocessor managing the lexing process. This lexer /// with the specified preprocessor managing the lexing process. This lexer
/// assumes that the associated file buffer and Preprocessor objects will /// assumes that the associated file buffer and Preprocessor objects will
/// outlive it, so it doesn't take ownership of either of them. /// 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) const char *BufStart, const char *BufEnd)
: PreprocessorLexer(&pp, fileloc), FileLoc(fileloc), // FIXME: This is really horrible and only needed for _Pragma lexers, split this
Features(pp.getLangOptions()) { // out of the main lexer path!
: PreprocessorLexer(&PP,
PP.getSourceManager().getCanonicalFileID(
PP.getSourceManager().getSpellingLoc(fileloc))),
FileLoc(fileloc),
Features(PP.getLangOptions()) {
SourceManager &SourceMgr = PP->getSourceManager(); SourceManager &SourceMgr = PP.getSourceManager();
unsigned InputFileID = SourceMgr.getSpellingLoc(FileLoc).getFileID(); const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(getFileID());
const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(InputFileID);
Is_PragmaLexer = false; Is_PragmaLexer = false;
InitCharacterInfo(); InitCharacterInfo();
@ -103,7 +107,7 @@ Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp,
// Default to keeping comments if the preprocessor wants them. // Default to keeping comments if the preprocessor wants them.
ExtendedTokenMode = 0; ExtendedTokenMode = 0;
SetCommentRetentionState(PP->getCommentRetentionState()); SetCommentRetentionState(PP.getCommentRetentionState());
} }
/// Lexer constructor - Create a new raw lexer object. This object is only /// 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 // all obviously single-char tokens. This could use
// Lexer::isObviouslySimpleCharacter for example to handle identifiers or // Lexer::isObviouslySimpleCharacter for example to handle identifiers or
// something. // something.
const char *BufEnd = SM.getBufferData(Loc).second;
const char *BufEnd = SM.getBufferData(Loc.getFileID()).second;
// Create a langops struct and enable trigraphs. This is sufficient for // Create a langops struct and enable trigraphs. This is sufficient for
// measuring tokens. // measuring tokens.
@ -303,6 +305,8 @@ SourceLocation Lexer::getSourceLocation(const char *Loc) const {
if (FileLoc.isFileID()) if (FileLoc.isFileID())
return SourceLocation::getFileLoc(FileLoc.getFileID(), CharNo); 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"); assert(PP && "This doesn't work on raw lexers");
return GetMappedTokenLoc(*PP, FileLoc, CharNo); return GetMappedTokenLoc(*PP, FileLoc, CharNo);
} }

Просмотреть файл

@ -394,8 +394,8 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart,
// info about where the current file is. // info about where the current file is.
const FileEntry *CurFileEnt = 0; const FileEntry *CurFileEnt = 0;
if (!FromDir) { if (!FromDir) {
unsigned FileID = getCurrentFileLexer()->getFileID(); FileID FID = getCurrentFileLexer()->getFileID();
CurFileEnt = SourceMgr.getFileEntryForID(FileID); CurFileEnt = SourceMgr.getFileEntryForID(FID);
} }
// Do a standard file entry lookup. // Do a standard file entry lookup.
@ -786,16 +786,16 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
SourceMgr.getFileCharacteristic(getCurrentFileLexer()->getFileID())); SourceMgr.getFileCharacteristic(getCurrentFileLexer()->getFileID()));
// Look up the file, create a File ID for it. // Look up the file, create a File ID for it.
unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(), FileID FID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
FileCharacter); FileCharacter);
if (FileID == 0) { if (FID.isInvalid()) {
Diag(FilenameTok, diag::err_pp_file_not_found) Diag(FilenameTok, diag::err_pp_file_not_found)
<< std::string(FilenameStart, FilenameEnd); << std::string(FilenameStart, FilenameEnd);
return; return;
} }
// Finally, if all is good, enter the new file! // Finally, if all is good, enter the new file!
EnterSourceFile(FileID, CurDir); EnterSourceFile(FID, CurDir);
} }
/// HandleIncludeNextDirective - Implements #include_next. /// HandleIncludeNextDirective - Implements #include_next.

Просмотреть файл

@ -66,8 +66,7 @@ PreprocessorLexer *Preprocessor::getCurrentFileLexer() const {
/// EnterSourceFile - Add a source file to the top of the include stack and /// 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 /// start lexing tokens from it instead of the current buffer. Return true
/// on failure. /// on failure.
void Preprocessor::EnterSourceFile(unsigned FileID, void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir) {
const DirectoryLookup *CurDir) {
assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!"); assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!");
++NumEnteredSourceFiles; ++NumEnteredSourceFiles;
@ -75,8 +74,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
MaxIncludeStackDepth = IncludeMacroStack.size(); MaxIncludeStackDepth = IncludeMacroStack.size();
if (PTH) { if (PTH) {
PTHLexer* PL = PTHLexer *PL = PTH->CreateLexer(FID, SourceMgr.getFileEntryForID(FID));
PTH->CreateLexer(FileID, getSourceManager().getFileEntryForID(FileID));
if (PL) { if (PL) {
EnterSourceFileWithPTH(PL, CurDir); 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); 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. // Notify the client, if desired, that we are in a new source file.
if (Callbacks) { if (Callbacks) {
unsigned FileID = CurPPLexer->getFileID(); FileID FID = CurPPLexer->getFileID();
SrcMgr::CharacteristicKind FileType = SrcMgr::CharacteristicKind FileType = SourceMgr.getFileCharacteristic(FID);
SourceMgr.getFileCharacteristic(CurPPLexer->getFileID()); Callbacks->FileChanged(SourceMgr.getLocForStartOfFile(FID),
Callbacks->FileChanged(SourceLocation::getFileLoc(FileID, 0),
PPCallbacks::EnterFile, FileType); PPCallbacks::EnterFile, FileType);
} }
} }

Просмотреть файл

@ -23,7 +23,6 @@
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/OwningPtr.h"
using namespace clang; using namespace clang;
#define DISK_TOKEN_SIZE (1+1+3+4+2) #define DISK_TOKEN_SIZE (1+1+3+4+2)
@ -48,15 +47,14 @@ static inline uint32_t Read32(const char*& data) {
// PTHLexer methods. // PTHLexer methods.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D, PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const char *D,
const char* ppcond, const char *ppcond,
PTHSpellingSearch& mySpellingSrch, PTHSpellingSearch &mySpellingSrch, PTHManager &PM)
PTHManager& PM) : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
: PreprocessorLexer(&pp, fileloc), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
PPCond(ppcond), CurPPCondPtr(ppcond), MySpellingSrch(mySpellingSrch), PPCond(ppcond), CurPPCondPtr(ppcond), MySpellingSrch(mySpellingSrch),
PTHMgr(PM) PTHMgr(PM) {
{
FileID = fileloc.getFileID(); FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID);
} }
void PTHLexer::Lex(Token& Tok) { void PTHLexer::Lex(Token& Tok) {
@ -96,7 +94,7 @@ LexNextToken:
Tok.setFlag(flags); Tok.setFlag(flags);
assert(!LexingRawMode); assert(!LexingRawMode);
Tok.setIdentifierInfo(perID ? PTHMgr.GetIdentifierInfo(perID-1) : 0); Tok.setIdentifierInfo(perID ? PTHMgr.GetIdentifierInfo(perID-1) : 0);
Tok.setLocation(SourceLocation::getFileLoc(FileID, FileOffset)); Tok.setLocation(FileStartLoc.getFileLocWithOffset(FileOffset));
Tok.setLength(Len); Tok.setLength(Len);
//===--------------------------------------==// //===--------------------------------------==//
@ -295,23 +293,27 @@ SourceLocation PTHLexer::getSourceLocation() {
| (((uint32_t) ((uint8_t) p[1])) << 8) | (((uint32_t) ((uint8_t) p[1])) << 8)
| (((uint32_t) ((uint8_t) p[2])) << 16) | (((uint32_t) ((uint8_t) p[2])) << 16)
| (((uint32_t) ((uint8_t) p[3])) << 24); | (((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(). // getSpelling() - Use cached data in PTH files for getSpelling().
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
unsigned PTHManager::getSpelling(unsigned FileID, unsigned fpos, unsigned PTHManager::getSpelling(FileID FID, unsigned FPos,
const char *& Buffer) { const char *&Buffer) {
llvm::DenseMap<FileID, PTHSpellingSearch*>::iterator I =SpellingMap.find(FID);
llvm::DenseMap<unsigned,PTHSpellingSearch*>::iterator I =
SpellingMap.find(FileID);
if (I == SpellingMap.end()) if (I == SpellingMap.end())
return 0; 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, unsigned PTHManager::getSpellingAtPTHOffset(unsigned PTHOffset,
@ -420,14 +422,17 @@ unsigned PTHSpellingSearch::getSpellingBinarySearch(unsigned fpos,
return 0; return 0;
} }
unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) { unsigned PTHLexer::getSpelling(SourceLocation Loc, const char *&Buffer) {
SourceManager& SM = PP->getSourceManager(); SourceManager &SM = PP->getSourceManager();
sloc = SM.getSpellingLoc(sloc); Loc = SM.getSpellingLoc(Loc);
unsigned fid = SM.getCanonicalFileID(sloc); std::pair<FileID, unsigned> LocInfo = SM.getDecomposedFileLoc(Loc);
unsigned fpos = SM.getFullFilePos(sloc);
FileID FID = LocInfo.first;
unsigned FPos = LocInfo.second;
return (fid == FileID ) ? MySpellingSrch.getSpellingLinearSearch(fpos, Buffer) if (FID == getFileID())
: PTHMgr.getSpelling(fid, fpos, Buffer); 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) if (!FE)
return 0; return 0;
// Lookup the FileEntry object in our file lookup data structure. It will // 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 // return a variant that indicates whether or not there is an offset within
// the PTH file that contains cached tokens. // 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. if (!FileData.isValid()) // No tokens available.
return 0; return 0;
@ -694,9 +698,8 @@ PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
// Create the SpellingSearch object for this FileID. // Create the SpellingSearch object for this FileID.
PTHSpellingSearch* ss = new PTHSpellingSearch(*this, len, spellingTable); PTHSpellingSearch* ss = new PTHSpellingSearch(*this, len, spellingTable);
SpellingMap[FileID] = ss; SpellingMap[FID] = ss;
assert(PP && "No preprocessor set yet!"); assert(PP && "No preprocessor set yet!");
return new PTHLexer(*PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond, return new PTHLexer(*PP, FID, data, ppcond, *ss, *this);
*ss, *this);
} }

Просмотреть файл

@ -191,10 +191,8 @@ void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
} }
// Get the current file lexer we're looking at. Ignore _Pragma 'files' etc. // 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. // Mark the file as a once-only file now.
HeaderInfo.MarkFileIncludeOnce(SourceMgr.getFileEntryForID(FileID)); HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
} }
void Preprocessor::HandlePragmaMark() { void Preprocessor::HandlePragmaMark() {
@ -256,8 +254,7 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
PreprocessorLexer *TheLexer = getCurrentFileLexer(); PreprocessorLexer *TheLexer = getCurrentFileLexer();
// Mark the file as a system header. // Mark the file as a system header.
const FileEntry *File = SourceMgr.getFileEntryForID(TheLexer->getFileID()); HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry());
HeaderInfo.MarkFileSystemHeader(File);
// Notify the client, if desired, that we are in a new source file. // Notify the client, if desired, that we are in a new source file.
if (Callbacks) if (Callbacks)
@ -299,8 +296,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
return; return;
} }
unsigned FileID = getCurrentFileLexer()->getFileID(); const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry();
const FileEntry *CurFile = SourceMgr.getFileEntryForID(FileID);
// If this file is older than the file it depends on, emit a diagnostic. // If this file is older than the file it depends on, emit a diagnostic.
if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) { if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) {

Просмотреть файл

@ -200,9 +200,7 @@ std::string Preprocessor::getSpelling(const Token &Tok) const {
if (PTH) { if (PTH) {
SourceLocation SLoc = SourceMgr.getSpellingLoc(Tok.getLocation()); SourceLocation SLoc = SourceMgr.getSpellingLoc(Tok.getLocation());
unsigned fid = SourceMgr.getCanonicalFileID(SLoc); if (unsigned Len = PTH->getSpelling(SLoc, TokStart)) {
unsigned fpos = SourceMgr.getFullFilePos(SLoc);
if (unsigned Len = PTH->getSpelling(fid, fpos, TokStart)) {
assert(!Tok.needsCleaning()); assert(!Tok.needsCleaning());
return std::string(TokStart, TokStart+Len); return std::string(TokStart, TokStart+Len);
} }
@ -256,10 +254,8 @@ unsigned Preprocessor::getSpelling(const Token &Tok,
if (CurPTHLexer) { if (CurPTHLexer) {
Len = CurPTHLexer.get()->getSpelling(Tok.getLocation(), Buffer); Len = CurPTHLexer.get()->getSpelling(Tok.getLocation(), Buffer);
} else { } else {
SourceLocation SLoc = SourceMgr.getSpellingLoc(Tok.getLocation()); Len = PTH->getSpelling(SourceMgr.getSpellingLoc(Tok.getLocation()),
unsigned FID = SourceMgr.getCanonicalFileID(SLoc); Buffer);
unsigned FPos = SourceMgr.getFullFilePos(SLoc);
Len = PTH->getSpelling(FID, FPos, Buffer);
} }
// Did we find a spelling? If so return its length. Otherwise fall // Did we find a spelling? If so return its length. Otherwise fall
@ -656,15 +652,14 @@ static void InitializePredefinedMacros(Preprocessor &PP,
/// which implicitly adds the builtin defines etc. /// which implicitly adds the builtin defines etc.
void Preprocessor::EnterMainSourceFile() { void Preprocessor::EnterMainSourceFile() {
unsigned MainFileID = SourceMgr.getMainFileID(); FileID MainFileID = SourceMgr.getMainFileID();
// Enter the main file source buffer. // Enter the main file source buffer.
EnterSourceFile(MainFileID, 0); EnterSourceFile(MainFileID, 0);
// Tell the header info that the main file was entered. If the file is later // Tell the header info that the main file was entered. If the file is later
// #imported, it won't be re-entered. // #imported, it won't be re-entered.
if (const FileEntry *FE = if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID))
SourceMgr.getFileEntryForLoc(SourceLocation::getFileLoc(MainFileID, 0)))
HeaderInfo.IncrementIncludeCount(FE); HeaderInfo.IncrementIncludeCount(FE);
std::vector<char> PrologFile; std::vector<char> PrologFile;
@ -685,11 +680,11 @@ void Preprocessor::EnterMainSourceFile() {
llvm::MemoryBuffer::getMemBufferCopy(&PrologFile.front(),&PrologFile.back(), llvm::MemoryBuffer::getMemBufferCopy(&PrologFile.front(),&PrologFile.back(),
"<predefines>"); "<predefines>");
assert(SB && "Cannot fail to create predefined source buffer"); assert(SB && "Cannot fail to create predefined source buffer");
unsigned FileID = SourceMgr.createFileIDForMemBuffer(SB); FileID FID = SourceMgr.createFileIDForMemBuffer(SB);
assert(FileID && "Could not create FileID for predefines?"); assert(!FID.isInvalid() && "Could not create FileID for predefines?");
// Start parsing the predefines. // Start parsing the predefines.
EnterSourceFile(FileID, 0); EnterSourceFile(FID, 0);
} }

Просмотреть файл

@ -17,14 +17,6 @@
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
using namespace clang; using namespace clang;
PreprocessorLexer::PreprocessorLexer(Preprocessor* pp, SourceLocation L)
: PP(pp), FileID(pp->getSourceManager().getSpellingLoc(L).getFileID()),
ParsingPreprocessorDirective(false),
ParsingFilename(false),
LexingRawMode(false) {}
PreprocessorLexer::~PreprocessorLexer() {}
/// LexIncludeFilename - After the preprocessor has parsed a #include, lex and /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
/// (potentially) macro expand the filename. /// (potentially) macro expand the filename.
void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) { void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
@ -45,3 +37,9 @@ void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
if (FilenameTok.is(tok::eom)) if (FilenameTok.is(tok::eom))
PP->Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename); PP->Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
} }
/// getFileEntry - Return the FileEntry corresponding to this FileID. Like
/// getFileID(), this only works for lexers with attached preprocessors.
const FileEntry *PreprocessorLexer::getFileEntry() const {
return PP->getSourceManager().getFileEntryForID(getFileID());
}

Просмотреть файл

@ -24,7 +24,6 @@ static const unsigned ScratchBufSize = 4060;
ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) { ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) {
// Set BytesUsed so that the first call to getToken will require an alloc. // Set BytesUsed so that the first call to getToken will require an alloc.
BytesUsed = ScratchBufSize; BytesUsed = ScratchBufSize;
FileID = 0;
} }
/// getToken - Splat the specified text into a temporary MemoryBuffer and /// getToken - Splat the specified text into a temporary MemoryBuffer and
@ -44,7 +43,7 @@ SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len) {
assert(BytesUsed-Len < (1 << SourceLocation::FilePosBits) && assert(BytesUsed-Len < (1 << SourceLocation::FilePosBits) &&
"Out of range file position!"); "Out of range file position!");
return SourceLocation::getFileLoc(FileID, BytesUsed-Len); return BufferStartLoc.getFileLocWithOffset(BytesUsed-Len);
} }
@ -66,7 +65,8 @@ void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) {
llvm::MemoryBuffer *Buf = llvm::MemoryBuffer *Buf =
llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>"); llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>");
FileID = SourceMgr.createFileIDForMemBuffer(Buf); FileID FID = SourceMgr.createFileIDForMemBuffer(Buf);
BufferStartLoc = SourceMgr.getLocForStartOfFile(FID);
CurBuffer = const_cast<char*>(Buf->getBufferStart()); CurBuffer = const_cast<char*>(Buf->getBufferStart());
BytesUsed = 0; BytesUsed = 0;
} }

Просмотреть файл

@ -392,8 +392,7 @@ bool TokenLexer::PasteTokens(Token &Tok) {
SourceManager &SourceMgr = PP.getSourceManager(); SourceManager &SourceMgr = PP.getSourceManager();
const char *ResultStrData = SourceMgr.getCharacterData(ResultTokLoc); const char *ResultStrData = SourceMgr.getCharacterData(ResultTokLoc);
const llvm::MemoryBuffer *Buffer = const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ResultTokLoc);
SourceMgr.getBuffer(ResultTokLoc.getFileID());
// Make a lexer object so that we lex and expand the paste result. // Make a lexer object so that we lex and expand the paste result.
Lexer TL(ResultTokLoc, PP.getLangOptions(), ResultStrData, Lexer TL(ResultTokLoc, PP.getLangOptions(), ResultStrData,

Просмотреть файл

@ -33,8 +33,8 @@ void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
SourceManager &SM = R.getSourceMgr(); SourceManager &SM = R.getSourceMgr();
B = SM.getInstantiationLoc(B); B = SM.getInstantiationLoc(B);
E = SM.getInstantiationLoc(E); E = SM.getInstantiationLoc(E);
unsigned FileID = SM.getCanonicalFileID(B); FileID FID = SM.getCanonicalFileID(B);
assert(SM.getCanonicalFileID(E) == FileID && "B/E not in the same file!"); assert(SM.getCanonicalFileID(E) == FID && "B/E not in the same file!");
unsigned BOffset = SM.getFullFilePos(B); unsigned BOffset = SM.getFullFilePos(B);
unsigned EOffset = SM.getFullFilePos(E); unsigned EOffset = SM.getFullFilePos(E);
@ -42,8 +42,8 @@ void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
// Include the whole end token in the range. // Include the whole end token in the range.
EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr()); EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr());
HighlightRange(R.getEditBuffer(FileID), BOffset, EOffset, HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
SM.getBufferData(FileID).first, StartTag, EndTag); SM.getBufferData(FID).first, StartTag, EndTag);
} }
/// HighlightRange - This is the same as the above method, but takes /// HighlightRange - This is the same as the above method, but takes
@ -97,16 +97,16 @@ void html::HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
} }
} }
void html::EscapeText(Rewriter& R, unsigned FileID, void html::EscapeText(Rewriter &R, FileID FID,
bool EscapeSpaces, bool ReplaceTabs) { bool EscapeSpaces, bool ReplaceTabs) {
const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
const char* C = Buf->getBufferStart(); const char* C = Buf->getBufferStart();
const char* FileEnd = Buf->getBufferEnd(); const char* FileEnd = Buf->getBufferEnd();
assert (C <= FileEnd); assert (C <= FileEnd);
RewriteBuffer &RB = R.getEditBuffer(FileID); RewriteBuffer &RB = R.getEditBuffer(FID);
unsigned ColNo = 0; unsigned ColNo = 0;
for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) { for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) {
@ -217,13 +217,13 @@ static void AddLineNumber(RewriteBuffer &RB, unsigned LineNo,
} }
} }
void html::AddLineNumbers(Rewriter& R, unsigned FileID) { void html::AddLineNumbers(Rewriter& R, FileID FID) {
const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
const char* FileBeg = Buf->getBufferStart(); const char* FileBeg = Buf->getBufferStart();
const char* FileEnd = Buf->getBufferEnd(); const char* FileEnd = Buf->getBufferEnd();
const char* C = FileBeg; const char* C = FileBeg;
RewriteBuffer &RB = R.getEditBuffer(FileID); RewriteBuffer &RB = R.getEditBuffer(FID);
assert (C <= FileEnd); assert (C <= FileEnd);
@ -263,15 +263,15 @@ void html::AddLineNumbers(Rewriter& R, unsigned FileID) {
RB.InsertTextAfter(FileEnd - FileBeg, "</table>", strlen("</table>")); RB.InsertTextAfter(FileEnd - FileBeg, "</table>", strlen("</table>"));
} }
void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID, void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
const char *title) { const char *title) {
const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
const char* FileStart = Buf->getBufferStart(); const char* FileStart = Buf->getBufferStart();
const char* FileEnd = Buf->getBufferEnd(); const char* FileEnd = Buf->getBufferEnd();
SourceLocation StartLoc = SourceLocation::getFileLoc(FileID, 0); SourceLocation StartLoc = R.getSourceMgr().getLocForStartOfFile(FID);
SourceLocation EndLoc = SourceLocation::getFileLoc(FileID, FileEnd-FileStart); SourceLocation EndLoc = StartLoc.getFileLocWithOffset(FileEnd-FileStart);
std::string s; std::string s;
llvm::raw_string_ostream os(s); llvm::raw_string_ostream os(s);
@ -340,15 +340,15 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID,
/// information about keywords, macro expansions etc. This uses the macro /// information about keywords, macro expansions etc. This uses the macro
/// table state from the end of the file, so it won't be perfectly perfect, /// table state from the end of the file, so it won't be perfectly perfect,
/// but it will be reasonably close. /// but it will be reasonably close.
void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) { void html::SyntaxHighlight(Rewriter &R, FileID FID, Preprocessor &PP) {
RewriteBuffer &RB = R.getEditBuffer(FileID); RewriteBuffer &RB = R.getEditBuffer(FID);
const SourceManager &SourceMgr = PP.getSourceManager(); const SourceManager &SourceMgr = PP.getSourceManager();
std::pair<const char*, const char*> File = SourceMgr.getBufferData(FileID); std::pair<const char*, const char*> File = SourceMgr.getBufferData(FID);
const char *BufferStart = File.first; const char *BufferStart = File.first;
Lexer L(SourceLocation::getFileLoc(FileID, 0), PP.getLangOptions(), Lexer L(SourceMgr.getLocForStartOfFile(FID),
File.first, File.second); PP.getLangOptions(), File.first, File.second);
// Inform the preprocessor that we want to retain comments as tokens, so we // Inform the preprocessor that we want to retain comments as tokens, so we
// can highlight them. // can highlight them.
@ -421,9 +421,9 @@ void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) {
/// file, to reexpand macros and insert (into the HTML) information about the /// file, to reexpand macros and insert (into the HTML) information about the
/// macro expansions. This won't be perfectly perfect, but it will be /// macro expansions. This won't be perfectly perfect, but it will be
/// reasonably close. /// reasonably close.
void html::HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor& PP) { void html::HighlightMacros(Rewriter &R, FileID FID, Preprocessor& PP) {
RewriteBuffer &RB = R.getEditBuffer(FileID); RewriteBuffer &RB = R.getEditBuffer(FID);
// Inform the preprocessor that we don't want comments. // Inform the preprocessor that we don't want comments.
PP.SetCommentRetentionState(false, false); PP.SetCommentRetentionState(false, false);
@ -444,10 +444,10 @@ void html::HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor& PP) {
// Ignore tokens whose instantiation location was not the main file. // Ignore tokens whose instantiation location was not the main file.
SourceLocation LLoc = SourceMgr.getInstantiationLoc(Tok.getLocation()); SourceLocation LLoc = SourceMgr.getInstantiationLoc(Tok.getLocation());
std::pair<unsigned, unsigned> LLocInfo = std::pair<FileID, unsigned> LLocInfo =
SourceMgr.getDecomposedFileLoc(LLoc); SourceMgr.getDecomposedFileLoc(LLoc);
if (LLocInfo.first != FileID) { if (LLocInfo.first != FID) {
PP.Lex(Tok); PP.Lex(Tok);
continue; continue;
} }
@ -496,9 +496,9 @@ void html::HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor& PP) {
} }
} }
void html::HighlightMacros(Rewriter &R, unsigned FileID, void html::HighlightMacros(Rewriter &R, FileID FID,
PreprocessorFactory &PPF) { PreprocessorFactory &PPF) {
llvm::OwningPtr<Preprocessor> PP(PPF.CreatePreprocessor()); llvm::OwningPtr<Preprocessor> PP(PPF.CreatePreprocessor());
HighlightMacros(R, FileID, *PP); HighlightMacros(R, FID, *PP);
} }

Просмотреть файл

@ -71,8 +71,8 @@ int Rewriter::getRangeSize(SourceRange Range) const {
if (!isRewritable(Range.getBegin()) || if (!isRewritable(Range.getBegin()) ||
!isRewritable(Range.getEnd())) return -1; !isRewritable(Range.getEnd())) return -1;
unsigned StartOff, StartFileID; FileID StartFileID, EndFileID;
unsigned EndOff , EndFileID; unsigned StartOff, EndOff;
StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID); StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID); EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
@ -82,7 +82,7 @@ int Rewriter::getRangeSize(SourceRange Range) const {
// If edits have been made to this buffer, the delta between the range may // If edits have been made to this buffer, the delta between the range may
// have changed. // have changed.
std::map<unsigned, RewriteBuffer>::const_iterator I = std::map<FileID, RewriteBuffer>::const_iterator I =
RewriteBuffers.find(StartFileID); RewriteBuffers.find(StartFileID);
if (I != RewriteBuffers.end()) { if (I != RewriteBuffers.end()) {
const RewriteBuffer &RB = I->second; const RewriteBuffer &RB = I->second;
@ -109,8 +109,8 @@ std::string Rewriter::getRewritenText(SourceRange Range) const {
!isRewritable(Range.getEnd())) !isRewritable(Range.getEnd()))
return ""; return "";
unsigned StartOff, StartFileID; FileID StartFileID, EndFileID;
unsigned EndOff , EndFileID; unsigned StartOff, EndOff;
StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID); StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID); EndOff = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
@ -119,7 +119,7 @@ std::string Rewriter::getRewritenText(SourceRange Range) const {
// If edits have been made to this buffer, the delta between the range may // If edits have been made to this buffer, the delta between the range may
// have changed. // have changed.
std::map<unsigned, RewriteBuffer>::const_iterator I = std::map<FileID, RewriteBuffer>::const_iterator I =
RewriteBuffers.find(StartFileID); RewriteBuffers.find(StartFileID);
if (I == RewriteBuffers.end()) { if (I == RewriteBuffers.end()) {
// If the buffer hasn't been rewritten, just return the text from the input. // If the buffer hasn't been rewritten, just return the text from the input.
@ -149,24 +149,24 @@ std::string Rewriter::getRewritenText(SourceRange Range) const {
} }
unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc, unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
unsigned &FileID) const { FileID &FID) const {
assert(Loc.isValid() && "Invalid location"); assert(Loc.isValid() && "Invalid location");
std::pair<unsigned,unsigned> V = SourceMgr->getDecomposedFileLoc(Loc); std::pair<FileID,unsigned> V = SourceMgr->getDecomposedFileLoc(Loc);
FileID = V.first; FID = V.first;
return V.second; return V.second;
} }
/// getEditBuffer - Get or create a RewriteBuffer for the specified FileID. /// getEditBuffer - Get or create a RewriteBuffer for the specified FileID.
/// ///
RewriteBuffer &Rewriter::getEditBuffer(unsigned FileID) { RewriteBuffer &Rewriter::getEditBuffer(FileID FID) {
std::map<unsigned, RewriteBuffer>::iterator I = std::map<FileID, RewriteBuffer>::iterator I =
RewriteBuffers.lower_bound(FileID); RewriteBuffers.lower_bound(FID);
if (I != RewriteBuffers.end() && I->first == FileID) if (I != RewriteBuffers.end() && I->first == FID)
return I->second; return I->second;
I = RewriteBuffers.insert(I, std::make_pair(FileID, RewriteBuffer())); I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FileID); std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FID);
I->second.Initialize(MB.first, MB.second); I->second.Initialize(MB.first, MB.second);
return I->second; return I->second;
@ -177,18 +177,18 @@ RewriteBuffer &Rewriter::getEditBuffer(unsigned FileID) {
bool Rewriter::InsertText(SourceLocation Loc, const char *StrData, bool Rewriter::InsertText(SourceLocation Loc, const char *StrData,
unsigned StrLen, bool InsertAfter) { unsigned StrLen, bool InsertAfter) {
if (!isRewritable(Loc)) return true; if (!isRewritable(Loc)) return true;
unsigned FileID; FileID FID;
unsigned StartOffs = getLocationOffsetAndFileID(Loc, FileID); unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
getEditBuffer(FileID).InsertText(StartOffs, StrData, StrLen, InsertAfter); getEditBuffer(FID).InsertText(StartOffs, StrData, StrLen, InsertAfter);
return false; return false;
} }
/// RemoveText - Remove the specified text region. /// RemoveText - Remove the specified text region.
bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) { bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
if (!isRewritable(Start)) return true; if (!isRewritable(Start)) return true;
unsigned FileID; FileID FID;
unsigned StartOffs = getLocationOffsetAndFileID(Start, FileID); unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
getEditBuffer(FileID).RemoveText(StartOffs, Length); getEditBuffer(FID).RemoveText(StartOffs, Length);
return false; return false;
} }
@ -198,7 +198,7 @@ bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength, bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
const char *NewStr, unsigned NewLength) { const char *NewStr, unsigned NewLength) {
if (!isRewritable(Start)) return true; if (!isRewritable(Start)) return true;
unsigned StartFileID; FileID StartFileID;
unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID); unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength, getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength,

Просмотреть файл

@ -18,14 +18,14 @@
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
using namespace clang; using namespace clang;
TokenRewriter::TokenRewriter(unsigned FileID, SourceManager &SM, TokenRewriter::TokenRewriter(FileID FID, SourceManager &SM,
const LangOptions &LangOpts) { const LangOptions &LangOpts) {
ScratchBuf.reset(new ScratchBuffer(SM)); ScratchBuf.reset(new ScratchBuffer(SM));
std::pair<const char*,const char*> File = SM.getBufferData(FileID); std::pair<const char*,const char*> File = SM.getBufferData(FID);
// Create a lexer to lex all the tokens of the main file in raw mode. // Create a lexer to lex all the tokens of the main file in raw mode.
Lexer RawLex(SourceLocation::getFileLoc(FileID, 0), Lexer RawLex(SM.getLocForStartOfFile(FID),
LangOpts, File.first, File.second); LangOpts, File.first, File.second);
// Return all comments and whitespace as tokens. // Return all comments and whitespace as tokens.