diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 4d31be4ecf4e..d803cb6a97ae 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -608,7 +608,25 @@ private: const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir); - + + + + static bool IsNonPragmaNonMacroLexer(const Lexer* L, + const PreprocessorLexer* P) { + if (L) + return !L->isPragmaLexer(); + else + return P != 0; + } + + static bool IsNonPragmaNonMacroLexer(const IncludeStackInfo& I) { + return IsNonPragmaNonMacroLexer(I.TheLexer, I.ThePPLexer); + } + + bool IsNonPragmaNonMacroLexer() const { + return IsNonPragmaNonMacroLexer(CurLexer.get(), CurPPLexer); + } + //===--------------------------------------------------------------------===// // Caching stuff. void CachingLex(Token &Result); diff --git a/clang/include/clang/Lex/PreprocessorLexer.h b/clang/include/clang/Lex/PreprocessorLexer.h index de9c6b780a0c..df8049e214ee 100644 --- a/clang/include/clang/Lex/PreprocessorLexer.h +++ b/clang/include/clang/Lex/PreprocessorLexer.h @@ -26,6 +26,9 @@ class Preprocessor; class PreprocessorLexer { protected: Preprocessor *PP; // Preprocessor object controlling lexing. + + /// The SourceManager fileID corresponding to the file being lexed. + const unsigned FileID; //===--------------------------------------------------------------------===// // Context-specific lexing flags set by the preprocessor. @@ -64,7 +67,9 @@ protected: void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT friend class Preprocessor; - PreprocessorLexer(Preprocessor* pp) : PP(pp) {} + PreprocessorLexer(Preprocessor* pp, SourceLocation L); + PreprocessorLexer() : PP(0), FileID(0) {} + virtual ~PreprocessorLexer(); virtual void IndirectLex(Token& Result) = 0; @@ -119,6 +124,13 @@ protected: /// (potentially) macro expand the filename. If the sequence parsed is not /// lexically legal, emit a diagnostic and return a result EOM token. void LexIncludeFilename(Token &Result); + +public: + unsigned getFileID() const { + assert(PP && + "PreprocessorLexer::getFileID() should only be used with a Preprocessor"); + return FileID; + } }; } // end namespace clang diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 8ddd62fe9983..eebdd1e2eb3c 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -63,7 +63,8 @@ tok::ObjCKeywordKind Token::getObjCKeywordID() const { /// outlive it, so it doesn't take ownership of either of them. Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp, const char *BufStart, const char *BufEnd) - : PreprocessorLexer(&pp), FileLoc(fileloc), Features(pp.getLangOptions()) { + : PreprocessorLexer(&pp, fileloc), FileLoc(fileloc), + Features(pp.getLangOptions()) { SourceManager &SourceMgr = PP->getSourceManager(); unsigned InputFileID = SourceMgr.getPhysicalLoc(FileLoc).getFileID(); @@ -110,7 +111,9 @@ Lexer::Lexer(SourceLocation fileloc, Preprocessor &pp, Lexer::Lexer(SourceLocation fileloc, const LangOptions &features, const char *BufStart, const char *BufEnd, const llvm::MemoryBuffer *FromFile) - : PreprocessorLexer(0), FileLoc(fileloc), Features(features) { + : PreprocessorLexer(), FileLoc(fileloc), + Features(features) { + Is_PragmaLexer = false; InitCharacterInfo(); diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index ced7673ca23b..a1216b15bccd 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -303,8 +303,8 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart, // info about where the current file is. const FileEntry *CurFileEnt = 0; if (!FromDir) { - SourceLocation FileLoc = getCurrentFileLexer()->getFileLoc(); - CurFileEnt = SourceMgr.getFileEntryForLoc(FileLoc); + unsigned FileID = getCurrentFileLexer()->getFileID(); + CurFileEnt = SourceMgr.getFileEntryForID(FileID); } // Do a standard file entry lookup. @@ -317,8 +317,8 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart, // Otherwise, see if this is a subframework header. If so, this is relative // to one of the headers on the #include stack. Walk the list of the current // headers on the #include stack and pass them to HeaderInfo. - if (CurLexer && !CurLexer->Is_PragmaLexer) { - if ((CurFileEnt = SourceMgr.getFileEntryForLoc(CurLexer->getFileLoc()))) + if (IsNonPragmaNonMacroLexer()) { + if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))) if ((FE = HeaderInfo.LookupSubframeworkHeader(FilenameStart, FilenameEnd, CurFileEnt))) return FE; @@ -326,9 +326,9 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart, for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) { IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1]; - if (ISEntry.TheLexer && !ISEntry.TheLexer->Is_PragmaLexer) { + if (IsNonPragmaNonMacroLexer(ISEntry)) { if ((CurFileEnt = - SourceMgr.getFileEntryForLoc(ISEntry.TheLexer->getFileLoc()))) + SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID()))) if ((FE = HeaderInfo.LookupSubframeworkHeader(FilenameStart, FilenameEnd, CurFileEnt))) return FE; diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 87330983d658..3a2ed658fb3d 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -25,27 +25,17 @@ PPCallbacks::~PPCallbacks() {} // Miscellaneous Methods. //===----------------------------------------------------------------------===// -static inline bool IsNonPragmaNonMacroLexer(const Lexer* L, - const PreprocessorLexer* P) { - if (L) - return !L->isPragmaLexer(); - else - return P != 0; -} - /// isInPrimaryFile - Return true if we're in the top-level file, not in a /// #include. This looks through macro expansions and active _Pragma lexers. bool Preprocessor::isInPrimaryFile() const { - if (IsNonPragmaNonMacroLexer(CurLexer.get(), CurPPLexer)) + if (IsNonPragmaNonMacroLexer()) return IncludeMacroStack.empty(); // If there are any stacked lexers, we're in a #include. - assert(IsNonPragmaNonMacroLexer(IncludeMacroStack[0].TheLexer, - IncludeMacroStack[0].ThePPLexer) && + assert(IsNonPragmaNonMacroLexer(IncludeMacroStack[0]) && "Top level include stack isn't our primary lexer?"); for (unsigned i = 1, e = IncludeMacroStack.size(); i != e; ++i) - if (IsNonPragmaNonMacroLexer(IncludeMacroStack[i].TheLexer, - IncludeMacroStack[i].ThePPLexer)) + if (IsNonPragmaNonMacroLexer(IncludeMacroStack[i])) return false; return true; } @@ -91,7 +81,7 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *CurDir) { // Add the current lexer to the include stack. - if (CurLexer || CurTokenLexer) + if (CurPPLexer || CurTokenLexer) PushIncludeMacroStack(); CurLexer.reset(TheLexer); @@ -212,6 +202,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { // We're done with the #included file. CurLexer.reset(); + CurPPLexer = 0; // This is the end of the top-level file. If the diag::pp_macro_not_used // diagnostic is enabled, look for macros that have not been used. diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index 8062102e6cc0..d22285cae5c6 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -18,8 +18,8 @@ using namespace clang; PTHLexer::PTHLexer(Preprocessor& pp, SourceLocation fileloc, const Token *TokArray, unsigned NumToks) - : PreprocessorLexer(&pp), FileLoc(fileloc), Tokens(TokArray), - NumTokens(NumToks), CurToken(0) { + : PreprocessorLexer(&pp, fileloc), FileLoc(fileloc), + Tokens(TokArray), NumTokens(NumToks), CurToken(0) { assert (Tokens[NumTokens-1].is(tok::eof)); --NumTokens; diff --git a/clang/lib/Lex/PreprocessorLexer.cpp b/clang/lib/Lex/PreprocessorLexer.cpp index 20bce413b74d..2ce181ef83a2 100644 --- a/clang/lib/Lex/PreprocessorLexer.cpp +++ b/clang/lib/Lex/PreprocessorLexer.cpp @@ -18,6 +18,9 @@ using namespace clang; +PreprocessorLexer::PreprocessorLexer(Preprocessor* pp, SourceLocation L) + : PP(pp), FileID(pp->getSourceManager().getPhysicalLoc(L).getFileID()) {} + PreprocessorLexer::~PreprocessorLexer() {} void PreprocessorLexer::Diag(SourceLocation Loc, unsigned DiagID,