@@ -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)
@@ -127,9 +172,9 @@ clang_experimental_DependencyScannerService_create_v0(CXDependencyMode Format) {
127
172
// FIXME: Pass default CASOpts and nullptr as CachingOnDiskFileSystem now.
128
173
CASOptions CASOpts;
129
174
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> FS;
130
- return wrap (new DependencyScanningService (
175
+ return wrap (new DependencyScannerService{ DependencyScanningService (
131
176
ScanningMode::DependencyDirectivesScan, unwrap (Format), CASOpts,
132
- /* CAS=*/ nullptr , /* ActionCache=*/ nullptr , FS));
177
+ /* CAS=*/ nullptr , /* ActionCache=*/ nullptr , FS)} );
133
178
}
134
179
135
180
ScanningOutputFormat DependencyScannerServiceOptions::getFormat () const {
@@ -165,10 +210,10 @@ clang_experimental_DependencyScannerService_create_v1(
165
210
FS = llvm::cantFail (
166
211
llvm::cas::createCachingOnDiskFileSystem (CAS));
167
212
}
168
- return wrap (new DependencyScanningService (
213
+ return wrap (new DependencyScannerService{ DependencyScanningService (
169
214
ScanningMode::DependencyDirectivesScan, Format, unwrap (Opts)->CASOpts ,
170
215
std::move (CAS), std::move (Cache), std::move (FS),
171
- unwrap (Opts)->OptimizeArgs ));
216
+ unwrap (Opts)->OptimizeArgs )} );
172
217
}
173
218
174
219
void clang_experimental_DependencyScannerService_dispose_v0 (
@@ -177,17 +222,17 @@ void clang_experimental_DependencyScannerService_dispose_v0(
177
222
}
178
223
179
224
CXDependencyScannerWorker clang_experimental_DependencyScannerWorker_create_v0 (
180
- CXDependencyScannerService Service ) {
181
- ScanningOutputFormat Format = unwrap (Service )->getFormat ();
225
+ CXDependencyScannerService S ) {
226
+ ScanningOutputFormat Format = unwrap (S )->Service . getFormat ();
182
227
bool IsIncludeTreeOutput = Format == ScanningOutputFormat::IncludeTree ||
183
228
Format == ScanningOutputFormat::FullIncludeTree;
184
229
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
185
230
llvm::vfs::createPhysicalFileSystem ();
186
231
if (IsIncludeTreeOutput)
187
- FS = llvm::cas::createCASProvidingFileSystem (unwrap (Service )->getCAS (),
232
+ FS = llvm::cas::createCASProvidingFileSystem (unwrap (S )->Service . getCAS (),
188
233
std::move (FS));
189
234
190
- return wrap (new DependencyScanningWorker (* unwrap (Service) , FS));
235
+ return wrap (new DependencyScanningWorker (unwrap (S)-> Service , FS));
191
236
}
192
237
193
238
void clang_experimental_DependencyScannerWorker_dispose_v0 (
@@ -223,46 +268,6 @@ struct DependencyScannerWorkerScanSettings {
223
268
MLO;
224
269
};
225
270
226
- struct CStringsManager {
227
- SmallVector<std::unique_ptr<std::vector<const char *>>> OwnedCStr;
228
- SmallVector<std::unique_ptr<std::vector<std::string>>> OwnedStdStr;
229
-
230
- // / Doesn't own the string contents.
231
- CXCStringArray createCStringsRef (ArrayRef<std::string> Strings) {
232
- OwnedCStr.push_back (std::make_unique<std::vector<const char *>>());
233
- std::vector<const char *> &CStrings = *OwnedCStr.back ();
234
- CStrings.reserve (Strings.size ());
235
- for (const auto &String : Strings)
236
- CStrings.push_back (String.c_str ());
237
- return {CStrings.data (), CStrings.size ()};
238
- }
239
-
240
- // / Doesn't own the string contents.
241
- CXCStringArray createCStringsRef (const llvm::StringSet<> &StringsUnordered) {
242
- std::vector<StringRef> Strings;
243
-
244
- for (auto SI = StringsUnordered.begin (), SE = StringsUnordered.end ();
245
- SI != SE; ++SI)
246
- Strings.push_back (SI->getKey ());
247
-
248
- llvm::sort (Strings);
249
-
250
- OwnedCStr.push_back (std::make_unique<std::vector<const char *>>());
251
- std::vector<const char *> &CStrings = *OwnedCStr.back ();
252
- CStrings.reserve (Strings.size ());
253
- for (const auto &String : Strings)
254
- CStrings.push_back (String.data ());
255
- return {CStrings.data (), CStrings.size ()};
256
- }
257
-
258
- // / Gets ownership of string contents.
259
- CXCStringArray createCStringsOwned (std::vector<std::string> &&Strings) {
260
- OwnedStdStr.push_back (
261
- std::make_unique<std::vector<std::string>>(std::move (Strings)));
262
- return createCStringsRef (*OwnedStdStr.back ());
263
- }
264
- };
265
-
266
271
struct DependencyGraph {
267
272
TranslationUnitDeps TUDeps;
268
273
SmallString<256 > SerialDiagBuf;
@@ -561,6 +566,38 @@ CXDiagnosticSet clang_experimental_DepGraph_getDiagnostics(CXDepGraph Graph) {
561
566
return unwrap (Graph)->getDiagnosticSet ();
562
567
}
563
568
569
+ CXCStringArray
570
+ clang_experimental_DependencyScannerService_getInvalidNegStatCachedPaths (
571
+ CXDependencyScannerService S) {
572
+ DependencyScanningService &Service = unwrap (S)->Service ;
573
+ CStringsManager &StrMgr = unwrap (S)->StrMgr ;
574
+
575
+ // FIXME: CAS currently does not use the shared cache, and cannot produce
576
+ // the same diagnostics. We should add such a diagnostics to CAS as well.
577
+ if (Service.useCASFS ())
578
+ return {nullptr , 0 };
579
+
580
+ DependencyScanningFilesystemSharedCache &SharedCache =
581
+ Service.getSharedCache ();
582
+
583
+ // Note that it is critical that this FS is the same as the default virtual
584
+ // file system we pass to the DependencyScanningWorkers.
585
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
586
+ llvm::vfs::createPhysicalFileSystem ();
587
+
588
+ auto InvaidNegStatCachedPaths =
589
+ SharedCache.getInvalidNegativeStatCachedPaths (*FS);
590
+
591
+ // FIXME: This code here creates copies of strings from
592
+ // InvaidNegStatCachedPaths. It is acceptable because this C-API is expected
593
+ // to be called only at the end of a CXDependencyScannerService's lifetime.
594
+ // In other words, it is called very infrequently. We can change
595
+ // CStringsManager's interface to accommodate handling arbitrary StringRefs
596
+ // (which may not be null terminated) if we want to avoid copying.
597
+ return StrMgr.createCStringsOwned (
598
+ {InvaidNegStatCachedPaths.begin (), InvaidNegStatCachedPaths.end ()});
599
+ }
600
+
564
601
static std::string
565
602
lookupModuleOutput (const ModuleDeps &MD, ModuleOutputKind MOK, void *MLOContext,
566
603
std::variant<CXModuleLookupOutputCallback *,
0 commit comments