1 //===- ExpandModularHeadersPPCallbacks.h - clang-tidy -----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_
10 #define LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_
12 #include "clang/Lex/PPCallbacks.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "llvm/ADT/DenseSet.h"
17 class OverlayFileSystem
;
18 class InMemoryFileSystem
;
19 } // namespace llvm::vfs
22 class CompilerInstance
;
24 namespace serialization
{
26 } // namespace serialization
30 /// Handles PPCallbacks and re-runs preprocessing of the whole
31 /// translation unit with modules disabled.
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
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
41 class ExpandModularHeadersPPCallbacks
: public PPCallbacks
{
43 ExpandModularHeadersPPCallbacks(
45 IntrusiveRefCntPtr
<llvm::vfs::OverlayFileSystem
> OverlayFS
);
46 ~ExpandModularHeadersPPCallbacks();
48 /// Returns the preprocessor that provides callbacks for the whole
49 /// translation unit, including the main file, textual headers, and modular
52 /// This preprocessor is separate from the one used by the rest of the
54 Preprocessor
*getPreprocessor() const;
59 void handleModuleFile(serialization::ModuleFile
*MF
);
60 void parseToLocation(SourceLocation Loc
);
62 // Handle PPCallbacks.
63 void FileChanged(SourceLocation Loc
, FileChangeReason Reason
,
64 SrcMgr::CharacteristicKind FileType
,
65 FileID PrevFID
) override
;
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
*Imported
,
73 SrcMgr::CharacteristicKind FileType
) override
;
75 void EndOfMainFile() override
;
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
*,
84 void PragmaDetectMismatch(SourceLocation Loc
, StringRef
, StringRef
) override
;
85 void PragmaDebug(SourceLocation Loc
, StringRef
) override
;
86 void PragmaMessage(SourceLocation Loc
, StringRef
, PragmaMessageKind
,
88 void PragmaDiagnosticPush(SourceLocation Loc
, StringRef
) override
;
89 void PragmaDiagnosticPop(SourceLocation Loc
, StringRef
) override
;
90 void PragmaDiagnostic(SourceLocation Loc
, StringRef
, diag::Severity
,
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
;
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
;
125 CompilerInstance
&Compiler
;
126 // Additional filesystem for replay. Provides all input files from modules.
127 llvm::IntrusiveRefCntPtr
<llvm::vfs::InMemoryFileSystem
> InMemoryFs
;
129 SourceManager
&Sources
;
130 DiagnosticsEngine Diags
;
131 LangOptions LangOpts
;
132 TrivialModuleLoader ModuleLoader
;
134 std::unique_ptr
<HeaderSearch
> HeaderInfo
;
135 std::unique_ptr
<Preprocessor
> PP
;
136 bool EnteredMainFile
= false;
137 bool StartedLexing
= false;
141 } // namespace tooling
144 #endif // LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_