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
16namespace llvm::vfs {
17class OverlayFileSystem;
18class InMemoryFileSystem;
19} // namespace llvm::vfs
20
21namespace clang {
22class CompilerInstance;
23
24namespace serialization {
25class ModuleFile;
26} // namespace serialization
27
28namespace 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.
41class ExpandModularHeadersPPCallbacks : public PPCallbacks {
42public:
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
56private:
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

source code of clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h