@@ -77,10 +77,10 @@ static bool checkHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
77
77
const HeaderSearchOptions &ExistingHSOpts,
78
78
DiagnosticsEngine *Diags,
79
79
const LangOptions &LangOpts) {
80
- if (LangOpts.Modules ) {
80
+ if (LangOpts.Modules && ExistingHSOpts. ModulesIncludeVFSUsage ) {
81
81
if (HSOpts.VFSOverlayFiles != ExistingHSOpts.VFSOverlayFiles ) {
82
82
if (Diags) {
83
- Diags->Report (diag::err_pch_vfsoverlay_mismatch );
83
+ Diags->Report (diag::warn_pch_vfsoverlay_mismatch );
84
84
auto VFSNote = [&](int Type, ArrayRef<std::string> VFSOverlays) {
85
85
if (VFSOverlays.empty ()) {
86
86
Diags->Report (diag::note_pch_vfsoverlay_empty) << Type;
@@ -92,7 +92,6 @@ static bool checkHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
92
92
VFSNote (0 , HSOpts.VFSOverlayFiles );
93
93
VFSNote (1 , ExistingHSOpts.VFSOverlayFiles );
94
94
}
95
- return true ;
96
95
}
97
96
}
98
97
return false ;
@@ -107,9 +106,11 @@ class PrebuiltModuleListener : public ASTReaderListener {
107
106
PrebuiltModuleListener (CompilerInstance &CI,
108
107
PrebuiltModuleFilesT &PrebuiltModuleFiles,
109
108
llvm::SmallVector<std::string> &NewModuleFiles,
109
+ PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap,
110
110
DiagnosticsEngine &Diags)
111
111
: CI(CI), PrebuiltModuleFiles(PrebuiltModuleFiles),
112
- NewModuleFiles (NewModuleFiles), Diags(Diags) {}
112
+ NewModuleFiles (NewModuleFiles),
113
+ PrebuiltModuleVFSMap(PrebuiltModuleVFSMap), Diags(Diags) {}
113
114
114
115
bool needsImportVisitation () const override { return true ; }
115
116
@@ -118,10 +119,19 @@ class PrebuiltModuleListener : public ASTReaderListener {
118
119
NewModuleFiles.push_back (Filename.str ());
119
120
}
120
121
122
+ void visitModuleFile (StringRef Filename,
123
+ serialization::ModuleKind Kind) override {
124
+ CurrentFile = Filename;
125
+ }
126
+
121
127
bool ReadHeaderSearchPaths (const HeaderSearchOptions &HSOpts,
122
128
bool Complain) override {
123
- return checkHeaderSearchPaths (
124
- HSOpts, CI.getHeaderSearchOpts (), Complain ? &Diags : nullptr , CI.getLangOpts ());
129
+ std::vector<std::string> VFSOverlayFiles = HSOpts.VFSOverlayFiles ;
130
+ PrebuiltModuleVFSMap.insert (
131
+ {CurrentFile, llvm::StringSet<>(VFSOverlayFiles)});
132
+ return checkHeaderSearchPaths (HSOpts, CI.getHeaderSearchOpts (),
133
+ Complain ? &Diags : nullptr ,
134
+ CI.getLangOpts ());
125
135
}
126
136
127
137
bool readModuleCacheKey (StringRef ModuleName, StringRef Filename,
@@ -136,19 +146,25 @@ class PrebuiltModuleListener : public ASTReaderListener {
136
146
CompilerInstance &CI;
137
147
PrebuiltModuleFilesT &PrebuiltModuleFiles;
138
148
llvm::SmallVector<std::string> &NewModuleFiles;
149
+ PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap;
139
150
DiagnosticsEngine &Diags;
151
+ std::string CurrentFile;
140
152
};
141
153
142
154
// / Visit the given prebuilt module and collect all of the modules it
143
155
// / transitively imports and contributing input files.
144
156
static bool visitPrebuiltModule (StringRef PrebuiltModuleFilename,
145
157
CompilerInstance &CI,
146
158
PrebuiltModuleFilesT &ModuleFiles,
159
+ PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap,
147
160
DiagnosticsEngine &Diags) {
148
161
// List of module files to be processed.
149
162
llvm::SmallVector<std::string> Worklist;
150
- PrebuiltModuleListener Listener (CI, ModuleFiles, Worklist, Diags);
163
+ PrebuiltModuleListener Listener (CI, ModuleFiles, Worklist,
164
+ PrebuiltModuleVFSMap, Diags);
151
165
166
+ Listener.visitModuleFile (PrebuiltModuleFilename,
167
+ serialization::MK_ExplicitModule);
152
168
if (ASTReader::readASTFileControlBlock (
153
169
PrebuiltModuleFilename, CI.getFileManager (), CI.getModuleCache (),
154
170
CI.getPCHContainerReader (),
@@ -157,6 +173,7 @@ static bool visitPrebuiltModule(StringRef PrebuiltModuleFilename,
157
173
return true ;
158
174
159
175
while (!Worklist.empty ()) {
176
+ Listener.visitModuleFile (Worklist.back (), serialization::MK_ExplicitModule);
160
177
if (ASTReader::readASTFileControlBlock (
161
178
Worklist.pop_back_val (), CI.getFileManager (), CI.getModuleCache (),
162
179
CI.getPCHContainerReader (),
@@ -193,8 +210,18 @@ static void sanitizeDiagOpts(DiagnosticOptions &DiagOpts) {
193
210
DiagOpts.ShowCarets = false ;
194
211
// Don't write out diagnostic file.
195
212
DiagOpts.DiagnosticSerializationFile .clear ();
196
- // Don't emit warnings as errors (and all other warnings too).
197
- DiagOpts.IgnoreWarnings = true ;
213
+ // Don't emit warnings except for scanning specific warnings.
214
+ // TODO: It would be useful to add a more principled way to ignore all
215
+ // warnings that come from source code. The issue is that we need to
216
+ // ignore warnings that could be surpressed by
217
+ // `#pragma clang diagnostic`, while still allowing some scanning
218
+ // warnings for things we're not ready to turn into errors yet.
219
+ // See `test/ClangScanDeps/diagnostic-pragmas.c` for an example.
220
+ llvm::erase_if (DiagOpts.Warnings , [](StringRef Warning) {
221
+ return llvm::StringSwitch<bool >(Warning)
222
+ .Cases (" pch-vfs-diff" , " error=pch-vfs-diff" , false )
223
+ .Default (true );
224
+ });
198
225
}
199
226
200
227
// Clang implements -D and -U by splatting text into a predefines buffer. This
@@ -435,14 +462,19 @@ class DependencyScanningAction : public tooling::ToolAction {
435
462
if (VerboseOS)
436
463
ScanInstance.setVerboseOutputStream (*VerboseOS);
437
464
465
+ // Some DiagnosticConsumers require that finish() is called.
466
+ auto DiagConsumerFinisher =
467
+ llvm::make_scope_exit ([DiagConsumer]() { DiagConsumer->finish (); });
468
+
438
469
ScanInstance.getPreprocessorOpts ().AllowPCHWithDifferentModulesCachePath =
439
470
true ;
440
471
441
472
ScanInstance.getFrontendOpts ().GenerateGlobalModuleIndex = false ;
442
473
ScanInstance.getFrontendOpts ().UseGlobalModuleIndex = false ;
443
474
ScanInstance.getFrontendOpts ().ModulesShareFileManager = false ;
444
475
ScanInstance.getHeaderSearchOpts ().ModuleFormat = " raw" ;
445
- ScanInstance.getHeaderSearchOpts ().ModulesIncludeVFSUsage = true ;
476
+ ScanInstance.getHeaderSearchOpts ().ModulesIncludeVFSUsage =
477
+ any (OptimizeArgs & ScanningOptimizations::VFS);
446
478
447
479
ScanInstance.setFileManager (FileMgr);
448
480
// Support for virtual file system overlays.
@@ -455,12 +487,13 @@ class DependencyScanningAction : public tooling::ToolAction {
455
487
// Store the list of prebuilt module files into header search options. This
456
488
// will prevent the implicit build to create duplicate modules and will
457
489
// force reuse of the existing prebuilt module files instead.
490
+ PrebuiltModuleVFSMapT PrebuiltModuleVFSMap;
458
491
if (!ScanInstance.getPreprocessorOpts ().ImplicitPCHInclude .empty ())
459
492
if (visitPrebuiltModule (
460
493
ScanInstance.getPreprocessorOpts ().ImplicitPCHInclude ,
461
494
ScanInstance,
462
495
ScanInstance.getHeaderSearchOpts ().PrebuiltModuleFiles ,
463
- ScanInstance.getDiagnostics ()))
496
+ PrebuiltModuleVFSMap, ScanInstance.getDiagnostics ()))
464
497
return false ;
465
498
466
499
// Use the dependency scanning optimized file system if requested to do so.
@@ -544,8 +577,8 @@ class DependencyScanningAction : public tooling::ToolAction {
544
577
545
578
MDC = std::make_shared<ModuleDepCollector>(
546
579
std::move (Opts), ScanInstance, Consumer, Controller,
547
- OriginalInvocation, OptimizeArgs, EagerLoadModules ,
548
- Format == ScanningOutputFormat::P1689);
580
+ OriginalInvocation, std::move (PrebuiltModuleVFSMap), OptimizeArgs ,
581
+ EagerLoadModules, Format == ScanningOutputFormat::P1689);
549
582
ScanInstance.addDependencyCollector (MDC);
550
583
ScanInstance.setGenModuleActionWrapper (
551
584
[&Controller = Controller](const FrontendOptions &Opts,
@@ -587,6 +620,8 @@ class DependencyScanningAction : public tooling::ToolAction {
587
620
if (ScanInstance.getDiagnostics ().hasErrorOccurred ())
588
621
return false ;
589
622
623
+ // Each action is responsible for calling finish.
624
+ DiagConsumerFinisher.release ();
590
625
if (!ScanInstance.ExecuteAction (*Action))
591
626
return false ;
592
627
0 commit comments