Skip to content

Commit a46a3c5

Browse files
authored
Merge pull request #39605 from zoecarver/cxx-interop-import-as-class
[cxx-interop] Implement foreign reference types.
2 parents 454c101 + fc3b3a1 commit a46a3c5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1645
-146
lines changed

include/swift/AST/Decl.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/AST/GenericParamKey.h"
2929
#include "swift/AST/IfConfigClause.h"
3030
#include "swift/AST/LayoutConstraint.h"
31+
#include "swift/AST/ReferenceCounting.h"
3132
#include "swift/AST/StorageImpl.h"
3233
#include "swift/AST/TypeAlignments.h"
3334
#include "swift/AST/TypeWalker.h"
@@ -37,10 +38,10 @@
3738
#include "swift/Basic/Compiler.h"
3839
#include "swift/Basic/Debug.h"
3940
#include "swift/Basic/InlineBitfield.h"
41+
#include "swift/Basic/Located.h"
4042
#include "swift/Basic/NullablePtr.h"
4143
#include "swift/Basic/OptionalEnum.h"
4244
#include "swift/Basic/Range.h"
43-
#include "swift/Basic/Located.h"
4445
#include "llvm/ADT/DenseSet.h"
4546
#include "llvm/Support/TrailingObjects.h"
4647
#include <type_traits>
@@ -3906,7 +3907,8 @@ class ClassDecl final : public NominalTypeDecl {
39063907
///
39073908
/// \see getForeignClassKind
39083909
bool isForeign() const {
3909-
return getForeignClassKind() != ForeignKind::Normal;
3910+
return getForeignClassKind() != ForeignKind::Normal ||
3911+
const_cast<ClassDecl *>(this)->isForeignReferenceType();
39103912
}
39113913

39123914
/// Whether the class is (known to be) a default actor.
@@ -3941,9 +3943,22 @@ class ClassDecl final : public NominalTypeDecl {
39413943
bool isNativeNSObjectSubclass() const;
39423944

39433945
/// Whether the class uses the ObjC object model (reference counting,
3944-
/// allocation, etc.) instead of the Swift model.
3945-
bool usesObjCObjectModel() const {
3946-
return checkAncestry(AncestryFlags::ObjCObjectModel);
3946+
/// allocation, etc.), the Swift model, or has no reference counting at all.
3947+
ReferenceCounting getObjectModel() {
3948+
if (isForeignReferenceType())
3949+
return ReferenceCounting::None;
3950+
3951+
if (checkAncestry(AncestryFlags::ObjCObjectModel))
3952+
return ReferenceCounting::ObjC;
3953+
3954+
return ReferenceCounting::Native;
3955+
}
3956+
3957+
LayoutConstraintKind getLayoutConstraintKind() {
3958+
if (getObjectModel() == ReferenceCounting::ObjC)
3959+
return LayoutConstraintKind::Class;
3960+
3961+
return LayoutConstraintKind::NativeClass;
39473962
}
39483963

39493964
/// Returns true if the class has designated initializers that are not listed
@@ -4065,6 +4080,11 @@ class ClassDecl final : public NominalTypeDecl {
40654080
bool hasKnownSwiftImplementation() const {
40664081
return !hasClangNode();
40674082
}
4083+
4084+
/// Used to determine if this class decl is a foriegn reference type. I.e., a
4085+
/// non-reference-counted swift reference type that was imported from a C++
4086+
/// record.
4087+
bool isForeignReferenceType();
40684088
};
40694089

40704090
/// A convenience wrapper around the \c SelfReferencePosition::Kind enum.

include/swift/AST/DiagnosticsIRGen.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,10 @@ ERROR(temporary_allocation_alignment_not_positive,none,
5959
ERROR(temporary_allocation_alignment_not_power_of_2,none,
6060
"alignment value must be a power of two", ())
6161

62+
ERROR(foreign_reference_types_unsupported,none,
63+
"attempt to use a foreign reference type in a generic context. "
64+
"Foreign reference types are currently not supported. Using foreign "
65+
"reference types in a generic context is not yet implemented.", ())
66+
6267
#define UNDEFINE_DIAGNOSTIC_MACROS
6368
#include "DefineDiagnosticMacros.h"

include/swift/AST/ReferenceCounting.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ enum class ReferenceCounting : uint8_t {
2929
/// Blocks are always ObjC reference counting compatible.
3030
ObjC,
3131

32+
/// The object has no reference counting. This is used by foreign reference
33+
/// types.
34+
None,
35+
3236
/// The object uses _Block_copy/_Block_release reference counting.
3337
///
3438
/// This is a strict subset of ObjC; all blocks are also ObjC reference

include/swift/AST/Type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,8 @@ class CanType : public Type {
488488
NominalTypeDecl *getAnyNominal() const;
489489
GenericTypeDecl *getAnyGeneric() const;
490490

491+
bool isForeignReferenceType(); // in Types.h
492+
491493
CanType getOptionalObjectType() const {
492494
return getOptionalObjectTypeImpl(*this);
493495
}

include/swift/AST/Types.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -811,16 +811,19 @@ class alignas(1 << TypeAlignInBits) TypeBase
811811

812812
/// If this is a class type or a bound generic class type, returns the
813813
/// (possibly generic) class.
814-
ClassDecl *getClassOrBoundGenericClass();
815-
814+
ClassDecl *getClassOrBoundGenericClass() const;
815+
816816
/// If this is a struct type or a bound generic struct type, returns
817817
/// the (possibly generic) class.
818818
StructDecl *getStructOrBoundGenericStruct();
819819

820820
/// If this is an enum or a bound generic enum type, returns the
821821
/// (possibly generic) enum.
822822
EnumDecl *getEnumOrBoundGenericEnum();
823-
823+
824+
/// If this is a class, check if this class is a foreign reference type.
825+
bool isForeignReferenceType();
826+
824827
/// Determine whether this type may have a superclass, which holds for
825828
/// classes, bound generic classes, and archetypes that are only instantiable
826829
/// with a class type.
@@ -6198,7 +6201,7 @@ inline bool TypeBase::canDynamicallyBeOptionalType(bool includeExistential) {
61986201
return isArchetypeOrExistential && !T.isAnyClassReferenceType();
61996202
}
62006203

6201-
inline ClassDecl *TypeBase::getClassOrBoundGenericClass() {
6204+
inline ClassDecl *TypeBase::getClassOrBoundGenericClass() const {
62026205
return getCanonicalType().getClassOrBoundGenericClass();
62036206
}
62046207

@@ -6262,8 +6265,6 @@ inline GenericTypeDecl *TypeBase::getAnyGeneric() {
62626265
return getCanonicalType().getAnyGeneric();
62636266
}
62646267

6265-
6266-
62676268
inline bool TypeBase::isBuiltinIntegerType(unsigned n) {
62686269
if (auto intTy = dyn_cast<BuiltinIntegerType>(getCanonicalType()))
62696270
return intTy->getWidth().isFixedWidth()

include/swift/ClangImporter/ClangImporterRequests.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ class CXXNamespaceMemberLookup
132132

133133
/// The input type for a record member lookup request.
134134
struct ClangRecordMemberLookupDescriptor final {
135-
StructDecl *recordDecl;
135+
NominalTypeDecl *recordDecl;
136136
DeclName name;
137137

138-
ClangRecordMemberLookupDescriptor(StructDecl *recordDecl, DeclName name)
138+
ClangRecordMemberLookupDescriptor(NominalTypeDecl *recordDecl, DeclName name)
139139
: recordDecl(recordDecl), name(name) {
140140
assert(isa<clang::RecordDecl>(recordDecl->getClangDecl()));
141141
}

include/swift/SIL/SILType.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,13 @@ class SILType {
236236
NominalTypeDecl *getNominalOrBoundGenericNominal() const {
237237
return getASTType().getNominalOrBoundGenericNominal();
238238
}
239-
239+
240+
/// If this type maps to a Swift class, check if that class is a foreign
241+
/// reference type.
242+
bool isForeignReferenceType() const {
243+
return getASTType().isForeignReferenceType();
244+
}
245+
240246
/// True if the type is an address type.
241247
bool isAddress() const { return getCategory() == SILValueCategory::Address; }
242248

lib/AST/ClangTypeConverter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,8 @@ ClangTypeConverter::visitBoundGenericType(BoundGenericType *type) {
545545
auto args = type->getGenericArgs();
546546
assert((args.size() == 1) && "Optional should have 1 generic argument.");
547547
clang::QualType innerTy = convert(args[0]);
548-
if (swift::canImportAsOptional(innerTy.getTypePtrOrNull()))
548+
if (swift::canImportAsOptional(innerTy.getTypePtrOrNull()) ||
549+
args[0]->isForeignReferenceType())
549550
return innerTy;
550551
return clang::QualType();
551552
}

lib/AST/Decl.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1957,7 +1957,11 @@ static bool isPolymorphic(const AbstractStorageDecl *storage) {
19571957
return true;
19581958

19591959
if (auto *classDecl = dyn_cast<ClassDecl>(storage->getDeclContext())) {
1960-
if (storage->isFinal() || classDecl->isFinal())
1960+
// Accesses to members of foreign reference types should be made directly
1961+
// to storage as these are references to clang records which are not allowed
1962+
// to have dynamic dispatch.
1963+
if (storage->isFinal() || classDecl->isFinal() ||
1964+
classDecl->isForeignReferenceType())
19611965
return false;
19621966

19631967
return true;
@@ -4737,6 +4741,10 @@ bool ClassDecl::walkSuperclasses(
47374741
return false;
47384742
}
47394743

4744+
bool ClassDecl::isForeignReferenceType() {
4745+
return getClangDecl() && isa<clang::RecordDecl>(getClangDecl());
4746+
}
4747+
47404748
EnumCaseDecl *EnumCaseDecl::create(SourceLoc CaseLoc,
47414749
ArrayRef<EnumElementDecl *> Elements,
47424750
DeclContext *DC) {

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4443,11 +4443,8 @@ bool GenericSignatureBuilder::updateSuperclass(
44434443
auto layoutReqSource =
44444444
source.getSource(*this, type)->viaLayout(*this, superclass);
44454445

4446-
auto layout =
4447-
LayoutConstraint::getLayoutConstraint(
4448-
superclass->getClassOrBoundGenericClass()->usesObjCObjectModel()
4449-
? LayoutConstraintKind::Class
4450-
: LayoutConstraintKind::NativeClass,
4446+
auto layout = LayoutConstraint::getLayoutConstraint(
4447+
superclass->getClassOrBoundGenericClass()->getLayoutConstraintKind(),
44514448
getASTContext());
44524449
addLayoutRequirementDirect(type, layout, layoutReqSource);
44534450
return true;

0 commit comments

Comments
 (0)