From 2b2453a7d8fe732561795431f39ceb2b2a832d84 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 17 Jan 2009 06:22:33 +0000 Subject: [PATCH] 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 --- Driver/ASTConsumers.cpp | 6 +- Driver/CacheTokens.cpp | 4 +- Driver/DiagChecker.cpp | 6 +- Driver/HTMLPrint.cpp | 16 ++--- Driver/RewriteBlocks.cpp | 4 +- Driver/RewriteMacros.cpp | 2 +- Driver/RewriteObjC.cpp | 10 +-- Driver/clang.cpp | 6 +- include/clang/Basic/SourceLocation.h | 60 ++++++++++++++++- include/clang/Basic/SourceManager.h | 82 ++++++++++++++---------- include/clang/Lex/PTHLexer.h | 10 +-- include/clang/Lex/PTHManager.h | 14 ++-- include/clang/Lex/Preprocessor.h | 6 +- include/clang/Lex/PreprocessorLexer.h | 22 ++++--- include/clang/Lex/ScratchBuffer.h | 5 +- include/clang/Rewrite/HTMLRewrite.h | 20 ++---- include/clang/Rewrite/Rewriter.h | 13 ++-- include/clang/Rewrite/TokenRewriter.h | 2 +- lib/Basic/SourceLocation.cpp | 2 +- lib/Basic/SourceManager.cpp | 61 ++++++++++-------- lib/Driver/HTMLDiagnostics.cpp | 92 +++++++++++++-------------- lib/Driver/PlistDiagnostics.cpp | 29 +++++---- lib/Lex/Lexer.cpp | 24 ++++--- lib/Lex/PPDirectives.cpp | 12 ++-- lib/Lex/PPLexerChange.cpp | 15 ++--- lib/Lex/PTHLexer.cpp | 63 +++++++++--------- lib/Lex/Pragma.cpp | 10 +-- lib/Lex/Preprocessor.cpp | 21 +++--- lib/Lex/PreprocessorLexer.cpp | 14 ++-- lib/Lex/ScratchBuffer.cpp | 6 +- lib/Lex/TokenLexer.cpp | 3 +- lib/Rewrite/HTMLRewrite.cpp | 50 +++++++-------- lib/Rewrite/Rewriter.cpp | 44 ++++++------- lib/Rewrite/TokenRewriter.cpp | 6 +- 34 files changed, 403 insertions(+), 337 deletions(-) diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 9487a05072..6729746573 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -903,10 +903,10 @@ public: return; SourceManager& SourceMgr = TU.getContext().getSourceManager(); - unsigned ID = SourceMgr.getMainFileID(); - assert (ID && "MainFileID not set!"); + FileID ID = SourceMgr.getMainFileID(); + assert(!ID.isInvalid() && "MainFileID not set!"); 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 logic should probably be moved elsewhere later. diff --git a/Driver/CacheTokens.cpp b/Driver/CacheTokens.cpp index 4693b20bac..d447b90548 100644 --- a/Driver/CacheTokens.cpp +++ b/Driver/CacheTokens.cpp @@ -485,8 +485,8 @@ void PTHWriter::GeneratePTH() { const llvm::MemoryBuffer *B = C.getBuffer(); if (!B) continue; - unsigned FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User); - Lexer L(SourceLocation::getFileLoc(FID, 0), LOpts, + FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User); + Lexer L(SM.getLocForStartOfFile(FID), LOpts, B->getBufferStart(), B->getBufferEnd(), B); PM[FE] = LexTokens(L); } diff --git a/Driver/DiagChecker.cpp b/Driver/DiagChecker.cpp index 8fa827ab19..6503214c52 100644 --- a/Driver/DiagChecker.cpp +++ b/Driver/DiagChecker.cpp @@ -117,12 +117,12 @@ static void FindExpectedDiags(Preprocessor &PP, DiagList &ExpectedNotes) { // 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. - unsigned FileID = PP.getSourceManager().getMainFileID(); + FileID FID = PP.getSourceManager().getMainFileID(); std::pair File = - PP.getSourceManager().getBufferData(FileID); + PP.getSourceManager().getBufferData(FID); // 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); // Return comments as tokens, this is how we find expected diagnostics. diff --git a/Driver/HTMLPrint.cpp b/Driver/HTMLPrint.cpp index 0956c2bca5..b2bb29c9eb 100644 --- a/Driver/HTMLPrint.cpp +++ b/Driver/HTMLPrint.cpp @@ -60,19 +60,19 @@ HTMLPrinter::~HTMLPrinter() { return; // Format the file. - unsigned FileID = R.getSourceMgr().getMainFileID(); - const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FileID); + FileID FID = R.getSourceMgr().getMainFileID(); + const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID); - html::AddLineNumbers(R, FileID); - html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName()); + html::AddLineNumbers(R, FID); + html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName()); // If we have a preprocessor, relex the file and syntax highlight. // We might not have a preprocessor if we come from a deserialized AST file, // for example. - if (PP) html::SyntaxHighlight(R, FileID, *PP); - if (PPF) html::HighlightMacros(R, FileID, *PP); - html::EscapeText(R, FileID, false, true); + if (PP) html::SyntaxHighlight(R, FID, *PP); + if (PPF) html::HighlightMacros(R, FID, *PP); + html::EscapeText(R, FID, false, true); // Open the output. FILE *OutputFILE; @@ -87,7 +87,7 @@ HTMLPrinter::~HTMLPrinter() { } // Emit the HTML. - const RewriteBuffer &RewriteBuf = R.getEditBuffer(FileID); + const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID); char *Buffer = (char*)malloc(RewriteBuf.size()); std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer); fwrite(Buffer, 1, RewriteBuf.size(), OutputFILE); diff --git a/Driver/RewriteBlocks.cpp b/Driver/RewriteBlocks.cpp index e4e470a447..c729a904f6 100644 --- a/Driver/RewriteBlocks.cpp +++ b/Driver/RewriteBlocks.cpp @@ -37,7 +37,7 @@ class RewriteBlocks : public ASTConsumer { ASTContext *Context; SourceManager *SM; - unsigned MainFileID; + FileID MainFileID; const char *MainFileStart, *MainFileEnd; // Block expressions. @@ -223,7 +223,7 @@ void RewriteBlocks::Initialize(ASTContext &context) { Preamble += "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n"; Preamble += "#endif\n"; - InsertText(SourceLocation::getFileLoc(MainFileID, 0), + InsertText(SM->getLocForStartOfFile(MainFileID), Preamble.c_str(), Preamble.size()); } diff --git a/Driver/RewriteMacros.cpp b/Driver/RewriteMacros.cpp index fb423c6413..ecf4b416d8 100644 --- a/Driver/RewriteMacros.cpp +++ b/Driver/RewriteMacros.cpp @@ -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 // 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); // Switch on comment lexing because we really do want them. diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp index cee66f73b1..8af30f22e8 100644 --- a/Driver/RewriteObjC.cpp +++ b/Driver/RewriteObjC.cpp @@ -47,7 +47,7 @@ namespace { ASTContext *Context; SourceManager *SM; TranslationUnitDecl *TUDecl; - unsigned MainFileID; + FileID MainFileID; const char *MainFileStart, *MainFileEnd; SourceLocation LastIncLoc; @@ -597,7 +597,7 @@ void RewriteObjC::HandleTopLevelDecl(Decl *D) { //===----------------------------------------------------------------------===// void RewriteObjC::RewriteInclude() { - SourceLocation LocStart = SourceLocation::getFileLoc(MainFileID, 0); + SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); std::pair MainBuf = SM->getBufferData(MainFileID); const char *MainBufStart = MainBuf.first; const char *MainBufEnd = MainBuf.second; @@ -645,8 +645,8 @@ void RewriteObjC::RewriteTabs() { unsigned Spaces = 8-(VCol & 7); // Get the location of the tab. - SourceLocation TabLoc = - SourceLocation::getFileLoc(MainFileID, BufPtr-MainBufStart); + SourceLocation TabLoc = SM->getLocForStartOfFile(MainFileID); + TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart); // Rewrite the single tab character into a sequence of spaces. ReplaceText(TabLoc, 1, " ", Spaces); @@ -4501,7 +4501,7 @@ void RewriteObjC::HandleTranslationUnit(TranslationUnit& TU) { RewriteInclude(); - InsertText(SourceLocation::getFileLoc(MainFileID, 0), + InsertText(SM->getLocForStartOfFile(MainFileID), Preamble.c_str(), Preamble.size(), false); if (ClassImplementation.size() || CategoryImplementation.size()) diff --git a/Driver/clang.cpp b/Driver/clang.cpp index b7aea6799e..094d360dab 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -919,14 +919,14 @@ static bool InitializePreprocessor(Preprocessor &PP, if (InFile != "-") { const FileEntry *File = FileMgr.getFile(InFile); if (File) SourceMgr.createMainFileID(File, SourceLocation()); - if (SourceMgr.getMainFileID() == 0) { + if (SourceMgr.getMainFileID().isInvalid()) { fprintf(stderr, "Error reading '%s'!\n",InFile.c_str()); return true; } } else { llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN(); if (SB) SourceMgr.createMainFileIDForMemBuffer(SB); - if (SourceMgr.getMainFileID() == 0) { + if (SourceMgr.getMainFileID().isInvalid()) { fprintf(stderr, "Error reading standard input! Empty?\n"); return true; } @@ -1335,7 +1335,7 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, std::pair File = SM.getBufferData(SM.getMainFileID()); // 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); RawLex.SetKeepWhitespaceMode(true); diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index ba359bddae..227313b7bf 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -18,13 +18,46 @@ #include "llvm/Bitcode/SerializationFwd.h" namespace llvm { -class MemoryBuffer; + class MemoryBuffer; + template struct DenseMapInfo; } namespace clang { class SourceManager; 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 /// a full include stack, line and column number information for a position in @@ -269,4 +302,29 @@ public: } // end namespace clang +namespace llvm { + /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and + /// DenseSets. + template <> + struct DenseMapInfo { + 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 diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 4db38017cc..4f46bad8db 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -256,47 +256,47 @@ class SourceManager { /// LastLineNo - These ivars serve as a cache used in the getLineNumber /// method which is used to speedup getLineNumber calls to nearby locations. - mutable unsigned LastLineNoFileIDQuery; + mutable FileID LastLineNoFileIDQuery; mutable SrcMgr::ContentCache *LastLineNoContentCache; mutable unsigned LastLineNoFilePos; mutable unsigned LastLineNoResult; /// MainFileID - The file ID for the main source file of the translation unit. - unsigned MainFileID; + FileID MainFileID; // SourceManager doesn't support copy construction. explicit SourceManager(const SourceManager&); void operator=(const SourceManager&); public: - SourceManager() : LastLineNoFileIDQuery(~0U), MainFileID(0) {} + SourceManager() {} ~SourceManager() {} void clearIDTables() { - MainFileID = 0; + MainFileID = FileID(); FileIDs.clear(); MacroIDs.clear(); - LastLineNoFileIDQuery = ~0U; + LastLineNoFileIDQuery = FileID(); LastLineNoContentCache = 0; } /// 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 /// being #included from the specified IncludePosition. This returns 0 on /// error and translates NULL into standard input. - unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, + FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter) { 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); } /// createMainFileID - Create the FileID for the main source file. - unsigned createMainFileID(const FileEntry *SourceFile, + FileID createMainFileID(const FileEntry *SourceFile, SourceLocation IncludePos) { - assert (MainFileID == 0 && "MainFileID already set!"); + assert(MainFileID.isInvalid() && "MainFileID already set!"); MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User); return MainFileID; } @@ -304,7 +304,7 @@ public: /// createFileIDForMemBuffer - Create a new FileID that represents the /// specified memory buffer. This does no caching of the buffer and takes /// 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(), SrcMgr::C_User); } @@ -312,12 +312,19 @@ public: /// createMainFileIDForMembuffer - Create the FileID for a memory buffer /// 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. - unsigned createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { - assert (MainFileID == 0 && "MainFileID already set!"); + FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { + assert(MainFileID.isInvalid() && "MainFileID already set!"); MainFileID = createFileIDForMemBuffer(Buffer); 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 /// that a token at Loc should actually be referenced from InstantiationLoc. SourceLocation getInstantiationLoc(SourceLocation Loc, @@ -325,13 +332,19 @@ public: /// getBuffer - Return the buffer for the specified FileID. /// - const llvm::MemoryBuffer *getBuffer(unsigned FileID) const { - return getContentCache(FileID)->getBuffer(); + const llvm::MemoryBuffer *getBuffer(FileID FID) const { + 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 /// data for the specified FileID. - std::pair getBufferData(unsigned FileID) const; + std::pair getBufferData(SourceLocation Loc) const; + std::pair getBufferData(FileID FID) const; /// getIncludeLoc - Return the location of the #include for the specified /// SourceLocation. If this is a macro expansion, this transparently figures @@ -414,8 +427,8 @@ public: } /// getFileEntryForID - Returns the FileEntry record for the provided FileID. - const FileEntry* getFileEntryForID(unsigned id) const { - return getContentCache(id)->Entry; + const FileEntry *getFileEntryForID(FileID FID) const { + return getContentCache(FID)->Entry; } /// getCanonicalFileID - Return the canonical FileID for a SourceLocation. @@ -423,14 +436,14 @@ public: /// into multiple chunks. This method returns the unique FileID without /// chunk information for a given SourceLocation. Use this method when /// you want to compare FileIDs across SourceLocations. - unsigned getCanonicalFileID(SourceLocation SpellingLoc) const { + FileID getCanonicalFileID(SourceLocation SpellingLoc) const { return getDecomposedFileLoc(SpellingLoc).first; } /// getDecomposedFileLoc - Decompose the specified file location into a raw /// FileID + Offset pair. The first element is the FileID, the second is the /// offset from the start of the buffer of the location. - std::pair getDecomposedFileLoc(SourceLocation Loc) const { + std::pair getDecomposedFileLoc(SourceLocation Loc) const { assert(Loc.isFileID() && "Isn't a File SourceLocation"); // TODO: Add a flag "is first chunk" to SLOC. @@ -444,7 +457,7 @@ public: 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 @@ -474,8 +487,8 @@ public: SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const { return getFIDInfo(getSpellingLoc(Loc).getFileID())->getFileCharacteristic(); } - SrcMgr::CharacteristicKind getFileCharacteristic(unsigned FileID) const { - return getFIDInfo(FileID)->getFileCharacteristic(); + SrcMgr::CharacteristicKind getFileCharacteristic(FileID FID) const { + return getFIDInfo(FID)->getFileCharacteristic(); } // Iterators over FileInfos. @@ -500,26 +513,29 @@ private: /// createFileID - Create a new fileID for the specified ContentCache and /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. - unsigned createFileID(const SrcMgr::ContentCache* File, - SourceLocation IncludePos, - SrcMgr::CharacteristicKind DirCharacter); + FileID createFileID(const SrcMgr::ContentCache* File, + SourceLocation IncludePos, + SrcMgr::CharacteristicKind DirCharacter); /// getContentCache - Create or return a cached ContentCache for the specified /// 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 /// memory buffer. const SrcMgr::ContentCache* - createMemBufferContentCache(const llvm::MemoryBuffer* Buf); + createMemBufferContentCache(const llvm::MemoryBuffer *Buf); - const SrcMgr::FileIDInfo* getFIDInfo(unsigned FileID) const { - assert(FileID-1 < FileIDs.size() && "Invalid FileID!"); - return &FileIDs[FileID-1]; + const SrcMgr::FileIDInfo *getFIDInfo(unsigned FID) const { + assert(FID-1 < FileIDs.size() && "Invalid FileID!"); + return &FileIDs[FID-1]; + } + const SrcMgr::FileIDInfo *getFIDInfo(FileID FID) const { + return getFIDInfo(FID.ID); } - const SrcMgr::ContentCache *getContentCache(unsigned FileID) const { - return getContentCache(getFIDInfo(FileID)); + const SrcMgr::ContentCache *getContentCache(FileID FID) const { + return getContentCache(getFIDInfo(FID.ID)); } /// Return the ContentCache structure for the specified FileID. diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h index f19d67958f..e58c5e3f2b 100644 --- a/include/clang/Lex/PTHLexer.h +++ b/include/clang/Lex/PTHLexer.h @@ -23,9 +23,7 @@ class PTHManager; class PTHSpellingSearch; class PTHLexer : public PreprocessorLexer { -private: - /// FileID - The SourceManager FileID for the original source file. - unsigned FileID; + SourceLocation FileStartLoc; /// TokBuf - Buffer from PTH file containing raw token data. const char* TokBuf; @@ -66,10 +64,8 @@ protected: friend class PTHManager; /// Create a PTHLexer for the specified token stream. - PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D, - const char* ppcond, - PTHSpellingSearch& mySpellingSrch, - PTHManager& PM); + PTHLexer(Preprocessor& pp, FileID FID, const char *D, const char* ppcond, + PTHSpellingSearch& mySpellingSrch, PTHManager &PM); public: ~PTHLexer() {} diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h index 634c088b8f..c4ecfd6ed1 100644 --- a/include/clang/Lex/PTHManager.h +++ b/include/clang/Lex/PTHManager.h @@ -62,7 +62,7 @@ class PTHManager : public IdentifierInfoLookup { const llvm::MemoryBuffer* Buf; /// A map from FileIDs to SpellingSearch objects. - llvm::DenseMap SpellingMap; + llvm::DenseMap SpellingMap; /// Alloc - Allocator used for IdentifierInfo objects. llvm::BumpPtrAllocator Alloc; @@ -117,20 +117,22 @@ public: /// Unlike the version in IdentifierTable, this returns a pointer instead /// of a reference. If the pointer is NULL then the IdentifierInfo cannot /// 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 /// 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 /// specified file. This method returns NULL if no cached tokens exist. /// 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 diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index b85c725490..e453fd04d6 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -284,7 +284,7 @@ public: /// 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 /// 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 /// tokens from it instead of the current buffer. Args specifies the @@ -456,10 +456,8 @@ public: char getSpelledCharacterAt(SourceLocation SL) const { if (PTH) { SL = SourceMgr.getSpellingLoc(SL); - unsigned FID = SourceMgr.getCanonicalFileID(SL); - unsigned FPos = SourceMgr.getFullFilePos(SL); const char *Data; - if (PTH->getSpelling(FID, FPos, Data)) + if (PTH->getSpelling(SL, Data)) return *Data; } diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h index a889a55b52..3cf0f92b30 100644 --- a/include/clang/Lex/PreprocessorLexer.h +++ b/include/clang/Lex/PreprocessorLexer.h @@ -27,8 +27,8 @@ class PreprocessorLexer { protected: Preprocessor *PP; // Preprocessor object controlling lexing. - /// The SourceManager fileID corresponding to the file being lexed. - const unsigned FileID; + /// The SourceManager FileID corresponding to the file being lexed. + const FileID FID; //===--------------------------------------------------------------------===// // Context-specific lexing flags set by the preprocessor. @@ -67,15 +67,17 @@ protected: void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT friend class Preprocessor; - PreprocessorLexer(Preprocessor* pp, SourceLocation L); - + PreprocessorLexer(Preprocessor *pp, FileID fid) + : PP(pp), FID(fid), ParsingPreprocessorDirective(false), + ParsingFilename(false), LexingRawMode(false) {} + PreprocessorLexer() - : PP(0), FileID(0), + : PP(0), ParsingPreprocessorDirective(false), ParsingFilename(false), LexingRawMode(false) {} - virtual ~PreprocessorLexer(); + virtual ~PreprocessorLexer() {} virtual void IndirectLex(Token& Result) = 0; @@ -143,11 +145,15 @@ public: /// getPP - Return the preprocessor object for this lexer. Preprocessor *getPP() const { return PP; } - unsigned getFileID() const { + FileID getFileID() const { assert(PP && "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 diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h index c1d134de11..eec6a251a5 100644 --- a/include/clang/Lex/ScratchBuffer.h +++ b/include/clang/Lex/ScratchBuffer.h @@ -14,9 +14,10 @@ #ifndef LLVM_CLANG_SCRATCHBUFFER_H #define LLVM_CLANG_SCRATCHBUFFER_H +#include "clang/Basic/SourceLocation.h" + namespace clang { class SourceManager; - class SourceLocation; /// ScratchBuffer - This class exposes a simple interface for the dynamic /// construction of tokens. This is used for builtin macros (e.g. __LINE__) as @@ -24,7 +25,7 @@ namespace clang { class ScratchBuffer { SourceManager &SourceMgr; char *CurBuffer; - unsigned FileID; + SourceLocation BufferStartLoc; unsigned BytesUsed; public: ScratchBuffer(SourceManager &SM); diff --git a/include/clang/Rewrite/HTMLRewrite.h b/include/clang/Rewrite/HTMLRewrite.h index bbb7f3490b..2f5696606e 100644 --- a/include/clang/Rewrite/HTMLRewrite.h +++ b/include/clang/Rewrite/HTMLRewrite.h @@ -51,7 +51,7 @@ namespace html { /// EscapeText - HTMLize a specified file so that special characters are /// 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); /// EscapeText - HTMLized the provided string so that special characters @@ -61,29 +61,21 @@ namespace html { std::string EscapeText(const std::string& s, 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); /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with /// 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 /// file, to reexpand macros and insert (into the HTML) information about the /// macro expansions. This won't be perfectly perfect, but it will be /// reasonably close. - void HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor &PP); - - - void HighlightMacros(Rewriter &R, unsigned FileID, PreprocessorFactory &PPF); - - - - - - + void HighlightMacros(Rewriter &R, FileID FID, Preprocessor &PP); + void HighlightMacros(Rewriter &R, FileID FID, PreprocessorFactory &PPF); } // end html namespace } // end clang namespace diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h index 59ed5d826b..b05770b2aa 100644 --- a/include/clang/Rewrite/Rewriter.h +++ b/include/clang/Rewrite/Rewriter.h @@ -118,7 +118,7 @@ private: // Methods only usable by Rewriter. class Rewriter { SourceManager *SourceMgr; - std::map RewriteBuffers; + std::map RewriteBuffers; public: explicit Rewriter(SourceManager &SM) : SourceMgr(&SM) {} explicit Rewriter() : SourceMgr(0) {} @@ -205,9 +205,9 @@ public: /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID. /// If no modification has been made to it, return null. - const RewriteBuffer *getRewriteBufferFor(unsigned FileID) const { - std::map::const_iterator I = - RewriteBuffers.find(FileID); + const RewriteBuffer *getRewriteBufferFor(FileID FID) const { + std::map::const_iterator I = + RewriteBuffers.find(FID); 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 /// want efficient low-level access to apis for scribbling on one specific /// FileID's buffer. - RewriteBuffer &getEditBuffer(unsigned FileID); + RewriteBuffer &getEditBuffer(FileID FID); private: - unsigned getLocationOffsetAndFileID(SourceLocation Loc, - unsigned &FileID) const; + unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const; }; } // end namespace clang diff --git a/include/clang/Rewrite/TokenRewriter.h b/include/clang/Rewrite/TokenRewriter.h index 1703ea7885..c8fd0f532c 100644 --- a/include/clang/Rewrite/TokenRewriter.h +++ b/include/clang/Rewrite/TokenRewriter.h @@ -48,7 +48,7 @@ namespace clang { public: /// TokenRewriter - This creates a TokenRewriter for the file with the /// specified FileID. - TokenRewriter(unsigned FileID, SourceManager &SM, const LangOptions &LO); + TokenRewriter(FileID FID, SourceManager &SM, const LangOptions &LO); ~TokenRewriter(); typedef std::list::const_iterator token_iterator; diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp index 2b7584efda..84fac86a6d 100644 --- a/lib/Basic/SourceLocation.cpp +++ b/lib/Basic/SourceLocation.cpp @@ -105,7 +105,7 @@ const char *FullSourceLoc::getCharacterData() const { const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const { assert(isValid()); - return SrcMgr->getBuffer(getFileID()); + return SrcMgr->getBuffer(*this); } void FullSourceLoc::dump() const { diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 1240262007..b6c4ffab4d 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -111,7 +111,7 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { /// createFileID - Create a new fileID for the specified ContentCache and /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. -unsigned SourceManager::createFileID(const ContentCache *File, +FileID SourceManager::createFileID(const ContentCache *File, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter) { // If FileEnt is really large (e.g. it's a large .i file), we may not be able @@ -123,7 +123,7 @@ unsigned SourceManager::createFileID(const ContentCache *File, FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter)); assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) && "Ran out of file ID's!"); - return FileIDs.size(); + return FileID::Create(FileIDs.size()); } // Create one FileID for each chunk of the file. @@ -140,7 +140,7 @@ unsigned SourceManager::createFileID(const ContentCache *File, assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) && "Ran out of file ID's!"); - return Result; + return FileID::Create(Result); } /// getInstantiationLoc - Return a new SourceLocation that encodes the fact @@ -181,13 +181,20 @@ SourceLocation SourceManager::getInstantiationLoc(SourceLocation SpellingLoc, } /// getBufferData - Return a pointer to the start and end of the character -/// data for the specified FileID. +/// data for the specified location. std::pair -SourceManager::getBufferData(unsigned FileID) const { - const llvm::MemoryBuffer *Buf = getBuffer(FileID); +SourceManager::getBufferData(SourceLocation Loc) const { + const llvm::MemoryBuffer *Buf = getBuffer(Loc); return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd()); } +std::pair +SourceManager::getBufferData(FileID FID) const { + const llvm::MemoryBuffer *Buf = getBuffer(FID); + return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd()); +} + + /// getCharacterData - Return a pointer to the start of the specified location /// in the appropriate MemoryBuffer. @@ -196,9 +203,11 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const { // heavily used by -E mode. SL = getSpellingLoc(SL); + std::pair LocInfo = getDecomposedFileLoc(SL); + // Note that calling 'getBuffer()' may lazily page in a source file. - return getContentCache(SL.getFileID())->getBuffer()->getBufferStart() + - getFullFilePos(SL); + return getContentCache(LocInfo.first)->getBuffer()->getBufferStart() + + LocInfo.second; } @@ -206,12 +215,12 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const { /// this is significantly cheaper to compute than the line number. This returns /// zero if the column number isn't known. unsigned SourceManager::getColumnNumber(SourceLocation Loc) const { - unsigned FileID = Loc.getFileID(); - if (FileID == 0) return 0; + if (Loc.getFileID() == 0) return 0; - unsigned FilePos = getFullFilePos(Loc); - const MemoryBuffer *Buffer = getBuffer(FileID); - const char *Buf = Buffer->getBufferStart(); + std::pair LocInfo = getDecomposedFileLoc(Loc); + unsigned FilePos = LocInfo.second; + + const char *Buf = getBuffer(LocInfo.first)->getBufferStart(); unsigned LineStart = FilePos; while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r') @@ -223,12 +232,11 @@ unsigned SourceManager::getColumnNumber(SourceLocation Loc) const { /// the SourceLocation specifies. This can be modified with #line directives, /// etc. const char *SourceManager::getSourceName(SourceLocation Loc) const { - unsigned FileID = Loc.getFileID(); - if (FileID == 0) return ""; + if (Loc.getFileID() == 0) return ""; // To get the source name, first consult the FileEntry (if one exists) before // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer. - const SrcMgr::ContentCache* C = getContentCache(FileID); + const SrcMgr::ContentCache *C = getContentCacheForLoc(Loc); return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier(); } @@ -282,15 +290,16 @@ static void ComputeLineNumbers(ContentCache* FI) { /// line offsets for the MemoryBuffer, so this is not cheap: use only when /// about to emit a diagnostic. unsigned SourceManager::getLineNumber(SourceLocation Loc) const { - unsigned FileID = Loc.getFileID(); - if (FileID == 0) return 0; + if (Loc.getFileID() == 0) return 0; - ContentCache* Content; + ContentCache *Content; - if (LastLineNoFileIDQuery == FileID) + std::pair LocInfo = getDecomposedFileLoc(Loc); + + if (LastLineNoFileIDQuery == LocInfo.first) Content = LastLineNoContentCache; else - Content = const_cast(getContentCache(FileID)); + Content = const_cast(getContentCache(LocInfo.first)); // If this is the first use of line information for this buffer, compute the /// SourceLineCache for it on demand. @@ -303,12 +312,12 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const { unsigned *SourceLineCacheStart = SourceLineCache; unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines; - unsigned QueriedFilePos = getFullFilePos(Loc)+1; + unsigned QueriedFilePos = LocInfo.second+1; // If the previous query was to the same file, we know both the file pos from // that query and the line number returned. This allows us to narrow the // search space from the entire file to something near the match. - if (LastLineNoFileIDQuery == FileID) { + if (LastLineNoFileIDQuery == LocInfo.first) { if (QueriedFilePos >= LastLineNoFilePos) { SourceLineCache = SourceLineCache+LastLineNoResult-1; @@ -362,7 +371,7 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const { = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos); unsigned LineNo = Pos-SourceLineCacheStart; - LastLineNoFileIDQuery = FileID; + LastLineNoFileIDQuery = LocInfo.first; LastLineNoContentCache = Content; LastLineNoFilePos = QueriedFilePos; LastLineNoResult = LineNo; @@ -492,7 +501,7 @@ MacroIDInfo MacroIDInfo::ReadVal(llvm::Deserializer& D) { void SourceManager::Emit(llvm::Serializer& S) const { S.EnterBlock(); S.EmitPtr(this); - S.EmitInt(MainFileID); + S.EmitInt(MainFileID.getOpaqueValue()); // Emit: FileInfos. Just emit the file name. S.EnterBlock(); @@ -527,7 +536,7 @@ SourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){ D.RegisterPtr(M); // Read: the FileID of the main source file of the translation unit. - M->MainFileID = D.ReadInt(); + M->MainFileID = FileID::Create(D.ReadInt()); std::vector Buf; diff --git a/lib/Driver/HTMLDiagnostics.cpp b/lib/Driver/HTMLDiagnostics.cpp index f335396ec4..81cedba557 100644 --- a/lib/Driver/HTMLDiagnostics.cpp +++ b/lib/Driver/HTMLDiagnostics.cpp @@ -49,10 +49,10 @@ public: virtual void HandlePathDiagnostic(const PathDiagnostic* D); - void HandlePiece(Rewriter& R, unsigned BugFileID, + void HandlePiece(Rewriter& R, FileID BugFileID, const PathDiagnosticPiece& P, unsigned num, unsigned max); - void HighlightRange(Rewriter& R, unsigned BugFileID, SourceRange Range); + void HighlightRange(Rewriter& R, FileID BugFileID, SourceRange Range); void ReportDiag(const PathDiagnostic& D); }; @@ -125,17 +125,15 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { return; SourceManager &SMgr = D.begin()->getLocation().getManager(); - unsigned FileID = 0; - bool FileIDInitialized = false; + FileID FID; // Verify that the entire path is from the same FileID. for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) { FullSourceLoc L = I->getLocation().getInstantiationLoc(); - if (!FileIDInitialized) { - FileID = SMgr.getCanonicalFileID(L); - FileIDInitialized = true; - } else if (SMgr.getCanonicalFileID(L) != FileID) + if (FID.isInvalid()) { + FID = SMgr.getCanonicalFileID(L); + } else if (SMgr.getCanonicalFileID(L) != FID) return; // FIXME: Emit a warning? // Check the source ranges. @@ -147,7 +145,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { if (!L.isFileID()) return; // FIXME: Emit a warning? - if (SMgr.getCanonicalFileID(L) != FileID) + if (SMgr.getCanonicalFileID(L) != FID) return; // FIXME: Emit a warning? L = SMgr.getInstantiationLoc(RI->getEnd()); @@ -155,12 +153,12 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { if (!L.isFileID()) return; // FIXME: Emit a warning? - if (SMgr.getCanonicalFileID(L) != FileID) + if (SMgr.getCanonicalFileID(L) != FID) return; // FIXME: Emit a warning? } } - if (!FileIDInitialized) + if (FID.isInvalid()) return; // FIXME: Emit a warning? // Create a new rewriter to generate HTML. @@ -174,31 +172,31 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend(); I!=E; ++I, --n) { - HandlePiece(R, FileID, *I, n, max); + HandlePiece(R, FID, *I, n, max); } // Add line numbers, header, footer, etc. - // unsigned FileID = R.getSourceMgr().getMainFileID(); - html::EscapeText(R, FileID); - html::AddLineNumbers(R, FileID); + // unsigned FID = R.getSourceMgr().getMainFileID(); + html::EscapeText(R, FID); + html::AddLineNumbers(R, FID); // If we have a preprocessor, relex the file and syntax highlight. // We might not have a preprocessor if we come from a deserialized AST file, // for example. - if (PP) html::SyntaxHighlight(R, FileID, *PP); + if (PP) html::SyntaxHighlight(R, FID, *PP); // FIXME: We eventually want to use PPF to create a fresh Preprocessor, // once we have worked out the bugs. // - // if (PPF) html::HighlightMacros(R, FileID, *PPF); + // if (PPF) html::HighlightMacros(R, FID, *PPF); // - if (PP) html::HighlightMacros(R, FileID, *PP); + if (PP) html::HighlightMacros(R, FID, *PP); // Get the full directory name of the analyzed file. - const FileEntry* Entry = SMgr.getFileEntryForID(FileID); + const FileEntry* Entry = SMgr.getFileEntryForID(FID); // This is a cludge; basically we want to append either the full // working directory if we have no directory information. This is @@ -241,7 +239,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { os << "\n\n" "

Annotated Source Code

\n"; - R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); + R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); } // Embed meta-data tags. @@ -252,7 +250,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { std::string s; llvm::raw_string_ostream os(s); os << "\n\n"; - R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); + R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); } const std::string& BugCategory = D.getCategory(); @@ -261,14 +259,14 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { std::string s; llvm::raw_string_ostream os(s); os << "\n\n"; - R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); + R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); } { std::string s; llvm::raw_string_ostream os(s); os << "\n\n"; - R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); + R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); } { @@ -276,22 +274,22 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { llvm::raw_string_ostream os(s); os << "\n\n"; - R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); + R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); } { std::string s; llvm::raw_string_ostream os(s); os << "\n\n"; - R.InsertStrBefore(SourceLocation::getFileLoc(FileID, 0), os.str()); + R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); } // Add CSS, header, and footer. - html::AddHeaderFooterInternalBuiltinCSS(R, FileID, Entry->getName()); + html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName()); // Get the rewrite buffer. - const RewriteBuffer *Buf = R.getRewriteBufferFor(FileID); + const RewriteBuffer *Buf = R.getRewriteBufferFor(FID); if (!Buf) { llvm::cerr << "warning: no diagnostics generated for main file.\n"; @@ -325,28 +323,26 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { os << *I; } -void HTMLDiagnostics::HandlePiece(Rewriter& R, unsigned BugFileID, +void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, const PathDiagnosticPiece& P, unsigned num, unsigned max) { // For now, just draw a box above the line in question, and emit the // warning. - FullSourceLoc Pos = P.getLocation(); if (!Pos.isValid()) return; - SourceManager& SM = R.getSourceMgr(); + SourceManager &SM = R.getSourceMgr(); FullSourceLoc LPos = Pos.getInstantiationLoc(); - unsigned FileID = SM.getCanonicalFileID(LPos); - - assert (&LPos.getManager() == &SM && "SourceManagers are different!"); + FileID FID = SM.getCanonicalFileID(LPos); + assert(&LPos.getManager() == &SM && "SourceManagers are different!"); if (SM.getCanonicalFileID(LPos) != BugFileID) return; - const llvm::MemoryBuffer *Buf = SM.getBuffer(FileID); + const llvm::MemoryBuffer *Buf = SM.getBuffer(FID); const char* FileStart = Buf->getBufferStart(); // Compute the column number. Rewind from the current position to the start @@ -436,30 +432,30 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, unsigned BugFileID, os << html::EscapeText(Msg) << ""; // Insert the new html. - unsigned DisplayPos = 0; - + unsigned DisplayPos; switch (P.getDisplayHint()) { - case PathDiagnosticPiece::Above: - DisplayPos = LineStart - FileStart; - break; - case PathDiagnosticPiece::Below: - DisplayPos = LineEnd - FileStart; - break; - default: - assert (false && "Unhandled hint."); + default: assert(0 && "Unhandled hint."); + case PathDiagnosticPiece::Above: + DisplayPos = LineStart - FileStart; + break; + case PathDiagnosticPiece::Below: + DisplayPos = LineEnd - FileStart; + break; } - - R.InsertStrBefore(SourceLocation::getFileLoc(FileID, DisplayPos), os.str()); + + SourceLocation Loc = + SM.getLocForStartOfFile(FID).getFileLocWithOffset(DisplayPos); + R.InsertStrBefore(Loc, os.str()); } // Now highlight the ranges. for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end(); I != E; ++I) - HighlightRange(R, FileID, *I); + HighlightRange(R, FID, *I); } -void HTMLDiagnostics::HighlightRange(Rewriter& R, unsigned BugFileID, +void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID, SourceRange Range) { SourceManager& SM = R.getSourceMgr(); diff --git a/lib/Driver/PlistDiagnostics.cpp b/lib/Driver/PlistDiagnostics.cpp index 14280288cd..0b2ca52f11 100644 --- a/lib/Driver/PlistDiagnostics.cpp +++ b/lib/Driver/PlistDiagnostics.cpp @@ -20,9 +20,9 @@ #include "llvm/System/Path.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" - using namespace clang; -typedef llvm::DenseMap FIDMap; + +typedef llvm::DenseMap FIDMap; namespace clang { class Preprocessor; @@ -51,27 +51,28 @@ clang::CreatePlistDiagnosticClient(const std::string& s, return new PlistDiagnostics(s); } -static void AddFID(FIDMap& FIDs, - llvm::SmallVectorImpl& V, +static void AddFID(FIDMap &FIDs, + llvm::SmallVectorImpl &V, SourceManager& SM, SourceLocation L) { - unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L)); - FIDMap::iterator I = FIDs.find(fid); + FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L)); + FIDMap::iterator I = FIDs.find(FID); if (I != FIDs.end()) return; - FIDs[fid] = V.size(); - V.push_back(fid); + FIDs[FID] = V.size(); + V.push_back(FID); } static unsigned GetFID(const FIDMap& FIDs, SourceManager& SM, SourceLocation L) { - unsigned fid = SM.getCanonicalFileID(SM.getInstantiationLoc(L)); - FIDMap::const_iterator I = FIDs.find(fid); - assert (I != FIDs.end()); + FileID FID = SM.getCanonicalFileID(SM.getInstantiationLoc(L)); + FIDMap::const_iterator I = FIDs.find(FID); + assert(I != FIDs.end()); return I->second; } static llvm::raw_ostream& Indent(llvm::raw_ostream& o, const unsigned indent) { - for (unsigned i = 0; i < indent; ++i) o << ' '; + for (unsigned i = 0; i < indent; ++i) + o << ' '; return o; } @@ -171,7 +172,7 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) { // Build up a set of FIDs that we use by scanning the locations and // ranges of the diagnostics. FIDMap FM; - llvm::SmallVector Fids; + llvm::SmallVector Fids; for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I) { AddFID(FM, Fids, SM, I->getLocation()); @@ -214,7 +215,7 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) { " files\n" " \n"; - for (llvm::SmallVectorImpl::iterator I=Fids.begin(), E=Fids.end(); + for (llvm::SmallVectorImpl::iterator I=Fids.begin(), E=Fids.end(); I!=E; ++I) o << " " << SM.getFileEntryForID(*I)->getName() << "\n"; diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 5a14c1356a..d63c8cc37b 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -62,14 +62,18 @@ tok::ObjCKeywordKind Token::getObjCKeywordID() const { /// with the specified preprocessor managing the lexing process. This lexer /// assumes that the associated file buffer and Preprocessor objects will /// outlive it, so it doesn't take ownership of either of them. -Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp, +Lexer::Lexer(SourceLocation fileloc, Preprocessor &PP, const char *BufStart, const char *BufEnd) - : PreprocessorLexer(&pp, fileloc), FileLoc(fileloc), - Features(pp.getLangOptions()) { +// FIXME: This is really horrible and only needed for _Pragma lexers, split this +// out of the main lexer path! + : PreprocessorLexer(&PP, + PP.getSourceManager().getCanonicalFileID( + PP.getSourceManager().getSpellingLoc(fileloc))), + FileLoc(fileloc), + Features(PP.getLangOptions()) { - SourceManager &SourceMgr = PP->getSourceManager(); - unsigned InputFileID = SourceMgr.getSpellingLoc(FileLoc).getFileID(); - const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(InputFileID); + SourceManager &SourceMgr = PP.getSourceManager(); + const llvm::MemoryBuffer *InputFile = SourceMgr.getBuffer(getFileID()); Is_PragmaLexer = false; InitCharacterInfo(); @@ -103,7 +107,7 @@ Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp, // Default to keeping comments if the preprocessor wants them. ExtendedTokenMode = 0; - SetCommentRetentionState(PP->getCommentRetentionState()); + SetCommentRetentionState(PP.getCommentRetentionState()); } /// Lexer constructor - Create a new raw lexer object. This object is only @@ -187,9 +191,7 @@ unsigned Lexer::MeasureTokenLength(SourceLocation Loc, // all obviously single-char tokens. This could use // Lexer::isObviouslySimpleCharacter for example to handle identifiers or // something. - - - const char *BufEnd = SM.getBufferData(Loc.getFileID()).second; + const char *BufEnd = SM.getBufferData(Loc).second; // Create a langops struct and enable trigraphs. This is sufficient for // measuring tokens. @@ -303,6 +305,8 @@ SourceLocation Lexer::getSourceLocation(const char *Loc) const { if (FileLoc.isFileID()) return SourceLocation::getFileLoc(FileLoc.getFileID(), CharNo); + // Otherwise, this is the _Pragma lexer case, which pretends that all of the + // tokens are lexed from where the _Pragma was defined. assert(PP && "This doesn't work on raw lexers"); return GetMappedTokenLoc(*PP, FileLoc, CharNo); } diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 0566ec54b0..f7551a2532 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -394,8 +394,8 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart, // info about where the current file is. const FileEntry *CurFileEnt = 0; if (!FromDir) { - unsigned FileID = getCurrentFileLexer()->getFileID(); - CurFileEnt = SourceMgr.getFileEntryForID(FileID); + FileID FID = getCurrentFileLexer()->getFileID(); + CurFileEnt = SourceMgr.getFileEntryForID(FID); } // Do a standard file entry lookup. @@ -786,16 +786,16 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok, SourceMgr.getFileCharacteristic(getCurrentFileLexer()->getFileID())); // Look up the file, create a File ID for it. - unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(), - FileCharacter); - if (FileID == 0) { + FileID FID = SourceMgr.createFileID(File, FilenameTok.getLocation(), + FileCharacter); + if (FID.isInvalid()) { Diag(FilenameTok, diag::err_pp_file_not_found) << std::string(FilenameStart, FilenameEnd); return; } // Finally, if all is good, enter the new file! - EnterSourceFile(FileID, CurDir); + EnterSourceFile(FID, CurDir); } /// HandleIncludeNextDirective - Implements #include_next. diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index 0ecca3a8cc..cc8ccc4c10 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -66,8 +66,7 @@ PreprocessorLexer *Preprocessor::getCurrentFileLexer() const { /// EnterSourceFile - Add a source file to the top of the include stack and /// start lexing tokens from it instead of the current buffer. Return true /// on failure. -void Preprocessor::EnterSourceFile(unsigned FileID, - const DirectoryLookup *CurDir) { +void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir) { assert(CurTokenLexer == 0 && "Cannot #include a file inside a macro!"); ++NumEnteredSourceFiles; @@ -75,8 +74,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID, MaxIncludeStackDepth = IncludeMacroStack.size(); if (PTH) { - PTHLexer* PL = - PTH->CreateLexer(FileID, getSourceManager().getFileEntryForID(FileID)); + PTHLexer *PL = PTH->CreateLexer(FID, SourceMgr.getFileEntryForID(FID)); if (PL) { EnterSourceFileWithPTH(PL, CurDir); @@ -84,7 +82,7 @@ void Preprocessor::EnterSourceFile(unsigned FileID, } } - Lexer *TheLexer = new Lexer(SourceLocation::getFileLoc(FileID, 0), *this); + Lexer *TheLexer = new Lexer(SourceMgr.getLocForStartOfFile(FID), *this); EnterSourceFileWithLexer(TheLexer, CurDir); } @@ -125,10 +123,9 @@ void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL, // Notify the client, if desired, that we are in a new source file. if (Callbacks) { - unsigned FileID = CurPPLexer->getFileID(); - SrcMgr::CharacteristicKind FileType = - SourceMgr.getFileCharacteristic(CurPPLexer->getFileID()); - Callbacks->FileChanged(SourceLocation::getFileLoc(FileID, 0), + FileID FID = CurPPLexer->getFileID(); + SrcMgr::CharacteristicKind FileType = SourceMgr.getFileCharacteristic(FID); + Callbacks->FileChanged(SourceMgr.getLocForStartOfFile(FID), PPCallbacks::EnterFile, FileType); } } diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp index 6401b9ac8f..b2870f46fd 100644 --- a/lib/Lex/PTHLexer.cpp +++ b/lib/Lex/PTHLexer.cpp @@ -23,7 +23,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/OwningPtr.h" - using namespace clang; #define DISK_TOKEN_SIZE (1+1+3+4+2) @@ -48,15 +47,14 @@ static inline uint32_t Read32(const char*& data) { // PTHLexer methods. //===----------------------------------------------------------------------===// -PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const char* D, - const char* ppcond, - PTHSpellingSearch& mySpellingSrch, - PTHManager& PM) - : PreprocessorLexer(&pp, fileloc), TokBuf(D), CurPtr(D), LastHashTokPtr(0), +PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const char *D, + const char *ppcond, + PTHSpellingSearch &mySpellingSrch, PTHManager &PM) + : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0), PPCond(ppcond), CurPPCondPtr(ppcond), MySpellingSrch(mySpellingSrch), - PTHMgr(PM) -{ - FileID = fileloc.getFileID(); + PTHMgr(PM) { + + FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID); } void PTHLexer::Lex(Token& Tok) { @@ -96,7 +94,7 @@ LexNextToken: Tok.setFlag(flags); assert(!LexingRawMode); Tok.setIdentifierInfo(perID ? PTHMgr.GetIdentifierInfo(perID-1) : 0); - Tok.setLocation(SourceLocation::getFileLoc(FileID, FileOffset)); + Tok.setLocation(FileStartLoc.getFileLocWithOffset(FileOffset)); Tok.setLength(Len); //===--------------------------------------==// @@ -295,23 +293,27 @@ SourceLocation PTHLexer::getSourceLocation() { | (((uint32_t) ((uint8_t) p[1])) << 8) | (((uint32_t) ((uint8_t) p[2])) << 16) | (((uint32_t) ((uint8_t) p[3])) << 24); - return SourceLocation::getFileLoc(FileID, offset); + return FileStartLoc.getFileLocWithOffset(offset); } //===----------------------------------------------------------------------===// // getSpelling() - Use cached data in PTH files for getSpelling(). //===----------------------------------------------------------------------===// -unsigned PTHManager::getSpelling(unsigned FileID, unsigned fpos, - const char *& Buffer) { - - llvm::DenseMap::iterator I = - SpellingMap.find(FileID); +unsigned PTHManager::getSpelling(FileID FID, unsigned FPos, + const char *&Buffer) { + llvm::DenseMap::iterator I =SpellingMap.find(FID); if (I == SpellingMap.end()) return 0; - return I->second->getSpellingBinarySearch(fpos, Buffer); + return I->second->getSpellingBinarySearch(FPos, Buffer); +} + +unsigned PTHManager::getSpelling(SourceLocation Loc, const char *&Buffer) { + std::pair LocInfo = + PP->getSourceManager().getDecomposedFileLoc(Loc); + return getSpelling(LocInfo.first, LocInfo.second, Buffer); } unsigned PTHManager::getSpellingAtPTHOffset(unsigned PTHOffset, @@ -420,14 +422,17 @@ unsigned PTHSpellingSearch::getSpellingBinarySearch(unsigned fpos, return 0; } -unsigned PTHLexer::getSpelling(SourceLocation sloc, const char *&Buffer) { - SourceManager& SM = PP->getSourceManager(); - sloc = SM.getSpellingLoc(sloc); - unsigned fid = SM.getCanonicalFileID(sloc); - unsigned fpos = SM.getFullFilePos(sloc); +unsigned PTHLexer::getSpelling(SourceLocation Loc, const char *&Buffer) { + SourceManager &SM = PP->getSourceManager(); + Loc = SM.getSpellingLoc(Loc); + std::pair LocInfo = SM.getDecomposedFileLoc(Loc); + + FileID FID = LocInfo.first; + unsigned FPos = LocInfo.second; - return (fid == FileID ) ? MySpellingSrch.getSpellingLinearSearch(fpos, Buffer) - : PTHMgr.getSpelling(fid, fpos, Buffer); + if (FID == getFileID()) + return MySpellingSrch.getSpellingLinearSearch(FPos, Buffer); + return PTHMgr.getSpelling(FID, FPos, Buffer); } //===----------------------------------------------------------------------===// @@ -662,15 +667,14 @@ IdentifierInfo* PTHManager::get(const char *NameStart, const char *NameEnd) { } -PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) { - +PTHLexer* PTHManager::CreateLexer(FileID FID, const FileEntry* FE) { if (!FE) return 0; // Lookup the FileEntry object in our file lookup data structure. It will // return a variant that indicates whether or not there is an offset within // the PTH file that contains cached tokens. - PTHFileLookup::Val FileData = ((PTHFileLookup*) FileLookup)->Lookup(FE); + PTHFileLookup::Val FileData = ((PTHFileLookup*)FileLookup)->Lookup(FE); if (!FileData.isValid()) // No tokens available. return 0; @@ -694,9 +698,8 @@ PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) { // Create the SpellingSearch object for this FileID. PTHSpellingSearch* ss = new PTHSpellingSearch(*this, len, spellingTable); - SpellingMap[FileID] = ss; + SpellingMap[FID] = ss; assert(PP && "No preprocessor set yet!"); - return new PTHLexer(*PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond, - *ss, *this); + return new PTHLexer(*PP, FID, data, ppcond, *ss, *this); } diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 667e4361a8..860301650b 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -191,10 +191,8 @@ void Preprocessor::HandlePragmaOnce(Token &OnceTok) { } // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc. - unsigned FileID = getCurrentFileLexer()->getFileID(); - // Mark the file as a once-only file now. - HeaderInfo.MarkFileIncludeOnce(SourceMgr.getFileEntryForID(FileID)); + HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry()); } void Preprocessor::HandlePragmaMark() { @@ -256,8 +254,7 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) { PreprocessorLexer *TheLexer = getCurrentFileLexer(); // Mark the file as a system header. - const FileEntry *File = SourceMgr.getFileEntryForID(TheLexer->getFileID()); - HeaderInfo.MarkFileSystemHeader(File); + HeaderInfo.MarkFileSystemHeader(TheLexer->getFileEntry()); // Notify the client, if desired, that we are in a new source file. if (Callbacks) @@ -299,8 +296,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) { return; } - unsigned FileID = getCurrentFileLexer()->getFileID(); - const FileEntry *CurFile = SourceMgr.getFileEntryForID(FileID); + const FileEntry *CurFile = getCurrentFileLexer()->getFileEntry(); // If this file is older than the file it depends on, emit a diagnostic. if (CurFile && CurFile->getModificationTime() < File->getModificationTime()) { diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index bbe0f5c0f9..976e1a2f7a 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -200,9 +200,7 @@ std::string Preprocessor::getSpelling(const Token &Tok) const { if (PTH) { SourceLocation SLoc = SourceMgr.getSpellingLoc(Tok.getLocation()); - unsigned fid = SourceMgr.getCanonicalFileID(SLoc); - unsigned fpos = SourceMgr.getFullFilePos(SLoc); - if (unsigned Len = PTH->getSpelling(fid, fpos, TokStart)) { + if (unsigned Len = PTH->getSpelling(SLoc, TokStart)) { assert(!Tok.needsCleaning()); return std::string(TokStart, TokStart+Len); } @@ -256,10 +254,8 @@ unsigned Preprocessor::getSpelling(const Token &Tok, if (CurPTHLexer) { Len = CurPTHLexer.get()->getSpelling(Tok.getLocation(), Buffer); } else { - SourceLocation SLoc = SourceMgr.getSpellingLoc(Tok.getLocation()); - unsigned FID = SourceMgr.getCanonicalFileID(SLoc); - unsigned FPos = SourceMgr.getFullFilePos(SLoc); - Len = PTH->getSpelling(FID, FPos, Buffer); + Len = PTH->getSpelling(SourceMgr.getSpellingLoc(Tok.getLocation()), + Buffer); } // 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. void Preprocessor::EnterMainSourceFile() { - unsigned MainFileID = SourceMgr.getMainFileID(); + FileID MainFileID = SourceMgr.getMainFileID(); // Enter the main file source buffer. EnterSourceFile(MainFileID, 0); // Tell the header info that the main file was entered. If the file is later // #imported, it won't be re-entered. - if (const FileEntry *FE = - SourceMgr.getFileEntryForLoc(SourceLocation::getFileLoc(MainFileID, 0))) + if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID)) HeaderInfo.IncrementIncludeCount(FE); std::vector PrologFile; @@ -685,11 +680,11 @@ void Preprocessor::EnterMainSourceFile() { llvm::MemoryBuffer::getMemBufferCopy(&PrologFile.front(),&PrologFile.back(), ""); assert(SB && "Cannot fail to create predefined source buffer"); - unsigned FileID = SourceMgr.createFileIDForMemBuffer(SB); - assert(FileID && "Could not create FileID for predefines?"); + FileID FID = SourceMgr.createFileIDForMemBuffer(SB); + assert(!FID.isInvalid() && "Could not create FileID for predefines?"); // Start parsing the predefines. - EnterSourceFile(FileID, 0); + EnterSourceFile(FID, 0); } diff --git a/lib/Lex/PreprocessorLexer.cpp b/lib/Lex/PreprocessorLexer.cpp index 07329e0cc7..e98afccbba 100644 --- a/lib/Lex/PreprocessorLexer.cpp +++ b/lib/Lex/PreprocessorLexer.cpp @@ -17,14 +17,6 @@ #include "clang/Basic/SourceManager.h" 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 /// (potentially) macro expand the filename. void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) { @@ -45,3 +37,9 @@ void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) { if (FilenameTok.is(tok::eom)) 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()); +} diff --git a/lib/Lex/ScratchBuffer.cpp b/lib/Lex/ScratchBuffer.cpp index 99fbdf7565..ec07a71baf 100644 --- a/lib/Lex/ScratchBuffer.cpp +++ b/lib/Lex/ScratchBuffer.cpp @@ -24,7 +24,6 @@ static const unsigned ScratchBufSize = 4060; ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) { // Set BytesUsed so that the first call to getToken will require an alloc. BytesUsed = ScratchBufSize; - FileID = 0; } /// 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) && "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::getNewMemBuffer(RequestLen, ""); - FileID = SourceMgr.createFileIDForMemBuffer(Buf); + FileID FID = SourceMgr.createFileIDForMemBuffer(Buf); + BufferStartLoc = SourceMgr.getLocForStartOfFile(FID); CurBuffer = const_cast(Buf->getBufferStart()); BytesUsed = 0; } diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp index 6399e867b3..fde29359fd 100644 --- a/lib/Lex/TokenLexer.cpp +++ b/lib/Lex/TokenLexer.cpp @@ -392,8 +392,7 @@ bool TokenLexer::PasteTokens(Token &Tok) { SourceManager &SourceMgr = PP.getSourceManager(); const char *ResultStrData = SourceMgr.getCharacterData(ResultTokLoc); - const llvm::MemoryBuffer *Buffer = - SourceMgr.getBuffer(ResultTokLoc.getFileID()); + const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ResultTokLoc); // Make a lexer object so that we lex and expand the paste result. Lexer TL(ResultTokLoc, PP.getLangOptions(), ResultStrData, diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp index a605a1e665..d61da4010a 100644 --- a/lib/Rewrite/HTMLRewrite.cpp +++ b/lib/Rewrite/HTMLRewrite.cpp @@ -33,8 +33,8 @@ void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E, SourceManager &SM = R.getSourceMgr(); B = SM.getInstantiationLoc(B); E = SM.getInstantiationLoc(E); - unsigned FileID = SM.getCanonicalFileID(B); - assert(SM.getCanonicalFileID(E) == FileID && "B/E not in the same file!"); + FileID FID = SM.getCanonicalFileID(B); + assert(SM.getCanonicalFileID(E) == FID && "B/E not in the same file!"); unsigned BOffset = SM.getFullFilePos(B); 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. EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr()); - HighlightRange(R.getEditBuffer(FileID), BOffset, EOffset, - SM.getBufferData(FileID).first, StartTag, EndTag); + HighlightRange(R.getEditBuffer(FID), BOffset, EOffset, + SM.getBufferData(FID).first, StartTag, EndTag); } /// 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) { - const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); + const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID); const char* C = Buf->getBufferStart(); const char* FileEnd = Buf->getBufferEnd(); assert (C <= FileEnd); - RewriteBuffer &RB = R.getEditBuffer(FileID); + RewriteBuffer &RB = R.getEditBuffer(FID); unsigned ColNo = 0; 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* FileEnd = Buf->getBufferEnd(); const char* C = FileBeg; - RewriteBuffer &RB = R.getEditBuffer(FileID); + RewriteBuffer &RB = R.getEditBuffer(FID); assert (C <= FileEnd); @@ -263,15 +263,15 @@ void html::AddLineNumbers(Rewriter& R, unsigned FileID) { RB.InsertTextAfter(FileEnd - FileBeg, "", strlen("")); } -void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID, +void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID, 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* FileEnd = Buf->getBufferEnd(); - SourceLocation StartLoc = SourceLocation::getFileLoc(FileID, 0); - SourceLocation EndLoc = SourceLocation::getFileLoc(FileID, FileEnd-FileStart); + SourceLocation StartLoc = R.getSourceMgr().getLocForStartOfFile(FID); + SourceLocation EndLoc = StartLoc.getFileLocWithOffset(FileEnd-FileStart); std::string 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 /// table state from the end of the file, so it won't be perfectly perfect, /// but it will be reasonably close. -void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) { - RewriteBuffer &RB = R.getEditBuffer(FileID); +void html::SyntaxHighlight(Rewriter &R, FileID FID, Preprocessor &PP) { + RewriteBuffer &RB = R.getEditBuffer(FID); const SourceManager &SourceMgr = PP.getSourceManager(); - std::pair File = SourceMgr.getBufferData(FileID); + std::pair File = SourceMgr.getBufferData(FID); const char *BufferStart = File.first; - Lexer L(SourceLocation::getFileLoc(FileID, 0), PP.getLangOptions(), - File.first, File.second); + Lexer L(SourceMgr.getLocForStartOfFile(FID), + PP.getLangOptions(), File.first, File.second); // Inform the preprocessor that we want to retain comments as tokens, so we // 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 /// macro expansions. This won't be perfectly perfect, but it will be /// 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. 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. SourceLocation LLoc = SourceMgr.getInstantiationLoc(Tok.getLocation()); - std::pair LLocInfo = + std::pair LLocInfo = SourceMgr.getDecomposedFileLoc(LLoc); - if (LLocInfo.first != FileID) { + if (LLocInfo.first != FID) { PP.Lex(Tok); 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) { llvm::OwningPtr PP(PPF.CreatePreprocessor()); - HighlightMacros(R, FileID, *PP); + HighlightMacros(R, FID, *PP); } diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp index ea8dcb9010..e92bd7d329 100644 --- a/lib/Rewrite/Rewriter.cpp +++ b/lib/Rewrite/Rewriter.cpp @@ -71,8 +71,8 @@ int Rewriter::getRangeSize(SourceRange Range) const { if (!isRewritable(Range.getBegin()) || !isRewritable(Range.getEnd())) return -1; - unsigned StartOff, StartFileID; - unsigned EndOff , EndFileID; + FileID StartFileID, EndFileID; + unsigned StartOff, EndOff; StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID); 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 // have changed. - std::map::const_iterator I = + std::map::const_iterator I = RewriteBuffers.find(StartFileID); if (I != RewriteBuffers.end()) { const RewriteBuffer &RB = I->second; @@ -109,8 +109,8 @@ std::string Rewriter::getRewritenText(SourceRange Range) const { !isRewritable(Range.getEnd())) return ""; - unsigned StartOff, StartFileID; - unsigned EndOff , EndFileID; + FileID StartFileID, EndFileID; + unsigned StartOff, EndOff; StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID); 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 // have changed. - std::map::const_iterator I = + std::map::const_iterator I = RewriteBuffers.find(StartFileID); if (I == RewriteBuffers.end()) { // 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 &FileID) const { + FileID &FID) const { assert(Loc.isValid() && "Invalid location"); - std::pair V = SourceMgr->getDecomposedFileLoc(Loc); - FileID = V.first; + std::pair V = SourceMgr->getDecomposedFileLoc(Loc); + FID = V.first; return V.second; } /// getEditBuffer - Get or create a RewriteBuffer for the specified FileID. /// -RewriteBuffer &Rewriter::getEditBuffer(unsigned FileID) { - std::map::iterator I = - RewriteBuffers.lower_bound(FileID); - if (I != RewriteBuffers.end() && I->first == FileID) +RewriteBuffer &Rewriter::getEditBuffer(FileID FID) { + std::map::iterator I = + RewriteBuffers.lower_bound(FID); + if (I != RewriteBuffers.end() && I->first == FID) return I->second; - I = RewriteBuffers.insert(I, std::make_pair(FileID, RewriteBuffer())); + I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer())); - std::pair MB = SourceMgr->getBufferData(FileID); + std::pair MB = SourceMgr->getBufferData(FID); I->second.Initialize(MB.first, MB.second); return I->second; @@ -177,18 +177,18 @@ RewriteBuffer &Rewriter::getEditBuffer(unsigned FileID) { bool Rewriter::InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen, bool InsertAfter) { if (!isRewritable(Loc)) return true; - unsigned FileID; - unsigned StartOffs = getLocationOffsetAndFileID(Loc, FileID); - getEditBuffer(FileID).InsertText(StartOffs, StrData, StrLen, InsertAfter); + FileID FID; + unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID); + getEditBuffer(FID).InsertText(StartOffs, StrData, StrLen, InsertAfter); return false; } /// RemoveText - Remove the specified text region. bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) { if (!isRewritable(Start)) return true; - unsigned FileID; - unsigned StartOffs = getLocationOffsetAndFileID(Start, FileID); - getEditBuffer(FileID).RemoveText(StartOffs, Length); + FileID FID; + unsigned StartOffs = getLocationOffsetAndFileID(Start, FID); + getEditBuffer(FID).RemoveText(StartOffs, Length); return false; } @@ -198,7 +198,7 @@ bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) { bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength, const char *NewStr, unsigned NewLength) { if (!isRewritable(Start)) return true; - unsigned StartFileID; + FileID StartFileID; unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID); getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength, diff --git a/lib/Rewrite/TokenRewriter.cpp b/lib/Rewrite/TokenRewriter.cpp index f288ac2402..85d83c2dea 100644 --- a/lib/Rewrite/TokenRewriter.cpp +++ b/lib/Rewrite/TokenRewriter.cpp @@ -18,14 +18,14 @@ #include "clang/Basic/SourceManager.h" using namespace clang; -TokenRewriter::TokenRewriter(unsigned FileID, SourceManager &SM, +TokenRewriter::TokenRewriter(FileID FID, SourceManager &SM, const LangOptions &LangOpts) { ScratchBuf.reset(new ScratchBuffer(SM)); - std::pair File = SM.getBufferData(FileID); + std::pair File = SM.getBufferData(FID); // 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); // Return all comments and whitespace as tokens.