@@ -41,12 +41,57 @@ struct DependencyScannerServiceOptions {
41
41
42
42
ScanningOutputFormat getFormat () const ;
43
43
};
44
+
45
+ struct CStringsManager {
46
+ SmallVector<std::unique_ptr<std::vector<const char *>>> OwnedCStr;
47
+ SmallVector<std::unique_ptr<std::vector<std::string>>> OwnedStdStr;
48
+
49
+ // / Doesn't own the string contents.
50
+ CXCStringArray createCStringsRef (ArrayRef<std::string> Strings) {
51
+ OwnedCStr.push_back (std::make_unique<std::vector<const char *>>());
52
+ std::vector<const char *> &CStrings = *OwnedCStr.back ();
53
+ CStrings.reserve (Strings.size ());
54
+ for (const auto &String : Strings)
55
+ CStrings.push_back (String.c_str ());
56
+ return {CStrings.data (), CStrings.size ()};
57
+ }
58
+
59
+ // / Doesn't own the string contents.
60
+ CXCStringArray createCStringsRef (const llvm::StringSet<> &StringsUnordered) {
61
+ std::vector<StringRef> Strings;
62
+
63
+ for (auto SI = StringsUnordered.begin (), SE = StringsUnordered.end ();
64
+ SI != SE; ++SI)
65
+ Strings.push_back (SI->getKey ());
66
+
67
+ llvm::sort (Strings);
68
+
69
+ OwnedCStr.push_back (std::make_unique<std::vector<const char *>>());
70
+ std::vector<const char *> &CStrings = *OwnedCStr.back ();
71
+ CStrings.reserve (Strings.size ());
72
+ for (const auto &String : Strings)
73
+ CStrings.push_back (String.data ());
74
+ return {CStrings.data (), CStrings.size ()};
75
+ }
76
+
77
+ // / Gets ownership of string contents.
78
+ CXCStringArray createCStringsOwned (std::vector<std::string> &&Strings) {
79
+ OwnedStdStr.push_back (
80
+ std::make_unique<std::vector<std::string>>(std::move (Strings)));
81
+ return createCStringsRef (*OwnedStdStr.back ());
82
+ }
83
+ };
84
+
85
+ struct DependencyScannerService {
86
+ DependencyScanningService Service;
87
+ CStringsManager StrMgr{};
88
+ };
44
89
} // end anonymous namespace
45
90
46
91
DEFINE_SIMPLE_CONVERSION_FUNCTIONS (DependencyScannerServiceOptions,
47
92
CXDependencyScannerServiceOptions)
48
93
49
- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScanningService ,
94
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScannerService ,
50
95
CXDependencyScannerService)
51
96
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScanningWorker,
52
97
CXDependencyScannerWorker)
@@ -142,9 +187,9 @@ clang_experimental_DependencyScannerService_create_v0(CXDependencyMode Format) {
142
187
// FIXME: Pass default CASOpts and nullptr as CachingOnDiskFileSystem now.
143
188
CASOptions CASOpts;
144
189
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> FS;
145
- return wrap (new DependencyScanningService (
190
+ return wrap (new DependencyScannerService{ DependencyScanningService (
146
191
ScanningMode::DependencyDirectivesScan, unwrap (Format), CASOpts,
147
- /* CAS=*/ nullptr , /* ActionCache=*/ nullptr , FS));
192
+ /* CAS=*/ nullptr , /* ActionCache=*/ nullptr , FS)} );
148
193
}
149
194
150
195
ScanningOutputFormat DependencyScannerServiceOptions::getFormat () const {
@@ -180,10 +225,10 @@ clang_experimental_DependencyScannerService_create_v1(
180
225
FS = llvm::cantFail (
181
226
llvm::cas::createCachingOnDiskFileSystem (CAS));
182
227
}
183
- return wrap (new DependencyScanningService (
228
+ return wrap (new DependencyScannerService{ DependencyScanningService (
184
229
ScanningMode::DependencyDirectivesScan, Format, unwrap (Opts)->CASOpts ,
185
230
std::move (CAS), std::move (Cache), std::move (FS),
186
- unwrap (Opts)->OptimizeArgs ));
231
+ unwrap (Opts)->OptimizeArgs )} );
187
232
}
188
233
189
234
void clang_experimental_DependencyScannerService_dispose_v0 (
@@ -213,17 +258,17 @@ void clang_experimental_FileDependenciesList_dispose(
213
258
}
214
259
215
260
CXDependencyScannerWorker clang_experimental_DependencyScannerWorker_create_v0 (
216
- CXDependencyScannerService Service ) {
217
- ScanningOutputFormat Format = unwrap (Service )->getFormat ();
261
+ CXDependencyScannerService S ) {
262
+ ScanningOutputFormat Format = unwrap (S )->Service . getFormat ();
218
263
bool IsIncludeTreeOutput = Format == ScanningOutputFormat::IncludeTree ||
219
264
Format == ScanningOutputFormat::FullIncludeTree;
220
265
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
221
266
llvm::vfs::createPhysicalFileSystem ();
222
267
if (IsIncludeTreeOutput)
223
- FS = llvm::cas::createCASProvidingFileSystem (unwrap (Service )->getCAS (),
268
+ FS = llvm::cas::createCASProvidingFileSystem (unwrap (S )->Service . getCAS (),
224
269
std::move (FS));
225
270
226
- return wrap (new DependencyScanningWorker (* unwrap (Service) , FS));
271
+ return wrap (new DependencyScanningWorker (unwrap (S)-> Service , FS));
227
272
}
228
273
229
274
void clang_experimental_DependencyScannerWorker_dispose_v0 (
@@ -432,46 +477,6 @@ struct DependencyScannerWorkerScanSettings {
432
477
MLO;
433
478
};
434
479
435
- struct CStringsManager {
436
- SmallVector<std::unique_ptr<std::vector<const char *>>> OwnedCStr;
437
- SmallVector<std::unique_ptr<std::vector<std::string>>> OwnedStdStr;
438
-
439
- // / Doesn't own the string contents.
440
- CXCStringArray createCStringsRef (ArrayRef<std::string> Strings) {
441
- OwnedCStr.push_back (std::make_unique<std::vector<const char *>>());
442
- std::vector<const char *> &CStrings = *OwnedCStr.back ();
443
- CStrings.reserve (Strings.size ());
444
- for (const auto &String : Strings)
445
- CStrings.push_back (String.c_str ());
446
- return {CStrings.data (), CStrings.size ()};
447
- }
448
-
449
- // / Doesn't own the string contents.
450
- CXCStringArray createCStringsRef (const llvm::StringSet<> &StringsUnordered) {
451
- std::vector<StringRef> Strings;
452
-
453
- for (auto SI = StringsUnordered.begin (), SE = StringsUnordered.end ();
454
- SI != SE; ++SI)
455
- Strings.push_back (SI->getKey ());
456
-
457
- llvm::sort (Strings);
458
-
459
- OwnedCStr.push_back (std::make_unique<std::vector<const char *>>());
460
- std::vector<const char *> &CStrings = *OwnedCStr.back ();
461
- CStrings.reserve (Strings.size ());
462
- for (const auto &String : Strings)
463
- CStrings.push_back (String.data ());
464
- return {CStrings.data (), CStrings.size ()};
465
- }
466
-
467
- // / Gets ownership of string contents.
468
- CXCStringArray createCStringsOwned (std::vector<std::string> &&Strings) {
469
- OwnedStdStr.push_back (
470
- std::make_unique<std::vector<std::string>>(std::move (Strings)));
471
- return createCStringsRef (*OwnedStdStr.back ());
472
- }
473
- };
474
-
475
480
struct DependencyGraph {
476
481
TranslationUnitDeps TUDeps;
477
482
SmallString<256 > SerialDiagBuf;
@@ -731,6 +736,38 @@ CXDiagnosticSet clang_experimental_DepGraph_getDiagnostics(CXDepGraph Graph) {
731
736
return unwrap (Graph)->getDiagnosticSet ();
732
737
}
733
738
739
+ CXCStringArray
740
+ clang_experimental_DependencyScannerService_getInvalidNegStatCachedPaths (
741
+ CXDependencyScannerService S) {
742
+ DependencyScanningService &Service = unwrap (S)->Service ;
743
+ CStringsManager &StrMgr = unwrap (S)->StrMgr ;
744
+
745
+ // FIXME: CAS currently does not use the shared cache, and cannot produce
746
+ // the same diagnostics. We should add such a diagnostics to CAS as well.
747
+ if (Service.useCASFS ())
748
+ return {nullptr , 0 };
749
+
750
+ DependencyScanningFilesystemSharedCache &SharedCache =
751
+ Service.getSharedCache ();
752
+
753
+ // Note that it is critical that this FS is the same as the default virtual
754
+ // file system we pass to the DependencyScanningWorkers.
755
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
756
+ llvm::vfs::createPhysicalFileSystem ();
757
+
758
+ auto InvaidNegStatCachedPaths =
759
+ SharedCache.getInvalidNegativeStatCachedPaths (*FS);
760
+
761
+ // FIXME: This code here creates copies of strings from
762
+ // InvaidNegStatCachedPaths. It is acceptable because this C-API is expected
763
+ // to be called only at the end of a CXDependencyScannerService's lifetime.
764
+ // In other words, it is called very infrequently. We can change
765
+ // CStringsManager's interface to accommodate handling arbitrary StringRefs
766
+ // (which may not be null terminated) if we want to avoid copying.
767
+ return StrMgr.createCStringsOwned (
768
+ {InvaidNegStatCachedPaths.begin (), InvaidNegStatCachedPaths.end ()});
769
+ }
770
+
734
771
static std::string
735
772
lookupModuleOutput (const ModuleDeps &MD, ModuleOutputKind MOK, void *MLOContext,
736
773
std::variant<CXModuleLookupOutputCallback *,
0 commit comments