10#include "clang/Basic/FileManager.h"
11#include "clang/Basic/TargetInfo.h"
12#include "clang/Frontend/CompilerInstance.h"
13#include "clang/Lex/PreprocessorOptions.h"
14#include "clang/Serialization/ASTReader.h"
17#define DEBUG_TYPE "clang-tidy"
26 if (!(File.getName().ends_with(
"module.modulemap") ||
27 File.getName().ends_with(
"module.private.modulemap") ||
28 File.getName().ends_with(
"module.map") ||
29 File.getName().ends_with(
"module_private.map")))
30 FilesToRecord.insert(File);
35 const SrcMgr::ContentCache &ContentCache,
36 llvm::vfs::InMemoryFileSystem &InMemoryFs) {
38 if (!FilesToRecord.count(File))
42 std::optional<StringRef> Data = ContentCache.getBufferDataIfLoaded();
46 InMemoryFs.addFile(File.getName(), 0,
47 llvm::MemoryBuffer::getMemBufferCopy(*Data));
49 FilesToRecord.erase(File);
56 for (
auto FileEntry : FilesToRecord)
57 llvm::dbgs() <<
"Did not record contents for input file: "
58 << FileEntry.getName() <<
"\n";
64 llvm::DenseSet<FileEntryRef> FilesToRecord;
69 IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS)
72 Sources(Compiler.getSourceManager()),
74 Diags(new DiagnosticIDs, new DiagnosticOptions,
75 new ForwardingDiagnosticConsumer(Compiler.getDiagnosticClient())),
76 LangOpts(Compiler.getLangOpts()) {
79 OverlayFS->pushOverlay(InMemoryFs);
81 Diags.setSourceManager(&Sources);
84 ProcessWarningOptions(Diags, Compiler.getDiagnosticOpts(),
85 Compiler.getVirtualFileSystem());
87 LangOpts.Modules =
false;
89 auto HSO = std::make_shared<HeaderSearchOptions>();
90 *HSO = Compiler.getHeaderSearchOpts();
92 HeaderInfo = std::make_unique<HeaderSearch>(HSO, Sources, Diags, LangOpts,
93 &Compiler.getTarget());
95 auto PO = std::make_shared<PreprocessorOptions>();
96 *PO = Compiler.getPreprocessorOpts();
98 PP = std::make_unique<clang::Preprocessor>(PO, Diags, LangOpts, Sources,
99 *HeaderInfo, ModuleLoader,
102 PP->Initialize(Compiler.getTarget(), Compiler.getAuxTarget());
103 InitializePreprocessor(*PP, *PO, Compiler.getPCHContainerReader(),
104 Compiler.getFrontendOpts(), Compiler.getCodeGenOpts());
105 ApplyHeaderSearchOptions(*HeaderInfo, *HSO, LangOpts,
106 Compiler.getTarget().getTriple());
115void ExpandModularHeadersPPCallbacks::handleModuleFile(
116 serialization::ModuleFile *MF) {
120 if (!VisitedModules.insert(MF).second)
125 Compiler.getASTReader()->visitInputFiles(
127 [
this](
const serialization::InputFile &IF,
bool ) {
128 Recorder->addNecessaryFile(*IF.getFile());
131 for (
auto *Import : MF->Imports)
132 handleModuleFile(Import);
135void ExpandModularHeadersPPCallbacks::parseToLocation(SourceLocation
Loc) {
137 for (
unsigned I = 0, N = Sources.loaded_sloc_entry_size(); I != N; ++I) {
138 Sources.getLoadedSLocEntry(I,
nullptr);
141 for (
auto It = Sources.fileinfo_begin(); It != Sources.fileinfo_end(); ++It) {
142 Recorder->recordFileContent(It->getFirst(), *It->getSecond(), *InMemoryFs);
144 Recorder->checkAllFilesRecorded();
146 if (!StartedLexing) {
147 StartedLexing =
true;
148 PP->Lex(CurrentToken);
150 while (!CurrentToken.is(tok::eof) &&
151 Sources.isBeforeInTranslationUnit(CurrentToken.getLocation(),
Loc)) {
152 PP->Lex(CurrentToken);
156void ExpandModularHeadersPPCallbacks::FileChanged(
157 SourceLocation
Loc, FileChangeReason Reason,
158 SrcMgr::CharacteristicKind FileType, FileID PrevFID = FileID()) {
159 if (!EnteredMainFile) {
160 EnteredMainFile =
true;
161 PP->EnterMainSourceFile();
165void ExpandModularHeadersPPCallbacks::InclusionDirective(
166 SourceLocation DirectiveLoc,
const Token &IncludeToken,
167 StringRef IncludedFilename,
bool IsAngled, CharSourceRange FilenameRange,
168 OptionalFileEntryRef IncludedFile, StringRef SearchPath,
169 StringRef RelativePath,
const Module *SuggestedModule,
bool ModuleImported,
170 SrcMgr::CharacteristicKind FileType) {
171 if (ModuleImported) {
172 serialization::ModuleFile *MF =
173 Compiler.getASTReader()->getModuleManager().lookup(
174 *SuggestedModule->getASTFile());
175 handleModuleFile(MF);
177 parseToLocation(DirectiveLoc);
180void ExpandModularHeadersPPCallbacks::EndOfMainFile() {
181 while (!CurrentToken.is(tok::eof))
182 PP->Lex(CurrentToken);
188void ExpandModularHeadersPPCallbacks::Ident(SourceLocation
Loc, StringRef) {
189 parseToLocation(
Loc);
191void ExpandModularHeadersPPCallbacks::PragmaDirective(SourceLocation
Loc,
192 PragmaIntroducerKind) {
193 parseToLocation(
Loc);
195void ExpandModularHeadersPPCallbacks::PragmaComment(SourceLocation
Loc,
196 const IdentifierInfo *,
198 parseToLocation(
Loc);
200void ExpandModularHeadersPPCallbacks::PragmaDetectMismatch(SourceLocation
Loc,
203 parseToLocation(
Loc);
205void ExpandModularHeadersPPCallbacks::PragmaDebug(SourceLocation
Loc,
207 parseToLocation(
Loc);
209void ExpandModularHeadersPPCallbacks::PragmaMessage(SourceLocation
Loc,
213 parseToLocation(
Loc);
215void ExpandModularHeadersPPCallbacks::PragmaDiagnosticPush(SourceLocation
Loc,
217 parseToLocation(
Loc);
219void ExpandModularHeadersPPCallbacks::PragmaDiagnosticPop(SourceLocation
Loc,
221 parseToLocation(
Loc);
223void ExpandModularHeadersPPCallbacks::PragmaDiagnostic(SourceLocation
Loc,
227 parseToLocation(
Loc);
229void ExpandModularHeadersPPCallbacks::HasInclude(SourceLocation
Loc, StringRef,
230 bool, OptionalFileEntryRef,
231 SrcMgr::CharacteristicKind) {
232 parseToLocation(
Loc);
234void ExpandModularHeadersPPCallbacks::PragmaOpenCLExtension(
235 SourceLocation NameLoc,
const IdentifierInfo *, SourceLocation StateLoc,
238 parseToLocation(NameLoc);
240void ExpandModularHeadersPPCallbacks::PragmaWarning(SourceLocation
Loc,
241 PragmaWarningSpecifier,
243 parseToLocation(
Loc);
245void ExpandModularHeadersPPCallbacks::PragmaWarningPush(SourceLocation
Loc,
247 parseToLocation(
Loc);
249void ExpandModularHeadersPPCallbacks::PragmaWarningPop(SourceLocation
Loc) {
250 parseToLocation(
Loc);
252void ExpandModularHeadersPPCallbacks::PragmaAssumeNonNullBegin(
253 SourceLocation
Loc) {
254 parseToLocation(
Loc);
256void ExpandModularHeadersPPCallbacks::PragmaAssumeNonNullEnd(
257 SourceLocation
Loc) {
258 parseToLocation(
Loc);
260void ExpandModularHeadersPPCallbacks::MacroExpands(
const Token &MacroNameTok,
261 const MacroDefinition &,
265 parseToLocation(
Range.getBegin());
267void ExpandModularHeadersPPCallbacks::MacroDefined(
const Token &MacroNameTok,
268 const MacroDirective *MD) {
269 parseToLocation(MD->getLocation());
271void ExpandModularHeadersPPCallbacks::MacroUndefined(
272 const Token &,
const MacroDefinition &,
const MacroDirective *Undef) {
274 parseToLocation(Undef->getLocation());
276void ExpandModularHeadersPPCallbacks::Defined(
const Token &MacroNameTok,
277 const MacroDefinition &,
280 parseToLocation(
Range.getBegin());
282void ExpandModularHeadersPPCallbacks::SourceRangeSkipped(
283 SourceRange
Range, SourceLocation EndifLoc) {
285 parseToLocation(EndifLoc);
287void ExpandModularHeadersPPCallbacks::If(SourceLocation
Loc, SourceRange,
288 ConditionValueKind) {
289 parseToLocation(
Loc);
291void ExpandModularHeadersPPCallbacks::Elif(SourceLocation
Loc, SourceRange,
292 ConditionValueKind, SourceLocation) {
293 parseToLocation(
Loc);
295void ExpandModularHeadersPPCallbacks::Ifdef(SourceLocation
Loc,
const Token &,
296 const MacroDefinition &) {
297 parseToLocation(
Loc);
299void ExpandModularHeadersPPCallbacks::Ifndef(SourceLocation
Loc,
const Token &,
300 const MacroDefinition &) {
301 parseToLocation(
Loc);
303void ExpandModularHeadersPPCallbacks::Else(SourceLocation
Loc, SourceLocation) {
304 parseToLocation(
Loc);
306void ExpandModularHeadersPPCallbacks::Endif(SourceLocation
Loc,
308 parseToLocation(
Loc);
CharSourceRange Range
SourceRange for the file name.
bool IsAngled
true if this was an include with angle brackets
llvm::IntrusiveRefCntPtr< llvm::vfs::InMemoryFileSystem > InMemoryFileSystem
std::unique_ptr< CompilerInvocation > CI
Some operations such as code completion produce a set of candidates.