Skip to content

Commit ac13ef5

Browse files
authored
Merge pull request #70445 from apple/egorzhdan/split-libcxx-lookup
[cxx-interop] Keep pulling in the entire libc++
2 parents ab5ab28 + 65eaafe commit ac13ef5

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,11 @@ namespace importer {
637637
/// Returns true if the given module has a 'cplusplus' requirement.
638638
bool requiresCPlusPlus(const clang::Module *module);
639639

640+
/// Returns true if the given module is one of the C++ standard library modules.
641+
/// This could be the top-level std module, or any of the libc++ split modules
642+
/// (std_vector, std_iosfwd, etc).
643+
bool isCxxStdModule(const clang::Module *module);
644+
640645
/// Returns the pointee type if the given type is a C++ `const`
641646
/// reference type, `None` otherwise.
642647
llvm::Optional<clang::QualType>

lib/ClangImporter/ClangImporter.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,7 +2163,8 @@ ModuleDecl *ClangImporter::Implementation::loadModule(
21632163
ASTContext &ctx = getNameImporter().getContext();
21642164

21652165
// `CxxStdlib` is the only accepted spelling of the C++ stdlib module name.
2166-
if (path.front().Item.is("std"))
2166+
if (path.front().Item.is("std") ||
2167+
path.front().Item.str().starts_with("std_"))
21672168
return nullptr;
21682169
if (path.front().Item == ctx.Id_CxxStdlib) {
21692170
ImportPath::Builder adjustedPath(ctx.getIdentifier("std"), importLoc);
@@ -3985,6 +3986,13 @@ ModuleDecl *ClangModuleUnit::getOverlayModule() const {
39853986
ImportPath::Module::Builder builder(M->getName());
39863987
(void) owner.loadModule(SourceLoc(), std::move(builder).get());
39873988
}
3989+
// If this Clang module is a part of the C++ stdlib, and we haven't loaded
3990+
// the overlay for it so far, it is a split libc++ module (e.g. std_vector).
3991+
// Load the CxxStdlib overlay explicitly.
3992+
if (!overlay && importer::isCxxStdModule(clangModule)) {
3993+
ImportPath::Module::Builder builder(Ctx.Id_CxxStdlib);
3994+
overlay = owner.loadModule(SourceLoc(), std::move(builder).get());
3995+
}
39883996
auto mutableThis = const_cast<ClangModuleUnit *>(this);
39893997
mutableThis->overlayModule.setPointerAndInt(overlay, true);
39903998
}
@@ -7697,12 +7705,7 @@ const clang::TypedefType *ClangImporter::getTypeDefForCXXCFOptionsDefinition(
76977705

76987706
bool importer::requiresCPlusPlus(const clang::Module *module) {
76997707
// The libc++ modulemap doesn't currently declare the requirement.
7700-
if (module->getTopLevelModuleName() == "std")
7701-
return true;
7702-
// In recent libc++ versions the module is split into multiple top-level
7703-
// modules (std_vector, std_utility, etc).
7704-
if (module->getTopLevelModule()->IsSystem &&
7705-
module->getTopLevelModuleName().starts_with("std_"))
7708+
if (isCxxStdModule(module))
77067709
return true;
77077710

77087711
// Modulemaps often declare the requirement for the top-level module only.
@@ -7716,6 +7719,18 @@ bool importer::requiresCPlusPlus(const clang::Module *module) {
77167719
});
77177720
}
77187721

7722+
bool importer::isCxxStdModule(const clang::Module *module) {
7723+
if (module->getTopLevelModuleName() == "std")
7724+
return true;
7725+
// In recent libc++ versions the module is split into multiple top-level
7726+
// modules (std_vector, std_utility, etc).
7727+
if (module->getTopLevelModule()->IsSystem &&
7728+
module->getTopLevelModuleName().starts_with("std_"))
7729+
return true;
7730+
7731+
return false;
7732+
}
7733+
77197734
llvm::Optional<clang::QualType>
77207735
importer::getCxxReferencePointeeTypeOrNone(const clang::Type *type) {
77217736
if (type->isReferenceType())

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3389,10 +3389,8 @@ namespace {
33893389
->getTopLevelModule()
33903390
->getFullModuleName() == n;
33913391
};
3392-
if (topLevelModuleEq(decl, "std") ||
3393-
(decl->getOwningModule() && decl->getOwningModule()->IsSystem &&
3394-
StringRef(decl->getOwningModule()->getTopLevelModule()->Name)
3395-
.starts_with("std_"))) {
3392+
if ((decl->getOwningModule() &&
3393+
importer::isCxxStdModule(decl->getOwningModule()))) {
33963394
if (isAlternativeCStdlibFunctionFromTextualHeader(decl)) {
33973395
return nullptr;
33983396
}

0 commit comments

Comments
 (0)