Skip to content

Commit c1ff2c3

Browse files
authored
Merge pull request #78057 from swiftlang/egorzhdan/relax-cxx-resilience
[cxx-interop] Allow more C++ decls in public Swift interfaces
2 parents ab5ad10 + e67f2b7 commit c1ff2c3

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

lib/Sema/TypeCheckAccess.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,6 +1828,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
18281828
}
18291829
};
18301830

1831+
bool isFragileClangDecl(const clang::Decl *decl);
1832+
18311833
bool isFragileClangType(clang::QualType type) {
18321834
if (type.isNull())
18331835
return true;
@@ -1842,20 +1844,21 @@ bool isFragileClangType(clang::QualType type) {
18421844
// Pointers to non-fragile types are non-fragile.
18431845
if (underlyingTypePtr->isPointerType())
18441846
return isFragileClangType(underlyingTypePtr->getPointeeType());
1847+
if (auto tagDecl = underlyingTypePtr->getAsTagDecl())
1848+
return isFragileClangDecl(tagDecl);
18451849
return true;
18461850
}
18471851

1848-
bool isFragileClangNode(const ClangNode &node) {
1849-
auto *decl = node.getAsDecl();
1850-
if (!decl)
1851-
return false;
1852+
bool isFragileClangDecl(const clang::Decl *decl) {
18521853
// Namespaces by themselves don't impact ABI.
18531854
if (isa<clang::NamespaceDecl>(decl))
18541855
return false;
18551856
// Objective-C type declarations are compatible with library evolution.
18561857
if (isa<clang::ObjCContainerDecl>(decl))
18571858
return false;
18581859
if (auto *fd = dyn_cast<clang::FunctionDecl>(decl)) {
1860+
if (auto *ctorDecl = dyn_cast<clang::CXXConstructorDecl>(fd))
1861+
return isFragileClangDecl(ctorDecl->getParent());
18591862
if (!isa<clang::CXXMethodDecl>(decl) &&
18601863
!isFragileClangType(fd->getDeclaredReturnType())) {
18611864
for (const auto *param : fd->parameters()) {
@@ -1891,9 +1894,21 @@ bool isFragileClangNode(const ClangNode &node) {
18911894
return !cxxRecordDecl->isCLike() &&
18921895
!cxxRecordDecl->getDeclContext()->isExternCContext();
18931896
}
1897+
if (auto *varDecl = dyn_cast<clang::VarDecl>(decl))
1898+
return isFragileClangType(varDecl->getType());
1899+
if (auto *fieldDecl = dyn_cast<clang::FieldDecl>(decl))
1900+
return isFragileClangType(fieldDecl->getType()) ||
1901+
isFragileClangDecl(fieldDecl->getParent());
18941902
return true;
18951903
}
18961904

1905+
bool isFragileClangNode(const ClangNode &node) {
1906+
auto *decl = node.getAsDecl();
1907+
if (!decl)
1908+
return false;
1909+
return isFragileClangDecl(decl);
1910+
}
1911+
18971912
} // end anonymous namespace
18981913

18991914
/// Returns the kind of origin, implementation-only import or SPI declaration,

test/Interop/Cxx/library-evolution/allow-c-in-cxx-mode-in-interfaces.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,24 @@ public func getMyCStruct() -> MyCStruct {
1818
return MyCStruct()
1919
}
2020

21+
extension MyCStruct {
22+
@inlinable public var y: CInt {
23+
get {
24+
return self.x
25+
}
26+
}
27+
28+
@inlinable public var anotherInstanceOfSelf: MyCStruct {
29+
get {
30+
return MyCStruct(x: self.x + 1)
31+
}
32+
}
33+
}
34+
2135
//--- main.swift
2236

2337
import UsesCLibrary
2438

2539
let _ = getMyCStruct()
40+
let _ = getMyCStruct().y
41+
let _ = getMyCStruct().anotherInstanceOfSelf

0 commit comments

Comments
 (0)