Skip to content
Merged
100 changes: 96 additions & 4 deletions clang/include/clang-c/Dependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,10 +585,102 @@ const char *clang_experimental_DepGraph_getTUContextHash(CXDepGraph);
CINDEX_LINKAGE
CXDiagnosticSet clang_experimental_DepGraph_getDiagnostics(CXDepGraph);

CINDEX_LINKAGE
CXCStringArray
clang_experimental_DependencyScannerService_getInvalidNegStatCachedPaths(
CXDependencyScannerService);
/**
* The kind of scanning file system cache out-of-date entries.
*/
typedef enum {
/**
* The entry is negatively stat cached (which indicates the file did not exist
* the first time it was looked up during scanning), but the cached file
* exists on the underlying file system.
*/
NegativelyCached,

/**
* The entry indicates that for the cached file, its cached size
* is different from its size reported by the underlying file system.
*/
SizeChanged
} CXDepScanFSCacheOutOfDateKind;

/**
* The opaque object that contains the scanning file system cache's out-of-date
* entires.
*/
typedef struct CXOpaqueDepScanFSOutOfDateEntrySet *CXDepScanFSOutOfDateEntrySet;

/**
* The opaque object that represents a single scanning file system cache's out-
* of-date entry.
*/
typedef struct CXOpaqueDepScanFSOutOfDateEntry *CXDepScanFSOutOfDateEntry;

/**
* Returns all the file system cache out-of-date entries given a
* \c CXDependencyScannerService .
*
* This function is intended to be called when the build has finished,
* and the \c CXDependencyScannerService instance is about to be disposed.
*
* The \c CXDependencyScannerService instance owns the strings used
* by the out-of-date entries and should be disposed after the
* out-of-date entries are used and disposed.
*/
CXDepScanFSOutOfDateEntrySet
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntrySet(
CXDependencyScannerService S);

/**
* Returns the number of out-of-date entries contained in a
* \c CXDepScanFSOutOfDateEntrySet .
*/
size_t
clang_experimental_DependencyScannerService_getNumOfFSCacheOutOfDateEntries(
CXDepScanFSOutOfDateEntrySet Entries);

/**
* Returns the out-of-date entry at offset \p Idx of the \c
* CXDepScanFSOutOfDateEntrySet instance.
*/
CXDepScanFSOutOfDateEntry
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntry(
CXDepScanFSOutOfDateEntrySet Entries, size_t Idx);

/**
* Given an instance of \c CXDepScanFSOutOfDateEntry, returns its Kind.
*/
CXDepScanFSCacheOutOfDateKind
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryKind(
CXDepScanFSOutOfDateEntry Entry);

/**
* Given an instance of \c CXDepScanFSOutOfDateEntry, returns the path.
*/
CXString
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryPath(
CXDepScanFSOutOfDateEntry Entry);

/**
* Given an instance of \c CXDepScanFSOutOfDateEntry of kind SizeChanged,
* returns the cached size.
*/
uint64_t
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryCachedSize(
CXDepScanFSOutOfDateEntry Entry);

/**
* Given an instance of \c CXDepScanFSOutOfDateEntry of kind SizeChanged,
* returns the actual size on the underlying file system.
*/
uint64_t
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryActualSize(
CXDepScanFSOutOfDateEntry Entry);

/**
* Dispose the \c CXDepScanFSOutOfDateEntrySet instance.
*/
void clang_experimental_DependencyScannerService_disposeFSCacheOutOfDateEntrySet(
CXDepScanFSOutOfDateEntrySet Entries);

/**
* Options used to generate a reproducer.
Expand Down
8 changes: 2 additions & 6 deletions clang/tools/c-index-test/core_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,12 +916,8 @@ static int scanDeps(ArrayRef<const char *> Args, std::string WorkingDirectory,
clang_disposeDiagnostic(Diag);
}

CXCStringArray InvalidNegativeStatCachedPaths =
clang_experimental_DependencyScannerService_getInvalidNegStatCachedPaths(
Service);

llvm::errs() << "note: number of invalid negatively stat cached paths: "
<< InvalidNegativeStatCachedPaths.Count << "\n";
llvm::errs() << "note: number of invalid negatively stat cached paths: " << 0
<< "\n";

return 1;
}
Expand Down
131 changes: 94 additions & 37 deletions clang/tools/libclang/CDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,43 +566,6 @@ CXDiagnosticSet clang_experimental_DepGraph_getDiagnostics(CXDepGraph Graph) {
return unwrap(Graph)->getDiagnosticSet();
}

CXCStringArray
clang_experimental_DependencyScannerService_getInvalidNegStatCachedPaths(
CXDependencyScannerService S) {
DependencyScanningService &Service = unwrap(S)->Service;
CStringsManager &StrMgr = unwrap(S)->StrMgr;

// FIXME: CAS currently does not use the shared cache, and cannot produce
// the same diagnostics. We should add such a diagnostics to CAS as well.
if (Service.useCASFS())
return {nullptr, 0};

DependencyScanningFilesystemSharedCache &SharedCache =
Service.getSharedCache();

// Note that it is critical that this FS is the same as the default virtual
// file system we pass to the DependencyScanningWorkers.
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
llvm::vfs::createPhysicalFileSystem();

auto OutOfDateEntries = SharedCache.getOutOfDateEntries(*FS);

// FIXME: replace this code with proper APIs that handles the
// OutOfDateEntries.
std::vector<const char *> OutOfDatePaths;
for (const auto &E : OutOfDateEntries)
OutOfDatePaths.emplace_back(E.Path);

// FIXME: This code here creates copies of strings from
// InvaidNegStatCachedPaths. It is acceptable because this C-API is expected
// to be called only at the end of a CXDependencyScannerService's lifetime.
// In other words, it is called very infrequently. We can change
// CStringsManager's interface to accommodate handling arbitrary StringRefs
// (which may not be null terminated) if we want to avoid copying.
return StrMgr.createCStringsOwned(
{OutOfDatePaths.begin(), OutOfDatePaths.end()});
}

static std::string
lookupModuleOutput(const ModuleDeps &MD, ModuleOutputKind MOK, void *MLOContext,
std::variant<CXModuleLookupOutputCallback *,
Expand Down Expand Up @@ -646,6 +609,100 @@ std::string OutputLookup::lookupModuleOutput(const ModuleDeps &MD,
return PCMPath.first->second;
}

namespace {
typedef std::vector<DependencyScanningFilesystemSharedCache::OutOfDateEntry>
DependencyScannerFSOutOfDateEntrySet;

typedef DependencyScanningFilesystemSharedCache::OutOfDateEntry
DependencyScannerFSOutOfDateEntry;
} // namespace

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScannerFSOutOfDateEntrySet,
CXDepScanFSOutOfDateEntrySet)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScannerFSOutOfDateEntry,
CXDepScanFSOutOfDateEntry)

CXDepScanFSOutOfDateEntrySet
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntrySet(
CXDependencyScannerService S) {
DependencyScanningService &Service = unwrap(S)->Service;

if (Service.useCASFS())
return nullptr;

// Note that it is critical that this FS is the same as the default virtual
// file system we pass to the DependencyScanningWorkers.
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
llvm::vfs::createPhysicalFileSystem();

DependencyScannerFSOutOfDateEntrySet *OODEntrySet =
new DependencyScannerFSOutOfDateEntrySet();
*OODEntrySet = Service.getSharedCache().getOutOfDateEntries(*FS);

return wrap(OODEntrySet);
}

size_t
clang_experimental_DependencyScannerService_getNumOfFSCacheOutOfDateEntries(
CXDepScanFSOutOfDateEntrySet Entries) {
return unwrap(Entries)->size();
}

CXDepScanFSOutOfDateEntry
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntry(
CXDepScanFSOutOfDateEntrySet Entries, size_t Idx) {
DependencyScannerFSOutOfDateEntrySet *EntSet = unwrap(Entries);
return wrap(&(*EntSet)[Idx]);
}

CXDepScanFSCacheOutOfDateKind
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryKind(
CXDepScanFSOutOfDateEntry Entry) {
DependencyScannerFSOutOfDateEntry *E = unwrap(Entry);
auto &Info = E->Info;
return std::visit(
llvm::makeVisitor(
[](const DependencyScannerFSOutOfDateEntry::NegativelyCachedInfo
&Info) { return NegativelyCached; },
[](const DependencyScannerFSOutOfDateEntry::SizeChangedInfo &Info) {
return SizeChanged;
}),
Info);
}

CXString
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryPath(
CXDepScanFSOutOfDateEntry Entry) {
return cxstring::createRef(unwrap(Entry)->Path);
}

static DependencyScannerFSOutOfDateEntry::SizeChangedInfo *
getOutOfDateEntrySizeChangedInfo(DependencyScannerFSOutOfDateEntry *E) {
auto *SizeInfo =
std::get_if<DependencyScannerFSOutOfDateEntry::SizeChangedInfo>(&E->Info);
assert(SizeInfo && "Wrong entry kind to get the original size!");
return SizeInfo;
}

uint64_t
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryCachedSize(
CXDepScanFSOutOfDateEntry Entry) {
DependencyScannerFSOutOfDateEntry *E = unwrap(Entry);
return getOutOfDateEntrySizeChangedInfo(E)->CachedSize;
}

uint64_t
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryActualSize(
CXDepScanFSOutOfDateEntry Entry) {
DependencyScannerFSOutOfDateEntry *E = unwrap(Entry);
return getOutOfDateEntrySizeChangedInfo(E)->ActualSize;
}

void clang_experimental_DependencyScannerService_disposeFSCacheOutOfDateEntrySet(
CXDepScanFSOutOfDateEntrySet Entries) {
delete unwrap(Entries);
}

namespace {
struct DependencyScannerReproducerOptions {
std::vector<std::string> BuildArgs;
Expand Down
9 changes: 8 additions & 1 deletion clang/tools/libclang/libclang.map
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,6 @@ LLVM_21 {
clang_experimental_DepGraphModule_isCWDIgnored;
clang_experimental_DepGraphModule_isInStableDirs;
clang_getFullyQualifiedName;
clang_experimental_DependencyScannerService_getInvalidNegStatCachedPaths;
clang_experimental_DependencyScannerReproducerOptions_create;
clang_experimental_DependencyScannerReproducerOptions_dispose;
clang_experimental_DependencyScanner_generateReproducer;
Expand All @@ -590,6 +589,14 @@ LLVM_21 {
clang_Cursor_getGCCAssemblyNumClobbers;
clang_Cursor_getGCCAssemblyClobber;
clang_Cursor_isGCCAssemblyVolatile;
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntrySet;
clang_experimental_DependencyScannerService_getNumOfFSCacheOutOfDateEntries;
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntry;
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryKind;
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryPath;
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryCachedSize;
clang_experimental_DependencyScannerService_getFSCacheOutOfDateEntryActualSize;
clang_experimental_DependencyScannerService_disposeFSCacheOutOfDateEntrySet;
};

# Example of how to add a new symbol version entry. If you do add a new symbol
Expand Down