[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
This commit is contained in:
Egor Zhdan
2023-09-15 17:10:04 +01:00
parent f7c2257f51
commit 6a2f10a388
6 changed files with 27 additions and 20 deletions

View File

@@ -306,9 +306,6 @@ public:
virtual EffectiveClangContext getEffectiveClangContext( virtual EffectiveClangContext getEffectiveClangContext(
const NominalTypeDecl *nominal) = 0; const NominalTypeDecl *nominal) = 0;
virtual const clang::TypedefType *
getTypeDefForCXXCFOptionsDefinition(const clang::Decl *candidateDecl) = 0;
virtual SourceLoc importSourceLocation(clang::SourceLocation loc) = 0; virtual SourceLoc importSourceLocation(clang::SourceLocation loc) = 0;
}; };

View File

@@ -603,8 +603,8 @@ public:
/// Enable the symbolic import experimental feature for the given callback. /// Enable the symbolic import experimental feature for the given callback.
void withSymbolicFeatureEnabled(llvm::function_ref<void(void)> callback); void withSymbolicFeatureEnabled(llvm::function_ref<void(void)> callback);
const clang::TypedefType *getTypeDefForCXXCFOptionsDefinition( static const clang::TypedefType *getTypedefForCXXCFOptionsDefinition(
const clang::Decl *candidateDecl) override; const clang::Decl *candidateDecl, const ASTContext &ctx);
SourceLoc importSourceLocation(clang::SourceLocation loc) override; SourceLoc importSourceLocation(clang::SourceLocation loc) override;
}; };

View File

@@ -2541,8 +2541,8 @@ ASTMangler::getTypeDefForCXXCFOptionsDefinition(const ValueDecl *decl) {
if (!clangDecl) if (!clangDecl)
return nullptr; return nullptr;
const auto &clangModuleLoader = decl->getASTContext().getClangModuleLoader(); auto &ctx = decl->getASTContext();
return clangModuleLoader->getTypeDefForCXXCFOptionsDefinition(clangDecl); return ClangImporter::getTypedefForCXXCFOptionsDefinition(clangDecl, ctx);
} }
const clang::NamedDecl * const clang::NamedDecl *

View File

@@ -7022,26 +7022,23 @@ void ClangImporter::withSymbolicFeatureEnabled(
oldImportSymbolicCXXDecls.get()); oldImportSymbolicCXXDecls.get());
} }
const clang::TypedefType *ClangImporter::getTypeDefForCXXCFOptionsDefinition( const clang::TypedefType *ClangImporter::getTypedefForCXXCFOptionsDefinition(
const clang::Decl *candidateDecl) { const clang::Decl *candidateDecl, const ASTContext &ctx) {
if (!ctx.LangOpts.EnableCXXInterop)
if (!Impl.SwiftContext.LangOpts.EnableCXXInterop)
return nullptr; return nullptr;
auto enumDecl = dyn_cast<clang::EnumDecl>(candidateDecl); auto enumDecl = dyn_cast<clang::EnumDecl>(candidateDecl);
if (!enumDecl) if (!enumDecl)
return nullptr; return nullptr;
if (!enumDecl->getDeclName().isEmpty()) if (!enumDecl->getDeclName().isEmpty())
return nullptr; return nullptr;
const clang::ElaboratedType *elaboratedType = const clang::ElaboratedType *elaboratedType =
dyn_cast<clang::ElaboratedType>(enumDecl->getIntegerType().getTypePtr()); enumDecl->getIntegerType()->getAs<clang::ElaboratedType>();
if (auto typedefType = if (auto typedefType =
elaboratedType elaboratedType
? dyn_cast<clang::TypedefType>(elaboratedType->desugar()) ? dyn_cast<clang::TypedefType>(elaboratedType->desugar())
: dyn_cast<clang::TypedefType>( : enumDecl->getIntegerType()->getAs<clang::TypedefType>()) {
enumDecl->getIntegerType().getTypePtr())) {
auto enumExtensibilityAttr = auto enumExtensibilityAttr =
elaboratedType elaboratedType
? enumDecl->getAttr<clang::EnumExtensibilityAttr>() ? enumDecl->getAttr<clang::EnumExtensibilityAttr>()
@@ -7054,8 +7051,13 @@ const clang::TypedefType *ClangImporter::getTypeDefForCXXCFOptionsDefinition(
enumExtensibilityAttr->getExtensibility() == enumExtensibilityAttr->getExtensibility() ==
clang::EnumExtensibilityAttr::Open && clang::EnumExtensibilityAttr::Open &&
hasFlagEnumAttr) { hasFlagEnumAttr) {
return Impl.isUnavailableInSwift(typedefType->getDecl()) ? typedefType // Make sure the typedef is marked as unavailable in Swift.
: nullptr; auto typedefDecl = typedefType->getDecl();
for (auto *attr :
typedefDecl->specific_attrs<clang::AvailabilityAttr>()) {
if (attr->getPlatform()->getName() == "swift")
return typedefType;
}
} }
} }

View File

@@ -2656,9 +2656,8 @@ ArgumentAttrs ClangImporter::Implementation::inferDefaultArgument(
if (declIter != declsInContext.end()) { if (declIter != declsInContext.end()) {
if (auto enumDecl = dyn_cast<clang::EnumDecl>(*declIter)) { if (auto enumDecl = dyn_cast<clang::EnumDecl>(*declIter)) {
if (auto cfOptionsTy = if (auto cfOptionsTy =
nameImporter.getContext() ClangImporter::getTypedefForCXXCFOptionsDefinition(
.getClangModuleLoader() enumDecl, nameImporter.getContext())) {
->getTypeDefForCXXCFOptionsDefinition(enumDecl)) {
if (cfOptionsTy->getDecl() == typedefDecl) { if (cfOptionsTy->getDecl() == typedefDecl) {
auto enumName = typedefDecl->getName(); auto enumName = typedefDecl->getName();
ArgumentAttrs argumentAttrs(DefaultArgumentKind::None, true, ArgumentAttrs argumentAttrs(DefaultArgumentKind::None, true,

View File

@@ -1,7 +1,16 @@
// RUN: rm -rf %t
// RUN: mkdir -p %t/pch
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -enable-objc-interop -enable-experimental-cxx-interop // RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -enable-objc-interop -enable-experimental-cxx-interop
// RUN: %target-swift-frontend -emit-pch -enable-objc-interop -enable-experimental-cxx-interop -o %t/pch/customNSOptions.pch %S/Inputs/customNSOptions.h
// 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
// REQUIRES: objc_interop // REQUIRES: objc_interop
#if !BRIDGING_HEADER
import CustomNSOptions import CustomNSOptions
#endif
let flags1: MyControlFlags = [] let flags1: MyControlFlags = []
let flags2: MyControlFlags = [.first] let flags2: MyControlFlags = [.first]