[ClangImporter] Prefer serialized bridging headers in LLDB.

Especially in an explicit modules project, LLDB might not know all the
search paths needed to imported the on disk header.

rdar://157063577
(cherry picked from commit a6678476d8)
This commit is contained in:
Adrian Prantl
2025-07-29 17:07:45 -07:00
parent 99a2db3392
commit 95ad22e799
3 changed files with 32 additions and 25 deletions

View File

@@ -444,12 +444,10 @@ bool ClangImporter::Implementation::shouldIgnoreBridgeHeaderTopLevelDecl(
return importer::isForwardDeclOfType(D);
}
ClangImporter::ClangImporter(ASTContext &ctx,
DependencyTracker *tracker,
ClangImporter::ClangImporter(ASTContext &ctx, DependencyTracker *tracker,
DWARFImporterDelegate *dwarfImporterDelegate)
: ClangModuleLoader(tracker),
Impl(*new Implementation(ctx, tracker, dwarfImporterDelegate)) {
}
Impl(*new Implementation(ctx, tracker, dwarfImporterDelegate)) {}
ClangImporter::~ClangImporter() {
delete &Impl;
@@ -1298,11 +1296,9 @@ std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
return CI;
}
std::unique_ptr<ClangImporter>
ClangImporter::create(ASTContext &ctx,
std::string swiftPCHHash, DependencyTracker *tracker,
DWARFImporterDelegate *dwarfImporterDelegate,
bool ignoreFileMapping) {
std::unique_ptr<ClangImporter> ClangImporter::create(
ASTContext &ctx, std::string swiftPCHHash, DependencyTracker *tracker,
DWARFImporterDelegate *dwarfImporterDelegate, bool ignoreFileMapping) {
std::unique_ptr<ClangImporter> importer{
new ClangImporter(ctx, tracker, dwarfImporterDelegate)};
auto &importerOpts = ctx.ClangImporterOpts;
@@ -1788,15 +1784,24 @@ bool ClangImporter::importHeader(StringRef header, ModuleDecl *adapter,
off_t expectedSize, time_t expectedModTime,
StringRef cachedContents, SourceLoc diagLoc) {
clang::FileManager &fileManager = Impl.Instance->getFileManager();
auto headerFile = fileManager.getFile(header, /*OpenFile=*/true);
// Prefer importing the header directly if the header content matches by
// checking size and mod time. This allows correct import if some no-modular
// headers are already imported into clang importer. If mod time is zero, then
// the module should be built from CAS and there is no mod time to verify.
if (headerFile && (*headerFile)->getSize() == expectedSize &&
(expectedModTime == 0 ||
(*headerFile)->getModificationTime() == expectedModTime)) {
return importBridgingHeader(header, adapter, diagLoc, false, true);
// Especially in an explicit modules project, LLDB might not know all the
// search paths needed to imported the on disk header, so prefer the
// serialized preprocessed contents when debugger support is on.
if (!Impl.SwiftContext.ClangImporterOpts.PreferSerializedBridgingHeader ||
cachedContents.empty()) {
auto headerFile = fileManager.getFile(header, /*OpenFile=*/true);
// Prefer importing the header directly if the header content matches by
// checking size and mod time. This allows correct import if some no-modular
// headers are already imported into clang importer. If mod time is zero,
// then the module should be built from CAS and there is no mod time to
// verify. LLDB prefers the serialized bridging header because, in an
// explicit modules project, LLDB might not know all the search paths needed
// to imported the on disk header.
if (headerFile && (*headerFile)->getSize() == expectedSize &&
(expectedModTime == 0 ||
(*headerFile)->getModificationTime() == expectedModTime)) {
return importBridgingHeader(header, adapter, diagLoc, false, true);
}
}
// If we've made it to here, this is some header other than the bridging
@@ -1806,9 +1811,8 @@ bool ClangImporter::importHeader(StringRef header, ModuleDecl *adapter,
if (!cachedContents.empty() && cachedContents.back() == '\0')
cachedContents = cachedContents.drop_back();
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer{
llvm::MemoryBuffer::getMemBuffer(cachedContents, header)
};
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer =
llvm::MemoryBuffer::getMemBufferCopy(cachedContents, header);
return Impl.importHeader(adapter, header, diagLoc, /*trackParsedSymbols=*/false,
std::move(sourceBuffer), true);
}