Skip to content

Commit 829b578

Browse files
committed
[cxx-interop] Refactor: do not rely on Clang module importer being available
This makes sure that we can emit a pch from a C++ header that uses `CF_OPTIONS`. rdar://112225263
1 parent f7c2257 commit 829b578

File tree

8 files changed

+58
-51
lines changed

8 files changed

+58
-51
lines changed

include/swift/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,9 @@ class ASTContext final {
833833
/// and results.
834834
const clang::Type *getClangTypeForIRGen(Type ty);
835835

836+
const clang::TypedefType *
837+
getTypedefForCXXCFOptionsDefinition(const clang::Decl *candidateDecl);
838+
836839
/// Determine whether the given Swift type is representable in a
837840
/// given foreign language.
838841
ForeignRepresentationInfo

include/swift/AST/ClangModuleLoader.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,6 @@ class ClangModuleLoader : public ModuleLoader {
306306
virtual EffectiveClangContext getEffectiveClangContext(
307307
const NominalTypeDecl *nominal) = 0;
308308

309-
virtual const clang::TypedefType *
310-
getTypeDefForCXXCFOptionsDefinition(const clang::Decl *candidateDecl) = 0;
311-
312309
virtual SourceLoc importSourceLocation(clang::SourceLocation loc) = 0;
313310
};
314311

include/swift/ClangImporter/ClangImporter.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,6 @@ class ClangImporter final : public ClangModuleLoader {
603603
/// Enable the symbolic import experimental feature for the given callback.
604604
void withSymbolicFeatureEnabled(llvm::function_ref<void(void)> callback);
605605

606-
const clang::TypedefType *getTypeDefForCXXCFOptionsDefinition(
607-
const clang::Decl *candidateDecl) override;
608-
609606
SourceLoc importSourceLocation(clang::SourceLocation loc) override;
610607
};
611608

lib/AST/ASTContext.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5732,6 +5732,48 @@ ASTContext::getClangTypeForIRGen(Type ty) {
57325732
return getClangTypeConverter().convert(ty).getTypePtrOrNull();
57335733
}
57345734

5735+
const clang::TypedefType *ASTContext::getTypedefForCXXCFOptionsDefinition(
5736+
const clang::Decl *candidateDecl) {
5737+
if (!LangOpts.EnableCXXInterop)
5738+
return nullptr;
5739+
5740+
auto enumDecl = dyn_cast<clang::EnumDecl>(candidateDecl);
5741+
if (!enumDecl)
5742+
return nullptr;
5743+
if (!enumDecl->getDeclName().isEmpty())
5744+
return nullptr;
5745+
5746+
const clang::ElaboratedType *elaboratedType =
5747+
enumDecl->getIntegerType()->getAs<clang::ElaboratedType>();
5748+
if (auto typedefType =
5749+
elaboratedType
5750+
? dyn_cast<clang::TypedefType>(elaboratedType->desugar())
5751+
: enumDecl->getIntegerType()->getAs<clang::TypedefType>()) {
5752+
auto enumExtensibilityAttr =
5753+
elaboratedType
5754+
? enumDecl->getAttr<clang::EnumExtensibilityAttr>()
5755+
: typedefType->getDecl()->getAttr<clang::EnumExtensibilityAttr>();
5756+
const bool hasFlagEnumAttr =
5757+
elaboratedType ? enumDecl->hasAttr<clang::FlagEnumAttr>()
5758+
: typedefType->getDecl()->hasAttr<clang::FlagEnumAttr>();
5759+
5760+
if (enumExtensibilityAttr &&
5761+
enumExtensibilityAttr->getExtensibility() ==
5762+
clang::EnumExtensibilityAttr::Open &&
5763+
hasFlagEnumAttr) {
5764+
// Make sure the typedef is marked as unavailable in Swift.
5765+
auto typedefDecl = typedefType->getDecl();
5766+
for (auto *attr :
5767+
typedefDecl->specific_attrs<clang::AvailabilityAttr>()) {
5768+
if (attr->getPlatform()->getName() == "swift")
5769+
return typedefType;
5770+
}
5771+
}
5772+
}
5773+
5774+
return nullptr;
5775+
}
5776+
57355777
GenericParamList *ASTContext::getSelfGenericParamList(DeclContext *dc) const {
57365778
auto *theParamList = getImpl().SelfGenericParamList;
57375779
if (theParamList)

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,8 +2541,8 @@ ASTMangler::getTypeDefForCXXCFOptionsDefinition(const ValueDecl *decl) {
25412541
if (!clangDecl)
25422542
return nullptr;
25432543

2544-
const auto &clangModuleLoader = decl->getASTContext().getClangModuleLoader();
2545-
return clangModuleLoader->getTypeDefForCXXCFOptionsDefinition(clangDecl);
2544+
auto &ctx = decl->getASTContext();
2545+
return ctx.getTypedefForCXXCFOptionsDefinition(clangDecl);
25462546
}
25472547

25482548
const clang::NamedDecl *

lib/ClangImporter/ClangImporter.cpp

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7022,46 +7022,6 @@ void ClangImporter::withSymbolicFeatureEnabled(
70227022
oldImportSymbolicCXXDecls.get());
70237023
}
70247024

7025-
const clang::TypedefType *ClangImporter::getTypeDefForCXXCFOptionsDefinition(
7026-
const clang::Decl *candidateDecl) {
7027-
7028-
if (!Impl.SwiftContext.LangOpts.EnableCXXInterop)
7029-
return nullptr;
7030-
7031-
auto enumDecl = dyn_cast<clang::EnumDecl>(candidateDecl);
7032-
if (!enumDecl)
7033-
return nullptr;
7034-
7035-
if (!enumDecl->getDeclName().isEmpty())
7036-
return nullptr;
7037-
7038-
const clang::ElaboratedType *elaboratedType =
7039-
dyn_cast<clang::ElaboratedType>(enumDecl->getIntegerType().getTypePtr());
7040-
if (auto typedefType =
7041-
elaboratedType
7042-
? dyn_cast<clang::TypedefType>(elaboratedType->desugar())
7043-
: dyn_cast<clang::TypedefType>(
7044-
enumDecl->getIntegerType().getTypePtr())) {
7045-
auto enumExtensibilityAttr =
7046-
elaboratedType
7047-
? enumDecl->getAttr<clang::EnumExtensibilityAttr>()
7048-
: typedefType->getDecl()->getAttr<clang::EnumExtensibilityAttr>();
7049-
const bool hasFlagEnumAttr =
7050-
elaboratedType ? enumDecl->hasAttr<clang::FlagEnumAttr>()
7051-
: typedefType->getDecl()->hasAttr<clang::FlagEnumAttr>();
7052-
7053-
if (enumExtensibilityAttr &&
7054-
enumExtensibilityAttr->getExtensibility() ==
7055-
clang::EnumExtensibilityAttr::Open &&
7056-
hasFlagEnumAttr) {
7057-
return Impl.isUnavailableInSwift(typedefType->getDecl()) ? typedefType
7058-
: nullptr;
7059-
}
7060-
}
7061-
7062-
return nullptr;
7063-
}
7064-
70657025
bool importer::requiresCPlusPlus(const clang::Module *module) {
70667026
// The libc++ modulemap doesn't currently declare the requirement.
70677027
if (module->getTopLevelModuleName() == "std")

lib/ClangImporter/ImportType.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2656,9 +2656,8 @@ ArgumentAttrs ClangImporter::Implementation::inferDefaultArgument(
26562656
if (declIter != declsInContext.end()) {
26572657
if (auto enumDecl = dyn_cast<clang::EnumDecl>(*declIter)) {
26582658
if (auto cfOptionsTy =
2659-
nameImporter.getContext()
2660-
.getClangModuleLoader()
2661-
->getTypeDefForCXXCFOptionsDefinition(enumDecl)) {
2659+
nameImporter.getContext().getTypedefForCXXCFOptionsDefinition(
2660+
enumDecl)) {
26622661
if (cfOptionsTy->getDecl() == typedefDecl) {
26632662
auto enumName = typedefDecl->getName();
26642663
ArgumentAttrs argumentAttrs(DefaultArgumentKind::None, true,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t/pch
3+
14
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -enable-objc-interop -enable-experimental-cxx-interop
5+
6+
// RUN: %target-swift-frontend -emit-pch -enable-objc-interop -enable-experimental-cxx-interop -o %t/pch/customNSOptions.pch %S/Inputs/customNSOptions.h
7+
// RUN: %target-typecheck-verify-swift -D BRIDGING_HEADER -I %S/Inputs -import-objc-header %t/pch/customNSOptions.pch -enable-objc-interop -enable-experimental-cxx-interop %s
8+
29
// REQUIRES: objc_interop
310

11+
#if !BRIDGING_HEADER
412
import CustomNSOptions
13+
#endif
514

615
let flags1: MyControlFlags = []
716
let flags2: MyControlFlags = [.first]

0 commit comments

Comments
 (0)