[clang] 197576c - [clang][lex] Refactor check for the first file include
Jan Svoboda via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 18 04:02:14 PST 2021
Author: Jan Svoboda
Date: 2021-11-18T13:01:07+01:00
New Revision: 197576c40986085cbd5250283e1e80a2679c9cf0
URL: https://github.com/llvm/llvm-project/commit/197576c40986085cbd5250283e1e80a2679c9cf0
DIFF: https://github.com/llvm/llvm-project/commit/197576c40986085cbd5250283e1e80a2679c9cf0.diff
LOG: [clang][lex] Refactor check for the first file include
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.
Reviewed By: dexonsmith
Differential Revision: https://reviews.llvm.org/D114093
Added:
Modified:
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
Removed:
################################################################################
diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h
index 7f5c4c260f55..b3445703f782 100644
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ b/clang/include/clang/Lex/HeaderSearch.h
@@ -443,8 +443,8 @@ class HeaderSearch {
/// \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 isImport, bool ModulesEnabled, Module *M,
+ bool &IsFirstIncludeOfFile);
/// Return whether the specified file is a normal header,
/// a system header, or a C++ friendly system header.
@@ -489,11 +489,6 @@ class HeaderSearch {
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.
diff --git a/clang/include/clang/Lex/Lexer.h b/clang/include/clang/Lex/Lexer.h
index 82f494e7c8cf..ba1706b1d13e 100644
--- a/clang/include/clang/Lex/Lexer.h
+++ b/clang/include/clang/Lex/Lexer.h
@@ -128,6 +128,9 @@ class Lexer : public PreprocessorLexer {
bool HasLeadingEmptyMacro;
+ /// True if this is the first time we're lexing the input file.
+ bool IsFirstTimeLexingFile;
+
// NewLinePtr - A pointer to new line character '\n' being lexed. For '\r\n',
// it also points to '\n.'
const char *NewLinePtr;
@@ -142,19 +145,22 @@ class Lexer : public PreprocessorLexer {
/// 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 @@ class Lexer : public PreprocessorLexer {
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.
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index b8b0890e3243..ea96bb12bec6 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -1368,7 +1368,7 @@ class Preprocessor {
///
/// 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.
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 150e7edb12c1..a0b60118a1a8 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -1310,9 +1310,12 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
const FileEntry *File, bool isImport,
- bool ModulesEnabled, Module *M) {
+ bool ModulesEnabled, Module *M,
+ bool &IsFirstIncludeOfFile) {
++NumIncluded; // Count # of attempted #includes.
+ IsFirstIncludeOfFile = false;
+
// Get information about this file.
HeaderFileInfo &FileInfo = getFileInfo(File);
@@ -1387,6 +1390,8 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
// Increment the number of times this file has been included.
++FileInfo.NumIncludes;
+ IsFirstIncludeOfFile = FileInfo.NumIncludes == 1;
+
return true;
}
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 55693c8f8cf4..38467a1835d0 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -133,10 +133,10 @@ void Lexer::InitLexer(const char *BufStart, const char *BufPtr,
/// 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 @@ Lexer::Lexer(FileID FID, const llvm::MemoryBufferRef &InputFile,
/// 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 @@ Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts,
/// 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");
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 79cfc7fcd5fd..ef7a5351953e 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -2143,12 +2143,14 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
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(
+ *this, &File->getFileEntry(), EnterOnce, getLangOpts().Modules,
+ SuggestedModule.getModule(), IsFirstIncludeOfFile)) {
// 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 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
}
// 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.
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index 9fbce62e51d6..f8b0a2c5f71b 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -67,7 +67,8 @@ 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.
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 @@ bool Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
CodeCompletionFileLoc.getLocWithOffset(CodeCompletionOffset);
}
- EnterSourceFileWithLexer(new Lexer(FID, *InputFile, *this), CurDir);
+ EnterSourceFileWithLexer(
+ new Lexer(FID, *InputFile, *this, IsFirstIncludeOfFile), CurDir);
return false;
}
@@ -377,7 +379,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, SourceLocation EndLoc,
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
More information about the cfe-commits
mailing list