Author: Argyrios Kyrtzidis Date: 2022-07-01T14:22:31-07:00 New Revision: 0d3a2b4c6601d4ff341119aa537db184197d83de
URL: https://github.com/llvm/llvm-project/commit/0d3a2b4c6601d4ff341119aa537db184197d83de DIFF: https://github.com/llvm/llvm-project/commit/0d3a2b4c6601d4ff341119aa537db184197d83de.diff LOG: [Lex] Introduce `PPCallbacks::LexedFileChanged()` preprocessor callback This is a preprocessor callback focused on the lexed file changing, without conflating effects of line number directives and other pragmas. A client that only cares about what files the lexer processes, like dependency generation, can use this more straightforward callback instead of `PPCallbacks::FileChanged()`. Clients that want the pragma directive effects as well can keep using `FileChanged()`. A use case where `PPCallbacks::LexedFileChanged()` is particularly simpler to use than `FileChanged()` is in a situation where a client wants to keep track of lexed file changes that include changes from/to the predefines buffer, where it becomes unnecessary complicated trying to use `FileChanged()` while filtering out the pragma directives effects callbacks. Also take the opportunity to provide information about the prior `FileID` the `Lexer` moved from, even when entering a new file. Differential Revision: https://reviews.llvm.org/D128947 Added: Modified: clang-tools-extra/test/pp-trace/pp-trace-include.cpp clang/include/clang/Lex/PPCallbacks.h clang/lib/Frontend/DependencyFile.cpp clang/lib/Lex/PPLexerChange.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp index 96b4014025b78..db0b2c89430a2 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp @@ -13,7 +13,7 @@ // CHECK-NEXT: Loc: "<built-in>:1:1" // CHECK-NEXT: Reason: EnterFile // CHECK-NEXT: FileType: C_User -// CHECK-NEXT: PrevFID: (invalid) +// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}pp-trace-include.cpp" // CHECK-NEXT: - Callback: FileChanged // CHECK-NEXT: Loc: "<built-in>:1:1" // CHECK-NEXT: Reason: RenameFile @@ -64,7 +64,7 @@ // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level1A.h:1:1" // CHECK-NEXT: Reason: EnterFile // CHECK-NEXT: FileType: C_User -// CHECK-NEXT: PrevFID: (invalid) +// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}pp-trace-include.cpp" // CHECK-NEXT: - Callback: InclusionDirective // CHECK-NEXT: HashLoc: "{{.*}}{{[/\\]}}Inputs/Level1A.h:1:1" // CHECK-NEXT: IncludeTok: include @@ -79,7 +79,7 @@ // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level2A.h:1:1" // CHECK-NEXT: Reason: EnterFile // CHECK-NEXT: FileType: C_User -// CHECK-NEXT: PrevFID: (invalid) +// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}Inputs/Level1A.h" // CHECK-NEXT: - Callback: MacroDefined // CHECK-NEXT: MacroNameTok: MACRO_2A // CHECK-NEXT: MacroDirective: MD_Define @@ -110,7 +110,7 @@ // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level1B.h:1:1" // CHECK-NEXT: Reason: EnterFile // CHECK-NEXT: FileType: C_User -// CHECK-NEXT: PrevFID: (invalid) +// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}pp-trace-include.cpp" // CHECK-NEXT: - Callback: InclusionDirective // CHECK-NEXT: HashLoc: "{{.*}}{{[/\\]}}Inputs/Level1B.h:1:1" // CHECK-NEXT: IncludeTok: include @@ -125,7 +125,7 @@ // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}Inputs/Level2B.h:1:1" // CHECK-NEXT: Reason: EnterFile // CHECK-NEXT: FileType: C_User -// CHECK-NEXT: PrevFID: (invalid) +// CHECK-NEXT: PrevFID: "{{.*}}{{[/\\]}}Inputs/Level1B.h" // CHECK-NEXT: - Callback: MacroDefined // CHECK-NEXT: MacroNameTok: MACRO_2B // CHECK-NEXT: MacroDirective: MD_Define diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h index 5f7cfab00e41a..045df8711a41b 100644 --- a/clang/include/clang/Lex/PPCallbacks.h +++ b/clang/include/clang/Lex/PPCallbacks.h @@ -43,12 +43,34 @@ class PPCallbacks { /// Callback invoked whenever a source file is entered or exited. /// /// \param Loc Indicates the new location. - /// \param PrevFID the file that was exited if \p Reason is ExitFile. + /// \param PrevFID the file that was exited if \p Reason is ExitFile or the + /// the file before the new one entered for \p Reason EnterFile. virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID = FileID()) { } + enum class LexedFileChangeReason { EnterFile, ExitFile }; + + /// Callback invoked whenever the \p Lexer moves to a diff erent file for + /// lexing. Unlike \p FileChanged line number directives and other related + /// pragmas do not trigger callbacks to \p LexedFileChanged. + /// + /// \param FID The \p FileID that the \p Lexer moved to. + /// + /// \param Reason Whether the \p Lexer entered a new file or exited one. + /// + /// \param FileType The \p CharacteristicKind of the file the \p Lexer moved + /// to. + /// + /// \param PrevFID The \p FileID the \p Lexer was using before the change. + /// + /// \param Loc The location where the \p Lexer entered a new file from or the + /// location that the \p Lexer moved into after exiting a file. + virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, + FileID PrevFID, SourceLocation Loc) {} + /// Callback invoked whenever a source file is skipped as the result /// of header guard optimization. /// @@ -420,6 +442,13 @@ class PPChainedCallbacks : public PPCallbacks { Second->FileChanged(Loc, Reason, FileType, PrevFID); } + void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, FileID PrevFID, + SourceLocation Loc) override { + First->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc); + Second->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc); + } + void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType) override { First->FileSkipped(SkippedFile, FilenameTok, FileType); diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp index 3a810e56571df..06ddb0f0db201 100644 --- a/clang/lib/Frontend/DependencyFile.cpp +++ b/clang/lib/Frontend/DependencyFile.cpp @@ -31,23 +31,21 @@ using namespace clang; namespace { struct DepCollectorPPCallbacks : public PPCallbacks { DependencyCollector &DepCollector; - SourceManager &SM; - DiagnosticsEngine &Diags; - DepCollectorPPCallbacks(DependencyCollector &L, SourceManager &SM, - DiagnosticsEngine &Diags) - : DepCollector(L), SM(SM), Diags(Diags) {} - - void FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind FileType, - FileID PrevFID) override { - if (Reason != PPCallbacks::EnterFile) + Preprocessor &PP; + DepCollectorPPCallbacks(DependencyCollector &L, Preprocessor &PP) + : DepCollector(L), PP(PP) {} + + void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, FileID PrevFID, + SourceLocation Loc) override { + if (Reason != PPCallbacks::LexedFileChangeReason::EnterFile) return; // Dependency generation really does want to go all the way to the // file entry for a source location to find out what is depended on. // We do not want #line markers to affect dependency generation! - if (Optional<StringRef> Filename = SM.getNonBuiltinFilenameForID( - SM.getFileID(SM.getExpansionLoc(Loc)))) + if (Optional<StringRef> Filename = + PP.getSourceManager().getNonBuiltinFilenameForID(FID)) DepCollector.maybeAddDependency( llvm::sys::path::remove_leading_dotslash(*Filename), /*FromModule*/ false, isSystem(FileType), /*IsModuleFile*/ false, @@ -90,7 +88,9 @@ struct DepCollectorPPCallbacks : public PPCallbacks { /*IsMissing=*/false); } - void EndOfMainFile() override { DepCollector.finishedMainFile(Diags); } + void EndOfMainFile() override { + DepCollector.finishedMainFile(PP.getDiagnostics()); + } }; struct DepCollectorMMCallbacks : public ModuleMapCallbacks { @@ -175,8 +175,7 @@ bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule, DependencyCollector::~DependencyCollector() { } void DependencyCollector::attachToPreprocessor(Preprocessor &PP) { - PP.addPPCallbacks(std::make_unique<DepCollectorPPCallbacks>( - *this, PP.getSourceManager(), PP.getDiagnostics())); + PP.addPPCallbacks(std::make_unique<DepCollectorPPCallbacks>(*this, PP)); PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks( std::make_unique<DepCollectorMMCallbacks>(*this)); } diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index e3379aecba725..36d3aa59bb2f7 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -111,6 +111,7 @@ bool Preprocessor::EnterSourceFile(FileID FID, ConstSearchDirIterator CurDir, /// and start lexing tokens from it instead of the current buffer. void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer, ConstSearchDirIterator CurDir) { + PreprocessorLexer *PrevPPLexer = CurPPLexer; // Add the current lexer to the include stack. if (CurPPLexer || CurTokenLexer) @@ -130,8 +131,17 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer, SrcMgr::CharacteristicKind FileType = SourceMgr.getFileCharacteristic(CurLexer->getFileLoc()); - Callbacks->FileChanged(CurLexer->getFileLoc(), - PPCallbacks::EnterFile, FileType); + FileID PrevFID; + SourceLocation EnterLoc; + if (PrevPPLexer) { + PrevFID = PrevPPLexer->getFileID(); + EnterLoc = PrevPPLexer->getSourceLocation(); + } + Callbacks->FileChanged(CurLexer->getFileLoc(), PPCallbacks::EnterFile, + FileType, PrevFID); + Callbacks->LexedFileChanged(CurLexer->getFileID(), + PPCallbacks::LexedFileChangeReason::EnterFile, + FileType, PrevFID, EnterLoc); } } @@ -486,10 +496,13 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { // Notify the client, if desired, that we are in a new source file. if (Callbacks && !isEndOfMacro && CurPPLexer) { + SourceLocation Loc = CurPPLexer->getSourceLocation(); SrcMgr::CharacteristicKind FileType = - SourceMgr.getFileCharacteristic(CurPPLexer->getSourceLocation()); - Callbacks->FileChanged(CurPPLexer->getSourceLocation(), - PPCallbacks::ExitFile, FileType, ExitedFID); + SourceMgr.getFileCharacteristic(Loc); + Callbacks->FileChanged(Loc, PPCallbacks::ExitFile, FileType, ExitedFID); + Callbacks->LexedFileChanged(CurPPLexer->getFileID(), + PPCallbacks::LexedFileChangeReason::ExitFile, + FileType, ExitedFID, Loc); } // Restore conditional stack as well as the recorded _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits