jansvoboda11 created this revision. jansvoboda11 added reviewers: Bigcheese, dexonsmith, vsapsai. jansvoboda11 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This patch refactors the code that checks whether a file has just been included for the first time. The `HeaderSearch::FirstTimeLexingFile` function is removed and the information is threaded to the original call site from `HeaderSearch::ShouldEnterIncludeFile`. This will make it possible to avoid tracking the number of includes in a follow up patch. Depends on D114092 <https://reviews.llvm.org/D114092>. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D114093 Files: clang/include/clang/Lex/HeaderSearch.h clang/include/clang/Lex/Lexer.h clang/include/clang/Lex/Preprocessor.h clang/lib/Lex/HeaderSearch.cpp clang/lib/Lex/Lexer.cpp clang/lib/Lex/PPDirectives.cpp clang/lib/Lex/PPLexerChange.cpp
Index: clang/lib/Lex/PPLexerChange.cpp =================================================================== --- clang/lib/Lex/PPLexerChange.cpp +++ clang/lib/Lex/PPLexerChange.cpp @@ -67,7 +67,8 @@ /// EnterSourceFile - Add a source file to the top of the include stack and /// start lexing tokens from it instead of the current buffer. bool Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir, - SourceLocation Loc) { + SourceLocation Loc, + bool IsFirstIncludeOfFile) { assert(!CurTokenLexer && "Cannot #include a file inside a macro!"); ++NumEnteredSourceFiles; @@ -91,7 +92,8 @@ CodeCompletionFileLoc.getLocWithOffset(CodeCompletionOffset); } - EnterSourceFileWithLexer(new Lexer(FID, *InputFile, *this), CurDir); + EnterSourceFileWithLexer( + new Lexer(FID, *InputFile, *this, IsFirstIncludeOfFile), CurDir); return false; } @@ -377,7 +379,7 @@ CurPPLexer->MIOpt.GetDefinedMacro()) { if (!isMacroDefined(ControllingMacro) && DefinedMacro != ControllingMacro && - HeaderInfo.FirstTimeLexingFile(FE)) { + CurLexer->isFirstTimeLexingFile()) { // If the edit distance between the two macros is more than 50%, // DefinedMacro may not be header guard, or can be header guard of Index: clang/lib/Lex/PPDirectives.cpp =================================================================== --- clang/lib/Lex/PPDirectives.cpp +++ clang/lib/Lex/PPDirectives.cpp @@ -2143,12 +2143,14 @@ IsImportDecl || IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import; + bool IsFirstIncludeOfFile = false; + // Ask HeaderInfo if we should enter this #include file. If not, #including // this file will have no effect. if (Action == Enter && File && - !HeaderInfo.ShouldEnterIncludeFile(*this, &File->getFileEntry(), - EnterOnce, getLangOpts().Modules, - SuggestedModule.getModule())) { + !HeaderInfo.ShouldEnterIncludeFile( + IsFirstIncludeOfFile, *this, &File->getFileEntry(), EnterOnce, + getLangOpts().Modules, SuggestedModule.getModule())) { // Even if we've already preprocessed this header once and know that we // don't need to see its contents again, we still need to import it if it's // modular because we might not have imported it from this submodule before. @@ -2340,7 +2342,8 @@ } // If all is good, enter the new file! - if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation())) + if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation(), + IsFirstIncludeOfFile)) return {ImportAction::None}; // Determine if we're switching to building a new submodule, and which one. Index: clang/lib/Lex/Lexer.cpp =================================================================== --- clang/lib/Lex/Lexer.cpp +++ clang/lib/Lex/Lexer.cpp @@ -133,10 +133,10 @@ /// assumes that the associated file buffer and Preprocessor objects will /// outlive it, so it doesn't take ownership of either of them. Lexer::Lexer(FileID FID, const llvm::MemoryBufferRef &InputFile, - Preprocessor &PP) + Preprocessor &PP, bool IsFirstIncludeOfFile) : PreprocessorLexer(&PP, FID), FileLoc(PP.getSourceManager().getLocForStartOfFile(FID)), - LangOpts(PP.getLangOpts()) { + LangOpts(PP.getLangOpts()), IsFirstTimeLexingFile(IsFirstIncludeOfFile) { InitLexer(InputFile.getBufferStart(), InputFile.getBufferStart(), InputFile.getBufferEnd()); @@ -147,8 +147,10 @@ /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the text /// range will outlive it, so it doesn't take ownership of it. Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts, - const char *BufStart, const char *BufPtr, const char *BufEnd) - : FileLoc(fileloc), LangOpts(langOpts) { + const char *BufStart, const char *BufPtr, const char *BufEnd, + bool IsFirstIncludeOfFile) + : FileLoc(fileloc), LangOpts(langOpts), + IsFirstTimeLexingFile(IsFirstIncludeOfFile) { InitLexer(BufStart, BufPtr, BufEnd); // We *are* in raw mode. @@ -159,9 +161,11 @@ /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the text /// range will outlive it, so it doesn't take ownership of it. Lexer::Lexer(FileID FID, const llvm::MemoryBufferRef &FromFile, - const SourceManager &SM, const LangOptions &langOpts) + const SourceManager &SM, const LangOptions &langOpts, + bool IsFirstIncludeOfFile) : Lexer(SM.getLocForStartOfFile(FID), langOpts, FromFile.getBufferStart(), - FromFile.getBufferStart(), FromFile.getBufferEnd()) {} + FromFile.getBufferStart(), FromFile.getBufferEnd(), + IsFirstIncludeOfFile) {} void Lexer::resetExtendedTokenMode() { assert(PP && "Cannot reset token mode without a preprocessor"); Index: clang/lib/Lex/HeaderSearch.cpp =================================================================== --- clang/lib/Lex/HeaderSearch.cpp +++ clang/lib/Lex/HeaderSearch.cpp @@ -1308,11 +1308,14 @@ HFI.isCompilingModuleHeader |= isCompilingModuleHeader; } -bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, +bool HeaderSearch::ShouldEnterIncludeFile(bool &IsFirstIncludeOfFile, + Preprocessor &PP, const FileEntry *File, bool isImport, bool ModulesEnabled, Module *M) { ++NumIncluded; // Count # of attempted #includes. + IsFirstIncludeOfFile = false; + // Get information about this file. HeaderFileInfo &FileInfo = getFileInfo(File); @@ -1387,6 +1390,8 @@ // Increment the number of times this file has been included. ++FileInfo.NumIncludes; + IsFirstIncludeOfFile = FileInfo.NumIncludes == 1; + return true; } Index: clang/include/clang/Lex/Preprocessor.h =================================================================== --- clang/include/clang/Lex/Preprocessor.h +++ clang/include/clang/Lex/Preprocessor.h @@ -1368,7 +1368,7 @@ /// /// Emits a diagnostic, doesn't enter the file, and returns true on error. bool EnterSourceFile(FileID FID, const DirectoryLookup *Dir, - SourceLocation Loc); + SourceLocation Loc, bool IsFirstIncludeOfFile = true); /// Add a Macro to the top of the include stack and start lexing /// tokens from it instead of the current buffer. Index: clang/include/clang/Lex/Lexer.h =================================================================== --- clang/include/clang/Lex/Lexer.h +++ clang/include/clang/Lex/Lexer.h @@ -137,24 +137,30 @@ void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd); + /// True if this is the first time we're lexing the input file. + bool IsFirstTimeLexingFile; + public: /// Lexer constructor - Create a new lexer object for the specified buffer /// 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(FileID FID, const llvm::MemoryBufferRef &InputFile, Preprocessor &PP); + Lexer(FileID FID, const llvm::MemoryBufferRef &InputFile, Preprocessor &PP, + bool IsFirstIncludeOfFile = true); /// Lexer constructor - Create a new raw lexer object. This object is only /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the /// text range will outlive it, so it doesn't take ownership of it. Lexer(SourceLocation FileLoc, const LangOptions &LangOpts, - const char *BufStart, const char *BufPtr, const char *BufEnd); + const char *BufStart, const char *BufPtr, const char *BufEnd, + bool IsFirstIncludeOfFile = true); /// Lexer constructor - Create a new raw lexer object. This object is only /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the /// text range will outlive it, so it doesn't take ownership of it. Lexer(FileID FID, const llvm::MemoryBufferRef &FromFile, - const SourceManager &SM, const LangOptions &LangOpts); + const SourceManager &SM, const LangOptions &LangOpts, + bool IsFirstIncludeOfFile = true); Lexer(const Lexer &) = delete; Lexer &operator=(const Lexer &) = delete; @@ -563,6 +569,9 @@ static StringRef getIndentationForLine(SourceLocation Loc, const SourceManager &SM); + /// Check if this is the first time we're lexing the input file. + bool isFirstTimeLexingFile() const { return IsFirstTimeLexingFile; } + private: //===--------------------------------------------------------------------===// // Internal implementation interfaces. Index: clang/include/clang/Lex/HeaderSearch.h =================================================================== --- clang/include/clang/Lex/HeaderSearch.h +++ clang/include/clang/Lex/HeaderSearch.h @@ -442,9 +442,9 @@ /// /// \return false if \#including the file will have no effect or true /// if we should include it. - bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File, - bool isImport, bool ModulesEnabled, - Module *M); + bool ShouldEnterIncludeFile(bool &IsFirstIncludeOfFile, Preprocessor &PP, + const FileEntry *File, bool isImport, + bool ModulesEnabled, Module *M); /// Return whether the specified file is a normal header, /// a system header, or a C++ friendly system header. @@ -489,11 +489,6 @@ getFileInfo(File).ControllingMacro = ControllingMacro; } - /// Return true if this is the first time encountering this header. - bool FirstTimeLexingFile(const FileEntry *File) { - return getFileInfo(File).NumIncludes == 1; - } - /// Determine whether this file is intended to be safe from /// multiple inclusions, e.g., it has \#pragma once or a controlling /// macro.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits