diff options
-rw-r--r-- | clang-tools-extra/test/pp-trace/pp-trace-include.cpp | 10 | ||||
-rw-r--r-- | clang/include/clang/Lex/PPCallbacks.h | 31 | ||||
-rw-r--r-- | clang/lib/Frontend/DependencyFile.cpp | 29 | ||||
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 23 |
4 files changed, 67 insertions, 26 deletions
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 96b4014..db0b2c8 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 5f7cfab..045df87 100644 --- a/clang/include/clang/Lex/PPCallbacks.h +++ b/clang/include/clang/Lex/PPCallbacks.h @@ -43,12 +43,34 @@ public: /// 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 different 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 @@ public: 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 3a810e5..06ddb0f 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 e3379ae..36d3aa5 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 |