xref: /llvm-project/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h (revision da95d926f6fce4ed9707c77908ad96624268f134)
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