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