1bbc89dcbSAlexander Kornienko //===- ExpandModularHeadersPPCallbacks.h - clang-tidy -----------*- C++ -*-===// 2bbc89dcbSAlexander Kornienko // 3bbc89dcbSAlexander Kornienko // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bbc89dcbSAlexander Kornienko // See https://llvm.org/LICENSE.txt for license information. 5bbc89dcbSAlexander Kornienko // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bbc89dcbSAlexander Kornienko // 7bbc89dcbSAlexander Kornienko //===----------------------------------------------------------------------===// 8bbc89dcbSAlexander Kornienko 9bbc89dcbSAlexander Kornienko #ifndef LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_ 10bbc89dcbSAlexander Kornienko #define LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_ 11bbc89dcbSAlexander Kornienko 12bbc89dcbSAlexander Kornienko #include "clang/Lex/PPCallbacks.h" 13bbc89dcbSAlexander Kornienko #include "clang/Lex/Preprocessor.h" 14bbc89dcbSAlexander Kornienko #include "llvm/ADT/DenseSet.h" 15bbc89dcbSAlexander Kornienko 164718da50SCarlos Galvez namespace llvm::vfs { 17e08464fbSReid Kleckner class OverlayFileSystem; 18e08464fbSReid Kleckner class InMemoryFileSystem; 194718da50SCarlos Galvez } // namespace llvm::vfs 20e08464fbSReid Kleckner 21bbc89dcbSAlexander Kornienko namespace clang { 22bbc89dcbSAlexander Kornienko class CompilerInstance; 23bbc89dcbSAlexander Kornienko 24bbc89dcbSAlexander Kornienko namespace serialization { 25bbc89dcbSAlexander Kornienko class ModuleFile; 26bbc89dcbSAlexander Kornienko } // namespace serialization 27bbc89dcbSAlexander Kornienko 28bbc89dcbSAlexander Kornienko namespace tooling { 29bbc89dcbSAlexander Kornienko 30282dc72cSDmitri Gribenko /// Handles PPCallbacks and re-runs preprocessing of the whole 31bbc89dcbSAlexander Kornienko /// translation unit with modules disabled. 32bbc89dcbSAlexander Kornienko /// 33bbc89dcbSAlexander Kornienko /// This way it's possible to get PPCallbacks for the whole translation unit 34bbc89dcbSAlexander Kornienko /// including the contents of the modular headers and all their transitive 35bbc89dcbSAlexander Kornienko /// includes. 36bbc89dcbSAlexander Kornienko /// 37bbc89dcbSAlexander Kornienko /// This allows existing tools based on PPCallbacks to retain their functionality 38bbc89dcbSAlexander Kornienko /// when running with C++ modules enabled. This only works in the backwards 39bbc89dcbSAlexander Kornienko /// compatible modules mode, i.e. when code can still be parsed in non-modular 40bbc89dcbSAlexander Kornienko /// way. 41bbc89dcbSAlexander Kornienko class ExpandModularHeadersPPCallbacks : public PPCallbacks { 42bbc89dcbSAlexander Kornienko public: 43bbc89dcbSAlexander Kornienko ExpandModularHeadersPPCallbacks( 44f1f16331SPiotr Zegar CompilerInstance *CI, 45bbc89dcbSAlexander Kornienko IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS); 46bbc89dcbSAlexander Kornienko ~ExpandModularHeadersPPCallbacks(); 47bbc89dcbSAlexander Kornienko 48282dc72cSDmitri Gribenko /// Returns the preprocessor that provides callbacks for the whole 49bbc89dcbSAlexander Kornienko /// translation unit, including the main file, textual headers, and modular 50bbc89dcbSAlexander Kornienko /// headers. 51bbc89dcbSAlexander Kornienko /// 52bbc89dcbSAlexander Kornienko /// This preprocessor is separate from the one used by the rest of the 53bbc89dcbSAlexander Kornienko /// compiler. 54bbc89dcbSAlexander Kornienko Preprocessor *getPreprocessor() const; 55bbc89dcbSAlexander Kornienko 56bbc89dcbSAlexander Kornienko private: 57bbc89dcbSAlexander Kornienko class FileRecorder; 58bbc89dcbSAlexander Kornienko 59bbc89dcbSAlexander Kornienko void handleModuleFile(serialization::ModuleFile *MF); 60bbc89dcbSAlexander Kornienko void parseToLocation(SourceLocation Loc); 61bbc89dcbSAlexander Kornienko 62bbc89dcbSAlexander Kornienko // Handle PPCallbacks. 63bbc89dcbSAlexander Kornienko void FileChanged(SourceLocation Loc, FileChangeReason Reason, 64bbc89dcbSAlexander Kornienko SrcMgr::CharacteristicKind FileType, 65bbc89dcbSAlexander Kornienko FileID PrevFID) override; 66bbc89dcbSAlexander Kornienko 67bbc89dcbSAlexander Kornienko void InclusionDirective(SourceLocation DirectiveLoc, 68bbc89dcbSAlexander Kornienko const Token &IncludeToken, StringRef IncludedFilename, 69bbc89dcbSAlexander Kornienko bool IsAngled, CharSourceRange FilenameRange, 70854c10f8SBenjamin Kramer OptionalFileEntryRef IncludedFile, 71d79ad2f1SJan Svoboda StringRef SearchPath, StringRef RelativePath, 72*da95d926SJan Svoboda const Module *SuggestedModule, bool ModuleImported, 73bbc89dcbSAlexander Kornienko SrcMgr::CharacteristicKind FileType) override; 74bbc89dcbSAlexander Kornienko 75bbc89dcbSAlexander Kornienko void EndOfMainFile() override; 76bbc89dcbSAlexander Kornienko 77bbc89dcbSAlexander Kornienko // Handle all other callbacks. 78bbc89dcbSAlexander Kornienko // Just parse to the corresponding location to generate PPCallbacks for the 79bbc89dcbSAlexander Kornienko // corresponding range 80bbc89dcbSAlexander Kornienko void Ident(SourceLocation Loc, StringRef) override; 81bbc89dcbSAlexander Kornienko void PragmaDirective(SourceLocation Loc, PragmaIntroducerKind) override; 82bbc89dcbSAlexander Kornienko void PragmaComment(SourceLocation Loc, const IdentifierInfo *, 83bbc89dcbSAlexander Kornienko StringRef) override; 84bbc89dcbSAlexander Kornienko void PragmaDetectMismatch(SourceLocation Loc, StringRef, StringRef) override; 85bbc89dcbSAlexander Kornienko void PragmaDebug(SourceLocation Loc, StringRef) override; 86bbc89dcbSAlexander Kornienko void PragmaMessage(SourceLocation Loc, StringRef, PragmaMessageKind, 87bbc89dcbSAlexander Kornienko StringRef) override; 88bbc89dcbSAlexander Kornienko void PragmaDiagnosticPush(SourceLocation Loc, StringRef) override; 89bbc89dcbSAlexander Kornienko void PragmaDiagnosticPop(SourceLocation Loc, StringRef) override; 90bbc89dcbSAlexander Kornienko void PragmaDiagnostic(SourceLocation Loc, StringRef, diag::Severity, 91bbc89dcbSAlexander Kornienko StringRef) override; 92854c10f8SBenjamin Kramer void HasInclude(SourceLocation Loc, StringRef, bool, OptionalFileEntryRef, 93bbc89dcbSAlexander Kornienko SrcMgr::CharacteristicKind) override; 94bbc89dcbSAlexander Kornienko void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *, 95bbc89dcbSAlexander Kornienko SourceLocation StateLoc, unsigned) override; 965cf06061SNico Weber void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier, 975cf06061SNico Weber ArrayRef<int>) override; 98bbc89dcbSAlexander Kornienko void PragmaWarningPush(SourceLocation Loc, int) override; 99bbc89dcbSAlexander Kornienko void PragmaWarningPop(SourceLocation Loc) override; 100bbc89dcbSAlexander Kornienko void PragmaAssumeNonNullBegin(SourceLocation Loc) override; 101bbc89dcbSAlexander Kornienko void PragmaAssumeNonNullEnd(SourceLocation Loc) override; 102bbc89dcbSAlexander Kornienko void MacroExpands(const Token &MacroNameTok, const MacroDefinition &, 103bbc89dcbSAlexander Kornienko SourceRange Range, const MacroArgs *) override; 104bbc89dcbSAlexander Kornienko void MacroDefined(const Token &MacroNameTok, 105bbc89dcbSAlexander Kornienko const MacroDirective *MD) override; 106bbc89dcbSAlexander Kornienko void MacroUndefined(const Token &, const MacroDefinition &, 107bbc89dcbSAlexander Kornienko const MacroDirective *Undef) override; 108bbc89dcbSAlexander Kornienko void Defined(const Token &MacroNameTok, const MacroDefinition &, 109bbc89dcbSAlexander Kornienko SourceRange Range) override; 110bbc89dcbSAlexander Kornienko void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override; 111bbc89dcbSAlexander Kornienko void If(SourceLocation Loc, SourceRange, ConditionValueKind) override; 112bbc89dcbSAlexander Kornienko void Elif(SourceLocation Loc, SourceRange, ConditionValueKind, 113bbc89dcbSAlexander Kornienko SourceLocation) override; 114bbc89dcbSAlexander Kornienko void Ifdef(SourceLocation Loc, const Token &, 115bbc89dcbSAlexander Kornienko const MacroDefinition &) override; 116bbc89dcbSAlexander Kornienko void Ifndef(SourceLocation Loc, const Token &, 117bbc89dcbSAlexander Kornienko const MacroDefinition &) override; 118bbc89dcbSAlexander Kornienko void Else(SourceLocation Loc, SourceLocation) override; 119bbc89dcbSAlexander Kornienko void Endif(SourceLocation Loc, SourceLocation) override; 120bbc89dcbSAlexander Kornienko 121bbc89dcbSAlexander Kornienko std::unique_ptr<FileRecorder> Recorder; 122bbc89dcbSAlexander Kornienko // Set of all the modules visited. Avoids processing a module more than once. 123bbc89dcbSAlexander Kornienko llvm::DenseSet<serialization::ModuleFile *> VisitedModules; 124bbc89dcbSAlexander Kornienko 125bbc89dcbSAlexander Kornienko CompilerInstance &Compiler; 126bbc89dcbSAlexander Kornienko // Additional filesystem for replay. Provides all input files from modules. 127bbc89dcbSAlexander Kornienko llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFs; 128bbc89dcbSAlexander Kornienko 129bbc89dcbSAlexander Kornienko SourceManager &Sources; 130bbc89dcbSAlexander Kornienko DiagnosticsEngine Diags; 131bbc89dcbSAlexander Kornienko LangOptions LangOpts; 132bbc89dcbSAlexander Kornienko TrivialModuleLoader ModuleLoader; 133bbc89dcbSAlexander Kornienko 134bbc89dcbSAlexander Kornienko std::unique_ptr<HeaderSearch> HeaderInfo; 1351ae5c63fSAlexander Kornienko std::unique_ptr<Preprocessor> PP; 136bbc89dcbSAlexander Kornienko bool EnteredMainFile = false; 137bbc89dcbSAlexander Kornienko bool StartedLexing = false; 138bbc89dcbSAlexander Kornienko Token CurrentToken; 139bbc89dcbSAlexander Kornienko }; 140bbc89dcbSAlexander Kornienko 141bbc89dcbSAlexander Kornienko } // namespace tooling 142bbc89dcbSAlexander Kornienko } // namespace clang 143bbc89dcbSAlexander Kornienko 144bbc89dcbSAlexander Kornienko #endif // LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_ 145